From 6519136ad8a77778da742c12f026c3e41fd50cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=B6zkan=20gezmi=C5=9F?= Date: Sat, 22 Nov 2025 15:55:59 +0300 Subject: [PATCH 1/2] Replace fromtimestamp with epoch-offset to support negative Unix timestamps on Windows and restore full historical XAUUSD data. --- README.md | 14 ++++++++++++++ tvDatafeed/main.py | 20 +++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 66c5d8f..1f15a09 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # **NOTE** +> **This is an improved fork of TvDatafeed.** +> +> - Windows compatibility: Dates before 1970 now work correctly when fetching historical data. +> - Nologin method: Can fetch more than 5000 bars for some symbols (typically daily timeframe, e.g., XAUUSD:OANDA). +> - See below for more details and usage notes. + +--- + +# **NOTE** + This is a fork of the original [TvDatafeed](https://github.com/rongardF/tvdatafeed.git) project by StreamAlpha. This fork has live data retrieving feature implemented. More information about this will be found in the TvDatafeedLive section down below in the README. @@ -57,6 +67,10 @@ tv = TvDatafeed() when using without login, following warning will be shown `you are using nologin method, data you access may be limited` +**Note:** The nologin method now works for more than 5000 bars for some symbols (e.g., `XAUUSD:OANDA`). Try your symbol to check availability. + +This extended limit is typically available for the daily timeframe. Other intervals may still be restricted. + --- ## Getting Data diff --git a/tvDatafeed/main.py b/tvDatafeed/main.py index de77ebc..6e669f8 100644 --- a/tvDatafeed/main.py +++ b/tvDatafeed/main.py @@ -133,14 +133,28 @@ def __send_message(self, func, args): @staticmethod def __create_df(raw_data, symbol): try: - out = re.search('"s":\[(.+?)\}\]', raw_data).group(1) + out = re.search(r'"s":\[(.+?)\}\]', raw_data).group(1) x = out.split(',{"') data = list() volume_data = True + epoch = datetime.datetime(1970, 1, 1) + for xi in x: - xi = re.split("\[|:|,|\]", xi) - ts = datetime.datetime.fromtimestamp(float(xi[4])) + xi = re.split(r"\[|:|,|\]", xi) + + try: + ts_raw = float(xi[4]) + except ValueError: + # malformed row, skip + continue + + try: + # works for negative timestamps too (pre-1970) + ts = epoch + datetime.timedelta(0, ts_raw) + except OverflowError: + # insane timestamp, skip + continue row = [ts] From 6d0f6315165c982550eeccfdbdade1fde11141e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=B6zkan=20gezmi=C5=9F?= Date: Sat, 22 Nov 2025 17:53:24 +0300 Subject: [PATCH 2/2] Replace fromtimestamp with epoch offset to support negative Unix timestamps on Windows --- tvDatafeed/main.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tvDatafeed/main.py b/tvDatafeed/main.py index 86bb0be..d4d6b3d 100644 --- a/tvDatafeed/main.py +++ b/tvDatafeed/main.py @@ -162,14 +162,35 @@ def __send_message(self, func, args): @staticmethod def __parse_data(raw_data, is_return_dataframe:bool) -> List[List]: try: - out = re.search(r""""s":\[(.+?)\}\]""", raw_data).group(1) + out = re.search(r'"s":\[(.+?)\}\]', raw_data).group(1) x = out.split(',{"') data = list() volume_data = True + epoch = datetime.datetime(1970, 1, 1) + for xi in x: xi = re.split(r"\[|:|,|\]", xi) - ts = datetime.datetime.fromtimestamp(float(xi[4])) if is_return_dataframe else int(xi[4].split('.')[0]) + + if is_return_dataframe: + try: + ts_raw = float(xi[4]) + except ValueError: + # malformed row, skip + continue + + try: + # works for negative timestamps too (pre-1970) + ts = epoch + datetime.timedelta(0, ts_raw) + except OverflowError: + # insane timestamp, skip + continue + else: + try: + ts = int(xi[4].split('.')[0]) + except ValueError: + # malformed row, skip + continue row = [ts]