From a28ffcbcf7bafe28ae539e27380e3531a4ed1fb8 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 15:50:06 +0200 Subject: [PATCH 1/6] remove slow unnecessary table scan --- freqtrade/optimize/backtesting.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index bfe8c33eb..833e7c145 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -78,15 +78,13 @@ def get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args): ) # calculate win/lose forwards from buy point - sell_subset = ticker[ticker.index > row.Index][['close', 'sell']] + sell_subset = ticker[ticker.index > row.Index][['close', 'sell', 'buy']] for row2 in sell_subset.itertuples(index=True): if max_open_trades > 0: # Increase trade_count_lock for every iteration trade_count_lock[row2.Index] = trade_count_lock.get(row2.Index, 0) + 1 - # Buy is on is in the buy_subset there is a row that matches the date - # of the sell event - buy_signal = (buy_subset.index == row2.Index).any() + buy_signal = row2.buy if(should_sell(trade, row2.close, row2.Index, buy_signal, row2.sell)): return row2, (pair, trade.calc_profit_percent(rate=row2.close), From 5c02f0983dc80d74ac97b2d950a20406df552acd Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 16:31:50 +0200 Subject: [PATCH 2/6] let Strategy hold a sorted roi map --- freqtrade/main.py | 2 +- freqtrade/strategy/strategy.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/freqtrade/main.py b/freqtrade/main.py index 163597eee..da17b6586 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -302,7 +302,7 @@ def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) - # Check if time matches and current rate is above threshold time_diff = (current_time - trade.open_date).total_seconds() / 60 - for duration, threshold in sorted(strategy.minimal_roi.items()): + for duration, threshold in strategy.minimal_roi.items(): if time_diff > float(duration) and current_profit > threshold: return True diff --git a/freqtrade/strategy/strategy.py b/freqtrade/strategy/strategy.py index 7ea8e81ac..9ef5a2071 100644 --- a/freqtrade/strategy/strategy.py +++ b/freqtrade/strategy/strategy.py @@ -7,6 +7,7 @@ import os import sys import logging import importlib +from collections import OrderedDict from pandas import DataFrame from freqtrade.strategy.interface import IStrategy @@ -69,7 +70,9 @@ class Strategy(object): ) # Minimal ROI designed for the strategy - self.minimal_roi = self.custom_strategy.minimal_roi + self.minimal_roi = OrderedDict(sorted( + self.custom_strategy.minimal_roi.items(), + key=lambda tuple: float(tuple[0]))) # sort after converting to number # Optimal stoploss designed for the strategy self.stoploss = self.custom_strategy.stoploss From 0454b4c8d53131e6b88f77f3b655287d0c35ab5e Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 19:37:10 +0200 Subject: [PATCH 3/6] remove unnecessary Decimal construction --- freqtrade/persistence.py | 8 ++++---- freqtrade/tests/test_persistence.py | 8 -------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 79903d66f..e3043089f 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -187,8 +187,8 @@ class Trade(_DECL_BASE): """ open_trade_price = self.calc_open_trade_price() close_trade_price = self.calc_close_trade_price( - rate=Decimal(rate or self.close_rate), - fee=Decimal(fee or self.fee) + rate=(rate or self.close_rate), + fee=(fee or self.fee) ) return float("{0:.8f}".format(close_trade_price - open_trade_price)) @@ -206,8 +206,8 @@ class Trade(_DECL_BASE): open_trade_price = self.calc_open_trade_price() close_trade_price = self.calc_close_trade_price( - rate=Decimal(rate or self.close_rate), - fee=Decimal(fee or self.fee) + rate=(rate or self.close_rate), + fee=(fee or self.fee) ) return float("{0:.8f}".format((close_trade_price / open_trade_price) - 1)) diff --git a/freqtrade/tests/test_persistence.py b/freqtrade/tests/test_persistence.py index 401de7acb..f6c5318ce 100644 --- a/freqtrade/tests/test_persistence.py +++ b/freqtrade/tests/test_persistence.py @@ -271,10 +271,6 @@ def test_calc_profit(limit_buy_order, limit_sell_order): # Lower than open rate assert trade.calc_profit(rate=0.00000123, fee=0.003) == -0.00089092 - # Only custom fee without sell order applied - with pytest.raises(TypeError): - trade.calc_profit(fee=0.003) - # Test when we apply a Sell order. Sell higher than open rate @ 0.00001173 trade.update(limit_sell_order) assert trade.calc_profit() == 0.00006217 @@ -299,10 +295,6 @@ def test_calc_profit_percent(limit_buy_order, limit_sell_order): # Get percent of profit with a custom rate (Lower than open rate) assert trade.calc_profit_percent(rate=0.00000123) == -0.88863827 - # Only custom fee without sell order applied - with pytest.raises(TypeError): - trade.calc_profit_percent(fee=0.003) - # Test when we apply a Sell order. Sell higher than open rate @ 0.00001173 trade.update(limit_sell_order) assert trade.calc_profit_percent() == 0.06201057 From 22c48d5cefd86758a9bc1b0cdddacd7669f63533 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 19:44:33 +0200 Subject: [PATCH 4/6] use faster time diff --- freqtrade/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/main.py b/freqtrade/main.py index da17b6586..59e45b897 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -301,7 +301,7 @@ def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) - return True # Check if time matches and current rate is above threshold - time_diff = (current_time - trade.open_date).total_seconds() / 60 + time_diff = (current_time.timestamp() - trade.open_date.timestamp()) / 60 for duration, threshold in strategy.minimal_roi.items(): if time_diff > float(duration) and current_profit > threshold: return True From 4760dd699d48433f48f946bfecf1c780eb30d858 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 20:56:10 +0200 Subject: [PATCH 5/6] remove surprisingly slow logging line --- freqtrade/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/main.py b/freqtrade/main.py index 59e45b897..05ea077c3 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -306,7 +306,6 @@ def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) - if time_diff > float(duration) and current_profit > threshold: return True - logger.debug('Threshold not reached. (cur_profit: %1.2f%%)', float(current_profit) * 100.0) return False From bf46f2e50d0025241bfa6d221fb8752b0ea60ef0 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 21:16:44 +0200 Subject: [PATCH 6/6] short circuit check for roi threshold --- freqtrade/main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/freqtrade/main.py b/freqtrade/main.py index 05ea077c3..48dfb3818 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -302,10 +302,12 @@ def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) - # Check if time matches and current rate is above threshold time_diff = (current_time.timestamp() - trade.open_date.timestamp()) / 60 - for duration, threshold in strategy.minimal_roi.items(): - if time_diff > float(duration) and current_profit > threshold: + for duration_string, threshold in strategy.minimal_roi.items(): + duration = float(duration_string) + if time_diff > duration and current_profit > threshold: return True - + if time_diff < duration: + return False return False