From 7bf88333dd7dc04ea301e07ef978a02ed61f9cc0 Mon Sep 17 00:00:00 2001 From: mijgame Date: Sat, 3 Feb 2018 20:31:55 +0100 Subject: [PATCH 01/18] Fix typos (#497) * Update config_full.json.example Typo * Update config.json.example --- config.json.example | 4 ++-- config_full.json.example | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config.json.example b/config.json.example index da855f1eb..2c464a925 100644 --- a/config.json.example +++ b/config.json.example @@ -34,8 +34,8 @@ }, "telegram": { "enabled": true, - "token": "your_instagram_token", - "chat_id": "your_instagram_chat_id" + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" }, "initial_state": "running", "internals": { diff --git a/config_full.json.example b/config_full.json.example index dc5bb7162..c74b59660 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -42,8 +42,8 @@ }, "telegram": { "enabled": true, - "token": "your_instagram_token", - "chat_id": "your_instagram_chat_id" + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" }, "initial_state": "running", "internals": { From f45c64d61beece7fa5c8232e9e8763c527ab61cc Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Sat, 3 Feb 2018 20:32:16 +0100 Subject: [PATCH 02/18] Update pymarketcap from 3.3.154 to 3.3.155 (#498) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b65dcfc2e..2be9f6996 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ hyperopt==0.1 # do not upgrade networkx before this is fixed https://github.com/hyperopt/hyperopt/issues/325 networkx==1.11 tabulate==0.8.2 -pymarketcap==3.3.154 +pymarketcap==3.3.155 # Required for plotting data #plotly==2.3.0 From 2c16ba18a4aa970615c16943ceceed7a579294d1 Mon Sep 17 00:00:00 2001 From: Gerald Lonlas Date: Sat, 3 Feb 2018 12:55:15 -0800 Subject: [PATCH 03/18] Fix config generation on setup.sh --- setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.sh b/setup.sh index 7d382190c..b38f2c645 100755 --- a/setup.sh +++ b/setup.sh @@ -116,8 +116,8 @@ function config_generator () { -e "s/\"fiat_display_currency\": \"USD\",/\"fiat_display_currency\": \"$fiat_currency\",/g" \ -e "s/\"your_exchange_key\"/\"$api_key\"/g" \ -e "s/\"your_exchange_secret\"/\"$api_secret\"/g" \ - -e "s/\"your_instagram_token\"/\"$token\"/g" \ - -e "s/\"your_instagram_chat_id\"/\"$chat_id\"/g" + -e "s/\"your_telegram_token\"/\"$token\"/g" \ + -e "s/\"your_telegram_chat_id\"/\"$chat_id\"/g" -e "s/\"dry_run\": false,/\"dry_run\": true,/g" config.json.example > config.json } From 3fb3d303656ee2f389519fa39758389778f867de Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Sat, 3 Feb 2018 23:38:59 +0100 Subject: [PATCH 04/18] Update pymarketcap from 3.3.155 to 3.3.158 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2be9f6996..4c75eba6b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ hyperopt==0.1 # do not upgrade networkx before this is fixed https://github.com/hyperopt/hyperopt/issues/325 networkx==1.11 tabulate==0.8.2 -pymarketcap==3.3.155 +pymarketcap==3.3.158 # Required for plotting data #plotly==2.3.0 From 6efd74449754d2e5ed6f9e529b9513d97e5677b9 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 4 Feb 2018 09:40:29 +0200 Subject: [PATCH 05/18] change buy and sell markers in plot_dataframe --- scripts/plot_dataframe.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/scripts/plot_dataframe.py b/scripts/plot_dataframe.py index b60b60b82..71d887d60 100755 --- a/scripts/plot_dataframe.py +++ b/scripts/plot_dataframe.py @@ -80,7 +80,14 @@ def plot_analyzed_dataframe(args) -> None: y=df_buy.close, mode='markers', name='buy', - marker=dict(symbol='x-dot') + marker=dict( + symbol='triangle-up-dot', + size=9, + line=dict( + width=1, + ), + color='green', + ) ) df_sell = df[df['sell'] == 1] sells = go.Scattergl( @@ -88,7 +95,14 @@ def plot_analyzed_dataframe(args) -> None: y=df_sell.close, mode='markers', name='sell', - marker=dict(symbol='diamond') + marker=dict( + symbol='triangle-down-dot', + size=9, + line=dict( + width=1, + ), + color='red', + ) ) bb_lower = go.Scatter( From fecd9f830ec4e8e9d5d1f3a70310d42bbe3f274a Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 4 Feb 2018 15:48:41 +0200 Subject: [PATCH 06/18] use substitution in argparse --- freqtrade/misc.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 22041094c..4fa70b678 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -145,15 +145,15 @@ def common_args_parser(description: str): ) parser.add_argument( '-c', '--config', - help='specify configuration file (default: config.json)', + help='specify configuration file (default: %(default)s)', dest='config', default='config.json', type=str, metavar='PATH', ) parser.add_argument( - '--datadir', - help='path to backtest data (default freqdata/tests/testdata)', + '-d', '--datadir', + help='path to backtest data (default: %(default)s', dest='datadir', default=os.path.join('freqtrade', 'tests', 'testdata'), type=str, @@ -161,7 +161,7 @@ def common_args_parser(description: str): ) parser.add_argument( '-s', '--strategy', - help='specify strategy file (default: freqtrade/strategy/default_strategy.py)', + help='specify strategy file (default: %(default)s)', dest='strategy', default='default_strategy', type=str, @@ -254,7 +254,7 @@ def backtesting_options(parser: argparse.ArgumentParser) -> None: def hyperopt_options(parser: argparse.ArgumentParser) -> None: parser.add_argument( '-e', '--epochs', - help='specify number of epochs (default: 100)', + help='specify number of epochs (default: %(default)d)', dest='epochs', default=100, type=int, From 192521523f3894d40a8d1d77308504912618e375 Mon Sep 17 00:00:00 2001 From: macd2 Date: Mon, 5 Feb 2018 07:05:12 +0100 Subject: [PATCH 07/18] add an option to control vertical spacing (#506) --- scripts/plot_dataframe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/plot_dataframe.py b/scripts/plot_dataframe.py index 71d887d60..8cb2a7bfd 100755 --- a/scripts/plot_dataframe.py +++ b/scripts/plot_dataframe.py @@ -137,7 +137,7 @@ def plot_analyzed_dataframe(args) -> None: name='Volume' ) - fig = tools.make_subplots(rows=3, cols=1, shared_xaxes=True, row_width=[1, 1, 4]) + fig = tools.make_subplots(rows=3, cols=1, shared_xaxes=True, row_width=[1, 1, 4],vertical_spacing=0.0001) fig.append_trace(candles, 1, 1) fig.append_trace(bb_lower, 1, 1) From 8c7b29734e15a3b5894200f0710768b94ffcc2b8 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Mon, 5 Feb 2018 18:09:09 +0200 Subject: [PATCH 08/18] use date info to calculate trade durations --- freqtrade/optimize/backtesting.py | 10 +++++----- freqtrade/optimize/hyperopt.py | 2 +- freqtrade/tests/optimize/test_backtesting.py | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d6d016aba..d13708b90 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -33,7 +33,7 @@ def get_timeframe(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow] def generate_text_table( - data: Dict[str, Dict], results: DataFrame, stake_currency, ticker_interval) -> str: + data: Dict[str, Dict], results: DataFrame, stake_currency) -> str: """ Generates and returns a text table for the given backtest data and the results dataframe :return: pretty printed table with tabulate as str @@ -49,7 +49,7 @@ def generate_text_table( len(result.index), result.profit_percent.mean() * 100.0, result.profit_BTC.sum(), - result.duration.mean() * ticker_interval, + result.duration.mean(), len(result[result.profit_BTC > 0]), len(result[result.profit_BTC < 0]) ]) @@ -60,7 +60,7 @@ def generate_text_table( len(results.index), results.profit_percent.mean() * 100.0, results.profit_BTC.sum(), - results.duration.mean() * ticker_interval, + results.duration.mean(), len(results[results.profit_BTC > 0]), len(results[results.profit_BTC < 0]) ]) @@ -91,7 +91,7 @@ def get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args): return row2, (pair, trade.calc_profit_percent(rate=row2.close), trade.calc_profit(rate=row2.close), - row2.Index - row.Index + (row2.date - row.date).seconds // 60 ), row2.date return None @@ -231,5 +231,5 @@ def start(args): }) logger.info( '\n==================================== BACKTESTING REPORT ====================================\n%s', # noqa - generate_text_table(data, results, config['stake_currency'], strategy.ticker_interval) + generate_text_table(data, results, config['stake_currency']) ) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 8b89e1985..12c061b4f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -406,7 +406,7 @@ def optimizer(params): total_profit = results.profit_percent.sum() trade_count = len(results.index) - trade_duration = results.duration.mean() * 5 + trade_duration = results.duration.mean() if trade_count == 0 or trade_duration > MAX_ACCEPTED_TRADE_DURATION: print('.', end='') diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index 0dd4f777a..bf060e374 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -29,12 +29,12 @@ def test_generate_text_table(): 'loss': [0, 0] } ) - print(generate_text_table({'BTC_ETH': {}}, results, 'BTC', 5)) - assert generate_text_table({'BTC_ETH': {}}, results, 'BTC', 5) == ( + print(generate_text_table({'BTC_ETH': {}}, results, 'BTC')) + assert generate_text_table({'BTC_ETH': {}}, results, 'BTC') == ( 'pair buy count avg profit % total profit BTC avg duration profit loss\n' # noqa '------- ----------- -------------- ------------------ -------------- -------- ------\n' # noqa - 'BTC_ETH 2 15.00 0.60000000 100.0 2 0\n' # noqa - 'TOTAL 2 15.00 0.60000000 100.0 2 0') # noqa + 'BTC_ETH 2 15.00 0.60000000 20.0 2 0\n' # noqa + 'TOTAL 2 15.00 0.60000000 20.0 2 0') # noqa def test_get_timeframe(default_strategy): From cf7c6d2e9c390c5118ac6baf84a9a42bd30677cc Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Mon, 5 Feb 2018 19:22:49 +0200 Subject: [PATCH 09/18] switch to properly using dates as indexes, makes date based searching and slicing a lot faster --- freqtrade/optimize/backtesting.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d13708b90..e7d2a0d8e 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -71,28 +71,28 @@ def get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args): stake_amount = args['stake_amount'] max_open_trades = args.get('max_open_trades', 0) trade = Trade(open_rate=row.close, - open_date=row.date, + open_date=row.Index, stake_amount=stake_amount, amount=stake_amount / row.open, fee=exchange.get_fee() ) # calculate win/lose forwards from buy point - sell_subset = ticker[ticker.date > row.date][['close', 'date', 'sell']] + sell_subset = ticker[ticker.index > row.Index][['close', 'sell']] for row2 in sell_subset.itertuples(index=True): if max_open_trades > 0: # Increase trade_count_lock for every iteration - trade_count_lock[row2.date] = trade_count_lock.get(row2.date, 0) + 1 + 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 = not buy_subset[buy_subset.date == row2.date].empty - if(should_sell(trade, row2.close, row2.date, buy_signal, row2.sell)): + buy_signal = not buy_subset[buy_subset.index == row2.Index].empty + if(should_sell(trade, row2.close, row2.Index, buy_signal, row2.sell)): return row2, (pair, trade.calc_profit_percent(rate=row2.close), trade.calc_profit(rate=row2.close), - (row2.date - row.date).seconds // 60 - ), row2.date + (row2.Index - row.Index).seconds // 60 + ), row2.Index return None @@ -120,22 +120,23 @@ def backtest(args) -> DataFrame: for pair, pair_data in processed.items(): pair_data['buy'], pair_data['sell'] = 0, 0 ticker = populate_sell_trend(populate_buy_trend(pair_data)) + ticker.set_index('date', inplace=True) # for each buy point lock_pair_until = None - headers = ['buy', 'open', 'close', 'date', 'sell'] + headers = ['buy', 'open', 'close', 'sell'] buy_subset = ticker[(ticker.buy == 1) & (ticker.sell == 0)][headers] for row in buy_subset.itertuples(index=True): if realistic: - if lock_pair_until is not None and row.date <= lock_pair_until: + if lock_pair_until is not None and row.Index <= lock_pair_until: continue if max_open_trades > 0: # Check if max_open_trades has already been reached for the given date - if not trade_count_lock.get(row.date, 0) < max_open_trades: + if not trade_count_lock.get(row.Index, 0) < max_open_trades: continue if max_open_trades > 0: # Increase lock - trade_count_lock[row.date] = trade_count_lock.get(row.date, 0) + 1 + trade_count_lock[row.Index] = trade_count_lock.get(row.Index, 0) + 1 ret = get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args) @@ -148,8 +149,8 @@ def backtest(args) -> DataFrame: # record a tuple of pair, current_profit_percent, # entry-date, duration records.append((pair, trade_entry[1], - row.date.strftime('%s'), - row2.date.strftime('%s'), + row.Index.strftime('%s'), + row2.Index.strftime('%s'), row.Index, trade_entry[3])) # For now export inside backtest(), maybe change so that backtest() # returns a tuple like: (dataframe, records, logs, etc) From 5cf2dd79f27351880ad685d1ef78bd45dae87730 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 11:33:38 +0200 Subject: [PATCH 10/18] don't reset index if not needed --- freqtrade/optimize/backtesting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index e7d2a0d8e..ea03803fc 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -120,7 +120,8 @@ def backtest(args) -> DataFrame: for pair, pair_data in processed.items(): pair_data['buy'], pair_data['sell'] = 0, 0 ticker = populate_sell_trend(populate_buy_trend(pair_data)) - ticker.set_index('date', inplace=True) + if 'date' in ticker: + ticker.set_index('date', inplace=True) # for each buy point lock_pair_until = None headers = ['buy', 'open', 'close', 'sell'] From a071571eac51b6b91f849421ddf540a68cfb17e2 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 12:13:12 +0200 Subject: [PATCH 11/18] switch to faster short circuiting condition --- freqtrade/optimize/backtesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ea03803fc..bfe8c33eb 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -86,7 +86,7 @@ def get_sell_trade_entry(pair, row, buy_subset, ticker, trade_count_lock, args): # Buy is on is in the buy_subset there is a row that matches the date # of the sell event - buy_signal = not buy_subset[buy_subset.index == row2.Index].empty + buy_signal = (buy_subset.index == row2.Index).any() if(should_sell(trade, row2.close, row2.Index, buy_signal, row2.sell)): return row2, (pair, trade.calc_profit_percent(rate=row2.close), From a28ffcbcf7bafe28ae539e27380e3531a4ed1fb8 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Tue, 6 Feb 2018 15:50:06 +0200 Subject: [PATCH 12/18] 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 13/18] 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 14/18] 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 15/18] 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 16/18] 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 17/18] 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 From 6f80aff3e2f48e17c39a509e17071b0fac144309 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Thu, 8 Feb 2018 13:32:34 +0200 Subject: [PATCH 18/18] cleanup plot scripts --- scripts/plot_dataframe.py | 48 ++++++++++++--------------------------- scripts/plot_profit.py | 2 -- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/scripts/plot_dataframe.py b/scripts/plot_dataframe.py index 8cb2a7bfd..e62465bf7 100755 --- a/scripts/plot_dataframe.py +++ b/scripts/plot_dataframe.py @@ -2,24 +2,15 @@ import sys import logging -import argparse -import os -from pandas import DataFrame -import talib.abstract as ta - -import plotly from plotly import tools from plotly.offline import plot import plotly.graph_objs as go -import freqtrade.vendor.qtpylib.indicators as qtpylib from freqtrade import exchange, analyze -from freqtrade.misc import common_args_parser from freqtrade.strategy.strategy import Strategy import freqtrade.misc as misc import freqtrade.optimize as optimize -import freqtrade.analyze as analyze logger = logging.getLogger(__name__) @@ -61,18 +52,17 @@ def plot_analyzed_dataframe(args) -> None: dataframe = dataframes[pair] dataframe = analyze.populate_buy_trend(dataframe) dataframe = analyze.populate_sell_trend(dataframe) - dates = misc.datesarray_to_datetimearray(dataframe['date']) if (len(dataframe.index) > 750): logger.warn('Ticker contained more than 750 candles, clipping.') df = dataframe.tail(750) candles = go.Candlestick(x=df.date, - open=df.open, - high=df.high, - low=df.low, - close=df.close, - name='Price') + open=df.open, + high=df.high, + low=df.low, + close=df.close, + name='Price') df_buy = df[df['buy'] == 1] buys = go.Scattergl( @@ -116,28 +106,20 @@ def plot_analyzed_dataframe(args) -> None: y=df.bb_upperband, name='BB upper', fill="tonexty", - fillcolor="rgba(0,176,246,0.2)", + fillcolor="rgba(0,176,246,0.2)", line={'color': "transparent"}, ) + macd = go.Scattergl(x=df['date'], y=df['macd'], name='MACD') + macdsignal = go.Scattergl(x=df['date'], y=df['macdsignal'], name='MACD signal') + volume = go.Bar(x=df['date'], y=df['volume'], name='Volume') - macd = go.Scattergl( - x=df['date'], - y=df['macd'], - name='MACD' + fig = tools.make_subplots( + rows=3, + cols=1, + shared_xaxes=True, + row_width=[1, 1, 4], + vertical_spacing=0.0001, ) - macdsignal = go.Scattergl( - x=df['date'], - y=df['macdsignal'], - name='MACD signal' - ) - - volume = go.Bar( - x=df['date'], - y=df['volume'], - name='Volume' - ) - - fig = tools.make_subplots(rows=3, cols=1, shared_xaxes=True, row_width=[1, 1, 4],vertical_spacing=0.0001) fig.append_trace(candles, 1, 1) fig.append_trace(bb_lower, 1, 1) diff --git a/scripts/plot_profit.py b/scripts/plot_profit.py index 6e15b3bb6..c51b29309 100755 --- a/scripts/plot_profit.py +++ b/scripts/plot_profit.py @@ -4,14 +4,12 @@ import sys import json import numpy as np -import plotly from plotly import tools from plotly.offline import plot import plotly.graph_objs as go import freqtrade.optimize as optimize import freqtrade.misc as misc -import freqtrade.exchange as exchange from freqtrade.strategy.strategy import Strategy