From 16a516a882f8936df3e4191e0311cedbc9d7a120 Mon Sep 17 00:00:00 2001 From: Italo Date: Wed, 19 Jan 2022 01:50:15 +0000 Subject: [PATCH 01/49] added plot functionality --- freqtrade/optimize/hyperopt.py | 65 +++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 209edd157..cfbc3ea82 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -32,6 +32,11 @@ from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4 from freqtrade.optimize.hyperopt_tools import HyperoptTools, hyperopt_serializer from freqtrade.optimize.optimize_reports import generate_strategy_stats from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver +from skopt.plots import plot_convergence, plot_regret, plot_evaluations, plot_objective +import matplotlib.pyplot as plt +import numpy as np +import random +from sklearn.base import clone # Suppress scikit-learn FutureWarnings from skopt @@ -476,7 +481,12 @@ class Hyperopt: asked = self.opt.ask(n_points=current_jobs) f_val = self.run_optimizer_parallel(parallel, asked, i) - self.opt.tell(asked, [v['loss'] for v in f_val]) + res = self.opt.tell(asked, [v['loss'] for v in f_val]) + + self.plot_optimizer(res, path='user_data/scripts', convergence=False, regret=False, mse=True, objective=True, jobs=jobs) + + if res.models and hasattr(res.models[-1], "kernel_"): + print(f'kernel: {res.models[-1].kernel_}') # Calculate progressbar outputs for j, val in enumerate(f_val): @@ -521,3 +531,56 @@ class Hyperopt: # This is printed when Ctrl+C is pressed quickly, before first epochs have # a chance to be evaluated. print("No epochs evaluated yet, no best result.") + + def plot_mse(self, res, ax, jobs): + if len(res.x_iters) < 10: + return + + if not hasattr(self, 'mse_list'): + self.mse_list = [] + + model = clone(res.models[-1]) + i_subset = random.sample(range(len(res.x_iters)), 100) if len(res.x_iters) > 100 else range(len(res.x_iters)) + + i_train = random.sample(i_subset, round(.8*len(i_subset))) # get 80% random indices + x_train = [x for i, x in enumerate(res.x_iters) if i in i_train] + y_train = [y for i, y in enumerate(res.func_vals) if i in i_train] + + i_test = [i for i in i_subset if i not in i_train] # get 20% random indices + x_test = [x for i, x in enumerate(res.x_iters) if i in i_test] + y_test = [y for i, y in enumerate(res.func_vals) if i in i_test] + model.fit(np.array(x_train), np.array(y_train)) + y_pred, sigma = model.predict(np.array(x_test), return_std=True) + mse = np.mean((y_test - y_pred) ** 2) + self.mse_list.append(mse) + + ax.plot(range(INITIAL_POINTS, INITIAL_POINTS + jobs * len(self.mse_list), jobs), self.mse_list, label='MSE', marker=".", markersize=12, lw=2) + + def plot_optimizer(self, res, path, jobs, convergence=True, regret=True, evaluations=True, objective=True, mse=True): + path = Path(path) + if convergence: + ax = plot_convergence(res) + ax.flatten()[0].figure.savefig(path / 'convergence.png') + + if regret: + ax = plot_regret(res) + ax.flatten()[0].figure.savefig(path / 'regret.png') + + if evaluations: +# print('evaluations') + ax = plot_evaluations(res) + ax.flatten()[0].figure.savefig(path / 'evaluations.png') + + if objective and res.models: +# print('objective') + ax = plot_objective(res, sample_source='result', n_samples=50, n_points=10) + ax.flatten()[0].figure.savefig(path / 'objective.png') + + if mse and res.models: +# print('mse') + fig, ax = plt.subplots() + ax.set_ylabel('MSE') + ax.set_xlabel('Epoch') + ax.set_title('MSE') + ax = self.plot_mse(res, ax, jobs) + fig.savefig(path / 'mse.png') From 2eec51bfcbdc27279b21390cc5fa3ee7069233f3 Mon Sep 17 00:00:00 2001 From: Italo Date: Wed, 19 Jan 2022 02:00:14 +0000 Subject: [PATCH 02/49] Update requirements-hyperopt.txt --- requirements-hyperopt.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 122243bf2..57bb25e2c 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -8,3 +8,4 @@ scikit-optimize==0.9.0 filelock==3.4.2 joblib==1.1.0 progressbar2==4.0.0 +matplotlib \ No newline at end of file From 52206e6f41926ef89f7d9c051c377de9fc16f7ff Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Thu, 20 Jan 2022 17:15:05 +0000 Subject: [PATCH 03/49] add buy tag to plot --- freqtrade/plot/plotting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 3769d4c5a..b8a747105 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -236,6 +236,7 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: if trades is not None and len(trades) > 0: # Create description for sell summarizing the trade trades['desc'] = trades.apply(lambda row: f"{row['profit_ratio']:.2%}, " + f"{row['buy_tag']}, " f"{row['sell_reason']}, " f"{row['trade_duration']} min", axis=1) From 0ce6c150ff6e1dfdba0a3a7bdda97288fd77eaa0 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sat, 22 Jan 2022 14:06:45 +0000 Subject: [PATCH 04/49] set stoploss at trade creation --- freqtrade/optimize/backtesting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ae4001f5f..9cfeedd75 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -521,6 +521,7 @@ class Backtesting: exchange='backtesting', orders=[] ) + trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss, initial=True) order = Order( ft_is_open=False, From a2fb241a3b210f100db025815fb3542410476b45 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Mon, 24 Jan 2022 01:35:42 +0000 Subject: [PATCH 05/49] increase initial points to 64 --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index cfbc3ea82..f49f3f307 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -50,7 +50,7 @@ progressbar.streams.wrap_stdout() logger = logging.getLogger(__name__) -INITIAL_POINTS = 30 +INITIAL_POINTS = 64 # Keep no more than SKOPT_MODEL_QUEUE_SIZE models # in the skopt model queue, to optimize memory consumption From 992eac9efaf8c7bdc98abd0c350ccb8930555cd0 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sat, 5 Feb 2022 17:36:19 +0000 Subject: [PATCH 06/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 60c54fe40..5e59135bd 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -50,7 +50,7 @@ progressbar.streams.wrap_stdout() logger = logging.getLogger(__name__) -INITIAL_POINTS = 64 +INITIAL_POINTS = 32 # Keep no more than SKOPT_MODEL_QUEUE_SIZE models # in the skopt model queue, to optimize memory consumption @@ -532,7 +532,8 @@ class Hyperopt: # a chance to be evaluated. print("No epochs evaluated yet, no best result.") - def plot_mse(self, res, ax, jobs): + def plot_mse(self, res, ax, jobs): + from sklearn.model_selection import cross_val_score if len(res.x_iters) < 10: return @@ -540,19 +541,26 @@ class Hyperopt: self.mse_list = [] model = clone(res.models[-1]) - i_subset = random.sample(range(len(res.x_iters)), 100) if len(res.x_iters) > 100 else range(len(res.x_iters)) + # i_subset = random.sample(range(len(res.x_iters)), 100) if len(res.x_iters) > 100 else range(len(res.x_iters)) - i_train = random.sample(i_subset, round(.8*len(i_subset))) # get 80% random indices - x_train = [x for i, x in enumerate(res.x_iters) if i in i_train] - y_train = [y for i, y in enumerate(res.func_vals) if i in i_train] + # i_train = random.sample(i_subset, round(.8*len(i_subset))) # get 80% random indices + # x_train = [x for i, x in enumerate(res.x_iters) if i in i_train] + # y_train = [y for i, y in enumerate(res.func_vals) if i in i_train] - i_test = [i for i in i_subset if i not in i_train] # get 20% random indices - x_test = [x for i, x in enumerate(res.x_iters) if i in i_test] - y_test = [y for i, y in enumerate(res.func_vals) if i in i_test] - model.fit(np.array(x_train), np.array(y_train)) - y_pred, sigma = model.predict(np.array(x_test), return_std=True) - mse = np.mean((y_test - y_pred) ** 2) - self.mse_list.append(mse) + # i_test = [i for i in i_subset if i not in i_train] # get 20% random indices + # x_test = [x for i, x in enumerate(res.x_iters) if i in i_test] + # y_test = [y for i, y in enumerate(res.func_vals) if i in i_test] + model.fit(res.x_iters, res.func_vals) + # Perform a cross-validation estimate of the coefficient of determination using + # the cross_validation module using all CPUs available on the machine + # K = 5 # folds + R2 = cross_val_score(model, X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() + print(f'R2: {R2}') + R2 = R2 if R2 > -5 else -5 + self.mse_list.append(R2) + # y_pred, sigma = model.predict(np.array(x_test), return_std=True) + # mse = np.mean((y_test - y_pred) ** 2) + # self.mse_list.append(mse) ax.plot(range(INITIAL_POINTS, INITIAL_POINTS + jobs * len(self.mse_list), jobs), self.mse_list, label='MSE', marker=".", markersize=12, lw=2) From 6a4cae1f8c2f7569dff9156431e36dd1162810b9 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 6 Feb 2022 00:17:48 +0000 Subject: [PATCH 07/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 5e59135bd..25055d06c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -540,7 +540,7 @@ class Hyperopt: if not hasattr(self, 'mse_list'): self.mse_list = [] - model = clone(res.models[-1]) + # model = clone(res.models[-1]) # i_subset = random.sample(range(len(res.x_iters)), 100) if len(res.x_iters) > 100 else range(len(res.x_iters)) # i_train = random.sample(i_subset, round(.8*len(i_subset))) # get 80% random indices @@ -550,11 +550,11 @@ class Hyperopt: # i_test = [i for i in i_subset if i not in i_train] # get 20% random indices # x_test = [x for i, x in enumerate(res.x_iters) if i in i_test] # y_test = [y for i, y in enumerate(res.func_vals) if i in i_test] - model.fit(res.x_iters, res.func_vals) + # model.fit(res.x_iters, res.func_vals) # Perform a cross-validation estimate of the coefficient of determination using # the cross_validation module using all CPUs available on the machine # K = 5 # folds - R2 = cross_val_score(model, X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() + R2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() print(f'R2: {R2}') R2 = R2 if R2 > -5 else -5 self.mse_list.append(R2) From 6c1729e20b6ea87d341ad8b2e204409c7ded5be6 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 6 Feb 2022 01:07:30 +0000 Subject: [PATCH 08/49] ignore warnings --- freqtrade/optimize/hyperopt.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 25055d06c..d99c2b3b0 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -554,7 +554,9 @@ class Hyperopt: # Perform a cross-validation estimate of the coefficient of determination using # the cross_validation module using all CPUs available on the machine # K = 5 # folds - R2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + R2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() print(f'R2: {R2}') R2 = R2 if R2 > -5 else -5 self.mse_list.append(R2) From adf8f6b2d503649effaed161e81108df10483a76 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 6 Feb 2022 10:33:49 +0000 Subject: [PATCH 09/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 56 +++++++++++----------------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index d99c2b3b0..19132a14a 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -32,18 +32,17 @@ from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4 from freqtrade.optimize.hyperopt_tools import HyperoptTools, hyperopt_serializer from freqtrade.optimize.optimize_reports import generate_strategy_stats from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver -from skopt.plots import plot_convergence, plot_regret, plot_evaluations, plot_objective import matplotlib.pyplot as plt import numpy as np import random -from sklearn.base import clone - # Suppress scikit-learn FutureWarnings from skopt with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=FutureWarning) from skopt import Optimizer from skopt.space import Dimension + from sklearn.model_selection import cross_val_score + from skopt.plots import plot_convergence, plot_regret, plot_evaluations, plot_objective progressbar.streams.wrap_stderr() progressbar.streams.wrap_stdout() @@ -483,7 +482,7 @@ class Hyperopt: f_val = self.run_optimizer_parallel(parallel, asked, i) res = self.opt.tell(asked, [v['loss'] for v in f_val]) - self.plot_optimizer(res, path='user_data/scripts', convergence=False, regret=False, mse=True, objective=True, jobs=jobs) + self.plot_optimizer(res, path='user_data/scripts', convergence=False, regret=False, r2=True, objective=True, jobs=jobs) if res.models and hasattr(res.models[-1], "kernel_"): print(f'kernel: {res.models[-1].kernel_}') @@ -532,41 +531,21 @@ class Hyperopt: # a chance to be evaluated. print("No epochs evaluated yet, no best result.") - def plot_mse(self, res, ax, jobs): - from sklearn.model_selection import cross_val_score + def plot_r2(self, res, ax, jobs): if len(res.x_iters) < 10: return - if not hasattr(self, 'mse_list'): - self.mse_list = [] + if not hasattr(self, 'r2_list'): + self.r2_list = [] - # model = clone(res.models[-1]) - # i_subset = random.sample(range(len(res.x_iters)), 100) if len(res.x_iters) > 100 else range(len(res.x_iters)) - - # i_train = random.sample(i_subset, round(.8*len(i_subset))) # get 80% random indices - # x_train = [x for i, x in enumerate(res.x_iters) if i in i_train] - # y_train = [y for i, y in enumerate(res.func_vals) if i in i_train] - - # i_test = [i for i in i_subset if i not in i_train] # get 20% random indices - # x_test = [x for i, x in enumerate(res.x_iters) if i in i_test] - # y_test = [y for i, y in enumerate(res.func_vals) if i in i_test] - # model.fit(res.x_iters, res.func_vals) - # Perform a cross-validation estimate of the coefficient of determination using - # the cross_validation module using all CPUs available on the machine - # K = 5 # folds - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - R2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, cv=5, n_jobs=jobs).mean() - print(f'R2: {R2}') - R2 = R2 if R2 > -5 else -5 - self.mse_list.append(R2) - # y_pred, sigma = model.predict(np.array(x_test), return_std=True) - # mse = np.mean((y_test - y_pred) ** 2) - # self.mse_list.append(mse) + r2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, scoring='r2', cv=5, n_jobs=jobs).mean() + print(f'R2: {r2}') + r2 = r2 if r2 > -5 else -5 + self.r2_list.append(r2) - ax.plot(range(INITIAL_POINTS, INITIAL_POINTS + jobs * len(self.mse_list), jobs), self.mse_list, label='MSE', marker=".", markersize=12, lw=2) + ax.plot(range(INITIAL_POINTS, INITIAL_POINTS + jobs * len(self.r2_list), jobs), self.r2_list, label='R2', marker=".", markersize=12, lw=2) - def plot_optimizer(self, res, path, jobs, convergence=True, regret=True, evaluations=True, objective=True, mse=True): + def plot_optimizer(self, res, path, jobs, convergence=True, regret=True, evaluations=True, objective=True, r2=True): path = Path(path) if convergence: ax = plot_convergence(res) @@ -586,11 +565,10 @@ class Hyperopt: ax = plot_objective(res, sample_source='result', n_samples=50, n_points=10) ax.flatten()[0].figure.savefig(path / 'objective.png') - if mse and res.models: -# print('mse') + if r2 and res.models: fig, ax = plt.subplots() - ax.set_ylabel('MSE') + ax.set_ylabel('R2') ax.set_xlabel('Epoch') - ax.set_title('MSE') - ax = self.plot_mse(res, ax, jobs) - fig.savefig(path / 'mse.png') + ax.set_title('R2') + ax = self.plot_r2(res, ax, jobs) + fig.savefig(path / 'r2.png') From d03378b1df7c76b7d1931c174af9197abf977357 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 6 Feb 2022 15:32:59 +0000 Subject: [PATCH 10/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 19132a14a..ba32943cb 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -538,7 +538,10 @@ class Hyperopt: if not hasattr(self, 'r2_list'): self.r2_list = [] - r2 = cross_val_score(res.models[-1], X=res.x_iters, y=res.func_vals, scoring='r2', cv=5, n_jobs=jobs).mean() + model = res.models[-1] + model.criterion = 'squared_error' + + r2 = cross_val_score(model, X=res.x_iters, y=res.func_vals, scoring='r2', cv=5, n_jobs=jobs).mean() print(f'R2: {r2}') r2 = r2 if r2 > -5 else -5 self.r2_list.append(r2) From d2a54483050a587facad827afa6d3177cd68d702 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Fri, 11 Mar 2022 17:38:32 +0000 Subject: [PATCH 11/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ba32943cb..aa255967e 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -486,6 +486,7 @@ class Hyperopt: if res.models and hasattr(res.models[-1], "kernel_"): print(f'kernel: {res.models[-1].kernel_}') + print(datetime.now()) # Calculate progressbar outputs for j, val in enumerate(f_val): @@ -542,7 +543,6 @@ class Hyperopt: model.criterion = 'squared_error' r2 = cross_val_score(model, X=res.x_iters, y=res.func_vals, scoring='r2', cv=5, n_jobs=jobs).mean() - print(f'R2: {r2}') r2 = r2 if r2 > -5 else -5 self.r2_list.append(r2) From 89aae71c32c79d3cb3e21382ad237f86406d5cb2 Mon Sep 17 00:00:00 2001 From: Kavinkumar <33546454+mkavinkumar1@users.noreply.github.com> Date: Tue, 15 Mar 2022 11:41:39 +0530 Subject: [PATCH 12/49] correcting docs for pricing of ask strategy --- docs/includes/pricing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/includes/pricing.md b/docs/includes/pricing.md index ed8a45e68..4505d7fec 100644 --- a/docs/includes/pricing.md +++ b/docs/includes/pricing.md @@ -88,9 +88,9 @@ When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Fr #### Sell price without Orderbook enabled -When not using orderbook (`ask_strategy.use_order_book=False`), the price at the `ask_strategy.price_side` side (defaults to `"ask"`) from the ticker will be used as the sell price. +The following section uses `side` as the configured `ask_strategy.price_side`. -When not using orderbook (`ask_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price. +When not using orderbook (`ask_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's above the `last` traded price from the ticker. Otherwise (when the `side` price is below the `last` price), it calculates a rate between `side` and `last` price. The `ask_strategy.bid_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the last price and values between those interpolate between `side` and last price. From 47317e0f0659aaf8c126076ee0eaef6319f3f765 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Fri, 11 Mar 2022 17:53:29 +0100 Subject: [PATCH 13/49] version: use 'contains' to check for "develop" instead of literal comparison --- freqtrade/__init__.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 2747efc96..d57cc9852 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,27 +1,14 @@ """ Freqtrade bot """ -__version__ = 'develop' - -if __version__ == 'develop': +__version__ = 'dev' +if 'dev' in __version__: try: import subprocess - __version__ = 'develop-' + subprocess.check_output( + __version__ = __version__ + '-' + subprocess.check_output( ['git', 'log', '--format="%h"', '-n 1'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') - # from datetime import datetime - # last_release = subprocess.check_output( - # ['git', 'tag'] - # ).decode('utf-8').split()[-1].split(".") - # # Releases are in the format "2020.1" - we increment the latest version for dev. - # prefix = f"{last_release[0]}.{int(last_release[1]) + 1}" - # dev_version = int(datetime.now().timestamp() // 1000) - # __version__ = f"{prefix}.dev{dev_version}" - - # subprocess.check_output( - # ['git', 'log', '--format="%h"', '-n 1'], - # stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') except Exception: # pragma: no cover # git not available, ignore try: From 49e087df5b79d90381ac9ee64d0eaac88e044f74 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 20 Mar 2022 13:07:06 +0100 Subject: [PATCH 14/49] Allow Strategy subclassing in different files by enabling local imports --- docs/strategy-advanced.md | 9 ++-- freqtrade/resolvers/iresolver.py | 58 ++++++++++++++++------- tests/strategy/strats/strategy_test_v2.py | 2 +- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 3793abacf..fa1c09560 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -164,16 +164,15 @@ class MyAwesomeStrategy2(MyAwesomeStrategy): Both attributes and methods may be overridden, altering behavior of the original strategy in a way you need. !!! Note "Parent-strategy in different files" - If you have the parent-strategy in a different file, you'll need to add the following to the top of your "child"-file to ensure proper loading, otherwise freqtrade may not be able to load the parent strategy correctly. + If you have the parent-strategy in a different file, you can still import the strategy. + Assuming `myawesomestrategy.py` is the filename, and `MyAwesomeStrategy` the strategy you need to import: ``` python - import sys - from pathlib import Path - sys.path.append(str(Path(__file__).parent)) - from myawesomestrategy import MyAwesomeStrategy ``` + This is the recommended way to derive strategies to avoid problems with hyperopt parameter files. + ## Embedding Strategies Freqtrade provides you with an easy way to embed the strategy into your configuration file. diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index c6f97c976..8d132da70 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -6,6 +6,7 @@ This module load custom objects import importlib.util import inspect import logging +import sys from pathlib import Path from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union @@ -15,6 +16,22 @@ from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) +class PathModifier: + def __init__(self, path: Path): + self.path = path + + def __enter__(self): + """Inject path to allow importing with relative imports.""" + sys.path.insert(0, str(self.path)) + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """Undo insertion of local path.""" + str_path = str(self.path) + if str_path in sys.path: + sys.path.remove(str_path) + + class IResolver: """ This class contains all the logic to load custom classes @@ -57,27 +74,32 @@ class IResolver: # Generate spec based on absolute path # Pass object_name as first argument to have logging print a reasonable name. - spec = importlib.util.spec_from_file_location(object_name or "", str(module_path)) - if not spec: - return iter([None]) + with PathModifier(module_path.parent): - module = importlib.util.module_from_spec(spec) - try: - spec.loader.exec_module(module) # type: ignore # importlib does not use typehints - except (ModuleNotFoundError, SyntaxError, ImportError, NameError) as err: - # Catch errors in case a specific module is not installed - logger.warning(f"Could not import {module_path} due to '{err}'") - if enum_failed: + spec = importlib.util.spec_from_file_location(module_path.stem or "", str(module_path)) + if not spec: return iter([None]) - valid_objects_gen = ( - (obj, inspect.getsource(module)) for - name, obj in inspect.getmembers( - module, inspect.isclass) if ((object_name is None or object_name == name) - and issubclass(obj, cls.object_type) - and obj is not cls.object_type) - ) - return valid_objects_gen + module = importlib.util.module_from_spec(spec) + try: + spec.loader.exec_module(module) # type: ignore # importlib does not use typehints + except (ModuleNotFoundError, SyntaxError, ImportError, NameError) as err: + # Catch errors in case a specific module is not installed + logger.warning(f"Could not import {module_path} due to '{err}'") + if enum_failed: + return iter([None]) + + valid_objects_gen = ( + (obj, inspect.getsource(module)) for + name, obj in inspect.getmembers( + module, inspect.isclass) if ((object_name is None or object_name == name) + and issubclass(obj, cls.object_type) + and obj is not cls.object_type + and obj.__module__ == module_path.stem or "" + ) + ) + # The __module__ check ensures we only use strategies that are defined in this folder. + return valid_objects_gen @classmethod def _search_object(cls, directory: Path, *, object_name: str, add_source: bool = False diff --git a/tests/strategy/strats/strategy_test_v2.py b/tests/strategy/strats/strategy_test_v2.py index c57becdad..59f1f569e 100644 --- a/tests/strategy/strats/strategy_test_v2.py +++ b/tests/strategy/strats/strategy_test_v2.py @@ -7,7 +7,7 @@ from pandas import DataFrame import freqtrade.vendor.qtpylib.indicators as qtpylib from freqtrade.persistence import Trade -from freqtrade.strategy.interface import IStrategy +from freqtrade.strategy import IStrategy class StrategyTestV2(IStrategy): From 6ec7b84b92ec24264d5f573f8289cd466322196e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 20 Mar 2022 13:12:26 +0100 Subject: [PATCH 15/49] Modify hyperoptable strategy to use relative importing --- .../strategy/strats/hyperoptable_strategy.py | 88 +------------------ 1 file changed, 3 insertions(+), 85 deletions(-) diff --git a/tests/strategy/strats/hyperoptable_strategy.py b/tests/strategy/strats/hyperoptable_strategy.py index 88bdd078e..dc6b03a3e 100644 --- a/tests/strategy/strats/hyperoptable_strategy.py +++ b/tests/strategy/strats/hyperoptable_strategy.py @@ -1,14 +1,13 @@ # pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement -import talib.abstract as ta from pandas import DataFrame +from strategy_test_v2 import StrategyTestV2 import freqtrade.vendor.qtpylib.indicators as qtpylib -from freqtrade.strategy import (BooleanParameter, DecimalParameter, IntParameter, IStrategy, - RealParameter) +from freqtrade.strategy import BooleanParameter, DecimalParameter, IntParameter, RealParameter -class HyperoptableStrategy(IStrategy): +class HyperoptableStrategy(StrategyTestV2): """ Default Strategy provided by freqtrade bot. Please do not modify this strategy, it's intended for internal use only. @@ -16,38 +15,6 @@ class HyperoptableStrategy(IStrategy): or strategy repository https://github.com/freqtrade/freqtrade-strategies for samples and inspiration. """ - INTERFACE_VERSION = 2 - - # Minimal ROI designed for the strategy - minimal_roi = { - "40": 0.0, - "30": 0.01, - "20": 0.02, - "0": 0.04 - } - - # Optimal stoploss designed for the strategy - stoploss = -0.10 - - # Optimal ticker interval for the strategy - timeframe = '5m' - - # Optional order type mapping - order_types = { - 'buy': 'limit', - 'sell': 'limit', - 'stoploss': 'limit', - 'stoploss_on_exchange': False - } - - # Number of candles the strategy requires before producing valid signals - startup_candle_count: int = 20 - - # Optional time in force for orders - order_time_in_force = { - 'buy': 'gtc', - 'sell': 'gtc', - } buy_params = { 'buy_rsi': 35, @@ -91,55 +58,6 @@ class HyperoptableStrategy(IStrategy): """ return [] - def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - """ - Adds several different TA indicators to the given DataFrame - - Performance Note: For the best performance be frugal on the number of indicators - you are using. Let uncomment only the indicator you are using in your strategies - or your hyperopt configuration, otherwise you will waste your memory and CPU usage. - :param dataframe: Dataframe with data from the exchange - :param metadata: Additional information, like the currently traded pair - :return: a Dataframe with all mandatory indicators for the strategies - """ - - # Momentum Indicator - # ------------------------------------ - - # ADX - dataframe['adx'] = ta.ADX(dataframe) - - # MACD - macd = ta.MACD(dataframe) - dataframe['macd'] = macd['macd'] - dataframe['macdsignal'] = macd['macdsignal'] - dataframe['macdhist'] = macd['macdhist'] - - # Minus Directional Indicator / Movement - dataframe['minus_di'] = ta.MINUS_DI(dataframe) - - # Plus Directional Indicator / Movement - dataframe['plus_di'] = ta.PLUS_DI(dataframe) - - # RSI - dataframe['rsi'] = ta.RSI(dataframe) - - # Stoch fast - stoch_fast = ta.STOCHF(dataframe) - dataframe['fastd'] = stoch_fast['fastd'] - dataframe['fastk'] = stoch_fast['fastk'] - - # Bollinger bands - bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) - dataframe['bb_lowerband'] = bollinger['lower'] - dataframe['bb_middleband'] = bollinger['mid'] - dataframe['bb_upperband'] = bollinger['upper'] - - # EMA - Exponential Moving Average - dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) - - return dataframe - def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Based on TA indicators, populates the buy signal for the given dataframe From e9c4e6a69d9c173b30c6b4d2263ad658b1950b42 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 20 Mar 2022 13:14:52 +0100 Subject: [PATCH 16/49] Update derived strategy documentation --- docs/strategy-advanced.md | 11 +++++++---- freqtrade/resolvers/iresolver.py | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index fa1c09560..533402528 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -146,7 +146,7 @@ def version(self) -> str: The strategies can be derived from other strategies. This avoids duplication of your custom strategy code. You can use this technique to override small parts of your main strategy, leaving the rest untouched: -``` python +``` python title="user_data/strategies/myawesomestrategy.py" class MyAwesomeStrategy(IStrategy): ... stoploss = 0.13 @@ -155,6 +155,10 @@ class MyAwesomeStrategy(IStrategy): # should be in any custom strategy... ... +``` + +``` python title="user_data/strategies/MyAwesomeStrategy2.py" +from myawesomestrategy import MyAwesomeStrategy class MyAwesomeStrategy2(MyAwesomeStrategy): # Override something stoploss = 0.08 @@ -163,16 +167,15 @@ class MyAwesomeStrategy2(MyAwesomeStrategy): Both attributes and methods may be overridden, altering behavior of the original strategy in a way you need. +While keeping the subclass in the same file is technically possible, it can lead to some problems with hyperopt parameter files. + !!! Note "Parent-strategy in different files" If you have the parent-strategy in a different file, you can still import the strategy. Assuming `myawesomestrategy.py` is the filename, and `MyAwesomeStrategy` the strategy you need to import: ``` python - from myawesomestrategy import MyAwesomeStrategy ``` - This is the recommended way to derive strategies to avoid problems with hyperopt parameter files. - ## Embedding Strategies Freqtrade provides you with an easy way to embed the strategy into your configuration file. diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 8d132da70..3ab461041 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -75,8 +75,8 @@ class IResolver: # Generate spec based on absolute path # Pass object_name as first argument to have logging print a reasonable name. with PathModifier(module_path.parent): - - spec = importlib.util.spec_from_file_location(module_path.stem or "", str(module_path)) + module_name = module_path.stem or "" + spec = importlib.util.spec_from_file_location(module_name, str(module_path)) if not spec: return iter([None]) @@ -95,7 +95,7 @@ class IResolver: module, inspect.isclass) if ((object_name is None or object_name == name) and issubclass(obj, cls.object_type) and obj is not cls.object_type - and obj.__module__ == module_path.stem or "" + and obj.__module__ == module_name ) ) # The __module__ check ensures we only use strategies that are defined in this folder. From d796ce09352042160023235a404899d2973a55c7 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 20 Mar 2022 15:41:14 +0000 Subject: [PATCH 17/49] Update hyperopt.py 1. Try to get points using `self.opt.ask` first 2. Discard the points that have already been evaluated 3. Retry using `self.opt.ask` up to 3 times 4. If still some points are missing in respect to `n_points`, random sample some points 5. Repeat until at least `n_points` points in the `asked_non_tried` list 6. Return a list with legth truncated at `n_points` --- freqtrade/optimize/hyperopt.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index aa255967e..badaf2b3c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -413,6 +413,31 @@ class Hyperopt: f'({(self.max_date - self.min_date).days} days)..') # Store non-trimmed data - will be trimmed after signal generation. dump(preprocessed, self.data_pickle_file) + + def get_asked_points(self, n_points: int) -> List[Any]: + ''' + Steps: + 1. Try to get points using `self.opt.ask` first + 2. Discard the points that have already been evaluated + 3. Retry using `self.opt.ask` up to 3 times + 4. If still some points are missing in respect to `n_points`, random sample some points + 5. Repeat until at least `n_points` points in the `asked_non_tried` list + 6. Return a list with legth truncated at `n_points` + ''' + i = 0 + asked_non_tried = [] + while i < 100: + if len(asked_non_tried) < n_points: + if i < 3: + asked = self.opt.ask(n_points=n_points) + else: + # use random sample if `self.opt.ask` returns points points already tried + asked = self.opt.space.rvs(n_samples=n_points * 5) + asked_non_tried += [x for x in asked if x not in self.opt.Xi and x not in asked_non_tried] + i += 1 + else: + break + return asked_non_tried[:n_points] def start(self) -> None: self.random_state = self._set_random_state(self.config.get('hyperopt_random_state', None)) @@ -478,11 +503,11 @@ class Hyperopt: n_rest = (i + 1) * jobs - self.total_epochs current_jobs = jobs - n_rest if n_rest > 0 else jobs - asked = self.opt.ask(n_points=current_jobs) + asked = self.get_asked_points(n_points=current_jobs) f_val = self.run_optimizer_parallel(parallel, asked, i) res = self.opt.tell(asked, [v['loss'] for v in f_val]) - self.plot_optimizer(res, path='user_data/scripts', convergence=False, regret=False, r2=True, objective=True, jobs=jobs) + self.plot_optimizer(res, path='user_data/scripts', convergence=False, regret=False, r2=False, objective=True, jobs=jobs) if res.models and hasattr(res.models[-1], "kernel_"): print(f'kernel: {res.models[-1].kernel_}') From fca93d8dfec22dad88496774c8482d07d25ca325 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Sun, 20 Mar 2022 16:12:06 +0000 Subject: [PATCH 18/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index badaf2b3c..bbdc8bf27 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -414,30 +414,33 @@ class Hyperopt: # Store non-trimmed data - will be trimmed after signal generation. dump(preprocessed, self.data_pickle_file) - def get_asked_points(self, n_points: int) -> List[Any]: + def get_asked_points(self, n_points: int) -> List[List[Any]]: ''' + Enforce points returned from `self.opt.ask` have not been already evaluated + Steps: 1. Try to get points using `self.opt.ask` first 2. Discard the points that have already been evaluated 3. Retry using `self.opt.ask` up to 3 times 4. If still some points are missing in respect to `n_points`, random sample some points 5. Repeat until at least `n_points` points in the `asked_non_tried` list - 6. Return a list with legth truncated at `n_points` + 6. Return a list with length truncated at `n_points` ''' i = 0 - asked_non_tried = [] - while i < 100: - if len(asked_non_tried) < n_points: - if i < 3: - asked = self.opt.ask(n_points=n_points) - else: - # use random sample if `self.opt.ask` returns points points already tried - asked = self.opt.space.rvs(n_samples=n_points * 5) - asked_non_tried += [x for x in asked if x not in self.opt.Xi and x not in asked_non_tried] - i += 1 + asked_non_tried: List[List[Any]] = [] + while i < 100 and len(asked_non_tried) < n_points: + if i < 3: + asked = self.opt.ask(n_points=n_points) else: - break - return asked_non_tried[:n_points] + asked = self.opt.space.rvs(n_samples=n_points * 5) + asked_non_tried += [x for x in asked + if x not in self.opt.Xi + and x not in asked_non_tried] + i += 1 + if asked_non_tried: + return asked_non_tried[:n_points] + else: + return self.opt.ask(n_points=n_points) def start(self) -> None: self.random_state = self._set_random_state(self.config.get('hyperopt_random_state', None)) From f5e71a67fabdbb6b403e9ed87f94c2fa773effb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:11 +0000 Subject: [PATCH 19/49] Bump pymdown-extensions from 9.2 to 9.3 Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.2 to 9.3. - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.2...9.3) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 0ca0e4b63..01ce559ff 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,4 +1,4 @@ mkdocs==1.2.3 mkdocs-material==8.2.5 mdx_truly_sane_lists==1.2 -pymdown-extensions==9.2 +pymdown-extensions==9.3 From 1bc5d449a205c34c1672b0e0684b2936e884f1e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:16 +0000 Subject: [PATCH 20/49] Bump cryptography from 36.0.1 to 36.0.2 Bumps [cryptography](https://github.com/pyca/cryptography) from 36.0.1 to 36.0.2. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/36.0.1...36.0.2) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f0f030e78..e1c052353 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pandas-ta==0.3.14b ccxt==1.76.5 # Pin cryptography for now due to rust build errors with piwheels -cryptography==36.0.1 +cryptography==36.0.2 aiohttp==3.8.1 SQLAlchemy==1.4.32 python-telegram-bot==13.11 From 59c7403b1214cb21ba5a377bafe1b3191e825cac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:23 +0000 Subject: [PATCH 21/49] Bump urllib3 from 1.26.8 to 1.26.9 Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.8 to 1.26.9. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/1.26.9/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.8...1.26.9) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f0f030e78..c112a37b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ python-telegram-bot==13.11 arrow==1.2.2 cachetools==4.2.2 requests==2.27.1 -urllib3==1.26.8 +urllib3==1.26.9 jsonschema==4.4.0 TA-Lib==0.4.24 technical==1.3.0 From 5a136f04dfcdc7f7e3b4a6534ecd6c83a0abf373 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:33 +0000 Subject: [PATCH 22/49] Bump ccxt from 1.76.5 to 1.76.65 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.76.5 to 1.76.65. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg) - [Commits](https://github.com/ccxt/ccxt/compare/1.76.5...1.76.65) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f0f030e78..00ff46088 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ numpy==1.22.3 pandas==1.4.1 pandas-ta==0.3.14b -ccxt==1.76.5 +ccxt==1.76.65 # Pin cryptography for now due to rust build errors with piwheels cryptography==36.0.1 aiohttp==3.8.1 From 1a37100bd45a11c6665749b5ff028e0adac14a1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:41 +0000 Subject: [PATCH 23/49] Bump types-python-dateutil from 2.8.9 to 2.8.10 Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.9 to 2.8.10. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index c2f3eae8a..d9ca8c6ae 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -26,4 +26,4 @@ types-requests==2.27.12 types-tabulate==0.8.5 # Extensions to datetime library -types-python-dateutil==2.8.9 \ No newline at end of file +types-python-dateutil==2.8.10 \ No newline at end of file From 03090d8f3ffc34dc32f6d957385e2a52b894ad49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 03:01:45 +0000 Subject: [PATCH 24/49] Bump pytest from 7.1.0 to 7.1.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.0 to 7.1.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.1.0...7.1.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index c2f3eae8a..3d87763aa 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ coveralls==3.3.1 flake8==4.0.1 flake8-tidy-imports==4.6.0 mypy==0.940 -pytest==7.1.0 +pytest==7.1.1 pytest-asyncio==0.18.2 pytest-cov==3.0.0 pytest-mock==3.7.0 From 057db5aaabe4356e465986650469d6b1b953836e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 05:30:51 +0000 Subject: [PATCH 25/49] Bump types-requests from 2.27.12 to 2.27.14 Bumps [types-requests](https://github.com/python/typeshed) from 2.27.12 to 2.27.14. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index d9ca8c6ae..614921019 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -22,7 +22,7 @@ nbconvert==6.4.4 # mypy types types-cachetools==5.0.0 types-filelock==3.2.5 -types-requests==2.27.12 +types-requests==2.27.14 types-tabulate==0.8.5 # Extensions to datetime library From 7170b585f9a3c9e665bfe0c3fb5697e820a266d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 08:06:25 +0000 Subject: [PATCH 26/49] Bump mypy from 0.940 to 0.941 Bumps [mypy](https://github.com/python/mypy) from 0.940 to 0.941. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.940...v0.941) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index ca625238e..af19187fa 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ coveralls==3.3.1 flake8==4.0.1 flake8-tidy-imports==4.6.0 -mypy==0.940 +mypy==0.941 pytest==7.1.1 pytest-asyncio==0.18.2 pytest-cov==3.0.0 From c28e0b0d0cd8f252a93acd854701c658fdc2a3bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 08:06:41 +0000 Subject: [PATCH 27/49] Bump types-tabulate from 0.8.5 to 0.8.6 Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.5 to 0.8.6. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-tabulate dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index ca625238e..8bd1b68ba 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -23,7 +23,7 @@ nbconvert==6.4.4 types-cachetools==5.0.0 types-filelock==3.2.5 types-requests==2.27.14 -types-tabulate==0.8.5 +types-tabulate==0.8.6 # Extensions to datetime library types-python-dateutil==2.8.10 \ No newline at end of file From 487d3e891e454542e3f438986f080b2b852fae2f Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 21 Mar 2022 19:41:34 +0100 Subject: [PATCH 28/49] Revert version to develop for now --- freqtrade/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index d57cc9852..f8be8f66f 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,5 +1,5 @@ """ Freqtrade bot """ -__version__ = 'dev' +__version__ = 'develop' if 'dev' in __version__: try: From 2733aa33b6661523f721bd039cb8fd9e2ccdc7f1 Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Tue, 22 Mar 2022 00:28:11 +0000 Subject: [PATCH 29/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index bbdc8bf27..f08fa7233 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -430,6 +430,7 @@ class Hyperopt: asked_non_tried: List[List[Any]] = [] while i < 100 and len(asked_non_tried) < n_points: if i < 3: + self.opt.cache_ = {} asked = self.opt.ask(n_points=n_points) else: asked = self.opt.space.rvs(n_samples=n_points * 5) @@ -438,7 +439,7 @@ class Hyperopt: and x not in asked_non_tried] i += 1 if asked_non_tried: - return asked_non_tried[:n_points] + return asked_non_tried[:min(len(asked_non_tried), n_points)] else: return self.opt.ask(n_points=n_points) From b5a346a46de13e7aefcd6be27ac354e701322b6d Mon Sep 17 00:00:00 2001 From: Italo <45588475+italodamato@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:01:38 +0000 Subject: [PATCH 30/49] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index f08fa7233..d3f6a72f2 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -431,7 +431,7 @@ class Hyperopt: while i < 100 and len(asked_non_tried) < n_points: if i < 3: self.opt.cache_ = {} - asked = self.opt.ask(n_points=n_points) + asked = self.opt.ask(n_points=n_points * 5) else: asked = self.opt.space.rvs(n_samples=n_points * 5) asked_non_tried += [x for x in asked From e7418cdcdb9cf7916ff0a5464113c20817fe7486 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 22 Mar 2022 19:03:22 +0100 Subject: [PATCH 31/49] Remove obsolete note box closes #6581 --- docs/strategy-advanced.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 533402528..b1f154355 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -167,14 +167,7 @@ class MyAwesomeStrategy2(MyAwesomeStrategy): Both attributes and methods may be overridden, altering behavior of the original strategy in a way you need. -While keeping the subclass in the same file is technically possible, it can lead to some problems with hyperopt parameter files. - -!!! Note "Parent-strategy in different files" - If you have the parent-strategy in a different file, you can still import the strategy. - Assuming `myawesomestrategy.py` is the filename, and `MyAwesomeStrategy` the strategy you need to import: - - ``` python - ``` +While keeping the subclass in the same file is technically possible, it can lead to some problems with hyperopt parameter files, we therefore recommend to use separate strategy files, and import the parent strategy as shown above. ## Embedding Strategies From 094676def4255dc30e271ea274454484b848d66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=AE=E0=AE=A9=E0=AF=8B=E0=AE=9C=E0=AF=8D=E0=AE=95?= =?UTF-8?q?=E0=AF=81=E0=AE=AE=E0=AE=BE=E0=AE=B0=E0=AF=8D=20=E0=AE=AA?= =?UTF-8?q?=E0=AE=B4=E0=AE=A9=E0=AE=BF=E0=AE=9A=E0=AF=8D=E0=AE=9A=E0=AE=BE?= =?UTF-8?q?=E0=AE=AE=E0=AE=BF?= Date: Wed, 23 Mar 2022 20:47:55 +0530 Subject: [PATCH 32/49] Removed old datetime keys and added timestamp --- tests/conftest.py | 56 +++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 57122c01c..4192dc1cc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1019,7 +1019,6 @@ def limit_buy_order_open(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), 'timestamp': arrow.utcnow().int_timestamp, 'price': 0.00001099, 'amount': 90.99181073, @@ -1046,7 +1045,7 @@ def market_buy_order(): 'type': 'market', 'side': 'buy', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'price': 0.00004099, 'amount': 91.99181073, 'filled': 91.99181073, @@ -1062,7 +1061,7 @@ def market_sell_order(): 'type': 'market', 'side': 'sell', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'price': 0.00004173, 'amount': 91.99181073, 'filled': 91.99181073, @@ -1078,7 +1077,7 @@ def limit_buy_order_old(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'datetime': str(arrow.utcnow().shift(minutes=-601).datetime), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'price': 0.00001099, 'amount': 90.99181073, 'filled': 0.0, @@ -1094,7 +1093,7 @@ def limit_sell_order_old(): 'type': 'limit', 'side': 'sell', 'symbol': 'ETH/BTC', - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'price': 0.00001099, 'amount': 90.99181073, 'filled': 0.0, @@ -1110,7 +1109,7 @@ def limit_buy_order_old_partial(): 'type': 'limit', 'side': 'buy', 'symbol': 'ETH/BTC', - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'price': 0.00001099, 'amount': 90.99181073, 'filled': 23.0, @@ -1140,7 +1139,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': None, 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1161,7 +1160,7 @@ def limit_buy_order_canceled_empty(request): 'id': 'AZNPFF-4AC4N-7MKTAT', 'clientOrderId': None, 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'lastTradeTimestamp': None, 'status': 'canceled', 'symbol': 'LTC/USDT', @@ -1182,7 +1181,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': 'alb1234123', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1203,7 +1202,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': 'alb1234123', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1227,7 +1226,7 @@ def limit_sell_order_open(): 'type': 'limit', 'side': 'sell', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'timestamp': arrow.utcnow().int_timestamp, 'price': 0.00001173, 'amount': 90.99181073, @@ -1274,7 +1273,6 @@ def order_book_l2(): [0.04402, 37.64] ], 'timestamp': None, - 'datetime': None, 'nonce': 288004540 }) @@ -1308,7 +1306,6 @@ def order_book_l2_usd(): [25.578, 78.614] ], 'timestamp': None, - 'datetime': None, 'nonce': 2372149736 }) @@ -1355,7 +1352,6 @@ def tickers(): 'ETH/BTC': { 'symbol': 'ETH/BTC', 'timestamp': 1522014806207, - 'datetime': '2018-03-25T21:53:26.207Z', 'high': 0.061697, 'low': 0.060531, 'bid': 0.061588, @@ -1377,7 +1373,6 @@ def tickers(): 'TKN/BTC': { 'symbol': 'TKN/BTC', 'timestamp': 1522014806169, - 'datetime': '2018-03-25T21:53:26.169Z', 'high': 0.01885, 'low': 0.018497, 'bid': 0.018799, @@ -1394,7 +1389,6 @@ def tickers(): 'BLK/BTC': { 'symbol': 'BLK/BTC', 'timestamp': 1522014806072, - 'datetime': '2018-03-25T21:53:26.720Z', 'high': 0.007745, 'low': 0.007512, 'bid': 0.007729, @@ -1416,7 +1410,6 @@ def tickers(): 'LTC/BTC': { 'symbol': 'LTC/BTC', 'timestamp': 1523787258992, - 'datetime': '2018-04-15T10:14:19.992Z', 'high': 0.015978, 'low': 0.0157, 'bid': 0.015954, @@ -1438,7 +1431,6 @@ def tickers(): 'BTT/BTC': { 'symbol': 'BTT/BTC', 'timestamp': 1550936557206, - 'datetime': '2019-02-23T15:42:37.206Z', 'high': 0.00000026, 'low': 0.00000024, 'bid': 0.00000024, @@ -1460,7 +1452,6 @@ def tickers(): 'HOT/BTC': { 'symbol': 'HOT/BTC', 'timestamp': 1572273518661, - 'datetime': '2019-10-28T14:38:38.661Z', 'high': 0.00000011, 'low': 0.00000009, 'bid': 0.0000001, @@ -1482,7 +1473,6 @@ def tickers(): 'FUEL/BTC': { 'symbol': 'FUEL/BTC', 'timestamp': 1572340250771, - 'datetime': '2019-10-29T09:10:50.771Z', 'high': 0.00000040, 'low': 0.00000035, 'bid': 0.00000036, @@ -1504,7 +1494,6 @@ def tickers(): 'BTC/USDT': { 'symbol': 'BTC/USDT', 'timestamp': 1573758371399, - 'datetime': '2019-11-14T19:06:11.399Z', 'high': 8800.0, 'low': 8582.6, 'bid': 8648.16, @@ -1526,7 +1515,6 @@ def tickers(): 'ETH/USDT': { 'symbol': 'ETH/USDT', 'timestamp': 1522014804118, - 'datetime': '2018-03-25T21:53:24.118Z', 'high': 530.88, 'low': 512.0, 'bid': 529.73, @@ -1548,7 +1536,6 @@ def tickers(): 'TKN/USDT': { 'symbol': 'TKN/USDT', 'timestamp': 1522014806198, - 'datetime': '2018-03-25T21:53:26.198Z', 'high': 8718.0, 'low': 8365.77, 'bid': 8603.64, @@ -1570,7 +1557,6 @@ def tickers(): 'BLK/USDT': { 'symbol': 'BLK/USDT', 'timestamp': 1522014806145, - 'datetime': '2018-03-25T21:53:26.145Z', 'high': 66.95, 'low': 63.38, 'bid': 66.473, @@ -1592,7 +1578,6 @@ def tickers(): 'LTC/USDT': { 'symbol': 'LTC/USDT', 'timestamp': 1523787257812, - 'datetime': '2018-04-15T10:14:18.812Z', 'high': 129.94, 'low': 124.0, 'bid': 129.28, @@ -1614,7 +1599,6 @@ def tickers(): 'XRP/BTC': { 'symbol': 'XRP/BTC', 'timestamp': 1573758257534, - 'datetime': '2019-11-14T19:04:17.534Z', 'high': 3.126e-05, 'low': 3.061e-05, 'bid': 3.093e-05, @@ -1726,7 +1710,6 @@ def trades_for_order(): 'isBestMatch': True }, 'timestamp': 1521663363189, - 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/USDT', 'id': '34567', 'order': '123456', @@ -1762,7 +1745,6 @@ def fetch_trades_result(): 'm': False, 'M': True}, 'timestamp': 1565798399463, - 'datetime': '2019-08-14T15:59:59.463Z', 'symbol': 'ETH/BTC', 'id': '126181329', 'order': None, @@ -1782,7 +1764,6 @@ def fetch_trades_result(): 'm': False, 'M': True}, 'timestamp': 1565798399629, - 'datetime': '2019-08-14T15:59:59.629Z', 'symbol': 'ETH/BTC', 'id': '126181330', 'order': None, @@ -1802,7 +1783,6 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399752, - 'datetime': '2019-08-14T15:59:59.752Z', 'symbol': 'ETH/BTC', 'id': '126181331', 'order': None, @@ -1822,7 +1802,6 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399862, - 'datetime': '2019-08-14T15:59:59.862Z', 'symbol': 'ETH/BTC', 'id': '126181332', 'order': None, @@ -1842,7 +1821,6 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399872, - 'datetime': '2019-08-14T15:59:59.872Z', 'symbol': 'ETH/BTC', 'id': '126181333', 'order': None, @@ -1859,7 +1837,6 @@ def fetch_trades_result(): def trades_for_order2(): return [{'info': {}, 'timestamp': 1521663363189, - 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/ETH', 'id': '34567', 'order': '123456', @@ -1871,7 +1848,6 @@ def trades_for_order2(): 'fee': {'cost': 0.004, 'currency': 'LTC'}}, {'info': {}, 'timestamp': 1521663363189, - 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/ETH', 'id': '34567', 'order': '123456', @@ -1890,7 +1866,7 @@ def buy_order_fee(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'datetime': str(arrow.utcnow().shift(minutes=-601).datetime), + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'price': 0.245441, 'amount': 8.0, 'cost': 1.963528, @@ -2187,7 +2163,7 @@ def limit_buy_order_usdt_open(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.00, 'amount': 30.0, @@ -2214,7 +2190,7 @@ def limit_sell_order_usdt_open(): 'type': 'limit', 'side': 'sell', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.20, 'amount': 30.0, @@ -2240,7 +2216,7 @@ def market_buy_order_usdt(): 'type': 'market', 'side': 'buy', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.00, 'amount': 30.0, 'filled': 30.0, @@ -2261,7 +2237,6 @@ def market_buy_order_usdt_doublefee(market_buy_order_usdt): ] order['trades'] = [{ 'timestamp': None, - 'datetime': None, 'symbol': 'ETH/USDT', 'id': None, 'order': '123', @@ -2274,7 +2249,6 @@ def market_buy_order_usdt_doublefee(market_buy_order_usdt): 'fee': {'cost': 0.00025125, 'currency': 'BNB'} }, { 'timestamp': None, - 'datetime': None, 'symbol': 'ETH/USDT', 'id': None, 'order': '123', @@ -2296,7 +2270,7 @@ def market_sell_order_usdt(): 'type': 'market', 'side': 'sell', 'symbol': 'mocked', - 'datetime': arrow.utcnow().isoformat(), + 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.20, 'amount': 30.0, 'filled': 30.0, From dae9f4d877b921c935ea71a095ff85f9a0fffe80 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 24 Mar 2022 06:48:59 +0100 Subject: [PATCH 33/49] Update doc clarity, partially revert prior commit --- docs/includes/pricing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/includes/pricing.md b/docs/includes/pricing.md index 4505d7fec..103df6cd3 100644 --- a/docs/includes/pricing.md +++ b/docs/includes/pricing.md @@ -51,9 +51,9 @@ When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Fre #### Buy price without Orderbook enabled -The following section uses `side` as the configured `bid_strategy.price_side`. +The following section uses `side` as the configured `bid_strategy.price_side` (defaults to `"bid"`). -When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price. +When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price based on `bid_strategy.ask_last_balance`.. The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the `last` price and values between those interpolate between ask and last price. @@ -88,9 +88,9 @@ When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Fr #### Sell price without Orderbook enabled -The following section uses `side` as the configured `ask_strategy.price_side`. +The following section uses `side` as the configured `ask_strategy.price_side` (defaults to `"ask"`). -When not using orderbook (`ask_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's above the `last` traded price from the ticker. Otherwise (when the `side` price is below the `last` price), it calculates a rate between `side` and `last` price. +When not using orderbook (`ask_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's above the `last` traded price from the ticker. Otherwise (when the `side` price is below the `last` price), it calculates a rate between `side` and `last` price based on `ask_strategy.bid_last_balance`. The `ask_strategy.bid_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the last price and values between those interpolate between `side` and last price. From d94b84e38cf155f37a77f88ebb5cc2cc03d190d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=AE=E0=AE=A9=E0=AF=8B=E0=AE=9C=E0=AF=8D=E0=AE=95?= =?UTF-8?q?=E0=AF=81=E0=AE=AE=E0=AE=BE=E0=AE=B0=E0=AF=8D=20=E0=AE=AA?= =?UTF-8?q?=E0=AE=B4=E0=AE=A9=E0=AE=BF=E0=AE=9A=E0=AF=8D=E0=AE=9A=E0=AE=BE?= =?UTF-8?q?=E0=AE=AE=E0=AE=BF?= Date: Fri, 25 Mar 2022 08:55:58 +0530 Subject: [PATCH 34/49] datetime included again --- tests/conftest.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 4192dc1cc..e3c0cf070 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1020,6 +1020,7 @@ def limit_buy_order_open(): 'side': 'buy', 'symbol': 'mocked', 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001099, 'amount': 90.99181073, 'filled': 0.0, @@ -1046,6 +1047,7 @@ def market_buy_order(): 'side': 'buy', 'symbol': 'mocked', 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004099, 'amount': 91.99181073, 'filled': 91.99181073, @@ -1062,6 +1064,7 @@ def market_sell_order(): 'side': 'sell', 'symbol': 'mocked', 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004173, 'amount': 91.99181073, 'filled': 91.99181073, @@ -1077,6 +1080,7 @@ def limit_buy_order_old(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, 'price': 0.00001099, 'amount': 90.99181073, @@ -1094,6 +1098,7 @@ def limit_sell_order_old(): 'side': 'sell', 'symbol': 'ETH/BTC', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, 'filled': 0.0, @@ -1110,6 +1115,7 @@ def limit_buy_order_old_partial(): 'side': 'buy', 'symbol': 'ETH/BTC', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, 'filled': 23.0, @@ -1389,6 +1395,7 @@ def tickers(): 'BLK/BTC': { 'symbol': 'BLK/BTC', 'timestamp': 1522014806072, + 'datetime': '2018-03-25T21:53:26.072Z', 'high': 0.007745, 'low': 0.007512, 'bid': 0.007729, @@ -1867,6 +1874,7 @@ def buy_order_fee(): 'side': 'buy', 'symbol': 'mocked', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.245441, 'amount': 8.0, 'cost': 1.963528, @@ -2217,6 +2225,7 @@ def market_buy_order_usdt(): 'side': 'buy', 'symbol': 'mocked', 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'price': 2.00, 'amount': 30.0, 'filled': 30.0, @@ -2271,6 +2280,7 @@ def market_sell_order_usdt(): 'side': 'sell', 'symbol': 'mocked', 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'price': 2.20, 'amount': 30.0, 'filled': 30.0, From 3f98fcb0db723e4a6ded6dda7eae32f02da89b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=AE=E0=AE=A9=E0=AF=8B=E0=AE=9C=E0=AF=8D=E0=AE=95?= =?UTF-8?q?=E0=AF=81=E0=AE=AE=E0=AE=BE=E0=AE=B0=E0=AF=8D=20=E0=AE=AA?= =?UTF-8?q?=E0=AE=B4=E0=AE=A9=E0=AE=BF=E0=AE=9A=E0=AF=8D=E0=AE=9A=E0=AE=BE?= =?UTF-8?q?=E0=AE=AE=E0=AE=BF?= Date: Fri, 25 Mar 2022 09:19:39 +0530 Subject: [PATCH 35/49] all datetime included again --- tests/conftest.py | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index e3c0cf070..7dbd13bc3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1145,7 +1145,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': None, 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1166,7 +1166,7 @@ def limit_buy_order_canceled_empty(request): 'id': 'AZNPFF-4AC4N-7MKTAT', 'clientOrderId': None, 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'status': 'canceled', 'symbol': 'LTC/USDT', @@ -1187,7 +1187,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': 'alb1234123', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1208,7 +1208,7 @@ def limit_buy_order_canceled_empty(request): 'id': '1234512345', 'clientOrderId': 'alb1234123', 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', 'type': 'limit', @@ -1232,7 +1232,7 @@ def limit_sell_order_open(): 'type': 'limit', 'side': 'sell', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'timestamp': arrow.utcnow().int_timestamp, 'price': 0.00001173, 'amount': 90.99181073, @@ -1279,6 +1279,7 @@ def order_book_l2(): [0.04402, 37.64] ], 'timestamp': None, + 'datetime': None, 'nonce': 288004540 }) @@ -1312,6 +1313,7 @@ def order_book_l2_usd(): [25.578, 78.614] ], 'timestamp': None, + 'datetime': None, 'nonce': 2372149736 }) @@ -1358,6 +1360,7 @@ def tickers(): 'ETH/BTC': { 'symbol': 'ETH/BTC', 'timestamp': 1522014806207, + 'datetime': '2018-03-25T21:53:26.207Z', 'high': 0.061697, 'low': 0.060531, 'bid': 0.061588, @@ -1379,6 +1382,7 @@ def tickers(): 'TKN/BTC': { 'symbol': 'TKN/BTC', 'timestamp': 1522014806169, + 'datetime': '2018-03-25T21:53:26.169Z', 'high': 0.01885, 'low': 0.018497, 'bid': 0.018799, @@ -1417,6 +1421,7 @@ def tickers(): 'LTC/BTC': { 'symbol': 'LTC/BTC', 'timestamp': 1523787258992, + 'datetime': '2018-04-15T10:14:19.992Z', 'high': 0.015978, 'low': 0.0157, 'bid': 0.015954, @@ -1438,6 +1443,7 @@ def tickers(): 'BTT/BTC': { 'symbol': 'BTT/BTC', 'timestamp': 1550936557206, + 'datetime': '2019-02-23T15:42:37.206Z', 'high': 0.00000026, 'low': 0.00000024, 'bid': 0.00000024, @@ -1459,6 +1465,7 @@ def tickers(): 'HOT/BTC': { 'symbol': 'HOT/BTC', 'timestamp': 1572273518661, + 'datetime': '2019-10-28T14:38:38.661Z', 'high': 0.00000011, 'low': 0.00000009, 'bid': 0.0000001, @@ -1480,6 +1487,7 @@ def tickers(): 'FUEL/BTC': { 'symbol': 'FUEL/BTC', 'timestamp': 1572340250771, + 'datetime': '2019-10-29T09:10:50.771Z', 'high': 0.00000040, 'low': 0.00000035, 'bid': 0.00000036, @@ -1501,6 +1509,7 @@ def tickers(): 'BTC/USDT': { 'symbol': 'BTC/USDT', 'timestamp': 1573758371399, + 'datetime': '2019-11-14T19:06:11.399Z', 'high': 8800.0, 'low': 8582.6, 'bid': 8648.16, @@ -1522,6 +1531,7 @@ def tickers(): 'ETH/USDT': { 'symbol': 'ETH/USDT', 'timestamp': 1522014804118, + 'datetime': '2018-03-25T21:53:24.118Z', 'high': 530.88, 'low': 512.0, 'bid': 529.73, @@ -1543,6 +1553,7 @@ def tickers(): 'TKN/USDT': { 'symbol': 'TKN/USDT', 'timestamp': 1522014806198, + 'datetime': '2018-03-25T21:53:26.198Z', 'high': 8718.0, 'low': 8365.77, 'bid': 8603.64, @@ -1564,6 +1575,7 @@ def tickers(): 'BLK/USDT': { 'symbol': 'BLK/USDT', 'timestamp': 1522014806145, + 'datetime': '2018-03-25T21:53:26.145Z', 'high': 66.95, 'low': 63.38, 'bid': 66.473, @@ -1585,6 +1597,7 @@ def tickers(): 'LTC/USDT': { 'symbol': 'LTC/USDT', 'timestamp': 1523787257812, + 'datetime': '2018-04-15T10:14:18.812Z', 'high': 129.94, 'low': 124.0, 'bid': 129.28, @@ -1606,6 +1619,7 @@ def tickers(): 'XRP/BTC': { 'symbol': 'XRP/BTC', 'timestamp': 1573758257534, + 'datetime': '2019-11-14T19:04:17.534Z', 'high': 3.126e-05, 'low': 3.061e-05, 'bid': 3.093e-05, @@ -1717,6 +1731,7 @@ def trades_for_order(): 'isBestMatch': True }, 'timestamp': 1521663363189, + 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/USDT', 'id': '34567', 'order': '123456', @@ -1752,6 +1767,7 @@ def fetch_trades_result(): 'm': False, 'M': True}, 'timestamp': 1565798399463, + 'datetime': '2019-08-14T15:59:59.463Z', 'symbol': 'ETH/BTC', 'id': '126181329', 'order': None, @@ -1771,6 +1787,7 @@ def fetch_trades_result(): 'm': False, 'M': True}, 'timestamp': 1565798399629, + 'datetime': '2019-08-14T15:59:59.629Z', 'symbol': 'ETH/BTC', 'id': '126181330', 'order': None, @@ -1790,6 +1807,7 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399752, + 'datetime': '2019-08-14T15:59:59.752Z', 'symbol': 'ETH/BTC', 'id': '126181331', 'order': None, @@ -1809,6 +1827,7 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399862, + 'datetime': '2019-08-14T15:59:59.862Z', 'symbol': 'ETH/BTC', 'id': '126181332', 'order': None, @@ -1828,6 +1847,7 @@ def fetch_trades_result(): 'm': True, 'M': True}, 'timestamp': 1565798399872, + 'datetime': '2019-08-14T15:59:59.872Z', 'symbol': 'ETH/BTC', 'id': '126181333', 'order': None, @@ -1844,6 +1864,7 @@ def fetch_trades_result(): def trades_for_order2(): return [{'info': {}, 'timestamp': 1521663363189, + 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/ETH', 'id': '34567', 'order': '123456', @@ -1855,6 +1876,7 @@ def trades_for_order2(): 'fee': {'cost': 0.004, 'currency': 'LTC'}}, {'info': {}, 'timestamp': 1521663363189, + 'datetime': '2018-03-21T20:16:03.189Z', 'symbol': 'LTC/ETH', 'id': '34567', 'order': '123456', @@ -2171,7 +2193,7 @@ def limit_buy_order_usdt_open(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.00, 'amount': 30.0, @@ -2198,7 +2220,7 @@ def limit_sell_order_usdt_open(): 'type': 'limit', 'side': 'sell', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'datetime': arrow.utcnow().isoformat(), 'timestamp': arrow.utcnow().int_timestamp, 'price': 2.20, 'amount': 30.0, @@ -2246,6 +2268,7 @@ def market_buy_order_usdt_doublefee(market_buy_order_usdt): ] order['trades'] = [{ 'timestamp': None, + 'datetime': None, 'symbol': 'ETH/USDT', 'id': None, 'order': '123', @@ -2258,6 +2281,7 @@ def market_buy_order_usdt_doublefee(market_buy_order_usdt): 'fee': {'cost': 0.00025125, 'currency': 'BNB'} }, { 'timestamp': None, + 'datetime': None, 'symbol': 'ETH/USDT', 'id': None, 'order': '123', From a55bc9c1e4898b970f85ae477094ccb9c98212d6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 25 Mar 2022 08:02:27 +0100 Subject: [PATCH 36/49] Pin jinja in docs requirements --- docs/requirements-docs.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 01ce559ff..3afc212d3 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -2,3 +2,4 @@ mkdocs==1.2.3 mkdocs-material==8.2.5 mdx_truly_sane_lists==1.2 pymdown-extensions==9.3 +jinja2==3.0.3 From 2cb24ed310aad514081f881ec0f3333f0cb66f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=AE=E0=AE=A9=E0=AF=8B=E0=AE=9C=E0=AF=8D=E0=AE=95?= =?UTF-8?q?=E0=AF=81=E0=AE=AE=E0=AE=BE=E0=AE=B0=E0=AF=8D=20=E0=AE=AA?= =?UTF-8?q?=E0=AE=B4=E0=AE=A9=E0=AE=BF=E0=AE=9A=E0=AF=8D=E0=AE=9A=E0=AE=BE?= =?UTF-8?q?=E0=AE=AE=E0=AE=BF?= Date: Fri, 25 Mar 2022 13:45:05 +0530 Subject: [PATCH 37/49] Added in ms Just multiplied by 1000 as minuting checking in ms is not performed --- tests/conftest.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 7dbd13bc3..0f01d7e4a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1019,7 +1019,7 @@ def limit_buy_order_open(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -1046,7 +1046,7 @@ def market_buy_order(): 'type': 'market', 'side': 'buy', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004099, 'amount': 91.99181073, @@ -1063,7 +1063,7 @@ def market_sell_order(): 'type': 'market', 'side': 'sell', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004173, 'amount': 91.99181073, @@ -1081,7 +1081,7 @@ def limit_buy_order_old(): 'side': 'buy', 'symbol': 'mocked', 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'price': 0.00001099, 'amount': 90.99181073, 'filled': 0.0, @@ -1097,7 +1097,7 @@ def limit_sell_order_old(): 'type': 'limit', 'side': 'sell', 'symbol': 'ETH/BTC', - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -1114,7 +1114,7 @@ def limit_buy_order_old_partial(): 'type': 'limit', 'side': 'buy', 'symbol': 'ETH/BTC', - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -1144,7 +1144,7 @@ def limit_buy_order_canceled_empty(request): 'info': {}, 'id': '1234512345', 'clientOrderId': None, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', @@ -1165,7 +1165,7 @@ def limit_buy_order_canceled_empty(request): 'info': {}, 'id': 'AZNPFF-4AC4N-7MKTAT', 'clientOrderId': None, - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'status': 'canceled', @@ -1186,7 +1186,7 @@ def limit_buy_order_canceled_empty(request): 'info': {}, 'id': '1234512345', 'clientOrderId': 'alb1234123', - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', @@ -1207,7 +1207,7 @@ def limit_buy_order_canceled_empty(request): 'info': {}, 'id': '1234512345', 'clientOrderId': 'alb1234123', - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'lastTradeTimestamp': None, 'symbol': 'LTC/USDT', @@ -1233,7 +1233,7 @@ def limit_sell_order_open(): 'side': 'sell', 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'price': 0.00001173, 'amount': 90.99181073, 'filled': 0.0, @@ -1895,7 +1895,7 @@ def buy_order_fee(): 'type': 'limit', 'side': 'buy', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp, + 'timestamp': arrow.utcnow().shift(minutes=-601).int_timestamp * 1000, 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.245441, 'amount': 8.0, @@ -2194,7 +2194,7 @@ def limit_buy_order_usdt_open(): 'side': 'buy', 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'price': 2.00, 'amount': 30.0, 'filled': 0.0, @@ -2221,7 +2221,7 @@ def limit_sell_order_usdt_open(): 'side': 'sell', 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'price': 2.20, 'amount': 30.0, 'filled': 0.0, @@ -2246,7 +2246,7 @@ def market_buy_order_usdt(): 'type': 'market', 'side': 'buy', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'datetime': arrow.utcnow().isoformat(), 'price': 2.00, 'amount': 30.0, @@ -2303,7 +2303,7 @@ def market_sell_order_usdt(): 'type': 'market', 'side': 'sell', 'symbol': 'mocked', - 'timestamp': arrow.utcnow().int_timestamp, + 'timestamp': arrow.utcnow().int_timestamp * 1000, 'datetime': arrow.utcnow().isoformat(), 'price': 2.20, 'amount': 30.0, From 81957e004df08bd3b9b2b81ca6a9ed59872768fd Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 25 Mar 2022 15:38:38 +0100 Subject: [PATCH 38/49] Revert false update --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 0f01d7e4a..691584e74 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1399,7 +1399,7 @@ def tickers(): 'BLK/BTC': { 'symbol': 'BLK/BTC', 'timestamp': 1522014806072, - 'datetime': '2018-03-25T21:53:26.072Z', + 'datetime': '2018-03-25T21:53:26.720Z', 'high': 0.007745, 'low': 0.007512, 'bid': 0.007729, From 60f2a12bd9104fb7233fafda6052102265f89013 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 26 Mar 2022 08:23:02 +0100 Subject: [PATCH 39/49] Fix wrong datetime conversion --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 691584e74..0f01d7e4a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1399,7 +1399,7 @@ def tickers(): 'BLK/BTC': { 'symbol': 'BLK/BTC', 'timestamp': 1522014806072, - 'datetime': '2018-03-25T21:53:26.720Z', + 'datetime': '2018-03-25T21:53:26.072Z', 'high': 0.007745, 'low': 0.007512, 'bid': 0.007729, From d45cec20abf1ee43711d46a85f5a676250249147 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:01:22 +0000 Subject: [PATCH 40/49] Bump pytest-asyncio from 0.18.2 to 0.18.3 Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.18.2 to 0.18.3. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Changelog](https://github.com/pytest-dev/pytest-asyncio/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.18.2...v0.18.3) --- updated-dependencies: - dependency-name: pytest-asyncio dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 39ab62a68..44e94505f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==4.0.1 flake8-tidy-imports==4.6.0 mypy==0.941 pytest==7.1.1 -pytest-asyncio==0.18.2 +pytest-asyncio==0.18.3 pytest-cov==3.0.0 pytest-mock==3.7.0 pytest-random-order==1.0.4 From 9ba8303823e58b47aff55612ec80416af6fdc5f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:01:33 +0000 Subject: [PATCH 41/49] Bump ccxt from 1.76.65 to 1.77.36 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.76.65 to 1.77.36. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg) - [Commits](https://github.com/ccxt/ccxt/compare/1.76.65...1.77.36) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1a6dbd97f..f4ee31b23 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ numpy==1.22.3 pandas==1.4.1 pandas-ta==0.3.14b -ccxt==1.76.65 +ccxt==1.77.36 # Pin cryptography for now due to rust build errors with piwheels cryptography==36.0.2 aiohttp==3.8.1 From 8b1e2f55b492d439ac69cb1e0fba9adc7409b588 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:01:36 +0000 Subject: [PATCH 42/49] Bump mkdocs from 1.2.3 to 1.3.0 Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.2.3 to 1.3.0. - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.2.3...1.3.0) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 3afc212d3..f85c37595 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,4 +1,4 @@ -mkdocs==1.2.3 +mkdocs==1.3.0 mkdocs-material==8.2.5 mdx_truly_sane_lists==1.2 pymdown-extensions==9.3 From 6f64e8da8d3590ac7dddda9d6b7f80ed881519b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:01:48 +0000 Subject: [PATCH 43/49] Bump types-requests from 2.27.14 to 2.27.15 Bumps [types-requests](https://github.com/python/typeshed) from 2.27.14 to 2.27.15. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-requests dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 39ab62a68..8cdbdad6f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -22,7 +22,7 @@ nbconvert==6.4.4 # mypy types types-cachetools==5.0.0 types-filelock==3.2.5 -types-requests==2.27.14 +types-requests==2.27.15 types-tabulate==0.8.6 # Extensions to datetime library From 449af0ce9c2afeedfa2829be411f590d466e12df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:16:02 +0000 Subject: [PATCH 44/49] Bump peter-evans/dockerhub-description from 2.4.3 to 3 Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 2.4.3 to 3. - [Release notes](https://github.com/peter-evans/dockerhub-description/releases) - [Commits](https://github.com/peter-evans/dockerhub-description/compare/v2.4.3...v3) --- updated-dependencies: - dependency-name: peter-evans/dockerhub-description dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker_update_readme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_update_readme.yml b/.github/workflows/docker_update_readme.yml index ebb773ad7..822533ee2 100644 --- a/.github/workflows/docker_update_readme.yml +++ b/.github/workflows/docker_update_readme.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Docker Hub Description - uses: peter-evans/dockerhub-description@v2.4.3 + uses: peter-evans/dockerhub-description@v3 env: DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} From c570732157ac089ed38409e906eef75adb30db6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 03:16:05 +0000 Subject: [PATCH 45/49] Bump actions/cache from 2 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 216a53bc1..b8df7ab10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,14 +31,14 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache_dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 id: cache with: path: ~/dependencies/ key: ${{ runner.os }}-dependencies - name: pip cache (linux) - uses: actions/cache@v2 + uses: actions/cache@v3 if: runner.os == 'Linux' with: path: ~/.cache/pip @@ -126,14 +126,14 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache_dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 id: cache with: path: ~/dependencies/ key: ${{ runner.os }}-dependencies - name: pip cache (macOS) - uses: actions/cache@v2 + uses: actions/cache@v3 if: runner.os == 'macOS' with: path: ~/Library/Caches/pip @@ -218,7 +218,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Pip cache (Windows) - uses: actions/cache@preview + uses: actions/cache@v3 with: path: ~\AppData\Local\pip\Cache key: ${{ matrix.os }}-${{ matrix.python-version }}-pip From b321c0f5fb58a8cec9fc383c40849e39286c6f91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 04:30:05 +0000 Subject: [PATCH 46/49] Bump mkdocs-material from 8.2.5 to 8.2.8 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.5 to 8.2.8. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.5...8.2.8) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index f85c37595..719c09578 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,5 +1,5 @@ mkdocs==1.3.0 -mkdocs-material==8.2.5 +mkdocs-material==8.2.8 mdx_truly_sane_lists==1.2 pymdown-extensions==9.3 jinja2==3.0.3 From 3cffaed8df3bcaa363bdc674337c2e9bc9228e46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 04:30:07 +0000 Subject: [PATCH 47/49] Bump mypy from 0.941 to 0.942 Bumps [mypy](https://github.com/python/mypy) from 0.941 to 0.942. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.941...v0.942) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 2a7ffb65f..063cfaa45 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ coveralls==3.3.1 flake8==4.0.1 flake8-tidy-imports==4.6.0 -mypy==0.941 +mypy==0.942 pytest==7.1.1 pytest-asyncio==0.18.3 pytest-cov==3.0.0 From 89e7b3705bfd44dedf43a5435db883d619ea62e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 08:25:34 +0000 Subject: [PATCH 48/49] Bump jinja2 from 3.0.3 to 3.1.1 Bumps [jinja2](https://github.com/pallets/jinja) from 3.0.3 to 3.1.1. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.0.3...3.1.1) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- docs/requirements-docs.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index 719c09578..1f7db75c5 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -2,4 +2,4 @@ mkdocs==1.3.0 mkdocs-material==8.2.8 mdx_truly_sane_lists==1.2 pymdown-extensions==9.3 -jinja2==3.0.3 +jinja2==3.1.1 diff --git a/requirements.txt b/requirements.txt index f4ee31b23..de05b3f7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ TA-Lib==0.4.24 technical==1.3.0 tabulate==0.8.9 pycoingecko==2.2.0 -jinja2==3.0.3 +jinja2==3.1.1 tables==3.7.0 blosc==1.10.6 From 5552ad779c26ee1ea5beefdbbb35838e15474a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=AE=E0=AE=A9=E0=AF=8B=E0=AE=9C=E0=AF=8D=E0=AE=95?= =?UTF-8?q?=E0=AF=81=E0=AE=AE=E0=AE=BE=E0=AE=B0=E0=AF=8D=20=E0=AE=AA?= =?UTF-8?q?=E0=AE=B4=E0=AE=A9=E0=AE=BF=E0=AE=9A=E0=AF=8D=E0=AE=9A=E0=AE=BE?= =?UTF-8?q?=E0=AE=AE=E0=AE=BF?= Date: Mon, 28 Mar 2022 19:31:12 +0530 Subject: [PATCH 49/49] Corrected test_create_order --- tests/exchange/test_exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index ff8383997..b76cb23e6 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1098,7 +1098,7 @@ def test_create_order(default_conf, mocker, side, ordertype, rate, marketprice, exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order = exchange.create_order( - pair='ETH/BTC', ordertype=ordertype, side=side, amount=1, rate=200) + pair='ETH/BTC', ordertype=ordertype, side=side, amount=1, rate=rate) assert 'id' in order assert 'info' in order