From 9199fd5964e72f6ee35f973eb405731b5ebbae9b Mon Sep 17 00:00:00 2001 From: gaugau3000 Date: Thu, 28 Nov 2019 21:21:43 +0100 Subject: [PATCH 0001/1106] change doc into --- docs/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 206d635c6..6d9951a67 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,8 +12,7 @@ Follow @freqtrade ## Introduction -Freqtrade is a cryptocurrency trading bot written in Python. - +Freqtrade is a crypto-currency algorithmic trading software develop in python (3.6+) supported on windows, macOs and Linux. !!! Danger "DISCLAIMER" This software is for educational purposes only. Do not risk money which you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS. From 0e9e6b34438105ebc1f8dafa657c32fed815525b Mon Sep 17 00:00:00 2001 From: gaugau3000 Date: Thu, 28 Nov 2019 21:22:40 +0100 Subject: [PATCH 0002/1106] refactor feature details doc --- docs/index.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6d9951a67..d5eb271d9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,18 +22,13 @@ Freqtrade is a crypto-currency algorithmic trading software develop in python (3 ## Features - - Based on Python 3.6+: For botting on any operating system — Windows, macOS and Linux. - - Persistence: Persistence is achieved through sqlite database. - - Dry-run mode: Run the bot without playing money. - - Backtesting: Run a simulation of your buy/sell strategy with historical data. - - Strategy Optimization by machine learning: Use machine learning to optimize your buy/sell strategy parameters with real exchange data. - - Edge position sizing: Calculate your win rate, risk reward ratio, the best stoploss and adjust your position size before taking a position for each specific market. - - Whitelist crypto-currencies: Select which crypto-currency you want to trade or use dynamic whitelists based on market (pair) trade volume. - - Blacklist crypto-currencies: Select which crypto-currency you want to avoid. - - Manageable via Telegram or REST APi: Manage the bot with Telegram or via the builtin REST API. - - Display profit/loss in fiat: Display your profit/loss in any of 33 fiat currencies supported. - - Daily summary of profit/loss: Receive the daily summary of your profit/loss. - - Performance status report: Receive the performance status of your current trades. + 1. Download markets datas : download historical datas of the exchange and the markets your may want to trade with. + 2. Select markets : create your list or use an automatic one based on top traded volume (not available during backtesting). You can blacklist markets you don't want to trade. + 3. Backtest : Test your strategy on past datas (based on [ohcl](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles). + 4. Optimize : Find the best parameters for your strategy (use machine leaning) + 5. Run : Run the bot on exchange without playing money (dry-run) or with money (live). + 6. Run using edge (optionnal module) : the concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade (the sizing of the trade is based on a risk of a percentage of your capital) + 7. Control/Monitor/Analyse : use Telegram or a REST API (start/stop the bot, profit/loss, daily summary, current open trades results...). Futher analysis can be done as trades are saved (SQLite database) ## Requirements From 58d70b2079638244b51d84fd297c0e5dd8a77213 Mon Sep 17 00:00:00 2001 From: gaugau3000 Date: Fri, 29 Nov 2019 09:35:13 +0100 Subject: [PATCH 0003/1106] doc explicit optimization feature --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index d5eb271d9..5871479d9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ Freqtrade is a crypto-currency algorithmic trading software develop in python (3 1. Download markets datas : download historical datas of the exchange and the markets your may want to trade with. 2. Select markets : create your list or use an automatic one based on top traded volume (not available during backtesting). You can blacklist markets you don't want to trade. 3. Backtest : Test your strategy on past datas (based on [ohcl](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles). - 4. Optimize : Find the best parameters for your strategy (use machine leaning) + 4. Optimize : Find the best parameters for your strategy (use machining learning). You can optimize buy, sell, take profit and stop-loss. 5. Run : Run the bot on exchange without playing money (dry-run) or with money (live). 6. Run using edge (optionnal module) : the concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade (the sizing of the trade is based on a risk of a percentage of your capital) 7. Control/Monitor/Analyse : use Telegram or a REST API (start/stop the bot, profit/loss, daily summary, current open trades results...). Futher analysis can be done as trades are saved (SQLite database) From 5db883906af22eeb086174d1fcfae149f6978ed4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Dec 2019 06:52:33 +0100 Subject: [PATCH 0004/1106] Try to verify available amount on the exchange --- freqtrade/freqtradebot.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 0595e0d35..ac73f6d65 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -889,6 +889,27 @@ class FreqtradeBot: # TODO: figure out how to handle partially complete sell orders return False + def _safe_sell_amount(self, pair: str, amount: float) -> float: + """ + Get sellable amount. + Should be trade.amount - but will fall back to the available amount if necessary. + This should cover cases where get_real_amount() was not able to update the amount + for whatever reason. + :param pair: pair - used for logging + :param amount: amount we expect to be available + :return: amount to sell + :raise: DependencyException: if available balance is not within 2% of the available amount. + """ + wallet_amount = self.wallets.get_free(pair) + logger.info(f"Amounts: {wallet_amount} - {amount}") + if wallet_amount > amount: + return amount + elif wallet_amount > amount * 0.98: + logger.info(f"{pair} - Falling back to wallet-amount.") + return wallet_amount + else: + raise DependencyException("Not enough amount to sell.") + def execute_sell(self, trade: Trade, limit: float, sell_reason: SellType) -> None: """ Executes a limit sell for the given trade and limit @@ -919,10 +940,12 @@ class FreqtradeBot: # Emergencysells (default to market!) ordertype = self.strategy.order_types.get("emergencysell", "market") + amount = self._safe_sell_amount(trade.pair, trade.amount) + # Execute sell and update trade record order = self.exchange.sell(pair=str(trade.pair), ordertype=ordertype, - amount=trade.amount, rate=limit, + amount=amount, rate=limit, time_in_force=self.strategy.order_time_in_force['sell'] ) From 04257d8ecc357dea23face544f8e979834a20e19 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 13 Dec 2019 07:06:54 +0100 Subject: [PATCH 0005/1106] Add tests for safe_sell_amount --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 76 +++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ac73f6d65..3ebe89a71 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -901,7 +901,7 @@ class FreqtradeBot: :raise: DependencyException: if available balance is not within 2% of the available amount. """ wallet_amount = self.wallets.get_free(pair) - logger.info(f"Amounts: {wallet_amount} - {amount}") + logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount > amount: return amount elif wallet_amount > amount * 0.98: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index efab64a6a..9c2fd9ddc 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -883,7 +883,7 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: 'freqtrade.freqtradebot.FreqtradeBot', get_target_bid=get_bid, _get_min_pair_stake_amount=MagicMock(return_value=1) - ) + ) buy_mm = MagicMock(return_value={'id': limit_buy_order['id']}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -2314,6 +2314,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException()) + mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=300)) sellmock = MagicMock() patch_exchange(mocker) mocker.patch.multiple( @@ -2591,7 +2592,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple( - sell_flag=False, sell_type=SellType.NONE)) + sell_flag=False, sell_type=SellType.NONE)) freqtrade.create_trades() trade = Trade.query.first() @@ -2631,6 +2632,77 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke assert trade.sell_reason == SellType.SELL_SIGNAL.value +def test_sell_not_enough_balance(default_conf, limit_buy_order, + fee, mocker, caplog) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + get_ticker=MagicMock(return_value={ + 'bid': 0.00002172, + 'ask': 0.00002173, + 'last': 0.00002172 + }), + buy=MagicMock(return_value={'id': limit_buy_order['id']}), + get_fee=fee, + ) + + freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) + freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) + + freqtrade.create_trades() + + trade = Trade.query.first() + amnt = trade.amount + trade.update(limit_buy_order) + patch_get_signal(freqtrade, value=(False, True)) + mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=trade.amount * 0.985)) + + assert freqtrade.handle_trade(trade) is True + assert log_has_re(r'.*Falling back to wallet-amount.', caplog) + assert trade.amount != amnt + + +def test__safe_sell_amount(default_conf, caplog, mocker): + patch_RPCManager(mocker) + patch_exchange(mocker) + amount = 95.33 + amount_wallet = 95.29 + mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=amount_wallet)) + trade = Trade( + pair='LTC/ETH', + amount=amount, + exchange='binance', + open_rate=0.245441, + open_order_id="123456" + ) + freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) + + assert freqtrade._safe_sell_amount(trade.pair, trade.amount) == amount_wallet + assert log_has_re(r'.*Falling back to wallet-amount.', caplog) + + +def test__safe_sell_amount_error(default_conf, caplog, mocker): + patch_RPCManager(mocker) + patch_exchange(mocker) + amount = 95.33 + amount_wallet = 91.29 + mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=amount_wallet)) + trade = Trade( + pair='LTC/ETH', + amount=amount, + exchange='binance', + open_rate=0.245441, + open_order_id="123456" + ) + freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) + with pytest.raises(DependencyException, match=r"Not enough amount to sell."): + assert freqtrade._safe_sell_amount(trade.pair, trade.amount) + + def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplog) -> None: patch_RPCManager(mocker) patch_exchange(mocker) From 21622ac3138713555784e1ee58cfe61e127fcb40 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 16:34:30 +0100 Subject: [PATCH 0006/1106] Rename get_ticker to fetch_ticker --- freqtrade/exchange/exchange.py | 2 +- freqtrade/freqtradebot.py | 6 +- tests/exchange/test_exchange.py | 14 +-- tests/rpc/test_rpc.py | 36 +++---- tests/rpc/test_rpc_apiserver.py | 12 +-- tests/rpc/test_rpc_telegram.py | 28 +++--- tests/test_freqtradebot.py | 170 ++++++++++++++++---------------- tests/test_integration.py | 4 +- 8 files changed, 136 insertions(+), 136 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index e4e7aacce..384ec1fb7 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -524,7 +524,7 @@ class Exchange: raise OperationalException(e) from e @retrier - def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: + def fetch_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: if refresh or pair not in self._cached_ticker.keys(): try: if pair not in self._api.markets or not self._api.markets[pair].get('active'): diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8ae027fa2..ea9b892d7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -192,7 +192,7 @@ class FreqtradeBot: else: if not tick: logger.info('Using Last Ask / Last Price') - ticker = self.exchange.get_ticker(pair) + ticker = self.exchange.fetch_ticker(pair) else: ticker = tick if ticker['ask'] < ticker['last']: @@ -570,7 +570,7 @@ class FreqtradeBot: """ Get sell rate - either using get-ticker bid or first bid based on orderbook The orderbook portion is only used for rpc messaging, which would otherwise fail - for BitMex (has no bid/ask in get_ticker) + for BitMex (has no bid/ask in fetch_ticker) or remain static in any other case since it's not updating. :return: Bid rate """ @@ -582,7 +582,7 @@ class FreqtradeBot: rate = order_book['bids'][0][0] else: - rate = self.exchange.get_ticker(pair, refresh)['bid'] + rate = self.exchange.fetch_ticker(pair, refresh)['bid'] return rate def handle_trade(self, trade: Trade) -> bool: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 629f99aa2..7c273da9f 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -977,7 +977,7 @@ def test_get_tickers(default_conf, mocker, exchange_name): @pytest.mark.parametrize("exchange_name", EXCHANGES) -def test_get_ticker(default_conf, mocker, exchange_name): +def test_fetch_ticker(default_conf, mocker, exchange_name): api_mock = MagicMock() tick = { 'symbol': 'ETH/BTC', @@ -989,7 +989,7 @@ def test_get_ticker(default_conf, mocker, exchange_name): api_mock.markets = {'ETH/BTC': {'active': True}} exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) # retrieve original ticker - ticker = exchange.get_ticker(pair='ETH/BTC') + ticker = exchange.fetch_ticker(pair='ETH/BTC') assert ticker['bid'] == 0.00001098 assert ticker['ask'] == 0.00001099 @@ -1006,7 +1006,7 @@ def test_get_ticker(default_conf, mocker, exchange_name): # if not caching the result we should get the same ticker # if not fetching a new result we should get the cached ticker - ticker = exchange.get_ticker(pair='ETH/BTC') + ticker = exchange.fetch_ticker(pair='ETH/BTC') assert api_mock.fetch_ticker.call_count == 1 assert ticker['bid'] == 0.5 @@ -1018,19 +1018,19 @@ def test_get_ticker(default_conf, mocker, exchange_name): # Test caching api_mock.fetch_ticker = MagicMock() - exchange.get_ticker(pair='ETH/BTC', refresh=False) + exchange.fetch_ticker(pair='ETH/BTC', refresh=False) assert api_mock.fetch_ticker.call_count == 0 ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, - "get_ticker", "fetch_ticker", + "fetch_ticker", "fetch_ticker", pair='ETH/BTC', refresh=True) api_mock.fetch_ticker = MagicMock(return_value={}) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) - exchange.get_ticker(pair='ETH/BTC', refresh=True) + exchange.fetch_ticker(pair='ETH/BTC', refresh=True) with pytest.raises(DependencyException, match=r'Pair XRP/ETH not available'): - exchange.get_ticker(pair='XRP/ETH', refresh=True) + exchange.fetch_ticker(pair='XRP/ETH', refresh=True) @pytest.mark.parametrize("exchange_name", EXCHANGES) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 0a8c1cabd..3b897572c 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -29,7 +29,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -65,7 +65,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_order': '(limit buy rem=0.00000000)' } == results[0] - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) # invalidate ticker cache rpc._freqtrade.exchange._cached_ticker = {} @@ -104,7 +104,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -134,7 +134,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert 'ETH/BTC' == result[0][1] assert '-0.59% (-0.09)' == result[0][3] - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) # invalidate ticker cache rpc._freqtrade.exchange._cached_ticker = {} @@ -149,7 +149,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -201,7 +201,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -225,7 +225,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, # Update the ticker with a market going up mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up + fetch_ticker=ticker_sell_up ) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() @@ -239,7 +239,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, # Update the ticker with a market going up mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up + fetch_ticker=ticker_sell_up ) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() @@ -260,7 +260,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, assert prec_satoshi(stats['best_rate'], 6.2) # Test non-available pair - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) # invalidate ticker cache rpc._freqtrade.exchange._cached_ticker = {} @@ -287,7 +287,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -306,7 +306,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, # Update the ticker with a market going up mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up, + fetch_ticker=ticker_sell_up, get_fee=fee ) trade.update(limit_sell_order) @@ -439,7 +439,7 @@ def test_rpc_start(mocker, default_conf) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock() + fetch_ticker=MagicMock() ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) @@ -460,7 +460,7 @@ def test_rpc_stop(mocker, default_conf) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock() + fetch_ticker=MagicMock() ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) @@ -482,7 +482,7 @@ def test_rpc_stopbuy(mocker, default_conf) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock() + fetch_ticker=MagicMock() ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) @@ -502,7 +502,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: cancel_order_mock = MagicMock() mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, cancel_order=cancel_order_mock, get_order=MagicMock( return_value={ @@ -604,7 +604,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee, mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -637,7 +637,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -661,7 +661,7 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, limit_buy_order) -> None mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, buy=buy_mm ) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index f1e3421c5..36bb81e41 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -256,7 +256,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets): mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -292,7 +292,7 @@ def test_api_daily(botclient, mocker, ticker, fee, markets): mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -308,7 +308,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -323,7 +323,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -413,7 +413,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets): mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) @@ -541,7 +541,7 @@ def test_api_forcesell(botclient, mocker, ticker, fee, markets): mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets) ) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index b02f11394..ed2aad37e 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -150,7 +150,7 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) msg_mock = MagicMock() @@ -204,7 +204,7 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: def test_status_handle(default_conf, update, ticker, fee, mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) msg_mock = MagicMock() @@ -254,7 +254,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None: def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': 'mocked_order_id'}), get_fee=fee, ) @@ -307,7 +307,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) msg_mock = MagicMock() @@ -373,7 +373,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker + fetch_ticker=ticker ) msg_mock = MagicMock() mocker.patch.multiple( @@ -411,7 +411,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) msg_mock = MagicMock() @@ -443,7 +443,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, msg_mock.reset_mock() # Update the ticker with a market going up - mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up) + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', ticker_sell_up) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() @@ -700,7 +700,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, patch_whitelist(mocker, default_conf) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -715,7 +715,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, assert trade # Increase the price and sell it - mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up) + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', ticker_sell_up) # /forcesell 1 context = MagicMock() @@ -755,7 +755,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) @@ -769,7 +769,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, # Decrease the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_down + fetch_ticker=ticker_sell_down ) trade = Trade.query.first() @@ -812,7 +812,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None patch_whitelist(mocker, default_conf) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) default_conf['max_open_trades'] = 4 @@ -963,7 +963,7 @@ def test_performance_handle(default_conf, update, ticker, fee, ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) @@ -998,7 +998,7 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': 'mocked_order_id'}), get_fee=fee, ) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 341bc021f..13f1277b9 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -157,7 +157,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, patch_wallet(mocker, free=default_conf['stake_amount']) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee ) @@ -232,7 +232,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf buy_price = limit_buy_order['price'] mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': buy_price * 0.79, 'ask': buy_price * 0.79, 'last': buy_price * 0.79 @@ -272,7 +272,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, buy_price = limit_buy_order['price'] mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': buy_price * 0.85, 'ask': buy_price * 0.85, 'last': buy_price * 0.85 @@ -304,7 +304,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker, default_conf['max_open_trades'] = 2 mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -467,7 +467,7 @@ def test_create_trades(default_conf, ticker, limit_buy_order, fee, mocker) -> No patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -501,7 +501,7 @@ def test_create_trades_no_stake_amount(default_conf, ticker, limit_buy_order, patch_wallet(mocker, free=default_conf['stake_amount'] * 0.5) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -519,7 +519,7 @@ def test_create_trades_minimal_amount(default_conf, ticker, limit_buy_order, buy_mock = MagicMock(return_value={'id': limit_buy_order['id']}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=buy_mock, get_fee=fee, ) @@ -539,7 +539,7 @@ def test_create_trades_too_small_stake_amount(default_conf, ticker, limit_buy_or buy_mock = MagicMock(return_value={'id': limit_buy_order['id']}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=buy_mock, get_fee=fee, ) @@ -558,7 +558,7 @@ def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_balance=MagicMock(return_value=default_conf['stake_amount']), get_fee=fee, @@ -579,7 +579,7 @@ def test_create_trades_no_pairs_let(default_conf, ticker, limit_buy_order, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -600,7 +600,7 @@ def test_create_trades_no_pairs_in_whitelist(default_conf, ticker, limit_buy_ord patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -639,7 +639,7 @@ def test_create_trades_multiple_trades(default_conf, ticker, default_conf['max_open_trades'] = max_open mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': "12355555"}), get_fee=fee, ) @@ -658,7 +658,7 @@ def test_create_trades_preopen(default_conf, ticker, fee, mocker) -> None: default_conf['max_open_trades'] = 4 mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': "12355555"}), get_fee=fee, ) @@ -684,7 +684,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_order=MagicMock(return_value=limit_buy_order), get_fee=fee, @@ -718,7 +718,7 @@ def test_process_exchange_failures(default_conf, ticker, mocker) -> None: patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(side_effect=TemporaryError) ) sleep_mock = mocker.patch('time.sleep', side_effect=lambda _: None) @@ -735,7 +735,7 @@ def test_process_operational_exception(default_conf, ticker, mocker) -> None: patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(side_effect=OperationalException) ) worker = Worker(args=None, config=default_conf) @@ -753,7 +753,7 @@ def test_process_trade_handling(default_conf, ticker, limit_buy_order, fee, mock patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_order=MagicMock(return_value=limit_buy_order), get_fee=fee, @@ -780,7 +780,7 @@ def test_process_trade_no_whitelist_pair(default_conf, ticker, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_order=MagicMock(return_value=limit_buy_order), get_fee=fee, @@ -830,7 +830,7 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: refresh_mock = MagicMock() mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(side_effect=TemporaryError), refresh_latest_ohlcv=refresh_mock, ) @@ -853,7 +853,7 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: def test_balance_fully_ask_side(mocker, default_conf) -> None: default_conf['bid_strategy']['ask_last_balance'] = 0.0 freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 20, 'last': 10})) assert freqtrade.get_target_bid('ETH/BTC') == 20 @@ -862,7 +862,7 @@ def test_balance_fully_ask_side(mocker, default_conf) -> None: def test_balance_fully_last_side(mocker, default_conf) -> None: default_conf['bid_strategy']['ask_last_balance'] = 1.0 freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 20, 'last': 10})) assert freqtrade.get_target_bid('ETH/BTC') == 10 @@ -871,7 +871,7 @@ def test_balance_fully_last_side(mocker, default_conf) -> None: def test_balance_bigger_last_ask(mocker, default_conf) -> None: default_conf['bid_strategy']['ask_last_balance'] = 1.0 freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 5, 'last': 10})) assert freqtrade.get_target_bid('ETH/BTC') == 5 @@ -891,7 +891,7 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: buy_mm = MagicMock(return_value={'id': limit_buy_order['id']}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1000,7 +1000,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1100,7 +1100,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1134,7 +1134,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee, sell_mock = MagicMock(return_value={'id': limit_sell_order['id']}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1177,7 +1177,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, patch_RPCManager(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1231,7 +1231,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, assert freqtrade.handle_stoploss_on_exchange(trade) is False # price jumped 2x - mocker.patch('freqtrade.exchange.Exchange.get_ticker', MagicMock(return_value={ + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': 0.00002344, 'ask': 0.00002346, 'last': 0.00002344 @@ -1271,7 +1271,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1342,7 +1342,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, edge_conf['dry_run_wallet'] = 999.9 mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1406,7 +1406,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_order_mock) # price goes down 5% - mocker.patch('freqtrade.exchange.Exchange.get_ticker', MagicMock(return_value={ + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': 0.00001172 * 0.95, 'ask': 0.00001173 * 0.95, 'last': 0.00001172 * 0.95 @@ -1422,7 +1422,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, cancel_order_mock.assert_not_called() # price jumped 2x - mocker.patch('freqtrade.exchange.Exchange.get_ticker', MagicMock(return_value={ + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': 0.00002344, 'ask': 0.00002346, 'last': 0.00002344 @@ -1662,7 +1662,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -1701,7 +1701,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -1754,7 +1754,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order, patch_RPCManager(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -1786,7 +1786,7 @@ def test_handle_trade_use_sell_signal( patch_RPCManager(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -1814,7 +1814,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -1842,7 +1842,7 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, op patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old), cancel_order=cancel_order_mock, get_fee=fee @@ -1869,7 +1869,7 @@ def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old, o limit_buy_order_old.update({"status": "canceled"}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old), cancel_order=cancel_order_mock, get_fee=fee @@ -1896,7 +1896,7 @@ def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_ord mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(side_effect=DependencyException), cancel_order=cancel_order_mock, get_fee=fee @@ -1921,7 +1921,7 @@ def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_sell_order_old), cancel_order=cancel_order_mock ) @@ -1949,7 +1949,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_sell_order_old), cancel_order=cancel_order_mock ) @@ -1976,7 +1976,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), cancel_order=cancel_order_mock ) @@ -2003,7 +2003,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), cancel_order=cancel_order_mock, get_trades_for_order=MagicMock(return_value=trades_for_order), @@ -2040,7 +2040,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), cancel_order=cancel_order_mock, get_trades_for_order=MagicMock(return_value=trades_for_order), @@ -2084,7 +2084,7 @@ def test_check_handle_timedout_exception(default_conf, ticker, open_trade, mocke ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_order=MagicMock(side_effect=requests.exceptions.RequestException('Oh snap')), cancel_order=cancel_order_mock ) @@ -2174,7 +2174,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) patch_whitelist(mocker, default_conf) @@ -2190,7 +2190,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N # Increase the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up + fetch_ticker=ticker_sell_up ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], sell_reason=SellType.ROI) @@ -2222,7 +2222,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) patch_whitelist(mocker, default_conf) @@ -2238,7 +2238,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) # Decrease the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_down + fetch_ticker=ticker_sell_down ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], @@ -2272,7 +2272,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) patch_whitelist(mocker, default_conf) @@ -2288,7 +2288,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe # Decrease the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_down + fetch_ticker=ticker_sell_down ) default_conf['dry_run'] = True @@ -2330,7 +2330,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, c patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, sell=sellmock ) @@ -2367,7 +2367,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke cancel_order = MagicMock(return_value=True) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, @@ -2391,7 +2391,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke # Increase the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up + fetch_ticker=ticker_sell_up ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], @@ -2410,7 +2410,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, @@ -2474,7 +2474,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) patch_whitelist(mocker, default_conf) @@ -2490,7 +2490,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, # Increase the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_up + fetch_ticker=ticker_sell_up ) freqtrade.config['order_types']['sell'] = 'market' @@ -2528,7 +2528,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00002172, 'ask': 0.00002173, 'last': 0.00002172 @@ -2559,7 +2559,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00002172, 'ask': 0.00002173, 'last': 0.00002172 @@ -2588,7 +2588,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00000172, 'ask': 0.00000173, 'last': 0.00000172 @@ -2617,7 +2617,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.0000172, 'ask': 0.0000173, 'last': 0.0000172 @@ -2648,7 +2648,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, ) freqtrade = FreqtradeBot(default_conf) @@ -2663,7 +2663,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo # Decrease the price and sell it mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker_sell_down + fetch_ticker=ticker_sell_down ) freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'], @@ -2684,7 +2684,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.0000172, 'ask': 0.0000173, 'last': 0.0000172 @@ -2717,7 +2717,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001099, 'ask': 0.00001099, 'last': 0.00001099 @@ -2736,7 +2736,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) assert freqtrade.handle_trade(trade) is False # Raise ticker above buy price - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': 0.00001099 * 1.5, 'ask': 0.00001099 * 1.5, @@ -2747,7 +2747,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) assert freqtrade.handle_trade(trade) is False # Price fell - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': 0.00001099 * 1.1, 'ask': 0.00001099 * 1.1, @@ -2771,7 +2771,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': buy_price - 0.000001, 'ask': buy_price - 0.000001, 'last': buy_price - 0.000001 @@ -2795,7 +2795,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, assert freqtrade.handle_trade(trade) is False # Raise ticker above buy price - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.000003, 'ask': buy_price + 0.000003, @@ -2807,7 +2807,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, assert log_has(f"ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000138501 - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.000002, 'ask': buy_price + 0.000002, @@ -2828,7 +2828,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': buy_price - 0.000001, 'ask': buy_price - 0.000001, 'last': buy_price - 0.000001 @@ -2852,7 +2852,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, assert freqtrade.handle_trade(trade) is False # Raise ticker above buy price - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.000003, 'ask': buy_price + 0.000003, @@ -2865,7 +2865,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, assert log_has(f"ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000138501 - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.000002, 'ask': buy_price + 0.000002, @@ -2889,7 +2889,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': buy_price, 'ask': buy_price, 'last': buy_price @@ -2916,7 +2916,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, assert trade.stop_loss == 0.0000098910 # Raise ticker above buy price - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.0000004, 'ask': buy_price + 0.0000004, @@ -2930,7 +2930,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, assert trade.stop_loss == 0.0000098910 # price rises above the offset (rises 12% when the offset is 5.5%) - mocker.patch('freqtrade.exchange.Exchange.get_ticker', + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ 'bid': buy_price + 0.0000014, 'ask': buy_price + 0.0000014, @@ -2950,7 +2950,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order, patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00000172, 'ask': 0.00000173, 'last': 0.00000172 @@ -3287,7 +3287,7 @@ def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee, mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -3324,7 +3324,7 @@ def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_o mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) @@ -3347,7 +3347,7 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_order_book=order_book_l2, - get_ticker=ticker_mock, + fetch_ticker=ticker_mock, ) default_conf['exchange']['name'] = 'binance' @@ -3371,7 +3371,7 @@ def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_order_book=order_book_l2, - get_ticker=ticker_mock, + fetch_ticker=ticker_mock, ) default_conf['exchange']['name'] = 'binance' @@ -3421,7 +3421,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=MagicMock(return_value={ + fetch_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 @@ -3451,7 +3451,7 @@ def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_order_book=order_book_l2, - get_ticker=ticker, + fetch_ticker=ticker, ) pair = "ETH/BTC" @@ -3530,7 +3530,7 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, buy=MagicMock(return_value={'id': limit_buy_order['id']}), get_fee=fee, ) diff --git a/tests/test_integration.py b/tests/test_integration.py index 728e96d55..a80600cdc 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -55,7 +55,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, @@ -126,7 +126,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc )) mocker.patch.multiple( 'freqtrade.exchange.Exchange', - get_ticker=ticker, + fetch_ticker=ticker, get_fee=fee, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, From dc07037edfc2bebed2d3815c986a999d281c5b0e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 16:38:57 +0100 Subject: [PATCH 0007/1106] Add documentation for price finding --- docs/configuration.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 73534b6f1..bfa29529d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -393,6 +393,41 @@ The valid values are: "BTC", "ETH", "XRP", "LTC", "BCH", "USDT" ``` +## Prices used for orders + +Prices for regular orders can be controlled via the parameter structures `bid_strategy` for Buying, and `ask_strategy` for selling. +Prices are always retrieved right before an order is placed, either by querying the `fetch_ticker()` endpoint of the exchange (usually `/ticker`), or by using the orderbook. + +### Buy price with Orderbook enabled + +When buying with the orderbook enabled (`bid_strategy.use_order_book=True`) - Freqtrade will fetch the `bid_strategy.order_book_top` entries in the orderbook, and will then use the entry specified as `bid_strategy.order_book_top` on the `bids` side of the orderbook. 1 specifies the topmost entry in the Orderbook - while 2 would use the 2nd entry in the Orderbook. + +### Buy price without Orderbook + +When not using orderbook (`bid_strategy.use_order_book=False`), then Freqtrade will use the best `ask` price based on a call to `fetch_ticker()` if it's below the `last` traded price. +Otherwise, it'll use the following formula to calculate the rate: + +``` python +ticker['ask'] + ask_last_balance * (ticker['last'] - ticker['ask']) +``` + +This means - it uses the difference between last and ask (which must be negative, since ask was checked to be higher than last) and multiplies this with `bid_strategy.ask_last_balance` - lowering the price by `balance * (difference between last and ask). + +### Sell price with Orderbook enabled + +When selling with the Orderbook enabled (`ask_strategy.use_order_book=True`) - Freqtrade will fetch the `ask_strategy.order_book_max` entries in the orderbook. Freqtrade will then validate each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` side for a profitable sell-possibility and will place a sell order at the first profitable spot. + +The idea here is to place the sell-order early, to be ahead in the queue. +A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. + +!!! Warning "Orderbook and stoploss_on_exchange" + Using `ask_strategy.order_book_max` higher than 1 may increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be need to be cancelled as soon as the order is placed. + + +### Sell price without orderbook + +When not using orderbook (`ask_strategy.use_order_book=False`), then the best `bid` will be used as sell rate based on a call to `fetch_ticker()`. + ## Pairlists Pairlists define the list of pairs that the bot should trade. From d73ba71ec63d08d9ddc98c983f10aa7509cd9b0b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 16:41:54 +0100 Subject: [PATCH 0008/1106] Improve formatting of orderbook doc --- docs/configuration.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index bfa29529d..e4d29825e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -398,11 +398,13 @@ The valid values are: Prices for regular orders can be controlled via the parameter structures `bid_strategy` for Buying, and `ask_strategy` for selling. Prices are always retrieved right before an order is placed, either by querying the `fetch_ticker()` endpoint of the exchange (usually `/ticker`), or by using the orderbook. -### Buy price with Orderbook enabled +### Buy price + +#### Buy price with Orderbook enabled When buying with the orderbook enabled (`bid_strategy.use_order_book=True`) - Freqtrade will fetch the `bid_strategy.order_book_top` entries in the orderbook, and will then use the entry specified as `bid_strategy.order_book_top` on the `bids` side of the orderbook. 1 specifies the topmost entry in the Orderbook - while 2 would use the 2nd entry in the Orderbook. -### Buy price without Orderbook +#### Buy price without Orderbook When not using orderbook (`bid_strategy.use_order_book=False`), then Freqtrade will use the best `ask` price based on a call to `fetch_ticker()` if it's below the `last` traded price. Otherwise, it'll use the following formula to calculate the rate: @@ -413,7 +415,9 @@ ticker['ask'] + ask_last_balance * (ticker['last'] - ticker['ask']) This means - it uses the difference between last and ask (which must be negative, since ask was checked to be higher than last) and multiplies this with `bid_strategy.ask_last_balance` - lowering the price by `balance * (difference between last and ask). -### Sell price with Orderbook enabled +### Sell price + +#### Sell price with Orderbook enabled When selling with the Orderbook enabled (`ask_strategy.use_order_book=True`) - Freqtrade will fetch the `ask_strategy.order_book_max` entries in the orderbook. Freqtrade will then validate each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` side for a profitable sell-possibility and will place a sell order at the first profitable spot. @@ -424,7 +428,7 @@ A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting Using `ask_strategy.order_book_max` higher than 1 may increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be need to be cancelled as soon as the order is placed. -### Sell price without orderbook +#### Sell price without orderbook When not using orderbook (`ask_strategy.use_order_book=False`), then the best `bid` will be used as sell rate based on a call to `fetch_ticker()`. From 1c19856d26c8ea9ed48c293519f8f63a12cbb568 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 16:49:56 +0100 Subject: [PATCH 0009/1106] add section about depth_of_market --- docs/configuration.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index e4d29825e..5c748b0cb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -400,6 +400,12 @@ Prices are always retrieved right before an order is placed, either by querying ### Buy price +#### Check depth of market + +When enabling `bid_strategy.check_depth_of_market=True`, then buy signals will be filtered based on the orderbook size. + +#TODO: Finish this section + #### Buy price with Orderbook enabled When buying with the orderbook enabled (`bid_strategy.use_order_book=True`) - Freqtrade will fetch the `bid_strategy.order_book_top` entries in the orderbook, and will then use the entry specified as `bid_strategy.order_book_top` on the `bids` side of the orderbook. 1 specifies the topmost entry in the Orderbook - while 2 would use the 2nd entry in the Orderbook. @@ -419,7 +425,7 @@ This means - it uses the difference between last and ask (which must be negative #### Sell price with Orderbook enabled -When selling with the Orderbook enabled (`ask_strategy.use_order_book=True`) - Freqtrade will fetch the `ask_strategy.order_book_max` entries in the orderbook. Freqtrade will then validate each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` side for a profitable sell-possibility and will place a sell order at the first profitable spot. +When selling with the Orderbook enabled (`ask_strategy.use_order_book=True`) - Freqtrade will fetch the `ask_strategy.order_book_max` entries in the orderbook. Freqtrade will then validate each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` side for a profitable sell-possibility based on the strategy configuration and will place a sell order at the first profitable spot. The idea here is to place the sell-order early, to be ahead in the queue. A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. From 11e787c8846027f14e6bc0872743dd5529cf57f1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 19:27:54 +0100 Subject: [PATCH 0010/1106] Finish depth_of_market documentation piece --- docs/configuration.md | 45 ++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 5c748b0cb..ba592d436 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -57,12 +57,12 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* | `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled.
***Datatype:*** *Integer* | `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled.
***Datatype:*** *Integer* -| `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#understand-ask_last_balance). -| `bid_strategy.use_order_book` | Enable buying using the rates in Order Book Bids.
***Datatype:*** *Boolean* -| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in Order Book Bids. *Defaults to `1`.*
***Datatype:*** *Positive Integer* -| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book.
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The % difference of buy orders and sell orders found in Order Book. A value lesser than 1 means sell orders is greater, while value greater than 1 means buy orders is higher. *Defaults to `0`.*
***Datatype:*** *Float (as ratio)* -| `ask_strategy.use_order_book` | Enable selling of open trades using Order Book Asks.
***Datatype:*** *Boolean* +| `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#buy-price-without-orderbook). +| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled).
***Datatype:*** *Boolean* +| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled).
*Defaults to `1`.*
***Datatype:*** *Positive Integer* +| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market).
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market)
*Defaults to `0`.*
***Datatype:*** *Float (as ratio)* +| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled).
***Datatype:*** *Boolean* | `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
***Datatype:*** *Positive Integer* | `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
***Datatype:*** *Positive Integer* | `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `true`.*
***Datatype:*** *Boolean* @@ -88,9 +88,9 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* | `webhook.enabled` | Enable usage of Webhook notifications
***Datatype:*** *Boolean* | `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
***Datatype:*** *String* +| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* +| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* +| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Boolean* | `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *IPv4* | `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Integer between 1024 and 65535* @@ -207,13 +207,6 @@ before asking the strategy if we should buy or a sell an asset. After each wait every opened trade wether or not we should sell, and for all the remaining pairs (either the dynamic list of pairs or the static list of pairs) if we should buy. -### Understand ask_last_balance - -The `ask_last_balance` configuration parameter sets the bidding price. Value `0.0` will use `ask` price, `1.0` will -use the `last` price and values between those interpolate between ask and last -price. Using `ask` price will guarantee quick success in bid, but bot will also -end up paying more then would probably have been necessary. - ### Understand order_types The `order_types` configuration parameter maps actions (`buy`, `sell`, `stoploss`) to order-types (`market`, `limit`, ...) as well as configures stoploss to be on the exchange and defines stoploss on exchange update interval in seconds. @@ -398,13 +391,15 @@ The valid values are: Prices for regular orders can be controlled via the parameter structures `bid_strategy` for Buying, and `ask_strategy` for selling. Prices are always retrieved right before an order is placed, either by querying the `fetch_ticker()` endpoint of the exchange (usually `/ticker`), or by using the orderbook. -### Buy price +### Buy price #### Check depth of market -When enabling `bid_strategy.check_depth_of_market=True`, then buy signals will be filtered based on the orderbook size. +When enabling `bid_strategy.check_depth_of_market.enabled=True`, then buy signals will be filtered based on the orderbook size for each size (sum of all amounts). +Orderbook bid size is then divided by Orderbook ask size - and the resulting delta is compared to `bid_strategy.check_depth_of_market.bids_to_ask_delta`, and a buy is only executed if the orderbook delta is bigger or equal to the configured delta. -#TODO: Finish this section +!!! Note: + A calculated delta below 1 means that sell order size is greater, while value greater than 1 means buy order size is higher #### Buy price with Orderbook enabled @@ -413,15 +408,13 @@ When buying with the orderbook enabled (`bid_strategy.use_order_book=True`) - Fr #### Buy price without Orderbook When not using orderbook (`bid_strategy.use_order_book=False`), then Freqtrade will use the best `ask` price based on a call to `fetch_ticker()` if it's below the `last` traded price. -Otherwise, it'll use the following formula to calculate the rate: +Otherwise, it'll calculate a rate between `ask` and `last` price. -``` python -ticker['ask'] + ask_last_balance * (ticker['last'] - ticker['ask']) -``` +The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `ask` price, `1.0` will use the `last` price and values between those interpolate between ask and last +price. +Using `ask` price will guarantee quick success in bid, but bot will also end up paying more than what would have been necessary. -This means - it uses the difference between last and ask (which must be negative, since ask was checked to be higher than last) and multiplies this with `bid_strategy.ask_last_balance` - lowering the price by `balance * (difference between last and ask). - -### Sell price +### Sell price #### Sell price with Orderbook enabled From 1af962899d3f443b639d6953f406f145f1cab344 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 19:43:37 +0100 Subject: [PATCH 0011/1106] Fix note-box syntax error --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index ba592d436..8ae824277 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -398,7 +398,7 @@ Prices are always retrieved right before an order is placed, either by querying When enabling `bid_strategy.check_depth_of_market.enabled=True`, then buy signals will be filtered based on the orderbook size for each size (sum of all amounts). Orderbook bid size is then divided by Orderbook ask size - and the resulting delta is compared to `bid_strategy.check_depth_of_market.bids_to_ask_delta`, and a buy is only executed if the orderbook delta is bigger or equal to the configured delta. -!!! Note: +!!! Note A calculated delta below 1 means that sell order size is greater, while value greater than 1 means buy order size is higher #### Buy price with Orderbook enabled From e72c6a0d94d810b2976c4a6729291fe51602db9d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 20:02:15 +0100 Subject: [PATCH 0012/1106] use only first part of the currency to get wallet-amount (!!) --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4a48bba04..5656268c8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -903,7 +903,7 @@ class FreqtradeBot: :return: amount to sell :raise: DependencyException: if available balance is not within 2% of the available amount. """ - wallet_amount = self.wallets.get_free(pair) + wallet_amount = self.wallets.get_free(pair.split('/')[0]) logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount > amount: return amount From 6507a26cc160fdfe99a58fbd92a8e0a197f4edef Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 20:16:53 +0100 Subject: [PATCH 0013/1106] Fix some tests after merge --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 18 ++++++++++++++---- tests/test_integration.py | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5656268c8..a51ab0dbf 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -898,7 +898,7 @@ class FreqtradeBot: Should be trade.amount - but will fall back to the available amount if necessary. This should cover cases where get_real_amount() was not able to update the amount for whatever reason. - :param pair: pair - used for logging + :param pair: Pair we're trying to sell :param amount: amount we expect to be available :return: amount to sell :raise: DependencyException: if available balance is not within 2% of the available amount. diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 300d0ad32..cd5c92199 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1682,6 +1682,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock time.sleep(0.01) # Race condition fix trade.update(limit_buy_order) assert trade.is_open is True + freqtrade.wallets.update() patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) is True @@ -2549,6 +2550,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, trade = Trade.query.first() trade.update(limit_buy_order) + freqtrade.wallets.update() patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) is True assert trade.sell_reason == SellType.SELL_SIGNAL.value @@ -2579,6 +2581,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, trade = Trade.query.first() trade.update(limit_buy_order) + freqtrade.wallets.update() patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) is True assert trade.sell_reason == SellType.SELL_SIGNAL.value @@ -2639,6 +2642,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke trade = Trade.query.first() trade.update(limit_buy_order) + freqtrade.wallets.update() patch_get_signal(freqtrade, value=(False, True)) assert freqtrade.handle_trade(trade) is True assert trade.sell_reason == SellType.SELL_SIGNAL.value @@ -2676,7 +2680,7 @@ def test_sell_not_enough_balance(default_conf, limit_buy_order, assert trade.amount != amnt -def test__safe_sell_amount(default_conf, caplog, mocker): +def test__safe_sell_amount(default_conf, fee, caplog, mocker): patch_RPCManager(mocker) patch_exchange(mocker) amount = 95.33 @@ -2687,7 +2691,9 @@ def test__safe_sell_amount(default_conf, caplog, mocker): amount=amount, exchange='binance', open_rate=0.245441, - open_order_id="123456" + open_order_id="123456", + fee_open=fee.return_value, + fee_close=fee.return_value, ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) @@ -2696,7 +2702,7 @@ def test__safe_sell_amount(default_conf, caplog, mocker): assert log_has_re(r'.*Falling back to wallet-amount.', caplog) -def test__safe_sell_amount_error(default_conf, caplog, mocker): +def test__safe_sell_amount_error(default_conf, fee, caplog, mocker): patch_RPCManager(mocker) patch_exchange(mocker) amount = 95.33 @@ -2707,7 +2713,9 @@ def test__safe_sell_amount_error(default_conf, caplog, mocker): amount=amount, exchange='binance', open_rate=0.245441, - open_order_id="123456" + open_order_id="123456", + fee_open=fee.return_value, + fee_close=fee.return_value, ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) @@ -2775,6 +2783,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> trade = Trade.query.first() trade.update(limit_buy_order) + freqtrade.wallets.update() patch_get_signal(freqtrade, value=(True, True)) assert freqtrade.handle_trade(trade) is False @@ -3512,6 +3521,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order time.sleep(0.01) # Race condition fix trade.update(limit_buy_order) + freqtrade.wallets.update() assert trade.is_open is True patch_get_signal(freqtrade, value=(False, True)) diff --git a/tests/test_integration.py b/tests/test_integration.py index 728e96d55..2daf13db6 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -71,7 +71,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, ) mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock) wallets_mock = mocker.patch("freqtrade.wallets.Wallets.update", MagicMock()) - mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=1)) + mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=1000)) freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade.strategy.order_types['stoploss_on_exchange'] = True From 0c6b5e01fb4a617d86e1aa9105e1aba960fdd254 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 20:28:36 +0100 Subject: [PATCH 0014/1106] Try with github-token --- .github/workflows/ci.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6a111944..0e86abc9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,19 +64,16 @@ jobs: pip install -e . - name: Tests - env: - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} - COVERALLS_SERVICE_NAME: travis-ci - TRAVIS: "true" run: | pytest --random-order --cov=freqtrade --cov-config=.coveragerc + + - name: Coveralls + if: startsWith(matrix.os, 'ubuntu') + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | # Allow failure for coveralls - # Fake travis environment to get coveralls working correctly - export TRAVIS_PULL_REQUEST="https://github.com/${GITHUB_REPOSITORY}/pull/$(cat $GITHUB_EVENT_PATH | jq -r .number)" - export TRAVIS_BRANCH=${GITHUB_REF#"ref/heads"} - export CI_BRANCH=${GITHUB_REF#"ref/heads"} - echo "${TRAVIS_BRANCH}" - coveralls || true + coveralls -v || true - name: Backtesting run: | From 342f3f450b1a201b155994f61ce182cc31721db3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Dec 2019 20:38:21 +0100 Subject: [PATCH 0015/1106] try with coveralls token in yml ... --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e86abc9b..53b2e5440 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,7 +70,8 @@ jobs: - name: Coveralls if: startsWith(matrix.os, 'ubuntu') env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Coveralls token. Not used as secret due to github not providing secrets to forked repositories + COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu run: | # Allow failure for coveralls coveralls -v || true From fc5764f9df7c4341c9dd14560822ac4eec7fb6cc Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Dec 2019 19:55:21 +0100 Subject: [PATCH 0016/1106] Edge small cleanup --- freqtrade/optimize/edge_cli.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index a667ebb92..3848623db 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -42,11 +42,9 @@ class EdgeCli: # Set refresh_pairs to false for edge-cli (it must be true for edge) self.edge._refresh_pairs = False - self.timerange = TimeRange.parse_timerange(None if self.config.get( + self.edge._timerange = TimeRange.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) - self.edge._timerange = self.timerange - def _generate_edge_table(self, results: dict) -> str: floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') From 95bd9e8e0b5785031e70bedd0295cc763b54d541 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 22 Dec 2019 00:17:51 +0300 Subject: [PATCH 0017/1106] No underscores in cli options --- docs/bot-usage.md | 40 ++++++++++++++---------- freqtrade/configuration/cli_options.py | 8 ++--- freqtrade/configuration/configuration.py | 4 +-- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 25818aea6..86a990946 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -192,8 +192,8 @@ Backtesting also uses the config specified via `-c/--config`. usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH] [-i TICKER_INTERVAL] - [--timerange TIMERANGE] [--max_open_trades INT] - [--stake_amount STAKE_AMOUNT] [--fee FLOAT] + [--timerange TIMERANGE] [--max-open-trades INT] + [--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--eps] [--dmmp] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--export EXPORT] [--export-filename PATH] @@ -205,10 +205,12 @@ optional arguments: `1d`). --timerange TIMERANGE Specify what timerange of data to use. - --max_open_trades INT - Specify max_open_trades to use. - --stake_amount STAKE_AMOUNT - Specify stake_amount. + --max-open-trades INT + Override the value of the `max_open_trades` + configuration setting. + --stake-amount STAKE_AMOUNT + Override the value of the `stake_amount` configuration + setting. --fee FLOAT Specify fee ratio. Will be applied twice (on trade entry and exit). --eps, --enable-position-stacking @@ -270,8 +272,8 @@ to find optimal parameter values for your stategy. usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH] [-i TICKER_INTERVAL] [--timerange TIMERANGE] - [--max_open_trades INT] - [--stake_amount STAKE_AMOUNT] [--fee FLOAT] + [--max-open-trades INT] + [--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--hyperopt NAME] [--hyperopt-path PATH] [--eps] [-e INT] [--spaces {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]] @@ -286,10 +288,12 @@ optional arguments: `1d`). --timerange TIMERANGE Specify what timerange of data to use. - --max_open_trades INT - Specify max_open_trades to use. - --stake_amount STAKE_AMOUNT - Specify stake_amount. + --max-open-trades INT + Override the value of the `max_open_trades` + configuration setting. + --stake-amount STAKE_AMOUNT + Override the value of the `stake_amount` configuration + setting. --fee FLOAT Specify fee ratio. Will be applied twice (on trade entry and exit). --hyperopt NAME Specify hyperopt class name which will be used by the @@ -360,7 +364,7 @@ To know your trade expectancy and winrate against historical data, you can use E usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH] [-i TICKER_INTERVAL] [--timerange TIMERANGE] - [--max_open_trades INT] [--stake_amount STAKE_AMOUNT] + [--max-open-trades INT] [--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--stoplosses STOPLOSS_RANGE] optional arguments: @@ -370,10 +374,12 @@ optional arguments: `1d`). --timerange TIMERANGE Specify what timerange of data to use. - --max_open_trades INT - Specify max_open_trades to use. - --stake_amount STAKE_AMOUNT - Specify stake_amount. + --max-open-trades INT + Override the value of the `max_open_trades` + configuration setting. + --stake-amount STAKE_AMOUNT + Override the value of the `stake_amount` configuration + setting. --fee FLOAT Specify fee ratio. Will be applied twice (on trade entry and exit). --stoplosses STOPLOSS_RANGE diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index 30902dfe9..4b6429f20 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -118,14 +118,14 @@ AVAILABLE_CLI_OPTIONS = { help='Specify what timerange of data to use.', ), "max_open_trades": Arg( - '--max_open_trades', - help='Specify max_open_trades to use.', + '--max-open-trades', + help='Override the value of the `max_open_trades` configuration setting.', type=int, metavar='INT', ), "stake_amount": Arg( - '--stake_amount', - help='Specify stake_amount.', + '--stake-amount', + help='Override the value of the `stake_amount` configuration setting.', type=float, ), # Backtesting diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index e517a0558..001e89303 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -223,13 +223,13 @@ class Configuration: logger.info('max_open_trades set to unlimited ...') elif 'max_open_trades' in self.args and self.args["max_open_trades"]: config.update({'max_open_trades': self.args["max_open_trades"]}) - logger.info('Parameter --max_open_trades detected, ' + logger.info('Parameter --max-open-trades detected, ' 'overriding max_open_trades to: %s ...', config.get('max_open_trades')) elif config['runmode'] in NON_UTIL_MODES: logger.info('Using max_open_trades: %s ...', config.get('max_open_trades')) self._args_to_config(config, argname='stake_amount', - logstring='Parameter --stake_amount detected, ' + logstring='Parameter --stake-amount detected, ' 'overriding stake_amount to: {} ...') self._args_to_config(config, argname='fee', From 9ec4368c6f9cee11cbc72ca5f518fcff57859b02 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:20:42 +0100 Subject: [PATCH 0018/1106] Add release documentation --- docs/developer.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/developer.md b/docs/developer.md index 5b07aff03..c679b8a49 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -266,4 +266,29 @@ Once the PR against master is merged (best right after merging): * Use the button "Draft a new release" in the Github UI (subsection releases). * Use the version-number specified as tag. * Use "master" as reference (this step comes after the above PR is merged). -* Use the above changelog as release comment (as codeblock). +* Use the above changelog as release comment (as codeblock) + +### After-release + +* Update version in develop by postfixing that with `-dev` (`2019.6 -> 2019.6-dev`). +* Create a PR against develop to update that branch. + +## Releases + +### pypi + +To create a pypi release, please run the following commands: + +Additional requirement: `wheel`, `twine` (for uploading), account on pypi with proper permissions. + +``` bash +python setup.py sdist bdist_wheel + +# For pypi test (to check if some change to the installation did work) +twine upload --repository-url https://test.pypi.org/legacy/ dist/* + +# For production: +twine upload dist/* +``` + +Please don't push non-releases to the productive / real pypi instance. From c417877eb8d6ad8cc63f9b7585846837f872b701 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 5 Oct 2019 13:41:54 +0200 Subject: [PATCH 0019/1106] sort pytest dependencies --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3710bcdc0..29f9db10c 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ setup(name='freqtrade', license='GPLv3', packages=['freqtrade'], setup_requires=['pytest-runner', 'numpy'], - tests_require=['pytest', 'pytest-mock', 'pytest-cov'], + tests_require=['pytest', 'pytest-asyncio', 'pytest-cov', 'pytest-mock', ], install_requires=[ # from requirements-common.txt 'ccxt>=1.18.1080', From 1a73159200278edc3de3f484811c0ecde6dbaaa9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 23 Oct 2019 06:43:22 +0200 Subject: [PATCH 0020/1106] Modify classifiers --- setup.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 29f9db10c..7d8d7b68d 100644 --- a/setup.py +++ b/setup.py @@ -99,8 +99,12 @@ setup(name='freqtrade', ], }, classifiers=[ - 'Programming Language :: Python :: 3.6', - 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', - 'Topic :: Office/Business :: Financial :: Investment', + 'Environment :: Console', 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Operating System :: MacOS', + 'Operating System :: Unix', + 'Topic :: Office/Business :: Financial :: Investment', ]) From 1ff0d0f1fa05137560475d7c209768fb30d3aefc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:35:06 +0100 Subject: [PATCH 0021/1106] Add unfilledtimeout to strategy overrides --- docs/configuration.md | 5 +++-- freqtrade/resolvers/strategy_resolver.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 73534b6f1..846c4510d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -55,8 +55,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `trailing_stop_positive` | Changes stoploss once profit has been reached. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Float* | `trailing_stop_positive_offset` | Offset on when to apply `trailing_stop_positive`. Percentage value which should be positive. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `0.0` (no offset).*
***Datatype:*** *Float* | `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled.
***Datatype:*** *Integer* -| `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled.
***Datatype:*** *Integer* +| `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Integer* +| `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Integer* | `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#understand-ask_last_balance). | `bid_strategy.use_order_book` | Enable buying using the rates in Order Book Bids.
***Datatype:*** *Boolean* | `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in Order Book Bids. *Defaults to `1`.*
***Datatype:*** *Positive Integer* @@ -124,6 +124,7 @@ Values set in the configuration file always overwrite values set in the strategy * `order_time_in_force` * `stake_currency` * `stake_amount` +* `unfilledtimeout` * `use_sell_signal` (ask_strategy) * `sell_profit_only` (ask_strategy) * `ignore_roi_if_buy_signal` (ask_strategy) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 9a76b9b74..a2d14fbf3 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -61,6 +61,7 @@ class StrategyResolver(IResolver): ("stake_currency", None, False), ("stake_amount", None, False), ("startup_candle_count", None, False), + ("unfilledtimeout", None, False), ("use_sell_signal", True, True), ("sell_profit_only", False, True), ("ignore_roi_if_buy_signal", False, True), From 9835312033a300dce9bae1e92381b5bcffbdfa48 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:46:00 +0100 Subject: [PATCH 0022/1106] Improve pair_lock handling --- freqtrade/strategy/interface.py | 15 ++++++++++++++- tests/strategy/test_interface.py | 13 +++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 985ff37de..4f2e990d2 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -168,11 +168,24 @@ class IStrategy(ABC): """ Locks pair until a given timestamp happens. Locked pairs are not analyzed, and are prevented from opening new trades. + Locks can only count up (allowing users to lock pairs for a longer period of time). + To remove a lock from a pair, use `unlock_pair()` :param pair: Pair to lock :param until: datetime in UTC until the pair should be blocked from opening new trades. Needs to be timezone aware `datetime.now(timezone.utc)` """ - self._pair_locked_until[pair] = until + if pair not in self._pair_locked_until or self._pair_locked_until[pair] < until: + self._pair_locked_until[pair] = until + + def unlock_pair(self, pair) -> None: + """ + Unlocks a pair previously locked using lock_pair. + Not used by freqtrade itself, but intended to be used if users lock pairs + manually from within the strategy, to allow an easy way to unlock pairs. + :param pair: Unlock pair to allow trading again + """ + if pair in self._pair_locked_until: + del self._pair_locked_until[pair] def is_pair_locked(self, pair: str) -> bool: """ diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 605622b8f..89c38bda1 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -302,6 +302,19 @@ def test_is_pair_locked(default_conf): # ETH/BTC locked for 4 minutes assert strategy.is_pair_locked(pair) + # Test lock does not change + lock = strategy._pair_locked_until[pair] + strategy.lock_pair(pair, arrow.utcnow().shift(minutes=2).datetime) + assert lock == strategy._pair_locked_until[pair] + # XRP/BTC should not be locked now pair = 'XRP/BTC' assert not strategy.is_pair_locked(pair) + + # Unlocking a pair that's not locked should not raise an error + strategy.unlock_pair(pair) + + # Unlock original pair + pair = 'ETH/BTC' + strategy.unlock_pair(pair) + assert not strategy.is_pair_locked(pair) From 89b4f45fe353773cafe09fb9a18a941a7b1cfb9b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:47:37 +0100 Subject: [PATCH 0023/1106] Remove section about strategy template - use new-strategy intead --- docs/strategy-customization.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 4efca7d2f..c4a477f80 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -479,11 +479,6 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: Printing more than a few rows is also possible (simply use `print(dataframe)` instead of `print(dataframe.tail())`), however not recommended, as that will be very verbose (~500 lines per pair every 5 seconds). -### Where can i find a strategy template? - -The strategy template is located in the file -[user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_strategy.py). - ### Specify custom strategy location If you want to use a strategy from a different directory you can pass `--strategy-path` From a71deeda94f4c55ae1a8f30d10d034ffb0acbcd4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:55:40 +0100 Subject: [PATCH 0024/1106] Document lock-pair implementation --- docs/strategy-customization.md | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index c4a477f80..011f64d70 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -455,6 +455,49 @@ Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of !!! Warning Trade history is not available during backtesting or hyperopt. +### Prevent trades from happening for a specific pair + +Freqtrade locks pairs automatically for the current candle (until that candle is over) when a pair is sold, preventing an immediate re-buy of that pair. + +Locked pairs will show the message `Pair is currently locked.`. + +#### Locking pairs from within the strategy + +Sometimes it may be desired to lock a pair after certain events happen (e.g. multiple losing trades in a row). + +Freqtrade has an easy method to do this from within the strategy, by calling `self.lock_pair(pair, until)`. +Until should be a time in the future, after which trading will be reenabled for that pair. + +Locks can also be lifted manually, by calling `self.unlock_pair(pair)`. + +!!! Note + Locked pairs are not persisted, so a restart of the bot, or calling `/reload_conf` will reset locked pairs. + +!!! Warning + Locking pairs is not functional during backtesting. + +##### Pair locking example + +``` python +from freqtrade.persistence import Trade +from datetime import timedelta, datetime, timezone +# Put the above lines a the top of the strategy file, next to all the other imports +# -------- + +# Within populate indicators (or populate_buy): +if self.config['runmode'] in ('live', 'dry_run'): + # fetch closed trades for the last 2 days + trades = Trade.get_trades([Trade.pair == metadata['pair'], + Trade.open_date > datetime.utcnow() - timedelta(days=2), + Trade.is_open == False, + ]).all() + # Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy + sumprofit = sum(trade.close_profit for trade in trades) + if sumprofit < 0: + # Lock pair for 2 days + self.lock_pair(metadata['pair'], until=datetime.now(timezone.utc) + timedelta(days=2)) +``` + ### Print created dataframe To inspect the created dataframe, you can issue a print-statement in either `populate_buy_trend()` or `populate_sell_trend()`. From 43c25c8a328edf307dc979be0ae88a3cd3d508f8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 09:59:25 +0100 Subject: [PATCH 0025/1106] add documentation for is_pair_locked --- docs/strategy-customization.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 011f64d70..129939b25 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -466,10 +466,12 @@ Locked pairs will show the message `Pair is currently locked.`. Sometimes it may be desired to lock a pair after certain events happen (e.g. multiple losing trades in a row). Freqtrade has an easy method to do this from within the strategy, by calling `self.lock_pair(pair, until)`. -Until should be a time in the future, after which trading will be reenabled for that pair. +`until` must be a datetime object in the future, after which trading will be reenabled for that pair. Locks can also be lifted manually, by calling `self.unlock_pair(pair)`. +To verify if a pair is currently locked, use `self.is_pair_locked(pair)`. + !!! Note Locked pairs are not persisted, so a restart of the bot, or calling `/reload_conf` will reset locked pairs. From ffd7034c005ead82a79e4a60e20e23e225953141 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 10:16:16 +0100 Subject: [PATCH 0026/1106] Persist dry-run trade per default --- freqtrade/constants.py | 2 +- tests/test_persistence.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 5c7190b41..d7c6249d5 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -10,7 +10,7 @@ HYPEROPT_EPOCH = 100 # epochs RETRY_TIMEOUT = 30 # sec DEFAULT_HYPEROPT_LOSS = 'DefaultHyperOptLoss' DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite' -DEFAULT_DB_DRYRUN_URL = 'sqlite://' +DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite' UNLIMITED_STAKE_AMOUNT = 'unlimited' DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05 REQUIRED_ORDERTIF = ['buy', 'sell'] diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 25ad8b6a7..b9a636e1a 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -100,7 +100,7 @@ def test_init_dryrun_db(default_conf, mocker): init(default_conf['db_url'], default_conf['dry_run']) assert create_engine_mock.call_count == 1 - assert create_engine_mock.mock_calls[0][1][0] == 'sqlite://' + assert create_engine_mock.mock_calls[0][1][0] == 'sqlite:///tradesv3.dryrun.sqlite' @pytest.mark.usefixtures("init_persistence") From dc567f99d67e5a82026fd3a5ff3002323ac51b24 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 10:16:49 +0100 Subject: [PATCH 0027/1106] Update documentation to new handling of dry-mode database --- docs/bot-usage.md | 8 +++-- docs/configuration.md | 2 +- docs/docker.md | 3 +- docs/plotting.md | 72 +++++++++++++++++-------------------------- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 86a990946..e856755d2 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -45,14 +45,17 @@ optional arguments: -h, --help show this help message and exit --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` for - Live Run mode, `sqlite://` for Dry Run). + Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for + Dry Run). --sd-notify Notify systemd service manager. --dry-run Enforce dry-run for trading (removes Exchange secrets and simulates trades). Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH Specify configuration file (default: `config.json`). @@ -68,6 +71,7 @@ Strategy arguments: Specify strategy class name which will be used by the bot. --strategy-path PATH Specify additional strategy lookup path. + ``` ### How to specify which configuration file be used? diff --git a/docs/configuration.md b/docs/configuration.md index 73534b6f1..fbd4c9815 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -96,7 +96,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Integer between 1024 and 65535* | `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* | `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite://` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances.
***Datatype:*** *String, SQLAlchemy connect string* +| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances.
***Datatype:*** *String, SQLAlchemy connect string* | `initial_state` | Defines the initial application state. More information below.
*Defaults to `stopped`.*
***Datatype:*** *Enum, either `stopped` or `running`* | `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below.
***Datatype:*** *Boolean* | `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`.
***Datatype:*** *ClassName* diff --git a/docs/docker.md b/docs/docker.md index ff5bf7f25..d1684abc5 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -164,8 +164,7 @@ docker run -d \ ``` !!! Note - db-url defaults to `sqlite:///tradesv3.sqlite` but it defaults to `sqlite://` if `dry_run=True` is being used. - To override this behaviour use a custom db-url value: i.e.: `--db-url sqlite:///tradesv3.dryrun.sqlite` + When using docker, it's best to specify `--db-url` explicitly to ensure that the database URL and the mounted database file match. !!! Note All available bot command line parameters can be added to the end of the `docker run` command. diff --git a/docs/plotting.md b/docs/plotting.md index 982a5cd65..ba737562f 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -23,58 +23,43 @@ The `freqtrade plot-dataframe` subcommand shows an interactive graph with three Possible arguments: ``` -usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] [-s NAME] - [--strategy-path PATH] [-p PAIRS [PAIRS ...]] - [--indicators1 INDICATORS1 [INDICATORS1 ...]] - [--indicators2 INDICATORS2 [INDICATORS2 ...]] - [--plot-limit INT] [--db-url PATH] - [--trade-source {DB,file}] [--export EXPORT] - [--export-filename PATH] - [--timerange TIMERANGE] [-i TICKER_INTERVAL] +usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-s NAME] + [--strategy-path PATH] [-p PAIRS [PAIRS ...]] [--indicators1 INDICATORS1 [INDICATORS1 ...]] + [--indicators2 INDICATORS2 [INDICATORS2 ...]] [--plot-limit INT] [--db-url PATH] + [--trade-source {DB,file}] [--export EXPORT] [--export-filename PATH] [--timerange TIMERANGE] + [-i TICKER_INTERVAL] optional arguments: -h, --help show this help message and exit -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] - Show profits for only these pairs. Pairs are space- - separated. + Show profits for only these pairs. Pairs are space-separated. --indicators1 INDICATORS1 [INDICATORS1 ...] - Set indicators from your strategy you want in the - first row of the graph. Space-separated list. Example: + Set indicators from your strategy you want in the first row of the graph. Space-separated list. Example: `ema3 ema5`. Default: `['sma', 'ema3', 'ema5']`. --indicators2 INDICATORS2 [INDICATORS2 ...] - Set indicators from your strategy you want in the - third row of the graph. Space-separated list. Example: + Set indicators from your strategy you want in the third row of the graph. Space-separated list. Example: `fastd fastk`. Default: `['macd', 'macdsignal']`. - --plot-limit INT Specify tick limit for plotting. Notice: too high - values cause huge files. Default: 750. - --db-url PATH Override trades database URL, this is useful in custom - deployments (default: `sqlite:///tradesv3.sqlite` for - Live Run mode, `sqlite://` for Dry Run). + --plot-limit INT Specify tick limit for plotting. Notice: too high values cause huge files. Default: 750. + --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` + for Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for Dry Run). --trade-source {DB,file} - Specify the source for trades (Can be DB or file - (backtest file)) Default: file - --export EXPORT Export backtest results, argument are: trades. - Example: `--export=trades` + Specify the source for trades (Can be DB or file (backtest file)) Default: file + --export EXPORT Export backtest results, argument are: trades. Example: `--export=trades` --export-filename PATH - Save backtest results to the file with this filename - (default: `user_data/backtest_results/backtest- - result.json`). Requires `--export` to be set as well. - Example: `--export-filename=user_data/backtest_results - /backtest_today.json` + Save backtest results to the file with this filename. Requires `--export` to be set as well. Example: + `--export-filename=user_data/backtest_results/backtest_today.json` --timerange TIMERANGE Specify what timerange of data to use. -i TICKER_INTERVAL, --ticker-interval TICKER_INTERVAL - Specify ticker interval (`1m`, `5m`, `30m`, `1h`, - `1d`). + Specify ticker interval (`1m`, `5m`, `30m`, `1h`, `1d`). Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. @@ -83,8 +68,7 @@ Common arguments: Strategy arguments: -s NAME, --strategy NAME - Specify strategy class name (default: - `DefaultStrategy`). + Specify strategy class name which will be used by the bot. --strategy-path PATH Specify additional strategy lookup path. ``` @@ -173,14 +157,14 @@ optional arguments: --export EXPORT Export backtest results, argument are: trades. Example: `--export=trades` --export-filename PATH - Save backtest results to the file with this filename - (default: `user_data/backtest_results/backtest- - result.json`). Requires `--export` to be set as well. - Example: `--export-filename=user_data/backtest_results - /backtest_today.json` + Save backtest results to the file with this filename. + Requires `--export` to be set as well. Example: + `--export-filename=user_data/backtest_results/backtest + _today.json` --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` for - Live Run mode, `sqlite://` for Dry Run). + Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for + Dry Run). --trade-source {DB,file} Specify the source for trades (Can be DB or file (backtest file)) Default: file @@ -190,7 +174,9 @@ optional arguments: Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH Specify configuration file (default: `config.json`). From 2195ae59d6227de123a85a1a547be0d956b49656 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 12:49:01 +0100 Subject: [PATCH 0028/1106] Use different time offsets to avoid confusion --- docs/strategy-customization.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 129939b25..d59b097d7 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -476,7 +476,7 @@ To verify if a pair is currently locked, use `self.is_pair_locked(pair)`. Locked pairs are not persisted, so a restart of the bot, or calling `/reload_conf` will reset locked pairs. !!! Warning - Locking pairs is not functional during backtesting. + Locking pairs is not functioning during backtesting. ##### Pair locking example @@ -496,8 +496,8 @@ if self.config['runmode'] in ('live', 'dry_run'): # Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy sumprofit = sum(trade.close_profit for trade in trades) if sumprofit < 0: - # Lock pair for 2 days - self.lock_pair(metadata['pair'], until=datetime.now(timezone.utc) + timedelta(days=2)) + # Lock pair for 12 hours + self.lock_pair(metadata['pair'], until=datetime.now(timezone.utc) + timedelta(hours=12)) ``` ### Print created dataframe From 76a93fabc7027f80b5a45b6365b36891d127d1aa Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 06:26:13 +0000 Subject: [PATCH 0029/1106] Bump python from 3.7.5-slim-stretch to 3.7.6-slim-stretch Bumps python from 3.7.5-slim-stretch to 3.7.6-slim-stretch. Signed-off-by: dependabot-preview[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index dc9b04403..f631d891d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.5-slim-stretch +FROM python:3.7.6-slim-stretch RUN apt-get update \ && apt-get -y install curl build-essential libssl-dev \ From 8f17b81329ea59ab7ad45a89501b9f42f79b32f4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 07:37:04 +0000 Subject: [PATCH 0030/1106] Bump ccxt from 1.20.84 to 1.21.12 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.20.84 to 1.21.12. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.20.84...1.21.12) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a6d9a6f5e..ed6d68742 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.20.84 +ccxt==1.21.12 SQLAlchemy==1.3.11 python-telegram-bot==12.2.0 arrow==0.15.4 From 20ad8a379d51f29d3e00a1f7c3a8cdfbf33ed64b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 07:38:05 +0000 Subject: [PATCH 0031/1106] Bump numpy from 1.17.4 to 1.18.0 Bumps [numpy](https://github.com/numpy/numpy) from 1.17.4 to 1.18.0. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt) - [Commits](https://github.com/numpy/numpy/compare/v1.17.4...v1.18.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ebf27abd4..e0e2942b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Load common requirements -r requirements-common.txt -numpy==1.17.4 +numpy==1.18.0 pandas==0.25.3 From 31a7e9feedb72675845f8e1e1cf2fb29e91d8bc7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 07:38:10 +0000 Subject: [PATCH 0032/1106] Bump mypy from 0.750 to 0.761 Bumps [mypy](https://github.com/python/mypy) from 0.750 to 0.761. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.750...v0.761) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index fe5b4e369..1357bba00 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ coveralls==1.9.2 flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==3.1.0 -mypy==0.750 +mypy==0.761 pytest==5.3.2 pytest-asyncio==0.10.0 pytest-cov==2.8.1 From 9cfbe98a237549bef2c3d3e87e2d6a933911b8b0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 07:39:25 +0000 Subject: [PATCH 0033/1106] Bump scipy from 1.3.3 to 1.4.1 Bumps [scipy](https://github.com/scipy/scipy) from 1.3.3 to 1.4.1. - [Release notes](https://github.com/scipy/scipy/releases) - [Commits](https://github.com/scipy/scipy/compare/v1.3.3...v1.4.1) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index b2428e37d..9b408dbed 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -2,7 +2,7 @@ -r requirements.txt # Required for hyperopt -scipy==1.3.3 +scipy==1.4.1 scikit-learn==0.22 scikit-optimize==0.5.2 filelock==3.0.12 From 779278ed507d1f7f9070ee50f8349b720b499869 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2019 08:28:05 +0000 Subject: [PATCH 0034/1106] Bump sqlalchemy from 1.3.11 to 1.3.12 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.11 to 1.3.12. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index ed6d68742..9d0fd4756 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,7 +1,7 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs ccxt==1.21.12 -SQLAlchemy==1.3.11 +SQLAlchemy==1.3.12 python-telegram-bot==12.2.0 arrow==0.15.4 cachetools==4.0.0 From 1c5f8070e547d3c1766779697e553efa47742d42 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 09:53:55 +0100 Subject: [PATCH 0035/1106] Refactor build_paths to staticmethod --- freqtrade/resolvers/iresolver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 3bad42fd9..0b986debb 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -17,7 +17,8 @@ class IResolver: This class contains all the logic to load custom classes """ - def build_search_paths(self, config, current_path: Path, user_subdir: Optional[str] = None, + @staticmethod + def build_search_paths(config, current_path: Path, user_subdir: Optional[str] = None, extra_dir: Optional[str] = None) -> List[Path]: abs_paths: List[Path] = [current_path] From 5fefa9e97c01b83accd9ddd8c44bad83f331304d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 09:56:12 +0100 Subject: [PATCH 0036/1106] Convert PairlistResolver to static loader --- freqtrade/pairlist/pairlistmanager.py | 14 ++++---- freqtrade/resolvers/pairlist_resolver.py | 43 ++++++++++++++---------- tests/pairlist/test_pairlist.py | 2 +- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/freqtrade/pairlist/pairlistmanager.py b/freqtrade/pairlist/pairlistmanager.py index fa5382c37..1530710d2 100644 --- a/freqtrade/pairlist/pairlistmanager.py +++ b/freqtrade/pairlist/pairlistmanager.py @@ -28,13 +28,13 @@ class PairListManager(): if 'method' not in pl: logger.warning(f"No method in {pl}") continue - pairl = PairListResolver(pl.get('method'), - exchange=exchange, - pairlistmanager=self, - config=config, - pairlistconfig=pl, - pairlist_pos=len(self._pairlists) - ).pairlist + pairl = PairListResolver.load_pairlist(pl.get('method'), + exchange=exchange, + pairlistmanager=self, + config=config, + pairlistconfig=pl, + pairlist_pos=len(self._pairlists) + ) self._tickers_needed = pairl.needstickers or self._tickers_needed self._pairlists.append(pairl) diff --git a/freqtrade/resolvers/pairlist_resolver.py b/freqtrade/resolvers/pairlist_resolver.py index d849f4ffb..5b5bcee3a 100644 --- a/freqtrade/resolvers/pairlist_resolver.py +++ b/freqtrade/resolvers/pairlist_resolver.py @@ -18,23 +18,32 @@ class PairListResolver(IResolver): This class contains all the logic to load custom PairList class """ - __slots__ = ['pairlist'] + __slots__ = [] - def __init__(self, pairlist_name: str, exchange, pairlistmanager, - config: dict, pairlistconfig: dict, pairlist_pos: int) -> None: + @staticmethod + def load_pairlist(pairlist_name: str, exchange, pairlistmanager, + config: dict, pairlistconfig: dict, pairlist_pos: int) -> IPairList: """ - Load the custom class from config parameter - :param config: configuration dictionary or None + Load the pairlist with pairlist_name + :param pairlist_name: Classname of the pairlist + :param exchange: Initialized exchange class + :param pairlistmanager: Initialized pairlist manager + :param config: configuration dictionary + :param pairlistconfig: Configuration dedicated to this pairlist + :param pairlist_pos: Position of the pairlist in the list of pairlists + :return: initialized Pairlist class """ - self.pairlist = self._load_pairlist(pairlist_name, config, - kwargs={'exchange': exchange, - 'pairlistmanager': pairlistmanager, - 'config': config, - 'pairlistconfig': pairlistconfig, - 'pairlist_pos': pairlist_pos}) - def _load_pairlist( - self, pairlist_name: str, config: dict, kwargs: dict) -> IPairList: + return PairListResolver._load_pairlist(pairlist_name, config, + kwargs={'exchange': exchange, + 'pairlistmanager': pairlistmanager, + 'config': config, + 'pairlistconfig': pairlistconfig, + 'pairlist_pos': pairlist_pos}) + + + @staticmethod + def _load_pairlist(pairlist_name: str, config: dict, kwargs: dict) -> IPairList: """ Search and loads the specified pairlist. :param pairlist_name: name of the module to import @@ -44,11 +53,11 @@ class PairListResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('pairlist').resolve() - abs_paths = self.build_search_paths(config, current_path=current_path, - user_subdir=None, extra_dir=None) + abs_paths = IResolver.build_search_paths(config, current_path=current_path, + user_subdir=None, extra_dir=None) - pairlist = self._load_object(paths=abs_paths, object_type=IPairList, - object_name=pairlist_name, kwargs=kwargs) + pairlist = IResolver._load_object(paths=abs_paths, object_type=IPairList, + object_name=pairlist_name, kwargs=kwargs) if pairlist: return pairlist raise OperationalException( diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 43285cdb1..e7f098777 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -53,7 +53,7 @@ def test_load_pairlist_noexist(mocker, markets, default_conf): with pytest.raises(OperationalException, match=r"Impossible to load Pairlist 'NonexistingPairList'. " r"This class does not exist or contains Python code errors."): - PairListResolver('NonexistingPairList', bot.exchange, plm, default_conf, {}, 1) + PairListResolver.load_pairlist('NonexistingPairList', bot.exchange, plm, default_conf, {}, 1) def test_refresh_market_pair_not_in_whitelist(mocker, markets, static_pl_conf): From 560acb7cea6fa34bcf1eb0473cc373970fb97fd0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:03:18 +0100 Subject: [PATCH 0037/1106] Convert ExchangeResolver to static loader class --- freqtrade/freqtradebot.py | 2 +- freqtrade/optimize/backtesting.py | 2 +- freqtrade/resolvers/exchange_resolver.py | 20 +++++++++++--------- freqtrade/resolvers/pairlist_resolver.py | 3 --- freqtrade/utils.py | 8 ++++---- tests/conftest.py | 2 +- tests/exchange/test_exchange.py | 8 ++++---- tests/pairlist/test_pairlist.py | 3 ++- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8ae027fa2..001b7f02d 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -60,7 +60,7 @@ class FreqtradeBot: # Check config consistency here since strategies can set certain options validate_config_consistency(config) - self.exchange = ExchangeResolver(self.config['exchange']['name'], self.config).exchange + self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) persistence.init(self.config.get('db_url', None), clean_open_orders=self.config.get('dry_run', False)) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 726257cdd..bab997cb1 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -60,7 +60,7 @@ class Backtesting: # Reset keys for backtesting remove_credentials(self.config) self.strategylist: List[IStrategy] = [] - self.exchange = ExchangeResolver(self.config['exchange']['name'], self.config).exchange + self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) if config.get('fee'): self.fee = config['fee'] diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index 60f37b1c9..e28a5cf80 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -15,9 +15,8 @@ class ExchangeResolver(IResolver): This class contains all the logic to load a custom exchange class """ - __slots__ = ['exchange'] - - def __init__(self, exchange_name: str, config: dict, validate: bool = True) -> None: + @staticmethod + def load_exchange(exchange_name: str, config: dict, validate: bool = True) -> Exchange: """ Load the custom class from config parameter :param config: configuration dictionary @@ -25,17 +24,20 @@ class ExchangeResolver(IResolver): # Map exchange name to avoid duplicate classes for identical exchanges exchange_name = MAP_EXCHANGE_CHILDCLASS.get(exchange_name, exchange_name) exchange_name = exchange_name.title() + exchange = None try: - self.exchange = self._load_exchange(exchange_name, kwargs={'config': config, - 'validate': validate}) + exchange = ExchangeResolver._load_exchange(exchange_name, + kwargs={'config': config, + 'validate': validate}) except ImportError: logger.info( f"No {exchange_name} specific subclass found. Using the generic class instead.") - if not hasattr(self, "exchange"): - self.exchange = Exchange(config, validate=validate) + if not exchange: + exchange = Exchange(config, validate=validate) + return exchange - def _load_exchange( - self, exchange_name: str, kwargs: dict) -> Exchange: + @staticmethod + def _load_exchange(exchange_name: str, kwargs: dict) -> Exchange: """ Loads the specified exchange. Only checks for exchanges exported in freqtrade.exchanges diff --git a/freqtrade/resolvers/pairlist_resolver.py b/freqtrade/resolvers/pairlist_resolver.py index 5b5bcee3a..611660ff4 100644 --- a/freqtrade/resolvers/pairlist_resolver.py +++ b/freqtrade/resolvers/pairlist_resolver.py @@ -18,8 +18,6 @@ class PairListResolver(IResolver): This class contains all the logic to load custom PairList class """ - __slots__ = [] - @staticmethod def load_pairlist(pairlist_name: str, exchange, pairlistmanager, config: dict, pairlistconfig: dict, pairlist_pos: int) -> IPairList: @@ -41,7 +39,6 @@ class PairListResolver(IResolver): 'pairlistconfig': pairlistconfig, 'pairlist_pos': pairlist_pos}) - @staticmethod def _load_pairlist(pairlist_name: str, config: dict, kwargs: dict) -> IPairList: """ diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 9e01c7ea6..18966c574 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -198,7 +198,7 @@ def start_download_data(args: Dict[str, Any]) -> None: pairs_not_available: List[str] = [] # Init exchange - exchange = ExchangeResolver(config['exchange']['name'], config).exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) try: if config.get('download_trades'): @@ -233,7 +233,7 @@ def start_list_timeframes(args: Dict[str, Any]) -> None: config['ticker_interval'] = None # Init exchange - exchange = ExchangeResolver(config['exchange']['name'], config, validate=False).exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) if args['print_one_column']: print('\n'.join(exchange.timeframes)) @@ -252,7 +252,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) # Init exchange - exchange = ExchangeResolver(config['exchange']['name'], config, validate=False).exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) # By default only active pairs/markets are to be shown active_only = not args.get('list_pairs_all', False) @@ -333,7 +333,7 @@ def start_test_pairlist(args: Dict[str, Any]) -> None: from freqtrade.pairlist.pairlistmanager import PairListManager config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - exchange = ExchangeResolver(config['exchange']['name'], config, validate=False).exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) quote_currencies = args.get('quote_currencies') if not quote_currencies: diff --git a/tests/conftest.py b/tests/conftest.py index 82111528e..501f89fff 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -77,7 +77,7 @@ def get_patched_exchange(mocker, config, api_mock=None, id='bittrex', patch_exchange(mocker, api_mock, id, mock_markets) config["exchange"]["name"] = id try: - exchange = ExchangeResolver(id, config).exchange + exchange = ExchangeResolver.load_exchange(id, config) except ImportError: exchange = Exchange(config) return exchange diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 629f99aa2..dccf7d74f 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -124,19 +124,19 @@ def test_exchange_resolver(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - exchange = ExchangeResolver('Bittrex', default_conf).exchange + exchange = ExchangeResolver.load_exchange('Bittrex', default_conf) assert isinstance(exchange, Exchange) assert log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) caplog.clear() - exchange = ExchangeResolver('kraken', default_conf).exchange + exchange = ExchangeResolver.load_exchange('kraken', default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Kraken) assert not isinstance(exchange, Binance) assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) - exchange = ExchangeResolver('binance', default_conf).exchange + exchange = ExchangeResolver.load_exchange('binance', default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Binance) assert not isinstance(exchange, Kraken) @@ -145,7 +145,7 @@ def test_exchange_resolver(default_conf, mocker, caplog): caplog) # Test mapping - exchange = ExchangeResolver('binanceus', default_conf).exchange + exchange = ExchangeResolver.load_exchange('binanceus', default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Binance) assert not isinstance(exchange, Kraken) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index e7f098777..21929de2b 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -53,7 +53,8 @@ def test_load_pairlist_noexist(mocker, markets, default_conf): with pytest.raises(OperationalException, match=r"Impossible to load Pairlist 'NonexistingPairList'. " r"This class does not exist or contains Python code errors."): - PairListResolver.load_pairlist('NonexistingPairList', bot.exchange, plm, default_conf, {}, 1) + PairListResolver.load_pairlist('NonexistingPairList', bot.exchange, plm, + default_conf, {}, 1) def test_refresh_market_pair_not_in_whitelist(mocker, markets, static_pl_conf): From 248ef5a0eac41a82febd07ef8b1e4f421f7cce38 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:06:19 +0100 Subject: [PATCH 0038/1106] Convert HyperoptResolver to static loader --- freqtrade/optimize/hyperopt.py | 2 +- freqtrade/resolvers/hyperopt_resolver.py | 29 +++++++++++++----------- tests/optimize/test_hyperopt.py | 6 ++--- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 521a4d790..a4a8f79d1 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -64,7 +64,7 @@ class Hyperopt: self.backtesting = Backtesting(self.config) - self.custom_hyperopt = HyperOptResolver(self.config).hyperopt + self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config) self.custom_hyperoptloss = HyperOptLossResolver(self.config).hyperoptloss self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function diff --git a/freqtrade/resolvers/hyperopt_resolver.py b/freqtrade/resolvers/hyperopt_resolver.py index 05efa1164..a7f922c7b 100644 --- a/freqtrade/resolvers/hyperopt_resolver.py +++ b/freqtrade/resolvers/hyperopt_resolver.py @@ -20,11 +20,11 @@ class HyperOptResolver(IResolver): """ This class contains all the logic to load custom hyperopt class """ - __slots__ = ['hyperopt'] - def __init__(self, config: Dict) -> None: + @staticmethod + def load_hyperopt(config: Dict) -> IHyperOpt: """ - Load the custom class from config parameter + Load the custom hyperopt class from config parameter :param config: configuration dictionary """ if not config.get('hyperopt'): @@ -33,21 +33,23 @@ class HyperOptResolver(IResolver): hyperopt_name = config['hyperopt'] - self.hyperopt = self._load_hyperopt(hyperopt_name, config, - extra_dir=config.get('hyperopt_path')) + hyperopt = HyperOptResolver._load_hyperopt(hyperopt_name, config, + extra_dir=config.get('hyperopt_path')) - if not hasattr(self.hyperopt, 'populate_indicators'): + if not hasattr(hyperopt, 'populate_indicators'): logger.warning("Hyperopt class does not provide populate_indicators() method. " "Using populate_indicators from the strategy.") - if not hasattr(self.hyperopt, 'populate_buy_trend'): + if not hasattr(hyperopt, 'populate_buy_trend'): logger.warning("Hyperopt class does not provide populate_buy_trend() method. " "Using populate_buy_trend from the strategy.") - if not hasattr(self.hyperopt, 'populate_sell_trend'): + if not hasattr(hyperopt, 'populate_sell_trend'): logger.warning("Hyperopt class does not provide populate_sell_trend() method. " "Using populate_sell_trend from the strategy.") + return hyperopt + @staticmethod def _load_hyperopt( - self, hyperopt_name: str, config: Dict, extra_dir: Optional[str] = None) -> IHyperOpt: + hyperopt_name: str, config: Dict, extra_dir: Optional[str] = None) -> IHyperOpt: """ Search and loads the specified hyperopt. :param hyperopt_name: name of the module to import @@ -57,11 +59,12 @@ class HyperOptResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - abs_paths = self.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, extra_dir=extra_dir) + abs_paths = IResolver.build_search_paths(config, current_path=current_path, + user_subdir=USERPATH_HYPEROPTS, + extra_dir=extra_dir) - hyperopt = self._load_object(paths=abs_paths, object_type=IHyperOpt, - object_name=hyperopt_name, kwargs={'config': config}) + hyperopt = IResolver._load_object(paths=abs_paths, object_type=IHyperOpt, + object_name=hyperopt_name, kwargs={'config': config}) if hyperopt: return hyperopt raise OperationalException( diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 29b8b5b16..37de32ab0 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -163,7 +163,7 @@ def test_hyperoptresolver(mocker, default_conf, caplog) -> None: MagicMock(return_value=hyperopt(default_conf)) ) default_conf.update({'hyperopt': 'DefaultHyperOpt'}) - x = HyperOptResolver(default_conf).hyperopt + x = HyperOptResolver.load_hyperopt(default_conf) assert not hasattr(x, 'populate_indicators') assert not hasattr(x, 'populate_buy_trend') assert not hasattr(x, 'populate_sell_trend') @@ -180,7 +180,7 @@ def test_hyperoptresolver_wrongname(mocker, default_conf, caplog) -> None: default_conf.update({'hyperopt': "NonExistingHyperoptClass"}) with pytest.raises(OperationalException, match=r'Impossible to load Hyperopt.*'): - HyperOptResolver(default_conf).hyperopt + HyperOptResolver.load_hyperopt(default_conf) def test_hyperoptresolver_noname(default_conf): @@ -188,7 +188,7 @@ def test_hyperoptresolver_noname(default_conf): with pytest.raises(OperationalException, match="No Hyperopt set. Please use `--hyperopt` to specify " "the Hyperopt class to use."): - HyperOptResolver(default_conf) + HyperOptResolver.load_hyperopt(default_conf) def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None: From 6d5aca4f323dd06cac94cbf598173be6fb3ed645 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:09:08 +0100 Subject: [PATCH 0039/1106] Convert hyperoptloss resolver to static loader --- freqtrade/optimize/hyperopt.py | 2 +- freqtrade/resolvers/hyperopt_resolver.py | 26 +++++++++++++----------- tests/optimize/test_hyperopt.py | 14 ++++++------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a4a8f79d1..48f883ac5 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -66,7 +66,7 @@ class Hyperopt: self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config) - self.custom_hyperoptloss = HyperOptLossResolver(self.config).hyperoptloss + self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function self.trials_file = (self.config['user_data_dir'] / diff --git a/freqtrade/resolvers/hyperopt_resolver.py b/freqtrade/resolvers/hyperopt_resolver.py index a7f922c7b..0726b0627 100644 --- a/freqtrade/resolvers/hyperopt_resolver.py +++ b/freqtrade/resolvers/hyperopt_resolver.py @@ -77,9 +77,9 @@ class HyperOptLossResolver(IResolver): """ This class contains all the logic to load custom hyperopt loss class """ - __slots__ = ['hyperoptloss'] - def __init__(self, config: Dict) -> None: + @staticmethod + def load_hyperoptloss(config: Dict) -> IHyperOptLoss: """ Load the custom class from config parameter :param config: configuration dictionary @@ -89,20 +89,21 @@ class HyperOptLossResolver(IResolver): # default hyperopt loss hyperoptloss_name = config.get('hyperopt_loss') or DEFAULT_HYPEROPT_LOSS - self.hyperoptloss = self._load_hyperoptloss( + hyperoptloss = HyperOptLossResolver._load_hyperoptloss( hyperoptloss_name, config, extra_dir=config.get('hyperopt_path')) # Assign ticker_interval to be used in hyperopt - self.hyperoptloss.__class__.ticker_interval = str(config['ticker_interval']) + hyperoptloss.__class__.ticker_interval = str(config['ticker_interval']) - if not hasattr(self.hyperoptloss, 'hyperopt_loss_function'): + if not hasattr(hyperoptloss, 'hyperopt_loss_function'): raise OperationalException( f"Found HyperoptLoss class {hyperoptloss_name} does not " "implement `hyperopt_loss_function`.") + return hyperoptloss - def _load_hyperoptloss( - self, hyper_loss_name: str, config: Dict, - extra_dir: Optional[str] = None) -> IHyperOptLoss: + @staticmethod + def _load_hyperoptloss(hyper_loss_name: str, config: Dict, + extra_dir: Optional[str] = None) -> IHyperOptLoss: """ Search and loads the specified hyperopt loss class. :param hyper_loss_name: name of the module to import @@ -112,11 +113,12 @@ class HyperOptLossResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - abs_paths = self.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, extra_dir=extra_dir) + abs_paths = IResolver.build_search_paths(config, current_path=current_path, + user_subdir=USERPATH_HYPEROPTS, + extra_dir=extra_dir) - hyperoptloss = self._load_object(paths=abs_paths, object_type=IHyperOptLoss, - object_name=hyper_loss_name) + hyperoptloss = IResolver._load_object(paths=abs_paths, object_type=IHyperOptLoss, + object_name=hyper_loss_name) if hyperoptloss: return hyperoptloss diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 37de32ab0..9c6e73c53 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -198,7 +198,7 @@ def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None: 'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver._load_hyperoptloss', MagicMock(return_value=hl) ) - x = HyperOptLossResolver(default_conf).hyperoptloss + x = HyperOptLossResolver.load_hyperoptloss(default_conf) assert hasattr(x, "hyperopt_loss_function") @@ -206,7 +206,7 @@ def test_hyperoptlossresolver_wrongname(mocker, default_conf, caplog) -> None: default_conf.update({'hyperopt_loss': "NonExistingLossClass"}) with pytest.raises(OperationalException, match=r'Impossible to load HyperoptLoss.*'): - HyperOptLossResolver(default_conf).hyperopt + HyperOptLossResolver.load_hyperoptloss(default_conf) def test_start_not_installed(mocker, default_conf, caplog, import_fails) -> None: @@ -286,7 +286,7 @@ def test_start_filelock(mocker, default_conf, caplog) -> None: def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None: - hl = HyperOptLossResolver(default_conf).hyperoptloss + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, 600) over = hl.hyperopt_loss_function(hyperopt_results, 600 + 100) under = hl.hyperopt_loss_function(hyperopt_results, 600 - 100) @@ -298,7 +298,7 @@ def test_loss_calculation_prefer_shorter_trades(default_conf, hyperopt_results) resultsb = hyperopt_results.copy() resultsb.loc[1, 'trade_duration'] = 20 - hl = HyperOptLossResolver(default_conf).hyperoptloss + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) longer = hl.hyperopt_loss_function(hyperopt_results, 100) shorter = hl.hyperopt_loss_function(resultsb, 100) assert shorter < longer @@ -310,7 +310,7 @@ def test_loss_calculation_has_limited_profit(default_conf, hyperopt_results) -> results_under = hyperopt_results.copy() results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 - hl = HyperOptLossResolver(default_conf).hyperoptloss + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, 600) over = hl.hyperopt_loss_function(results_over, 600) under = hl.hyperopt_loss_function(results_under, 600) @@ -325,7 +325,7 @@ def test_sharpe_loss_prefers_higher_profits(default_conf, hyperopt_results) -> N results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 default_conf.update({'hyperopt_loss': 'SharpeHyperOptLoss'}) - hl = HyperOptLossResolver(default_conf).hyperoptloss + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), @@ -343,7 +343,7 @@ def test_onlyprofit_loss_prefers_higher_profits(default_conf, hyperopt_results) results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 default_conf.update({'hyperopt_loss': 'OnlyProfitHyperOptLoss'}) - hl = HyperOptLossResolver(default_conf).hyperoptloss + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), datetime(2019, 1, 1), datetime(2019, 5, 1)) over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), From c6d22339788e9686552d171bf19cb00d41f7cb0a Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:23:48 +0100 Subject: [PATCH 0040/1106] Convert StrategyLoader to static loader --- docs/strategy_analysis_example.md | 6 +- freqtrade/freqtradebot.py | 2 +- freqtrade/optimize/backtesting.py | 4 +- freqtrade/optimize/edge_cli.py | 2 +- freqtrade/plot/plotting.py | 2 +- freqtrade/resolvers/strategy_resolver.py | 65 ++++---- .../templates/strategy_analysis_example.ipynb | 6 +- tests/strategy/test_strategy.py | 141 +++++++++--------- 8 files changed, 116 insertions(+), 112 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 9e61bda65..cc6b9805f 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -44,9 +44,9 @@ candles.head() ```python # Load strategy using values set above from freqtrade.resolvers import StrategyResolver -strategy = StrategyResolver({'strategy': strategy_name, - 'user_data_dir': user_data_dir, - 'strategy_path': strategy_location}).strategy +strategy = StrategyResolver.load_strategy({'strategy': strategy_name, + 'user_data_dir': user_data_dir, + 'strategy_path': strategy_location}) # Generate buy/sell signals using strategy df = strategy.analyze_ticker(candles, {'pair': pair}) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 001b7f02d..1b89cc75b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -55,7 +55,7 @@ class FreqtradeBot: self.heartbeat_interval = self.config.get('internals', {}).get('heartbeat_interval', 60) - self.strategy: IStrategy = StrategyResolver(self.config).strategy + self.strategy: IStrategy = StrategyResolver.load_strategy(self.config) # Check config consistency here since strategies can set certain options validate_config_consistency(config) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index bab997cb1..ffa112bd5 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -75,12 +75,12 @@ class Backtesting: for strat in list(self.config['strategy_list']): stratconf = deepcopy(self.config) stratconf['strategy'] = strat - self.strategylist.append(StrategyResolver(stratconf).strategy) + self.strategylist.append(StrategyResolver.load_strategy(stratconf)) validate_config_consistency(stratconf) else: # No strategy list specified, only one strategy - self.strategylist.append(StrategyResolver(self.config).strategy) + self.strategylist.append(StrategyResolver.load_strategy(self.config)) validate_config_consistency(self.config) if "ticker_interval" not in self.config: diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index 3848623db..ea5cc663d 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -34,7 +34,7 @@ class EdgeCli: remove_credentials(self.config) self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT self.exchange = Exchange(self.config) - self.strategy = StrategyResolver(self.config).strategy + self.strategy = StrategyResolver.load_strategy(self.config) validate_config_consistency(self.config) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 85089af9c..7cd4ab854 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -340,7 +340,7 @@ def load_and_plot_trades(config: Dict[str, Any]): - Generate plot files :return: None """ - strategy = StrategyResolver(config).strategy + strategy = StrategyResolver.load_strategy(config) plot_elements = init_plotscript(config) trades = plot_elements['trades'] diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index a2d14fbf3..6d3fe5ff9 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -20,12 +20,11 @@ logger = logging.getLogger(__name__) class StrategyResolver(IResolver): """ - This class contains all the logic to load custom strategy class + This class contains the logic to load custom strategy class """ - __slots__ = ['strategy'] - - def __init__(self, config: Optional[Dict] = None) -> None: + @staticmethod + def load_strategy(config: Optional[Dict] = None) -> IStrategy: """ Load the custom class from config parameter :param config: configuration dictionary or None @@ -37,9 +36,9 @@ class StrategyResolver(IResolver): "the strategy class to use.") strategy_name = config['strategy'] - self.strategy: IStrategy = self._load_strategy(strategy_name, - config=config, - extra_dir=config.get('strategy_path')) + strategy: IStrategy = StrategyResolver._load_strategy( + strategy_name, config=config, + extra_dir=config.get('strategy_path')) # make sure ask_strategy dict is available if 'ask_strategy' not in config: @@ -68,9 +67,11 @@ class StrategyResolver(IResolver): ] for attribute, default, ask_strategy in attributes: if ask_strategy: - self._override_attribute_helper(config['ask_strategy'], attribute, default) + StrategyResolver._override_attribute_helper(strategy, config['ask_strategy'], + attribute, default) else: - self._override_attribute_helper(config, attribute, default) + StrategyResolver._override_attribute_helper(strategy, config, + attribute, default) # Loop this list again to have output combined for attribute, _, exp in attributes: @@ -80,14 +81,16 @@ class StrategyResolver(IResolver): logger.info("Strategy using %s: %s", attribute, config[attribute]) # Sort and apply type conversions - self.strategy.minimal_roi = OrderedDict(sorted( - {int(key): value for (key, value) in self.strategy.minimal_roi.items()}.items(), + strategy.minimal_roi = OrderedDict(sorted( + {int(key): value for (key, value) in strategy.minimal_roi.items()}.items(), key=lambda t: t[0])) - self.strategy.stoploss = float(self.strategy.stoploss) + strategy.stoploss = float(strategy.stoploss) - self._strategy_sanity_validations() + StrategyResolver._strategy_sanity_validations(strategy) + return strategy - def _override_attribute_helper(self, config, attribute: str, default): + @staticmethod + def _override_attribute_helper(strategy, config, attribute: str, default): """ Override attributes in the strategy. Prevalence: @@ -96,30 +99,32 @@ class StrategyResolver(IResolver): - default (if not None) """ if attribute in config: - setattr(self.strategy, attribute, config[attribute]) + setattr(strategy, attribute, config[attribute]) logger.info("Override strategy '%s' with value in config file: %s.", attribute, config[attribute]) - elif hasattr(self.strategy, attribute): - val = getattr(self.strategy, attribute) + elif hasattr(strategy, attribute): + val = getattr(strategy, attribute) # None's cannot exist in the config, so do not copy them if val is not None: config[attribute] = val # Explicitly check for None here as other "falsy" values are possible elif default is not None: - setattr(self.strategy, attribute, default) + setattr(strategy, attribute, default) config[attribute] = default - def _strategy_sanity_validations(self): - if not all(k in self.strategy.order_types for k in constants.REQUIRED_ORDERTYPES): - raise ImportError(f"Impossible to load Strategy '{self.strategy.__class__.__name__}'. " + @staticmethod + def _strategy_sanity_validations(strategy): + if not all(k in strategy.order_types for k in constants.REQUIRED_ORDERTYPES): + raise ImportError(f"Impossible to load Strategy '{strategy.__class__.__name__}'. " f"Order-types mapping is incomplete.") - if not all(k in self.strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF): - raise ImportError(f"Impossible to load Strategy '{self.strategy.__class__.__name__}'. " + if not all(k in strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF): + raise ImportError(f"Impossible to load Strategy '{strategy.__class__.__name__}'. " f"Order-time-in-force mapping is incomplete.") - def _load_strategy( - self, strategy_name: str, config: dict, extra_dir: Optional[str] = None) -> IStrategy: + @staticmethod + def _load_strategy(strategy_name: str, + config: dict, extra_dir: Optional[str] = None) -> IStrategy: """ Search and loads the specified strategy. :param strategy_name: name of the module to import @@ -129,9 +134,9 @@ class StrategyResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('strategy').resolve() - abs_paths = self.build_search_paths(config, current_path=current_path, - user_subdir=constants.USERPATH_STRATEGY, - extra_dir=extra_dir) + abs_paths = IResolver.build_search_paths(config, current_path=current_path, + user_subdir=constants.USERPATH_STRATEGY, + extra_dir=extra_dir) if ":" in strategy_name: logger.info("loading base64 encoded strategy") @@ -149,8 +154,8 @@ class StrategyResolver(IResolver): # register temp path with the bot abs_paths.insert(0, temp.resolve()) - strategy = self._load_object(paths=abs_paths, object_type=IStrategy, - object_name=strategy_name, kwargs={'config': config}) + strategy = IResolver._load_object(paths=abs_paths, object_type=IStrategy, + object_name=strategy_name, kwargs={'config': config}) if strategy: strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args) strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args) diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 2876ea938..eea8fb85f 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -73,9 +73,9 @@ "source": [ "# Load strategy using values set above\n", "from freqtrade.resolvers import StrategyResolver\n", - "strategy = StrategyResolver({'strategy': strategy_name,\n", - " 'user_data_dir': user_data_dir,\n", - " 'strategy_path': strategy_location}).strategy\n", + "strategy = StrategyResolver.load_strategy({'strategy': strategy_name,\n", + " 'user_data_dir': user_data_dir,\n", + " 'strategy_path': strategy_location})\n", "\n", "# Generate buy/sell signals using strategy\n", "df = strategy.analyze_ticker(candles, {'pair': pair})\n", diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 963d36c76..116eec56b 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -39,8 +39,8 @@ def test_load_strategy(default_conf, result): default_conf.update({'strategy': 'SampleStrategy', 'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates') }) - resolver = StrategyResolver(default_conf) - assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) + strategy = StrategyResolver.load_strategy(default_conf) + assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) def test_load_strategy_base64(result, caplog, default_conf): @@ -48,8 +48,8 @@ def test_load_strategy_base64(result, caplog, default_conf): encoded_string = urlsafe_b64encode(file.read()).decode("utf-8") default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)}) - resolver = StrategyResolver(default_conf) - assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) + strategy = StrategyResolver.load_strategy(default_conf) + assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) # Make sure strategy was loaded from base64 (using temp directory)!! assert log_has_re(r"Using resolved strategy SampleStrategy from '" r".*(/|\\).*(/|\\)SampleStrategy\.py'\.\.\.", caplog) @@ -57,13 +57,12 @@ def test_load_strategy_base64(result, caplog, default_conf): def test_load_strategy_invalid_directory(result, caplog, default_conf): default_conf['strategy'] = 'DefaultStrategy' - resolver = StrategyResolver(default_conf) extra_dir = Path.cwd() / 'some/path' - resolver._load_strategy('DefaultStrategy', config=default_conf, extra_dir=extra_dir) + strategy = StrategyResolver._load_strategy('DefaultStrategy', config=default_conf, extra_dir=extra_dir) assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog) - assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) + assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) def test_load_not_found_strategy(default_conf): @@ -71,7 +70,7 @@ def test_load_not_found_strategy(default_conf): with pytest.raises(OperationalException, match=r"Impossible to load Strategy 'NotFoundStrategy'. " r"This class does not exist or contains Python code errors."): - StrategyResolver(default_conf) + StrategyResolver.load_strategy(default_conf) def test_load_strategy_noname(default_conf): @@ -79,30 +78,30 @@ def test_load_strategy_noname(default_conf): with pytest.raises(OperationalException, match="No strategy set. Please use `--strategy` to specify " "the strategy class to use."): - StrategyResolver(default_conf) + StrategyResolver.load_strategy(default_conf) def test_strategy(result, default_conf): default_conf.update({'strategy': 'DefaultStrategy'}) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) metadata = {'pair': 'ETH/BTC'} - assert resolver.strategy.minimal_roi[0] == 0.04 + assert strategy.minimal_roi[0] == 0.04 assert default_conf["minimal_roi"]['0'] == 0.04 - assert resolver.strategy.stoploss == -0.10 + assert strategy.stoploss == -0.10 assert default_conf['stoploss'] == -0.10 - assert resolver.strategy.ticker_interval == '5m' + assert strategy.ticker_interval == '5m' assert default_conf['ticker_interval'] == '5m' - df_indicators = resolver.strategy.advise_indicators(result, metadata=metadata) + df_indicators = strategy.advise_indicators(result, metadata=metadata) assert 'adx' in df_indicators - dataframe = resolver.strategy.advise_buy(df_indicators, metadata=metadata) + dataframe = strategy.advise_buy(df_indicators, metadata=metadata) assert 'buy' in dataframe.columns - dataframe = resolver.strategy.advise_sell(df_indicators, metadata=metadata) + dataframe = strategy.advise_sell(df_indicators, metadata=metadata) assert 'sell' in dataframe.columns @@ -114,9 +113,9 @@ def test_strategy_override_minimal_roi(caplog, default_conf): "0": 0.5 } }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.minimal_roi[0] == 0.5 + assert strategy.minimal_roi[0] == 0.5 assert log_has("Override strategy 'minimal_roi' with value in config file: {'0': 0.5}.", caplog) @@ -126,9 +125,9 @@ def test_strategy_override_stoploss(caplog, default_conf): 'strategy': 'DefaultStrategy', 'stoploss': -0.5 }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.stoploss == -0.5 + assert strategy.stoploss == -0.5 assert log_has("Override strategy 'stoploss' with value in config file: -0.5.", caplog) @@ -138,10 +137,10 @@ def test_strategy_override_trailing_stop(caplog, default_conf): 'strategy': 'DefaultStrategy', 'trailing_stop': True }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.trailing_stop - assert isinstance(resolver.strategy.trailing_stop, bool) + assert strategy.trailing_stop + assert isinstance(strategy.trailing_stop, bool) assert log_has("Override strategy 'trailing_stop' with value in config file: True.", caplog) @@ -153,13 +152,13 @@ def test_strategy_override_trailing_stop_positive(caplog, default_conf): 'trailing_stop_positive_offset': -0.2 }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.trailing_stop_positive == -0.1 + assert strategy.trailing_stop_positive == -0.1 assert log_has("Override strategy 'trailing_stop_positive' with value in config file: -0.1.", caplog) - assert resolver.strategy.trailing_stop_positive_offset == -0.2 + assert strategy.trailing_stop_positive_offset == -0.2 assert log_has("Override strategy 'trailing_stop_positive' with value in config file: -0.1.", caplog) @@ -172,10 +171,10 @@ def test_strategy_override_ticker_interval(caplog, default_conf): 'ticker_interval': 60, 'stake_currency': 'ETH' }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.ticker_interval == 60 - assert resolver.strategy.stake_currency == 'ETH' + assert strategy.ticker_interval == 60 + assert strategy.stake_currency == 'ETH' assert log_has("Override strategy 'ticker_interval' with value in config file: 60.", caplog) @@ -187,9 +186,9 @@ def test_strategy_override_process_only_new_candles(caplog, default_conf): 'strategy': 'DefaultStrategy', 'process_only_new_candles': True }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.process_only_new_candles + assert strategy.process_only_new_candles assert log_has("Override strategy 'process_only_new_candles' with value in config file: True.", caplog) @@ -207,11 +206,11 @@ def test_strategy_override_order_types(caplog, default_conf): 'strategy': 'DefaultStrategy', 'order_types': order_types }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.order_types + assert strategy.order_types for method in ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']: - assert resolver.strategy.order_types[method] == order_types[method] + assert strategy.order_types[method] == order_types[method] assert log_has("Override strategy 'order_types' with value in config file:" " {'buy': 'market', 'sell': 'limit', 'stoploss': 'limit'," @@ -225,7 +224,7 @@ def test_strategy_override_order_types(caplog, default_conf): with pytest.raises(ImportError, match=r"Impossible to load Strategy 'DefaultStrategy'. " r"Order-types mapping is incomplete."): - StrategyResolver(default_conf) + StrategyResolver.load_strategy(default_conf) def test_strategy_override_order_tif(caplog, default_conf): @@ -240,11 +239,11 @@ def test_strategy_override_order_tif(caplog, default_conf): 'strategy': 'DefaultStrategy', 'order_time_in_force': order_time_in_force }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.order_time_in_force + assert strategy.order_time_in_force for method in ['buy', 'sell']: - assert resolver.strategy.order_time_in_force[method] == order_time_in_force[method] + assert strategy.order_time_in_force[method] == order_time_in_force[method] assert log_has("Override strategy 'order_time_in_force' with value in config file:" " {'buy': 'fok', 'sell': 'gtc'}.", caplog) @@ -257,7 +256,7 @@ def test_strategy_override_order_tif(caplog, default_conf): with pytest.raises(ImportError, match=r"Impossible to load Strategy 'DefaultStrategy'. " r"Order-time-in-force mapping is incomplete."): - StrategyResolver(default_conf) + StrategyResolver.load_strategy(default_conf) def test_strategy_override_use_sell_signal(caplog, default_conf): @@ -265,9 +264,9 @@ def test_strategy_override_use_sell_signal(caplog, default_conf): default_conf.update({ 'strategy': 'DefaultStrategy', }) - resolver = StrategyResolver(default_conf) - assert resolver.strategy.use_sell_signal - assert isinstance(resolver.strategy.use_sell_signal, bool) + strategy = StrategyResolver.load_strategy(default_conf) + assert strategy.use_sell_signal + assert isinstance(strategy.use_sell_signal, bool) # must be inserted to configuration assert 'use_sell_signal' in default_conf['ask_strategy'] assert default_conf['ask_strategy']['use_sell_signal'] @@ -278,10 +277,10 @@ def test_strategy_override_use_sell_signal(caplog, default_conf): 'use_sell_signal': False, }, }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert not resolver.strategy.use_sell_signal - assert isinstance(resolver.strategy.use_sell_signal, bool) + assert not strategy.use_sell_signal + assert isinstance(strategy.use_sell_signal, bool) assert log_has("Override strategy 'use_sell_signal' with value in config file: False.", caplog) @@ -290,9 +289,9 @@ def test_strategy_override_use_sell_profit_only(caplog, default_conf): default_conf.update({ 'strategy': 'DefaultStrategy', }) - resolver = StrategyResolver(default_conf) - assert not resolver.strategy.sell_profit_only - assert isinstance(resolver.strategy.sell_profit_only, bool) + strategy = StrategyResolver.load_strategy(default_conf) + assert not strategy.sell_profit_only + assert isinstance(strategy.sell_profit_only, bool) # must be inserted to configuration assert 'sell_profit_only' in default_conf['ask_strategy'] assert not default_conf['ask_strategy']['sell_profit_only'] @@ -303,10 +302,10 @@ def test_strategy_override_use_sell_profit_only(caplog, default_conf): 'sell_profit_only': True, }, }) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) - assert resolver.strategy.sell_profit_only - assert isinstance(resolver.strategy.sell_profit_only, bool) + assert strategy.sell_profit_only + assert isinstance(strategy.sell_profit_only, bool) assert log_has("Override strategy 'sell_profit_only' with value in config file: True.", caplog) @@ -315,11 +314,11 @@ def test_deprecate_populate_indicators(result, default_conf): default_location = path.join(path.dirname(path.realpath(__file__))) default_conf.update({'strategy': 'TestStrategyLegacy', 'strategy_path': default_location}) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") - indicators = resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) + indicators = strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated - check out the Sample strategy to see the current function headers!" \ @@ -328,7 +327,7 @@ def test_deprecate_populate_indicators(result, default_conf): with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") - resolver.strategy.advise_buy(indicators, {'pair': 'ETH/BTC'}) + strategy.advise_buy(indicators, {'pair': 'ETH/BTC'}) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated - check out the Sample strategy to see the current function headers!" \ @@ -337,7 +336,7 @@ def test_deprecate_populate_indicators(result, default_conf): with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") - resolver.strategy.advise_sell(indicators, {'pair': 'ETH_BTC'}) + strategy.advise_sell(indicators, {'pair': 'ETH_BTC'}) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "deprecated - check out the Sample strategy to see the current function headers!" \ @@ -349,47 +348,47 @@ def test_call_deprecated_function(result, monkeypatch, default_conf): default_location = path.join(path.dirname(path.realpath(__file__))) default_conf.update({'strategy': 'TestStrategyLegacy', 'strategy_path': default_location}) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) metadata = {'pair': 'ETH/BTC'} # Make sure we are using a legacy function - assert resolver.strategy._populate_fun_len == 2 - assert resolver.strategy._buy_fun_len == 2 - assert resolver.strategy._sell_fun_len == 2 - assert resolver.strategy.INTERFACE_VERSION == 1 + assert strategy._populate_fun_len == 2 + assert strategy._buy_fun_len == 2 + assert strategy._sell_fun_len == 2 + assert strategy.INTERFACE_VERSION == 1 - indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) + indicator_df = strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) assert 'adx' in indicator_df.columns - buydf = resolver.strategy.advise_buy(result, metadata=metadata) + buydf = strategy.advise_buy(result, metadata=metadata) assert isinstance(buydf, DataFrame) assert 'buy' in buydf.columns - selldf = resolver.strategy.advise_sell(result, metadata=metadata) + selldf = strategy.advise_sell(result, metadata=metadata) assert isinstance(selldf, DataFrame) assert 'sell' in selldf def test_strategy_interface_versioning(result, monkeypatch, default_conf): default_conf.update({'strategy': 'DefaultStrategy'}) - resolver = StrategyResolver(default_conf) + strategy = StrategyResolver.load_strategy(default_conf) metadata = {'pair': 'ETH/BTC'} # Make sure we are using a legacy function - assert resolver.strategy._populate_fun_len == 3 - assert resolver.strategy._buy_fun_len == 3 - assert resolver.strategy._sell_fun_len == 3 - assert resolver.strategy.INTERFACE_VERSION == 2 + assert strategy._populate_fun_len == 3 + assert strategy._buy_fun_len == 3 + assert strategy._sell_fun_len == 3 + assert strategy.INTERFACE_VERSION == 2 - indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) + indicator_df = strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) assert 'adx' in indicator_df.columns - buydf = resolver.strategy.advise_buy(result, metadata=metadata) + buydf = strategy.advise_buy(result, metadata=metadata) assert isinstance(buydf, DataFrame) assert 'buy' in buydf.columns - selldf = resolver.strategy.advise_sell(result, metadata=metadata) + selldf = strategy.advise_sell(result, metadata=metadata) assert isinstance(selldf, DataFrame) assert 'sell' in selldf From 90cabd7c21306f6f7fda068e40936e7f005ca825 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:46:35 +0100 Subject: [PATCH 0041/1106] Wrap line --- tests/strategy/test_strategy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 116eec56b..ce7ac1741 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -58,7 +58,8 @@ def test_load_strategy_base64(result, caplog, default_conf): def test_load_strategy_invalid_directory(result, caplog, default_conf): default_conf['strategy'] = 'DefaultStrategy' extra_dir = Path.cwd() / 'some/path' - strategy = StrategyResolver._load_strategy('DefaultStrategy', config=default_conf, extra_dir=extra_dir) + strategy = StrategyResolver._load_strategy('DefaultStrategy', config=default_conf, + extra_dir=extra_dir) assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog) From bb8acc61db3685f09e34169c0e4f8bb17fac8588 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 15:09:17 +0100 Subject: [PATCH 0042/1106] Convert datadir within config to Path (it's used as Path all the time!) --- freqtrade/configuration/configuration.py | 2 +- freqtrade/configuration/directory_operations.py | 4 ++-- freqtrade/data/dataprovider.py | 3 +-- freqtrade/utils.py | 9 ++++----- tests/test_configuration.py | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 001e89303..f73b52c10 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -403,7 +403,7 @@ class Configuration: config['pairs'] = config.get('exchange', {}).get('pair_whitelist') else: # Fall back to /dl_path/pairs.json - pairs_file = Path(config['datadir']) / "pairs.json" + pairs_file = config['datadir'] / "pairs.json" if pairs_file.exists(): with pairs_file.open('r') as f: config['pairs'] = json_load(f) diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index 3dd76a025..556f27742 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -9,7 +9,7 @@ from freqtrade.constants import USER_DATA_FILES logger = logging.getLogger(__name__) -def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str: +def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> Path: folder = Path(datadir) if datadir else Path(f"{config['user_data_dir']}/data") if not datadir: @@ -20,7 +20,7 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str if not folder.is_dir(): folder.mkdir(parents=True) logger.info(f'Created data directory: {datadir}') - return str(folder) + return folder def create_userdata_dir(directory: str, create_dir=False) -> Path: diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 7b7159145..2964d1cb7 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -5,7 +5,6 @@ including Klines, tickers, historic data Common Interface for bot and strategy to access data. """ import logging -from pathlib import Path from typing import Any, Dict, List, Optional, Tuple from pandas import DataFrame @@ -65,7 +64,7 @@ class DataProvider: """ return load_pair_history(pair=pair, timeframe=timeframe or self._config['ticker_interval'], - datadir=Path(self._config['datadir']) + datadir=self._config['datadir'] ) def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame: diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 9e01c7ea6..2ae9e1ecb 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -191,9 +191,8 @@ def start_download_data(args: Dict[str, Any]) -> None: "Downloading data requires a list of pairs. " "Please check the documentation on how to configure this.") - dl_path = Path(config['datadir']) logger.info(f'About to download pairs: {config["pairs"]}, ' - f'intervals: {config["timeframes"]} to {dl_path}') + f'intervals: {config["timeframes"]} to {config["datadir"]}') pairs_not_available: List[str] = [] @@ -203,17 +202,17 @@ def start_download_data(args: Dict[str, Any]) -> None: if config.get('download_trades'): pairs_not_available = refresh_backtest_trades_data( - exchange, pairs=config["pairs"], datadir=Path(config['datadir']), + exchange, pairs=config["pairs"], datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) # Convert downloaded trade data to different timeframes convert_trades_to_ohlcv( pairs=config["pairs"], timeframes=config["timeframes"], - datadir=Path(config['datadir']), timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) else: pairs_not_available = refresh_backtest_ohlcv_data( exchange, pairs=config["pairs"], timeframes=config["timeframes"], - datadir=Path(config['datadir']), timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) except KeyboardInterrupt: sys.exit("SIGINT received, aborting ...") diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 292d53315..6564417b3 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -977,7 +977,7 @@ def test_pairlist_resolving_fallback(mocker): assert config['pairs'] == ['ETH/BTC', 'XRP/BTC'] assert config['exchange']['name'] == 'binance' - assert config['datadir'] == str(Path.cwd() / "user_data/data/binance") + assert config['datadir'] == Path.cwd() / "user_data/data/binance" @pytest.mark.parametrize("setting", [ From ecbb77c17fa3130e2d3dbef2044a7c2d8447685b Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 15:13:55 +0100 Subject: [PATCH 0043/1106] Add forgotten option --- freqtrade/plot/plotting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 85089af9c..62081194f 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -37,7 +37,7 @@ def init_plotscript(config): timerange = TimeRange.parse_timerange(config.get("timerange")) tickers = history.load_data( - datadir=Path(str(config.get("datadir"))), + datadir=config.get("datadir"), pairs=pairs, timeframe=config.get('ticker_interval', '5m'), timerange=timerange, From c6b9c8eca0722305f6d450cf7d9cada9cae216ea Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 19:32:31 +0100 Subject: [PATCH 0044/1106] Forgot to save --- freqtrade/edge/__init__.py | 4 ++-- freqtrade/optimize/backtesting.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index e56071a98..e1dfe8e25 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -96,7 +96,7 @@ class Edge: if self._refresh_pairs: history.refresh_data( - datadir=Path(self.config['datadir']), + datadir=self.config['datadir'], pairs=pairs, exchange=self.exchange, timeframe=self.strategy.ticker_interval, @@ -104,7 +104,7 @@ class Edge: ) data = history.load_data( - datadir=Path(self.config['datadir']), + datadir=self.config['datadir'], pairs=pairs, timeframe=self.strategy.ticker_interval, timerange=self._timerange, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 726257cdd..630cd106f 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -109,7 +109,7 @@ class Backtesting: 'timerange') is None else str(self.config.get('timerange'))) data = history.load_data( - datadir=Path(self.config['datadir']), + datadir=self.config['datadir'], pairs=self.config['exchange']['pair_whitelist'], timeframe=self.timeframe, timerange=timerange, From 0ac5e5035c499e07569f63dca45ac11938a601c3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 20:43:31 +0100 Subject: [PATCH 0045/1106] Remove unused import --- freqtrade/edge/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index e1dfe8e25..9ad2485ef 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -1,7 +1,6 @@ # pragma pylint: disable=W0603 """ Edge positioning package """ import logging -from pathlib import Path from typing import Any, Dict, NamedTuple import arrow From 690eb2a52b1883e3faff22a29a2f68dcaad4aa2f Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 24 Dec 2019 07:19:35 +0300 Subject: [PATCH 0046/1106] configuration.md reviewed --- docs/configuration.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 8ae824277..b3292ee74 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -388,48 +388,51 @@ The valid values are: ## Prices used for orders -Prices for regular orders can be controlled via the parameter structures `bid_strategy` for Buying, and `ask_strategy` for selling. -Prices are always retrieved right before an order is placed, either by querying the `fetch_ticker()` endpoint of the exchange (usually `/ticker`), or by using the orderbook. +Prices for regular orders can be controlled via the parameter structures `bid_strategy` for buying and `ask_strategy` for selling. +Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data. + +!!! Note + Orderbook data used by Freqtrade are the data retrieved from exchange by the ccxt's function `fetch_order_book()`, i.e. are usually data from the L2-aggregated orderbook, while the ticker data are the structures returned by the ccxt's `fetch_ticker()`/`fetch_tickers()` functions. Refer to the ccxt library [documentation](https://github.com/ccxt/ccxt/wiki/Manual#market-data) for more details. ### Buy price #### Check depth of market -When enabling `bid_strategy.check_depth_of_market.enabled=True`, then buy signals will be filtered based on the orderbook size for each size (sum of all amounts). -Orderbook bid size is then divided by Orderbook ask size - and the resulting delta is compared to `bid_strategy.check_depth_of_market.bids_to_ask_delta`, and a buy is only executed if the orderbook delta is bigger or equal to the configured delta. +When check depth of market is enabled (i.e. `bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side. + +Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) side depth and the resulting delta is compared to the value of the `bid_strategy.check_depth_of_market.bids_to_ask_delta` parameter. The buy order is only executed if the orderbook delta is greater than or equal to the configured delta value. !!! Note - A calculated delta below 1 means that sell order size is greater, while value greater than 1 means buy order size is higher + A delta value below 1 means that `ask` (sell) orderbook side depth is greater than the depth of the `bid` (buy) orderbook side, while a value greater than 1 means opposite (depth of the buy side is higher than the depth of the sell side). #### Buy price with Orderbook enabled -When buying with the orderbook enabled (`bid_strategy.use_order_book=True`) - Freqtrade will fetch the `bid_strategy.order_book_top` entries in the orderbook, and will then use the entry specified as `bid_strategy.order_book_top` on the `bids` side of the orderbook. 1 specifies the topmost entry in the Orderbook - while 2 would use the 2nd entry in the Orderbook. +When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the `bid` (buy) side of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on. -#### Buy price without Orderbook +#### Buy price without Orderbook enabled -When not using orderbook (`bid_strategy.use_order_book=False`), then Freqtrade will use the best `ask` price based on a call to `fetch_ticker()` if it's below the `last` traded price. -Otherwise, it'll calculate a rate between `ask` and `last` price. +When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `ask` (sell) price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `ask` price is not below the `last` price), it calculates a rate between `ask` and `last` price. -The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `ask` price, `1.0` will use the `last` price and values between those interpolate between ask and last -price. -Using `ask` price will guarantee quick success in bid, but bot will also end up paying more than what would have been necessary. +The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `ask` price, while `1.0` will use the `last` price and values between those interpolate between ask and last price. + +Using `ask` price often guarantees quicker success in the bid, but the bot can also end up paying more than what would have been necessary. ### Sell price #### Sell price with Orderbook enabled -When selling with the Orderbook enabled (`ask_strategy.use_order_book=True`) - Freqtrade will fetch the `ask_strategy.order_book_max` entries in the orderbook. Freqtrade will then validate each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` side for a profitable sell-possibility based on the strategy configuration and will place a sell order at the first profitable spot. +When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` orderbook side are validated for a profitable sell-possibility based on the strategy configuration and the sell order is placed at the first profitable spot. + +The idea here is to place the sell order early, to be ahead in the queue. -The idea here is to place the sell-order early, to be ahead in the queue. A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. !!! Warning "Orderbook and stoploss_on_exchange" - Using `ask_strategy.order_book_max` higher than 1 may increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be need to be cancelled as soon as the order is placed. + Using `ask_strategy.order_book_max` higher than 1 may increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. +#### Sell price without Orderbook enabled -#### Sell price without orderbook - -When not using orderbook (`ask_strategy.use_order_book=False`), then the best `bid` will be used as sell rate based on a call to `fetch_ticker()`. +When not using orderbook (`ask_strategy.use_order_book=False`), the `bid` price from the ticker will be used as the sell price. ## Pairlists From f487dac047bfb1d61a93c5f45d9a08ddfcdab5bc Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 06:27:11 +0100 Subject: [PATCH 0047/1106] FIx bug in dry-run wallets causing balances to stay there after trades are sold --- freqtrade/wallets.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index dd706438f..54c3f9138 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -58,13 +58,15 @@ class Wallets: - Subtract currently tied up stake_amount in open trades - update balances for currencies currently in trades """ + # Recreate _wallets to reset closed trade balances + _wallets = {} closed_trades = Trade.get_trades(Trade.is_open.is_(False)).all() open_trades = Trade.get_trades(Trade.is_open.is_(True)).all() tot_profit = sum([trade.calc_profit() for trade in closed_trades]) tot_in_trades = sum([trade.stake_amount for trade in open_trades]) current_stake = self.start_cap + tot_profit - tot_in_trades - self._wallets[self._config['stake_currency']] = Wallet( + _wallets[self._config['stake_currency']] = Wallet( self._config['stake_currency'], current_stake, 0, @@ -73,12 +75,13 @@ class Wallets: for trade in open_trades: curr = trade.pair.split('/')[0] - self._wallets[curr] = Wallet( + _wallets[curr] = Wallet( curr, trade.amount, 0, trade.amount ) + self._wallets = _wallets def _update_live(self) -> None: From 33cfeaf9b01a51fc16d3dd9a437a6ffc5c670955 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 06:31:05 +0100 Subject: [PATCH 0048/1106] Remove i.e. where it doesn't fit --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index b3292ee74..b1b03c721 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -398,7 +398,7 @@ Prices are always retrieved right before an order is placed, either by querying #### Check depth of market -When check depth of market is enabled (i.e. `bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side. +When check depth of market is enabled (`bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side. Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) side depth and the resulting delta is compared to the value of the `bid_strategy.check_depth_of_market.bids_to_ask_delta` parameter. The buy order is only executed if the orderbook delta is greater than or equal to the configured delta value. From b8442d536a41e4b93872618f38239fadcaa20f28 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 06:47:25 +0100 Subject: [PATCH 0049/1106] Update integration test to also test dry-run-wallets --- tests/test_integration.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index 728e96d55..c5d08ec22 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -118,12 +118,10 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True default_conf['stake_amount'] = 'unlimited' + default_conf['dry_run_wallet'] = 1000 default_conf['exchange']['name'] = 'binance' default_conf['telegram']['enabled'] = True mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) - mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock( - side_effect=[1000, 800, 600, 400, 200] - )) mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_ticker=ticker, @@ -138,6 +136,14 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) + should_sell_mock = MagicMock(side_effect=[ + SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), + SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL), + SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), + SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), + SellCheckTuple(sell_flag=None, sell_type=SellType.NONE)] + ) + mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock) freqtrade = get_patched_freqtradebot(mocker, default_conf) rpc = RPC(freqtrade) @@ -158,3 +164,20 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc for trade in trades: assert trade.stake_amount == 200 + # Reset trade open order id's + trade.open_order_id = None + trades = Trade.get_open_trades() + assert len(trades) == 5 + bals = freqtrade.wallets.get_all_balances() + + freqtrade.process_maybe_execute_sells(trades) + trades = Trade.get_open_trades() + # One trade sold + assert len(trades) == 4 + # Validate that balance of sold trade is not in dry-run balances anymore. + bals2 = freqtrade.wallets.get_all_balances() + assert bals != bals2 + assert len(bals) == 6 + assert len(bals2) == 5 + assert 'LTC' in bals + assert 'LTC' not in bals2 From a105e5664a3d166a2c641a0da8ce10fea5f55d7b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 06:58:30 +0100 Subject: [PATCH 0050/1106] Align /balance output to show everything in stake currency the conversation to BTC does not make sense --- freqtrade/rpc/rpc.py | 3 ++- freqtrade/rpc/telegram.py | 4 ++-- tests/rpc/test_rpc_telegram.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 3b4b7570a..d6d442df5 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -341,13 +341,14 @@ class RPC: raise RPCException('All balances are zero.') symbol = fiat_display_currency - value = self._fiat_converter.convert_amount(total, 'BTC', + value = self._fiat_converter.convert_amount(total, stake_currency, symbol) if self._fiat_converter else 0 return { 'currencies': output, 'total': total, 'symbol': symbol, 'value': value, + 'stake': stake_currency, 'note': 'Simulated balances' if self._freqtrade.config.get('dry_run', False) else '' } diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index e0e2afd7b..e9ecdcff6 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -335,7 +335,7 @@ class Telegram(RPC): output = '' if self._config['dry_run']: output += ( - f"*Warning:*Simulated balances in Dry Mode.\n" + f"*Warning:* Simulated balances in Dry Mode.\n" "This mode is still experimental!\n" "Starting capital: " f"`{self._config['dry_run_wallet']}` {self._config['stake_currency']}.\n" @@ -358,7 +358,7 @@ class Telegram(RPC): output += curr_output output += "\n*Estimated Value*:\n" \ - "\t`BTC: {total: .8f}`\n" \ + "\t`{stake}: {total: .8f}`\n" \ "\t`{symbol}: {value: .2f}`\n".format(**result) self._send_msg(output) except RPCException as e: diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index b02f11394..8126ab64c 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -534,7 +534,7 @@ def test_balance_handle_empty_response_dry(default_conf, update, mocker) -> None telegram._balance(update=update, context=MagicMock()) result = msg_mock.call_args_list[0][0][0] assert msg_mock.call_count == 1 - assert "*Warning:*Simulated balances in Dry Mode." in result + assert "*Warning:* Simulated balances in Dry Mode." in result assert "Starting capital: `1000` BTC" in result From 83ed0b38c1d2fdd4305ad0c7d332ef944b24ebea Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 07:10:57 +0100 Subject: [PATCH 0051/1106] Wordwrap before keep it secret --- docs/configuration.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 43964e882..2f61343db 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -38,8 +38,8 @@ The prevelance for all Options is as follows: Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways. -| Command | Description | -|----------|-------------| +| Parameter | Description | +|------------|-------------| | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* @@ -72,9 +72,9 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `order_time_in_force` | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Dict* | `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
***Datatype:*** *String* | `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
***Datatype:*** *Boolean* -| `exchange.key` | API key to use for the exchange. Only required when you are in production mode. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* | `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#dynamic-pairlists)).
***Datatype:*** *List* | `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#dynamic-pairlists)).
***Datatype:*** *List* | `exchange.ccxt_config` | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
***Datatype:*** *Dict* @@ -84,8 +84,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `experimental.block_bad_exchanges` | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
*Defaults to `true`.*
***Datatype:*** *Boolean* | `pairlists` | Define one or more pairlists to be used. [More information below](#dynamic-pairlists).
*Defaults to `StaticPairList`.*
***Datatype:*** *List of Dicts* | `telegram.enabled` | Enable the usage of Telegram.
***Datatype:*** *Boolean* -| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* | `webhook.enabled` | Enable usage of Webhook notifications
***Datatype:*** *Boolean* | `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
***Datatype:*** *String* @@ -93,9 +93,9 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
***Datatype:*** *String* | `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Boolean* | `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *IPv4* -| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Integer between 1024 and 65535* -| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details. **Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Integer between 1024 and 65535* +| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* +| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* | `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances.
***Datatype:*** *String, SQLAlchemy connect string* | `initial_state` | Defines the initial application state. More information below.
*Defaults to `stopped`.*
***Datatype:*** *Enum, either `stopped` or `running`* | `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below.
***Datatype:*** *Boolean* From 48935d2932ca5b3317463bf78f3dda397eaf5126 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 07:25:18 +0100 Subject: [PATCH 0052/1106] Align edge documentation to configuration page --- docs/edge.md | 153 ++++++++++++++++++--------------------------------- 1 file changed, 54 insertions(+), 99 deletions(-) diff --git a/docs/edge.md b/docs/edge.md index c7b088476..769e48927 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -1,4 +1,4 @@ -# Edge positioning +# Edge positioning This page explains how to use Edge Positioning module in your bot in order to enter into a trade only if the trade has a reasonable win rate and risk reward ratio, and consequently adjust your position size and stoploss. @@ -9,6 +9,7 @@ This page explains how to use Edge Positioning module in your bot in order to en Edge does not consider anything else than buy/sell/stoploss signals. So trailing stoploss, ROI, and everything else are ignored in its calculation. ## Introduction + Trading is all about probability. No one can claim that he has a strategy working all the time. You have to assume that sometimes you lose. But it doesn't mean there is no rule, it only means rules should work "most of the time". Let's play a game: we toss a coin, heads: I give you 10$, tails: you give me 10$. Is it an interesting game? No, it's quite boring, isn't it? @@ -22,43 +23,61 @@ Let's complicate it more: you win 80% of the time but only 2$, I win 20% of the The question is: How do you calculate that? How do you know if you wanna play? The answer comes to two factors: + - Win Rate - Risk Reward Ratio ### Win Rate + Win Rate (*W*) is is the mean over some amount of trades (*N*) what is the percentage of winning trades to total number of trades (note that we don't consider how much you gained but only if you won or not). - W = (Number of winning trades) / (Total number of trades) = (Number of winning trades) / N +``` +W = (Number of winning trades) / (Total number of trades) = (Number of winning trades) / N +``` Complementary Loss Rate (*L*) is defined as - L = (Number of losing trades) / (Total number of trades) = (Number of losing trades) / N +``` +L = (Number of losing trades) / (Total number of trades) = (Number of losing trades) / N +``` or, which is the same, as - L = 1 – W +``` +L = 1 – W +``` ### Risk Reward Ratio + Risk Reward Ratio (*R*) is a formula used to measure the expected gains of a given investment against the risk of loss. It is basically what you potentially win divided by what you potentially lose: - R = Profit / Loss +``` +R = Profit / Loss +``` Over time, on many trades, you can calculate your risk reward by dividing your average profit on winning trades by your average loss on losing trades: - Average profit = (Sum of profits) / (Number of winning trades) +``` +Average profit = (Sum of profits) / (Number of winning trades) - Average loss = (Sum of losses) / (Number of losing trades) +Average loss = (Sum of losses) / (Number of losing trades) - R = (Average profit) / (Average loss) +R = (Average profit) / (Average loss) +``` ### Expectancy + At this point we can combine *W* and *R* to create an expectancy ratio. This is a simple process of multiplying the risk reward ratio by the percentage of winning trades and subtracting the percentage of losing trades, which is calculated as follows: - Expectancy Ratio = (Risk Reward Ratio X Win Rate) – Loss Rate = (R X W) – L +``` +Expectancy Ratio = (Risk Reward Ratio X Win Rate) – Loss Rate = (R X W) – L +``` So lets say your Win rate is 28% and your Risk Reward Ratio is 5: - Expectancy = (5 X 0.28) – 0.72 = 0.68 +``` +Expectancy = (5 X 0.28) – 0.72 = 0.68 +``` Superficially, this means that on average you expect this strategy’s trades to return .68 times the size of your loses. This is important for two reasons: First, it may seem obvious, but you know right away that you have a positive return. Second, you now have a number you can compare to other candidate systems to make decisions about which ones you employ. @@ -69,6 +88,7 @@ You can also use this value to evaluate the effectiveness of modifications to th **NOTICE:** It's important to keep in mind that Edge is testing your expectancy using historical data, there's no guarantee that you will have a similar edge in the future. It's still vital to do this testing in order to build confidence in your methodology, but be wary of "curve-fitting" your approach to the historical data as things are unlikely to play out the exact same way for future trades. ## How does it work? + If enabled in config, Edge will go through historical data with a range of stoplosses in order to find buy and sell/stoploss signals. It then calculates win rate and expectancy over *N* trades for each stoploss. Here is an example: | Pair | Stoploss | Win Rate | Risk Reward Ratio | Expectancy | @@ -83,6 +103,7 @@ The goal here is to find the best stoploss for the strategy in order to have the Edge module then forces stoploss value it evaluated to your strategy dynamically. ### Position size + Edge also dictates the stake amount for each trade to the bot according to the following factors: - Allowed capital at risk @@ -90,13 +111,17 @@ Edge also dictates the stake amount for each trade to the bot according to the f Allowed capital at risk is calculated as follows: - Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade) +``` +Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade) +``` Stoploss is calculated as described above against historical data. Your position size then will be: - Position size = (Allowed capital at risk) / Stoploss +``` +Position size = (Allowed capital at risk) / Stoploss +``` Example: @@ -115,100 +140,30 @@ Available capital doesn’t change before a position is sold. Let’s assume tha So the Bot receives another buy signal for trade 4 with a stoploss at 2% then your position size would be **0.055 / 0.02 = 2.75 ETH**. ## Configurations + Edge module has following configuration options: -#### enabled -If true, then Edge will run periodically. - -(defaults to false) - -#### process_throttle_secs -How often should Edge run in seconds? - -(defaults to 3600 so one hour) - -#### calculate_since_number_of_days -Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy -Note that it downloads historical data so increasing this number would lead to slowing down the bot. - -(defaults to 7) - -#### capital_available_percentage -This is the percentage of the total capital on exchange in stake currency. - -As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital. - -(defaults to 0.5) - -#### allowed_risk -Percentage of allowed risk per trade. - -(defaults to 0.01 so 1%) - -#### stoploss_range_min - -Minimum stoploss. - -(defaults to -0.01) - -#### stoploss_range_max - -Maximum stoploss. - -(defaults to -0.10) - -#### stoploss_range_step - -As an example if this is set to -0.01 then Edge will test the strategy for \[-0.01, -0,02, -0,03 ..., -0.09, -0.10\] ranges. -Note than having a smaller step means having a bigger range which could lead to slow calculation. - -If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10. - -(defaults to -0.01) - -#### minimum_winrate - -It filters out pairs which don't have at least minimum_winrate. - -This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio. - -(defaults to 0.60) - -#### minimum_expectancy - -It filters out pairs which have the expectancy lower than this number. - -Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return. - -(defaults to 0.20) - -#### min_trade_number - -When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable. - -Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something. - -(defaults to 10, it is highly recommended not to decrease this number) - -#### max_trade_duration_minute - -Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign. - -**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.). - -(defaults to 1 day, i.e. to 60 * 24 = 1440 minutes) - -#### remove_pumps - -Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off. - -(defaults to false) +| Parameter | Description | +|------------|-------------| +| `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* +| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7` (once per hour).*
***Datatype:*** *Integer* +| `capital_available_percentage` | This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5` (once per hour).*
***Datatype:*** *Float* +| `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* +| `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* +| `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* +| `stoploss_range_step` | As an example if this is set to -0.01 then Edge will test the strategy for `[-0.01, -0,02, -0,03 ..., -0.09, -0.10]` ranges.
**Note** than having a smaller step means having a bigger range which could lead to slow calculation.
If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10.
*Defaults to `-0.001`.*
***Datatype:*** *Float* +| `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate.
This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio.
*Defaults to `0.60`.*
***Datatype:*** *Float* +| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number.
Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return.
*Defaults to `0.20`.*
***Datatype:*** *Float* +| `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable.
Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something.
*Defaults to `10` (it is highly recommended not to decrease this number).*
***Datatype:*** *Integer* +| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
*Defaults to `1440` (one day).*
***Datatype:*** *Integer* +| `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.
*Defaults to `false`.*
***Datatype:*** *Boolean* ## Running Edge independently You can run Edge independently in order to see in details the result. Here is an example: -```bash +``` bash freqtrade edge ``` From a68445692bfdde1d9407a8d3bc1f82d785cd3def Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Dec 2019 16:08:33 +0100 Subject: [PATCH 0053/1106] Add first steps for list-strategies --- freqtrade/configuration/arguments.py | 19 ++++++++++++++++--- freqtrade/utils.py | 8 ++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 41c5c3957..5f7bc74f1 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -30,6 +30,8 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] +ARGS_LIST_STRATEGIES = ["strategy_path"] + ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"] @@ -62,7 +64,8 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop "print_json", "hyperopt_show_no_header"] NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs", - "hyperopt-list", "hyperopt-show", "plot-dataframe", "plot-profit"] + "list-strategies", "hyperopt-list", "hyperopt-show", "plot-dataframe", + "plot-profit"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] @@ -131,8 +134,9 @@ class Arguments: from freqtrade.utils import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, - start_new_hyperopt, start_new_strategy, - start_list_timeframes, start_test_pairlist, start_trading) + start_list_strategies, start_new_hyperopt, + start_new_strategy, start_list_timeframes, + start_test_pairlist, start_trading) from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit subparsers = self.parser.add_subparsers(dest='command', @@ -185,6 +189,15 @@ class Arguments: build_hyperopt_cmd.set_defaults(func=start_new_hyperopt) self._build_args(optionlist=ARGS_BUILD_HYPEROPT, parser=build_hyperopt_cmd) + # Add list-strategies subcommand + list_strategies_cmd = subparsers.add_parser( + 'list-strategies', + help='Print available strategies.', + parents=[_common_parser], + ) + list_strategies_cmd.set_defaults(func=start_list_strategies) + self._build_args(optionlist=ARGS_LIST_STRATEGIES, parser=list_strategies_cmd) + # Add list-exchanges subcommand list_exchanges_cmd = subparsers.add_parser( 'list-exchanges', diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 18966c574..c5fc47a74 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -224,6 +224,14 @@ def start_download_data(args: Dict[str, Any]) -> None: f"on exchange {exchange.name}.") +def start_list_strategies(args: Dict[str, Any]) -> None: + """ + Print Strategies available in a folder + """ + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + print(config) + + def start_list_timeframes(args: Dict[str, Any]) -> None: """ Print ticker intervals (timeframes) available on Exchange From eb1040ddb7445a49168792871ab417360bdfa4a1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 13:34:37 +0100 Subject: [PATCH 0054/1106] Convert resolvers to classmethods --- freqtrade/resolvers/exchange_resolver.py | 1 + freqtrade/resolvers/hyperopt_resolver.py | 23 +++++++++------- freqtrade/resolvers/iresolver.py | 34 +++++++++++++----------- freqtrade/resolvers/pairlist_resolver.py | 6 +++-- freqtrade/resolvers/strategy_resolver.py | 12 +++++---- tests/strategy/test_strategy.py | 2 -- 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index e28a5cf80..2b6a731a9 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -14,6 +14,7 @@ class ExchangeResolver(IResolver): """ This class contains all the logic to load a custom exchange class """ + object_type = Exchange @staticmethod def load_exchange(exchange_name: str, config: dict, validate: bool = True) -> Exchange: diff --git a/freqtrade/resolvers/hyperopt_resolver.py b/freqtrade/resolvers/hyperopt_resolver.py index 0726b0627..b9c750251 100644 --- a/freqtrade/resolvers/hyperopt_resolver.py +++ b/freqtrade/resolvers/hyperopt_resolver.py @@ -20,6 +20,7 @@ class HyperOptResolver(IResolver): """ This class contains all the logic to load custom hyperopt class """ + object_type = IHyperOpt @staticmethod def load_hyperopt(config: Dict) -> IHyperOpt: @@ -59,12 +60,13 @@ class HyperOptResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - abs_paths = IResolver.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, - extra_dir=extra_dir) + abs_paths = HyperOptResolver.build_search_paths(config, current_path=current_path, + user_subdir=USERPATH_HYPEROPTS, + extra_dir=extra_dir) - hyperopt = IResolver._load_object(paths=abs_paths, object_type=IHyperOpt, - object_name=hyperopt_name, kwargs={'config': config}) + hyperopt = HyperOptResolver._load_object(paths=abs_paths, + object_name=hyperopt_name, + kwargs={'config': config}) if hyperopt: return hyperopt raise OperationalException( @@ -77,6 +79,7 @@ class HyperOptLossResolver(IResolver): """ This class contains all the logic to load custom hyperopt loss class """ + object_type = IHyperOptLoss @staticmethod def load_hyperoptloss(config: Dict) -> IHyperOptLoss: @@ -113,12 +116,12 @@ class HyperOptLossResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - abs_paths = IResolver.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, - extra_dir=extra_dir) + abs_paths = HyperOptLossResolver.build_search_paths(config, current_path=current_path, + user_subdir=USERPATH_HYPEROPTS, + extra_dir=extra_dir) - hyperoptloss = IResolver._load_object(paths=abs_paths, object_type=IHyperOptLoss, - object_name=hyper_loss_name) + hyperoptloss = HyperOptLossResolver._load_object(paths=abs_paths, + object_name=hyper_loss_name) if hyperoptloss: return hyperoptloss diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 0b986debb..11937c1da 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -7,7 +7,7 @@ import importlib.util import inspect import logging from pathlib import Path -from typing import Any, List, Optional, Tuple, Union, Generator +from typing import Any, Generator, List, Optional, Tuple, Type, Union logger = logging.getLogger(__name__) @@ -16,6 +16,8 @@ class IResolver: """ This class contains all the logic to load custom classes """ + # Childclasses need to override this + object_type: Type[Any] @staticmethod def build_search_paths(config, current_path: Path, user_subdir: Optional[str] = None, @@ -32,12 +34,11 @@ class IResolver: return abs_paths - @staticmethod - def _get_valid_object(object_type, module_path: Path, + @classmethod + def _get_valid_object(cls, module_path: Path, object_name: str) -> Generator[Any, None, None]: """ Generator returning objects with matching object_type and object_name in the path given. - :param object_type: object_type (class) :param module_path: absolute path to the module :param object_name: Class name of the object :return: generator containing matching objects @@ -55,19 +56,21 @@ class IResolver: valid_objects_gen = ( obj for name, obj in inspect.getmembers(module, inspect.isclass) - if object_name == name and object_type in obj.__bases__ + if object_name == name and cls.object_type in obj.__bases__ ) return valid_objects_gen - @staticmethod - def _search_object(directory: Path, object_type, object_name: str, + @classmethod + def _search_object(cls, directory: Path, object_name: str, kwargs: dict = {}) -> Union[Tuple[Any, Path], Tuple[None, None]]: """ Search for the objectname in the given directory :param directory: relative or absolute directory path + :param object_name: ClassName of the object to load :return: object instance """ - logger.debug("Searching for %s %s in '%s'", object_type.__name__, object_name, directory) + logger.debug("Searching for %s %s in '%s'", + cls.object_type.__name__, object_name, directory) for entry in directory.iterdir(): # Only consider python files if not str(entry).endswith('.py'): @@ -75,14 +78,14 @@ class IResolver: continue module_path = entry.resolve() - obj = next(IResolver._get_valid_object(object_type, module_path, object_name), None) + obj = next(cls._get_valid_object(module_path, object_name), None) if obj: return (obj(**kwargs), module_path) return (None, None) - @staticmethod - def _load_object(paths: List[Path], object_type, object_name: str, + @classmethod + def _load_object(cls, paths: List[Path], object_name: str, kwargs: dict = {}) -> Optional[Any]: """ Try to load object from path list. @@ -90,13 +93,12 @@ class IResolver: for _path in paths: try: - (module, module_path) = IResolver._search_object(directory=_path, - object_type=object_type, - object_name=object_name, - kwargs=kwargs) + (module, module_path) = cls._search_object(directory=_path, + object_name=object_name, + kwargs=kwargs) if module: logger.info( - f"Using resolved {object_type.__name__.lower()[1:]} {object_name} " + f"Using resolved {cls.object_type.__name__.lower()[1:]} {object_name} " f"from '{module_path}'...") return module except FileNotFoundError: diff --git a/freqtrade/resolvers/pairlist_resolver.py b/freqtrade/resolvers/pairlist_resolver.py index 611660ff4..00ebc03aa 100644 --- a/freqtrade/resolvers/pairlist_resolver.py +++ b/freqtrade/resolvers/pairlist_resolver.py @@ -17,6 +17,7 @@ class PairListResolver(IResolver): """ This class contains all the logic to load custom PairList class """ + object_type = IPairList @staticmethod def load_pairlist(pairlist_name: str, exchange, pairlistmanager, @@ -53,8 +54,9 @@ class PairListResolver(IResolver): abs_paths = IResolver.build_search_paths(config, current_path=current_path, user_subdir=None, extra_dir=None) - pairlist = IResolver._load_object(paths=abs_paths, object_type=IPairList, - object_name=pairlist_name, kwargs=kwargs) + pairlist = PairListResolver._load_object(paths=abs_paths, + object_name=pairlist_name, + kwargs=kwargs) if pairlist: return pairlist raise OperationalException( diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 6d3fe5ff9..654103377 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -22,6 +22,7 @@ class StrategyResolver(IResolver): """ This class contains the logic to load custom strategy class """ + object_type = IStrategy @staticmethod def load_strategy(config: Optional[Dict] = None) -> IStrategy: @@ -134,9 +135,9 @@ class StrategyResolver(IResolver): """ current_path = Path(__file__).parent.parent.joinpath('strategy').resolve() - abs_paths = IResolver.build_search_paths(config, current_path=current_path, - user_subdir=constants.USERPATH_STRATEGY, - extra_dir=extra_dir) + abs_paths = StrategyResolver.build_search_paths(config, current_path=current_path, + user_subdir=constants.USERPATH_STRATEGY, + extra_dir=extra_dir) if ":" in strategy_name: logger.info("loading base64 encoded strategy") @@ -154,8 +155,9 @@ class StrategyResolver(IResolver): # register temp path with the bot abs_paths.insert(0, temp.resolve()) - strategy = IResolver._load_object(paths=abs_paths, object_type=IStrategy, - object_name=strategy_name, kwargs={'config': config}) + strategy = StrategyResolver._load_object(paths=abs_paths, + object_name=strategy_name, + kwargs={'config': config}) if strategy: strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args) strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index ce7ac1741..dba816621 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -20,7 +20,6 @@ def test_search_strategy(): s, _ = StrategyResolver._search_object( directory=default_location, - object_type=IStrategy, kwargs={'config': default_config}, object_name='DefaultStrategy' ) @@ -28,7 +27,6 @@ def test_search_strategy(): s, _ = StrategyResolver._search_object( directory=default_location, - object_type=IStrategy, kwargs={'config': default_config}, object_name='NotFoundStrategy' ) From 25e6d6a7bfdea9bd74b6f06375c4e11df2f903b1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 13:54:46 +0100 Subject: [PATCH 0055/1106] Combine load_object methods into one --- freqtrade/resolvers/hyperopt_resolver.py | 70 +++++------------------- freqtrade/resolvers/iresolver.py | 36 +++++++++++- freqtrade/resolvers/pairlist_resolver.py | 42 ++++---------- freqtrade/resolvers/strategy_resolver.py | 16 ++++-- tests/optimize/test_hyperopt.py | 4 +- 5 files changed, 68 insertions(+), 100 deletions(-) diff --git a/freqtrade/resolvers/hyperopt_resolver.py b/freqtrade/resolvers/hyperopt_resolver.py index b9c750251..c26fd09f2 100644 --- a/freqtrade/resolvers/hyperopt_resolver.py +++ b/freqtrade/resolvers/hyperopt_resolver.py @@ -5,7 +5,7 @@ This module load custom hyperopt """ import logging from pathlib import Path -from typing import Optional, Dict +from typing import Dict from freqtrade import OperationalException from freqtrade.constants import DEFAULT_HYPEROPT_LOSS, USERPATH_HYPEROPTS @@ -21,6 +21,9 @@ class HyperOptResolver(IResolver): This class contains all the logic to load custom hyperopt class """ object_type = IHyperOpt + object_type_str = "Hyperopt" + user_subdir = USERPATH_HYPEROPTS + initial_search_path = Path(__file__).parent.parent.joinpath('optimize').resolve() @staticmethod def load_hyperopt(config: Dict) -> IHyperOpt: @@ -34,8 +37,9 @@ class HyperOptResolver(IResolver): hyperopt_name = config['hyperopt'] - hyperopt = HyperOptResolver._load_hyperopt(hyperopt_name, config, - extra_dir=config.get('hyperopt_path')) + hyperopt = HyperOptResolver.load_object(hyperopt_name, config, + kwargs={'config': config}, + extra_dir=config.get('hyperopt_path')) if not hasattr(hyperopt, 'populate_indicators'): logger.warning("Hyperopt class does not provide populate_indicators() method. " @@ -48,38 +52,15 @@ class HyperOptResolver(IResolver): "Using populate_sell_trend from the strategy.") return hyperopt - @staticmethod - def _load_hyperopt( - hyperopt_name: str, config: Dict, extra_dir: Optional[str] = None) -> IHyperOpt: - """ - Search and loads the specified hyperopt. - :param hyperopt_name: name of the module to import - :param config: configuration dictionary - :param extra_dir: additional directory to search for the given hyperopt - :return: HyperOpt instance or None - """ - current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - - abs_paths = HyperOptResolver.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, - extra_dir=extra_dir) - - hyperopt = HyperOptResolver._load_object(paths=abs_paths, - object_name=hyperopt_name, - kwargs={'config': config}) - if hyperopt: - return hyperopt - raise OperationalException( - f"Impossible to load Hyperopt '{hyperopt_name}'. This class does not exist " - "or contains Python code errors." - ) - class HyperOptLossResolver(IResolver): """ This class contains all the logic to load custom hyperopt loss class """ object_type = IHyperOptLoss + object_type_str = "HyperoptLoss" + user_subdir = USERPATH_HYPEROPTS + initial_search_path = Path(__file__).parent.parent.joinpath('optimize').resolve() @staticmethod def load_hyperoptloss(config: Dict) -> IHyperOptLoss: @@ -92,8 +73,9 @@ class HyperOptLossResolver(IResolver): # default hyperopt loss hyperoptloss_name = config.get('hyperopt_loss') or DEFAULT_HYPEROPT_LOSS - hyperoptloss = HyperOptLossResolver._load_hyperoptloss( - hyperoptloss_name, config, extra_dir=config.get('hyperopt_path')) + hyperoptloss = HyperOptLossResolver.load_object(hyperoptloss_name, + config, kwargs={}, + extra_dir=config.get('hyperopt_path')) # Assign ticker_interval to be used in hyperopt hyperoptloss.__class__.ticker_interval = str(config['ticker_interval']) @@ -103,29 +85,3 @@ class HyperOptLossResolver(IResolver): f"Found HyperoptLoss class {hyperoptloss_name} does not " "implement `hyperopt_loss_function`.") return hyperoptloss - - @staticmethod - def _load_hyperoptloss(hyper_loss_name: str, config: Dict, - extra_dir: Optional[str] = None) -> IHyperOptLoss: - """ - Search and loads the specified hyperopt loss class. - :param hyper_loss_name: name of the module to import - :param config: configuration dictionary - :param extra_dir: additional directory to search for the given hyperopt - :return: HyperOptLoss instance or None - """ - current_path = Path(__file__).parent.parent.joinpath('optimize').resolve() - - abs_paths = HyperOptLossResolver.build_search_paths(config, current_path=current_path, - user_subdir=USERPATH_HYPEROPTS, - extra_dir=extra_dir) - - hyperoptloss = HyperOptLossResolver._load_object(paths=abs_paths, - object_name=hyper_loss_name) - if hyperoptloss: - return hyperoptloss - - raise OperationalException( - f"Impossible to load HyperoptLoss '{hyper_loss_name}'. This class does not exist " - "or contains Python code errors." - ) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 11937c1da..0101e37a3 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -9,6 +9,8 @@ import logging from pathlib import Path from typing import Any, Generator, List, Optional, Tuple, Type, Union +from freqtrade import OperationalException + logger = logging.getLogger(__name__) @@ -18,12 +20,15 @@ class IResolver: """ # Childclasses need to override this object_type: Type[Any] + object_type_str: str + user_subdir: Optional[str] = None + initial_search_path: Path - @staticmethod - def build_search_paths(config, current_path: Path, user_subdir: Optional[str] = None, + @classmethod + def build_search_paths(cls, config, user_subdir: Optional[str] = None, extra_dir: Optional[str] = None) -> List[Path]: - abs_paths: List[Path] = [current_path] + abs_paths: List[Path] = [cls.initial_search_path] if user_subdir: abs_paths.insert(0, config['user_data_dir'].joinpath(user_subdir)) @@ -105,3 +110,28 @@ class IResolver: logger.warning('Path "%s" does not exist.', _path.resolve()) return None + + @classmethod + def load_object(cls, object_name: str, config: dict, kwargs: dict, + extra_dir: Optional[str] = None) -> Any: + """ + Search and loads the specified object as configured in hte child class. + :param objectname: name of the module to import + :param config: configuration dictionary + :param extra_dir: additional directory to search for the given pairlist + :raises: OperationalException if the class is invalid or does not exist. + :return: Object instance or None + """ + + abs_paths = cls.build_search_paths(config, + user_subdir=cls.user_subdir, + extra_dir=extra_dir) + + pairlist = cls._load_object(paths=abs_paths, object_name=object_name, + kwargs=kwargs) + if pairlist: + return pairlist + raise OperationalException( + f"Impossible to load {cls.object_type_str} '{object_name}'. This class does not exist " + "or contains Python code errors." + ) diff --git a/freqtrade/resolvers/pairlist_resolver.py b/freqtrade/resolvers/pairlist_resolver.py index 00ebc03aa..77db74084 100644 --- a/freqtrade/resolvers/pairlist_resolver.py +++ b/freqtrade/resolvers/pairlist_resolver.py @@ -6,7 +6,6 @@ This module load custom pairlists import logging from pathlib import Path -from freqtrade import OperationalException from freqtrade.pairlist.IPairList import IPairList from freqtrade.resolvers import IResolver @@ -18,6 +17,9 @@ class PairListResolver(IResolver): This class contains all the logic to load custom PairList class """ object_type = IPairList + object_type_str = "Pairlist" + user_subdir = None + initial_search_path = Path(__file__).parent.parent.joinpath('pairlist').resolve() @staticmethod def load_pairlist(pairlist_name: str, exchange, pairlistmanager, @@ -32,34 +34,10 @@ class PairListResolver(IResolver): :param pairlist_pos: Position of the pairlist in the list of pairlists :return: initialized Pairlist class """ - - return PairListResolver._load_pairlist(pairlist_name, config, - kwargs={'exchange': exchange, - 'pairlistmanager': pairlistmanager, - 'config': config, - 'pairlistconfig': pairlistconfig, - 'pairlist_pos': pairlist_pos}) - - @staticmethod - def _load_pairlist(pairlist_name: str, config: dict, kwargs: dict) -> IPairList: - """ - Search and loads the specified pairlist. - :param pairlist_name: name of the module to import - :param config: configuration dictionary - :param extra_dir: additional directory to search for the given pairlist - :return: PairList instance or None - """ - current_path = Path(__file__).parent.parent.joinpath('pairlist').resolve() - - abs_paths = IResolver.build_search_paths(config, current_path=current_path, - user_subdir=None, extra_dir=None) - - pairlist = PairListResolver._load_object(paths=abs_paths, - object_name=pairlist_name, - kwargs=kwargs) - if pairlist: - return pairlist - raise OperationalException( - f"Impossible to load Pairlist '{pairlist_name}'. This class does not exist " - "or contains Python code errors." - ) + return PairListResolver.load_object(pairlist_name, config, + kwargs={'exchange': exchange, + 'pairlistmanager': pairlistmanager, + 'config': config, + 'pairlistconfig': pairlistconfig, + 'pairlist_pos': pairlist_pos}, + ) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 654103377..4fd5c586a 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -11,7 +11,9 @@ from inspect import getfullargspec from pathlib import Path from typing import Dict, Optional -from freqtrade import constants, OperationalException +from freqtrade import OperationalException +from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, + USERPATH_STRATEGY) from freqtrade.resolvers import IResolver from freqtrade.strategy.interface import IStrategy @@ -23,6 +25,9 @@ class StrategyResolver(IResolver): This class contains the logic to load custom strategy class """ object_type = IStrategy + object_type_str = "Strategy" + user_subdir = USERPATH_STRATEGY + initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve() @staticmethod def load_strategy(config: Optional[Dict] = None) -> IStrategy: @@ -115,11 +120,11 @@ class StrategyResolver(IResolver): @staticmethod def _strategy_sanity_validations(strategy): - if not all(k in strategy.order_types for k in constants.REQUIRED_ORDERTYPES): + if not all(k in strategy.order_types for k in REQUIRED_ORDERTYPES): raise ImportError(f"Impossible to load Strategy '{strategy.__class__.__name__}'. " f"Order-types mapping is incomplete.") - if not all(k in strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF): + if not all(k in strategy.order_time_in_force for k in REQUIRED_ORDERTIF): raise ImportError(f"Impossible to load Strategy '{strategy.__class__.__name__}'. " f"Order-time-in-force mapping is incomplete.") @@ -133,10 +138,9 @@ class StrategyResolver(IResolver): :param extra_dir: additional directory to search for the given strategy :return: Strategy instance or None """ - current_path = Path(__file__).parent.parent.joinpath('strategy').resolve() - abs_paths = StrategyResolver.build_search_paths(config, current_path=current_path, - user_subdir=constants.USERPATH_STRATEGY, + abs_paths = StrategyResolver.build_search_paths(config, + user_subdir=USERPATH_STRATEGY, extra_dir=extra_dir) if ":" in strategy_name: diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 9c6e73c53..fb492be35 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -159,7 +159,7 @@ def test_hyperoptresolver(mocker, default_conf, caplog) -> None: delattr(hyperopt, 'populate_buy_trend') delattr(hyperopt, 'populate_sell_trend') mocker.patch( - 'freqtrade.resolvers.hyperopt_resolver.HyperOptResolver._load_hyperopt', + 'freqtrade.resolvers.hyperopt_resolver.HyperOptResolver.load_object', MagicMock(return_value=hyperopt(default_conf)) ) default_conf.update({'hyperopt': 'DefaultHyperOpt'}) @@ -195,7 +195,7 @@ def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None: hl = DefaultHyperOptLoss mocker.patch( - 'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver._load_hyperoptloss', + 'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver.load_object', MagicMock(return_value=hl) ) x = HyperOptLossResolver.load_hyperoptloss(default_conf) From 5a11ca86bb69b1619cbba78cce05a205f669a67d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 14:01:28 +0100 Subject: [PATCH 0056/1106] Move instanciation out of search_object --- freqtrade/resolvers/iresolver.py | 13 ++++++------- tests/strategy/test_strategy.py | 5 +---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 0101e37a3..bbdc8ca91 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -66,13 +66,13 @@ class IResolver: return valid_objects_gen @classmethod - def _search_object(cls, directory: Path, object_name: str, - kwargs: dict = {}) -> Union[Tuple[Any, Path], Tuple[None, None]]: + def _search_object(cls, directory: Path, object_name: str + ) -> Union[Tuple[Any, Path], Tuple[None, None]]: """ Search for the objectname in the given directory :param directory: relative or absolute directory path :param object_name: ClassName of the object to load - :return: object instance + :return: object class """ logger.debug("Searching for %s %s in '%s'", cls.object_type.__name__, object_name, directory) @@ -86,7 +86,7 @@ class IResolver: obj = next(cls._get_valid_object(module_path, object_name), None) if obj: - return (obj(**kwargs), module_path) + return (obj, module_path) return (None, None) @classmethod @@ -99,13 +99,12 @@ class IResolver: for _path in paths: try: (module, module_path) = cls._search_object(directory=_path, - object_name=object_name, - kwargs=kwargs) + object_name=object_name) if module: logger.info( f"Using resolved {cls.object_type.__name__.lower()[1:]} {object_name} " f"from '{module_path}'...") - return module + return module(**kwargs) except FileNotFoundError: logger.warning('Path "%s" does not exist.', _path.resolve()) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index dba816621..7085223c5 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -15,19 +15,16 @@ from tests.conftest import log_has, log_has_re def test_search_strategy(): - default_config = {} default_location = Path(__file__).parent.parent.joinpath('strategy').resolve() s, _ = StrategyResolver._search_object( directory=default_location, - kwargs={'config': default_config}, object_name='DefaultStrategy' ) - assert isinstance(s, IStrategy) + assert issubclass(s, IStrategy) s, _ = StrategyResolver._search_object( directory=default_location, - kwargs={'config': default_config}, object_name='NotFoundStrategy' ) assert s is None From 2ab989e274c5bfb278e8b6397380b1714d806a80 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 15:28:35 +0100 Subject: [PATCH 0057/1106] Cleanup some code and add option --- freqtrade/configuration/arguments.py | 2 +- freqtrade/resolvers/iresolver.py | 35 +++++++++++++++++++++++----- freqtrade/utils.py | 14 +++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 5f7bc74f1..b2197619d 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -30,7 +30,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] -ARGS_LIST_STRATEGIES = ["strategy_path"] +ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column"] ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index bbdc8ca91..01ecbcb84 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -7,7 +7,7 @@ import importlib.util import inspect import logging from pathlib import Path -from typing import Any, Generator, List, Optional, Tuple, Type, Union +from typing import Any, Dict, Generator, List, Optional, Tuple, Type, Union from freqtrade import OperationalException @@ -41,7 +41,7 @@ class IResolver: @classmethod def _get_valid_object(cls, module_path: Path, - object_name: str) -> Generator[Any, None, None]: + object_name: Optional[str]) -> Generator[Any, None, None]: """ Generator returning objects with matching object_type and object_name in the path given. :param module_path: absolute path to the module @@ -51,7 +51,7 @@ 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, str(module_path)) + spec = importlib.util.spec_from_file_location(object_name or "", str(module_path)) module = importlib.util.module_from_spec(spec) try: spec.loader.exec_module(module) # type: ignore # importlib does not use typehints @@ -61,7 +61,7 @@ class IResolver: valid_objects_gen = ( obj for name, obj in inspect.getmembers(module, inspect.isclass) - if object_name == name and cls.object_type in obj.__bases__ + if (object_name is None or object_name == name) and cls.object_type in obj.__bases__ ) return valid_objects_gen @@ -74,8 +74,7 @@ class IResolver: :param object_name: ClassName of the object to load :return: object class """ - logger.debug("Searching for %s %s in '%s'", - cls.object_type.__name__, object_name, directory) + logger.debug(f"Searching for {cls.object_type.__name__} {object_name} in '{directory}'") for entry in directory.iterdir(): # Only consider python files if not str(entry).endswith('.py'): @@ -134,3 +133,27 @@ class IResolver: f"Impossible to load {cls.object_type_str} '{object_name}'. This class does not exist " "or contains Python code errors." ) + + @classmethod + def search_all_objects(cls, directory: Path) -> List[Dict[str, Any]]: + """ + Searches a directory for valid objects + :param directory: Path to search + :return: List of dicts containing 'name', 'class' and 'location' entires + """ + logger.debug(f"Searching for {cls.object_type.__name__} '{directory}'") + objects = [] + for entry in directory.iterdir(): + # Only consider python files + if not str(entry).endswith('.py'): + logger.debug('Ignoring %s', entry) + continue + module_path = entry.resolve() + logger.info(f"Path {module_path}") + for obj in cls._get_valid_object(module_path, object_name=None): + objects.append( + {'name': obj.__name__, + 'class': obj, + 'location': entry, + }) + return objects diff --git a/freqtrade/utils.py b/freqtrade/utils.py index c5fc47a74..06a62172a 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -23,7 +23,7 @@ from freqtrade.data.history import (convert_trades_to_ohlcv, from freqtrade.exchange import (available_exchanges, ccxt_exchanges, market_is_active, symbol_is_pair) from freqtrade.misc import plural, render_template -from freqtrade.resolvers import ExchangeResolver +from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -229,7 +229,17 @@ def start_list_strategies(args: Dict[str, Any]) -> None: Print Strategies available in a folder """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - print(config) + + directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGY)) + strategies = StrategyResolver.search_all_objects(directory) + # Sort alphabetically + strategies = sorted(strategies, key=lambda x: x['name']) + strats_to_print = [{'name': s['name'], 'location': s['location']} for s in strategies] + + if args['print_one_column']: + print('\n'.join([s['name'] for s in strategies])) + else: + print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) def start_list_timeframes(args: Dict[str, Any]) -> None: From 27b86170778c70dd4a83d2c02d06a12452fb1783 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 15:35:38 +0100 Subject: [PATCH 0058/1106] Add tests --- tests/strategy/test_strategy.py | 8 +++++++ tests/test_utils.py | 42 +++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 7085223c5..10b9f3466 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -30,6 +30,14 @@ def test_search_strategy(): assert s is None +def test_search_all_strategies(): + directory = Path(__file__).parent + strategies = StrategyResolver.search_all_objects(directory) + assert isinstance(strategies, list) + assert len(strategies) == 3 + assert isinstance(strategies[0], dict) + + def test_load_strategy(default_conf, result): default_conf.update({'strategy': 'SampleStrategy', 'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates') diff --git a/tests/test_utils.py b/tests/test_utils.py index 40ca9ac02..b8be1ae61 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,11 +7,12 @@ import pytest from freqtrade import OperationalException from freqtrade.state import RunMode from freqtrade.utils import (setup_utils_configuration, start_create_userdir, - start_download_data, start_list_exchanges, - start_list_markets, start_list_timeframes, - start_new_hyperopt, start_new_strategy, - start_test_pairlist, start_trading, - start_hyperopt_list, start_hyperopt_show) + start_download_data, start_hyperopt_list, + start_hyperopt_show, start_list_exchanges, + start_list_markets, start_list_strategies, + start_list_timeframes, start_new_hyperopt, + start_new_strategy, start_test_pairlist, + start_trading) from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) @@ -630,6 +631,37 @@ def test_download_data_trades(mocker, caplog): assert convert_mock.call_count == 1 +def test_start_list_strategies(mocker, caplog, capsys): + + args = [ + "list-strategies", + "--strategy-path", + str(Path(__file__).parent / "strategy"), + "-1" + ] + pargs = get_args(args) + # pargs['config'] = None + start_list_strategies(pargs) + captured = capsys.readouterr() + assert "TestStrategyLegacy" in captured.out + assert "strategy/legacy_strategy.py" not in captured.out + assert "DefaultStrategy" in captured.out + + # Test regular output + args = [ + "list-strategies", + "--strategy-path", + str(Path(__file__).parent / "strategy"), + ] + pargs = get_args(args) + # pargs['config'] = None + start_list_strategies(pargs) + captured = capsys.readouterr() + assert "TestStrategyLegacy" in captured.out + assert "strategy/legacy_strategy.py" in captured.out + assert "DefaultStrategy" in captured.out + + def test_start_test_pairlist(mocker, caplog, markets, tickers, default_conf, capsys): mocker.patch.multiple('freqtrade.exchange.Exchange', markets=PropertyMock(return_value=markets), From 66f9ece0619554f072fbc20c251b35dd6bbc6f33 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 15:35:53 +0100 Subject: [PATCH 0059/1106] Add documentation for strategy-list --- docs/utils.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/utils.md b/docs/utils.md index a9fbfc7d5..6eb37a386 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -108,6 +108,44 @@ With custom user directory freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt ``` +## List Strategies + +Use the `list-strategies` subcommand to see all strategies in one particular folder. + +``` +freqtrade list-strategies --help +usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--strategy-path PATH] [-1] + +optional arguments: + -h, --help show this help message and exit + --strategy-path PATH Specify additional strategy lookup path. + -1, --one-column Print output in one column. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. + +``` +Example: search default strategy folder within userdir + +``` bash +freqtrade list-strategies --user-data ~/.freqtrade/ +``` + +Example: search dedicated strategy path + +``` bash +freqtrade list-strategies --strategy-path ~/.freqtrade/strategies/ +``` + ## List Exchanges Use the `list-exchanges` subcommand to see the exchanges available for the bot. From 402c761a231edffe017ba93fdf821637e5ddab40 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 15:40:49 +0100 Subject: [PATCH 0060/1106] Change loglevel of Path output to debug --- docs/utils.md | 5 ++++- freqtrade/resolvers/iresolver.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 6eb37a386..f7501ae9d 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -132,8 +132,11 @@ Common arguments: Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH Path to userdata directory. - ``` + +!!! Warning + Using this command will try to load all python files from a folder. This can be a security risk if untrusted files reside in this folder, since all module-level code is executed. + Example: search default strategy folder within userdir ``` bash diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 01ecbcb84..e3c0d1ad0 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -149,7 +149,7 @@ class IResolver: logger.debug('Ignoring %s', entry) continue module_path = entry.resolve() - logger.info(f"Path {module_path}") + logger.debug(f"Path {module_path}") for obj in cls._get_valid_object(module_path, object_name=None): objects.append( {'name': obj.__name__, From ad75048678796a23e4dcf4a82464628a2860d6b4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Dec 2019 15:53:40 +0100 Subject: [PATCH 0061/1106] Fix testing with path in windows --- tests/test_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index b8be1ae61..185425efc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -644,7 +644,7 @@ def test_start_list_strategies(mocker, caplog, capsys): start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacy" in captured.out - assert "strategy/legacy_strategy.py" not in captured.out + assert str(Path("strategy/legacy_strategy.py")) not in captured.out assert "DefaultStrategy" in captured.out # Test regular output @@ -658,7 +658,7 @@ def test_start_list_strategies(mocker, caplog, capsys): start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacy" in captured.out - assert "strategy/legacy_strategy.py" in captured.out + assert str(Path("strategy/legacy_strategy.py")) in captured.out assert "DefaultStrategy" in captured.out From e5aed098b568900f34e7f3cbe85b8b8d21d76254 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 09:39:29 +0100 Subject: [PATCH 0062/1106] Enhance backtest results with sell reason profit / loss table --- freqtrade/optimize/backtesting.py | 6 ++++-- tests/optimize/test_backtesting.py | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ffa112bd5..21fb24b17 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -183,9 +183,11 @@ class Backtesting: Generate small table outlining Backtest results """ tabular_data = [] - headers = ['Sell Reason', 'Count'] + headers = ['Sell Reason', 'Count', 'Profit', 'Loss'] for reason, count in results['sell_reason'].value_counts().iteritems(): - tabular_data.append([reason.value, count]) + profit = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] >= 0)]) + loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)]) + tabular_data.append([reason.value, count, profit, loss]) return tabulate(tabular_data, headers=headers, tablefmt="pipe") def _generate_text_table_strategy(self, all_results: dict) -> str: diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 0ea35e41f..8a27c591f 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -394,8 +394,8 @@ def test_generate_text_table_sell_reason(default_conf, mocker): results = pd.DataFrame( { 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], - 'profit_percent': [0.1, 0.2, 0.3], - 'profit_abs': [0.2, 0.4, 0.5], + 'profit_percent': [0.1, 0.2, -0.3], + 'profit_abs': [0.2, 0.4, -0.5], 'trade_duration': [10, 30, 10], 'profit': [2, 0, 0], 'loss': [0, 0, 1], @@ -404,10 +404,10 @@ def test_generate_text_table_sell_reason(default_conf, mocker): ) result_str = ( - '| Sell Reason | Count |\n' - '|:--------------|--------:|\n' - '| roi | 2 |\n' - '| stop_loss | 1 |' + '| Sell Reason | Count | Profit | Loss |\n' + '|:--------------|--------:|---------:|-------:|\n' + '| roi | 2 | 2 | 0 |\n' + '| stop_loss | 1 | 0 | 1 |' ) assert backtesting._generate_text_table_sell_reason( data={'ETH/BTC': {}}, results=results) == result_str From 63f41cf1c692d69da8899fec520916d6e59699b1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 09:39:44 +0100 Subject: [PATCH 0063/1106] Update documentation with new result --- docs/backtesting.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 017289905..ac7c8e11a 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -137,12 +137,12 @@ A backtesting result will look like that: | ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 | 15 | | TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 | ========================================================= SELL REASON STATS ========================================================= -| Sell Reason | Count | -|:-------------------|--------:| -| trailing_stop_loss | 205 | -| stop_loss | 166 | -| sell_signal | 56 | -| force_sell | 2 | +| Sell Reason | Count | Profit | Loss | +|:-------------------|--------:|---------:|-------:| +| trailing_stop_loss | 205 | 150 | 55 | +| stop_loss | 166 | 0 | 166 | +| sell_signal | 56 | 36 | 20 | +| force_sell | 2 | 0 | 2 | ====================================================== LEFT OPEN TRADES REPORT ====================================================== | pair | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss | |:---------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:| @@ -154,6 +154,7 @@ A backtesting result will look like that: The 1st table contains all trades the bot made, including "left open trades". The 2nd table contains a recap of sell reasons. +This table can tell you which area needs some additional work (i.e. all `sell_signal` trades are losses, so we should disable the sell-signal or work on improving that). The 3rd table contains all trades the bot had to `forcesell` at the end of the backtest period to present a full picture. This is necessary to simulate realistic behaviour, since the backtest period has to end at some point, while realistically, you could leave the bot running forever. From 98647b490c6aa311e1b1735ebb5e1cab96020ef1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 19:27:08 +0100 Subject: [PATCH 0064/1106] Remove wrong "once per hour" listings --- docs/edge.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/edge.md b/docs/edge.md index 769e48927..e7909594e 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -147,8 +147,8 @@ Edge module has following configuration options: |------------|-------------| | `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* | `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* -| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7` (once per hour).*
***Datatype:*** *Integer* -| `capital_available_percentage` | This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5` (once per hour).*
***Datatype:*** *Float* +| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* +| `capital_available_percentage` | This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* | `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* | `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* | `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* From cadde3ab6d32a207e805f7043598e2c8e0eef3fb Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 16:15:44 +0100 Subject: [PATCH 0065/1106] Check if markets.info is a dict before using it --- freqtrade/exchange/exchange.py | 10 +++++++++- tests/exchange/test_exchange.py | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 384ec1fb7..01e84c06e 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -278,7 +278,15 @@ class Exchange: raise OperationalException( f'Pair {pair} is not available on {self.name}. ' f'Please remove {pair} from your whitelist.') - elif self.markets[pair].get('info', {}).get('IsRestricted', False): + + # From ccxt Documentation: + # markets.info: An associative array of non-common market properties, + # including fees, rates, limits and other general market information. + # The internal info array is different for each particular market, + # its contents depend on the exchange. + # It can also be a string or similar ... so we need to verify that first. + elif (isinstance(self.markets[pair].get('info', None), dict) + and self.markets[pair].get('info', {}).get('IsRestricted', False)): # Warn users about restricted pairs in whitelist. # We cannot determine reliably if Users are affected. logger.warning(f"Pair {pair} is restricted for some users on this exchange." diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8f335c16b..4190869ad 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -364,7 +364,8 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog): api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ 'ETH/BTC': {}, 'LTC/BTC': {}, 'NEO/BTC': {}, - 'XRP/BTC': {'info': {'IsRestricted': True}} + 'XRP/BTC': {'info': {'IsRestricted': True}}, + 'NEO/BTC': {'info': 'TestString'}, # info can also be a string ... }) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) From e51ac2c97356b5d5d11ed55426a83967ca674ca5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 16:22:41 +0100 Subject: [PATCH 0066/1106] Remove unavailable pair ... --- 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 4190869ad..2f95e4e01 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -363,7 +363,7 @@ def test_validate_pairs_exception(default_conf, mocker, caplog): def test_validate_pairs_restricted(default_conf, mocker, caplog): api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ - 'ETH/BTC': {}, 'LTC/BTC': {}, 'NEO/BTC': {}, + 'ETH/BTC': {}, 'LTC/BTC': {}, 'XRP/BTC': {'info': {'IsRestricted': True}}, 'NEO/BTC': {'info': 'TestString'}, # info can also be a string ... }) From 039dfc302ca2c8497aea27282f3ab20f5a0c4343 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 01:34:31 +0300 Subject: [PATCH 0067/1106] No need to convert pair name --- freqtrade/freqtradebot.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e21d89cd3..a9ce14bef 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -351,7 +351,6 @@ class FreqtradeBot: :param pair: pair for which we want to create a LIMIT_BUY :return: None """ - pair_s = pair.replace('_', '/') stake_currency = self.config['stake_currency'] fiat_currency = self.config.get('fiat_display_currency', None) time_in_force = self.strategy.order_time_in_force['buy'] @@ -362,10 +361,10 @@ class FreqtradeBot: # Calculate amount buy_limit_requested = self.get_target_bid(pair) - min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit_requested) + min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested) if min_stake_amount is not None and min_stake_amount > stake_amount: logger.warning( - f"Can't open a new trade for {pair_s}: stake amount " + f"Can't open a new trade for {pair}: stake amount " f"is too small ({stake_amount} < {min_stake_amount})" ) return False @@ -388,7 +387,7 @@ class FreqtradeBot: if float(order['filled']) == 0: logger.warning('Buy %s order with time in force %s for %s is %s by %s.' ' zero amount is fulfilled.', - order_tif, order_type, pair_s, order_status, self.exchange.name) + order_tif, order_type, pair, order_status, self.exchange.name) return False else: # the order is partially fulfilled @@ -396,7 +395,7 @@ class FreqtradeBot: # if the order is fulfilled fully or partially logger.warning('Buy %s order with time in force %s for %s is %s by %s.' ' %s amount fulfilled out of %s (%s remaining which is canceled).', - order_tif, order_type, pair_s, order_status, self.exchange.name, + order_tif, order_type, pair, order_status, self.exchange.name, order['filled'], order['amount'], order['remaining'] ) stake_amount = order['cost'] @@ -413,7 +412,7 @@ class FreqtradeBot: self.rpc.send_msg({ 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': self.exchange.name.capitalize(), - 'pair': pair_s, + 'pair': pair, 'limit': buy_limit_filled_price, 'order_type': order_type, 'stake_amount': stake_amount, From b6d1c5b17aca2e21d6cde9fd41513a5daf3aa0a2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 01:44:51 +0300 Subject: [PATCH 0068/1106] _get_trade_stake_amount() is not private --- freqtrade/freqtradebot.py | 4 ++-- freqtrade/rpc/rpc.py | 2 +- tests/test_freqtradebot.py | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a9ce14bef..9bd7e94fc 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -204,7 +204,7 @@ class FreqtradeBot: return used_rate - def _get_trade_stake_amount(self, pair) -> Optional[float]: + def get_trade_stake_amount(self, pair) -> Optional[float]: """ Check if stake amount can be fulfilled with the available balance for the stake currency @@ -309,7 +309,7 @@ class FreqtradeBot: self.dataprovider.ohlcv(_pair, self.strategy.ticker_interval)) if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']: - stake_amount = self._get_trade_stake_amount(_pair) + stake_amount = self.get_trade_stake_amount(_pair) if not stake_amount: continue diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index d6d442df5..35c312743 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -462,7 +462,7 @@ class RPC: raise RPCException(f'position for {pair} already open - id: {trade.id}') # gen stake amount - stakeamount = self._freqtrade._get_trade_stake_amount(pair) + stakeamount = self._freqtrade.get_trade_stake_amount(pair) # execute buy if self._freqtrade.execute_buy(pair, stakeamount, price): diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 13f1277b9..1d6cce7fa 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -136,7 +136,7 @@ def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: freqtrade = FreqtradeBot(default_conf) - result = freqtrade._get_trade_stake_amount('ETH/BTC') + result = freqtrade.get_trade_stake_amount('ETH/BTC') assert result == default_conf['stake_amount'] @@ -147,7 +147,7 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: freqtrade = FreqtradeBot(default_conf) with pytest.raises(DependencyException, match=r'.*stake amount.*'): - freqtrade._get_trade_stake_amount('ETH/BTC') + freqtrade.get_trade_stake_amount('ETH/BTC') def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, @@ -170,25 +170,25 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, patch_get_signal(freqtrade) # no open trades, order amount should be 'balance / max_open_trades' - result = freqtrade._get_trade_stake_amount('ETH/BTC') + result = freqtrade.get_trade_stake_amount('ETH/BTC') assert result == default_conf['stake_amount'] / conf['max_open_trades'] # create one trade, order amount should be 'balance / (max_open_trades - num_open_trades)' freqtrade.execute_buy('ETH/BTC', result) - result = freqtrade._get_trade_stake_amount('LTC/BTC') + result = freqtrade.get_trade_stake_amount('LTC/BTC') assert result == default_conf['stake_amount'] / (conf['max_open_trades'] - 1) # create 2 trades, order amount should be None freqtrade.execute_buy('LTC/BTC', result) - result = freqtrade._get_trade_stake_amount('XRP/BTC') + result = freqtrade.get_trade_stake_amount('XRP/BTC') assert result is None # set max_open_trades = None, so do not trade conf['max_open_trades'] = 0 freqtrade = FreqtradeBot(conf) - result = freqtrade._get_trade_stake_amount('NEO/BTC') + result = freqtrade.get_trade_stake_amount('NEO/BTC') assert result is None @@ -214,8 +214,8 @@ def test_edge_overrides_stake_amount(mocker, edge_conf) -> None: edge_conf['dry_run_wallet'] = 999.9 freqtrade = FreqtradeBot(edge_conf) - assert freqtrade._get_trade_stake_amount('NEO/BTC') == (999.9 * 0.5 * 0.01) / 0.20 - assert freqtrade._get_trade_stake_amount('LTC/BTC') == (999.9 * 0.5 * 0.01) / 0.21 + assert freqtrade.get_trade_stake_amount('NEO/BTC') == (999.9 * 0.5 * 0.01) / 0.20 + assert freqtrade.get_trade_stake_amount('LTC/BTC') == (999.9 * 0.5 * 0.01) / 0.21 def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf) -> None: @@ -570,7 +570,7 @@ def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade) assert not freqtrade.create_trades() - assert freqtrade._get_trade_stake_amount('ETH/BTC') is None + assert freqtrade.get_trade_stake_amount('ETH/BTC') is None def test_create_trades_no_pairs_let(default_conf, ticker, limit_buy_order, fee, From 86f269304099489279934f5622205bdad159d01e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 01:54:12 +0300 Subject: [PATCH 0069/1106] cosmetics --- freqtrade/freqtradebot.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9bd7e94fc..7827f29af 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -299,17 +299,17 @@ class FreqtradeBot: buycount = 0 # running get_signal on historical data fetched - for _pair in whitelist: - if self.strategy.is_pair_locked(_pair): - logger.info(f"Pair {_pair} is currently locked.") + for pair in whitelist: + if self.strategy.is_pair_locked(pair): + logger.info(f"Pair {pair} is currently locked.") continue (buy, sell) = self.strategy.get_signal( - _pair, self.strategy.ticker_interval, - self.dataprovider.ohlcv(_pair, self.strategy.ticker_interval)) + pair, self.strategy.ticker_interval, + self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']: - stake_amount = self.get_trade_stake_amount(_pair) + stake_amount = self.get_trade_stake_amount(pair) if not stake_amount: continue @@ -320,11 +320,11 @@ class FreqtradeBot: get('check_depth_of_market', {}) if (bidstrat_check_depth_of_market.get('enabled', False)) and\ (bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0): - if self._check_depth_of_market_buy(_pair, bidstrat_check_depth_of_market): - buycount += self.execute_buy(_pair, stake_amount) + if self._check_depth_of_market_buy(pair, bidstrat_check_depth_of_market): + buycount += self.execute_buy(pair, stake_amount) continue - buycount += self.execute_buy(_pair, stake_amount) + buycount += self.execute_buy(pair, stake_amount) return buycount > 0 From 243bcb23680f5989dce55c268240b074de9448fd Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 02:25:43 +0300 Subject: [PATCH 0070/1106] Make _check_available_stake_amount() a separate method --- freqtrade/freqtradebot.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7827f29af..24d250ffe 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -206,9 +206,8 @@ class FreqtradeBot: def get_trade_stake_amount(self, pair) -> Optional[float]: """ - Check if stake amount can be fulfilled with the available balance - for the stake currency - :return: float: Stake Amount + Calculate stake amount for the trade + :return: float: Stake amount """ if self.edge: return self.edge.stake_amount( @@ -220,16 +219,24 @@ class FreqtradeBot: else: stake_amount = self.config['stake_amount'] - available_amount = self.wallets.get_free(self.config['stake_currency']) - if stake_amount == constants.UNLIMITED_STAKE_AMOUNT: open_trades = len(Trade.get_open_trades()) if open_trades >= self.config['max_open_trades']: logger.warning("Can't open a new trade: max number of trades is reached") return None + available_amount = self.wallets.get_free(self.config['stake_currency']) return available_amount / (self.config['max_open_trades'] - open_trades) - # Check if stake_amount is fulfilled + return self._check_available_stake_amount(stake_amount) + + def _check_available_stake_amount(self, stake_amount) -> float: + """ + Check if stake amount can be fulfilled with the available balance + for the stake currency + :return: float: Stake amount + """ + available_amount = self.wallets.get_free(self.config['stake_currency']) + if available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " From abaeab89aadee4f8a6ee3a29d381fa58261fe0b1 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 02:36:32 +0300 Subject: [PATCH 0071/1106] Make _calculate_unlimited_stake_amount() a separate method --- freqtrade/freqtradebot.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 24d250ffe..7b111e2d4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -220,15 +220,22 @@ class FreqtradeBot: stake_amount = self.config['stake_amount'] if stake_amount == constants.UNLIMITED_STAKE_AMOUNT: - open_trades = len(Trade.get_open_trades()) - if open_trades >= self.config['max_open_trades']: - logger.warning("Can't open a new trade: max number of trades is reached") - return None - available_amount = self.wallets.get_free(self.config['stake_currency']) - return available_amount / (self.config['max_open_trades'] - open_trades) + return self._calculate_unlimited_stake_amount() return self._check_available_stake_amount(stake_amount) + def _calculate_unlimited_stake_amount(self) -> Optional[float]: + """ + Calculate stake amount for "unlimited" stake amount + :return: None if max number of trades reached + """ + open_trades = len(Trade.get_open_trades()) + if open_trades >= self.config['max_open_trades']: + logger.warning("Can't open a new trade: max number of trades is reached") + return None + available_amount = self.wallets.get_free(self.config['stake_currency']) + return available_amount / (self.config['max_open_trades'] - open_trades) + def _check_available_stake_amount(self, stake_amount) -> float: """ Check if stake amount can be fulfilled with the available balance From ef92fd775c0863530caae52e9b0b170c3fcc7b77 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 02:53:41 +0300 Subject: [PATCH 0072/1106] Align behavior: check for available in all cases: edge, unlimited and fixed --- freqtrade/freqtradebot.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7b111e2d4..2f4803cc5 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -210,7 +210,7 @@ class FreqtradeBot: :return: float: Stake amount """ if self.edge: - return self.edge.stake_amount( + stake_amount = self.edge.stake_amount( pair, self.wallets.get_free(self.config['stake_currency']), self.wallets.get_total(self.config['stake_currency']), @@ -218,9 +218,8 @@ class FreqtradeBot: ) else: stake_amount = self.config['stake_amount'] - - if stake_amount == constants.UNLIMITED_STAKE_AMOUNT: - return self._calculate_unlimited_stake_amount() + if stake_amount == constants.UNLIMITED_STAKE_AMOUNT: + stake_amount = self._calculate_unlimited_stake_amount() return self._check_available_stake_amount(stake_amount) @@ -236,7 +235,7 @@ class FreqtradeBot: available_amount = self.wallets.get_free(self.config['stake_currency']) return available_amount / (self.config['max_open_trades'] - open_trades) - def _check_available_stake_amount(self, stake_amount) -> float: + def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: """ Check if stake amount can be fulfilled with the available balance for the stake currency @@ -244,7 +243,7 @@ class FreqtradeBot: """ available_amount = self.wallets.get_free(self.config['stake_currency']) - if available_amount < stake_amount: + if stake_amount is not None and available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " f"lower than stake amount ({stake_amount} {self.config['stake_currency']})" From ed9cb4219df4305e5c3aa1133b45ca0637b9b6d4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 02:58:23 +0300 Subject: [PATCH 0073/1106] Make mypy happy --- freqtrade/freqtradebot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 2f4803cc5..4ec01cb60 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -209,6 +209,7 @@ class FreqtradeBot: Calculate stake amount for the trade :return: float: Stake amount """ + stake_amount: Optional[float] if self.edge: stake_amount = self.edge.stake_amount( pair, From 8eeabd2372b26987975a4dd772157e14de7a0044 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 03:22:50 +0300 Subject: [PATCH 0074/1106] Move warning to create_trades() --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4ec01cb60..44a83db1a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -231,7 +231,6 @@ class FreqtradeBot: """ open_trades = len(Trade.get_open_trades()) if open_trades >= self.config['max_open_trades']: - logger.warning("Can't open a new trade: max number of trades is reached") return None available_amount = self.wallets.get_free(self.config['stake_currency']) return available_amount / (self.config['max_open_trades'] - open_trades) @@ -324,7 +323,8 @@ class FreqtradeBot: if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']: stake_amount = self.get_trade_stake_amount(pair) - if not stake_amount: + if stake_amount is None: + logger.warning("Can't open a new trade: max number of trades is reached") continue logger.info(f"Buy signal found: about create a new trade with stake_amount: " From 3dbd83e35a7529215ef609e3090aa9d78475ecb4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 03:46:42 +0300 Subject: [PATCH 0075/1106] Introduce get_free_open_trades() method --- freqtrade/freqtradebot.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 44a83db1a..14d67b942 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -136,7 +136,7 @@ class FreqtradeBot: self.process_maybe_execute_sells(trades) # Then looking for buy opportunities - if len(trades) < self.config['max_open_trades']: + if self.get_free_open_trades(): self.process_maybe_execute_buys() # Check and handle any timed out open orders @@ -173,6 +173,14 @@ class FreqtradeBot: """ return [(pair, self.config['ticker_interval']) for pair in pairs] + def get_free_open_trades(self): + """ + Return the number of free open trades slots or 0 if + max number of open trades reached + """ + open_trades = len(Trade.get_open_trades()) + return max(0, self.config['max_open_trades'] - open_trades) + def get_target_bid(self, pair: str, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price @@ -229,11 +237,11 @@ class FreqtradeBot: Calculate stake amount for "unlimited" stake amount :return: None if max number of trades reached """ - open_trades = len(Trade.get_open_trades()) - if open_trades >= self.config['max_open_trades']: + free_open_trades = self.get_free_open_trades() + if not free_open_trades: return None available_amount = self.wallets.get_free(self.config['stake_currency']) - return available_amount / (self.config['max_open_trades'] - open_trades) + return available_amount / free_open_trades def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: """ @@ -321,12 +329,12 @@ class FreqtradeBot: pair, self.strategy.ticker_interval, self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) - if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']: - stake_amount = self.get_trade_stake_amount(pair) - if stake_amount is None: + if buy and not sell: + if not self.get_free_open_trades(): logger.warning("Can't open a new trade: max number of trades is reached") continue + stake_amount = self.get_trade_stake_amount(pair) logger.info(f"Buy signal found: about create a new trade with stake_amount: " f"{stake_amount} ...") From d6ca562b0378a289b160372d1a4a7df0d2da2d67 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 04:05:03 +0300 Subject: [PATCH 0076/1106] Make mypy happy and handle hypothetical case when stake_amount == 0 --- freqtrade/freqtradebot.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 14d67b942..9c18d2d95 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -335,6 +335,10 @@ class FreqtradeBot: continue stake_amount = self.get_trade_stake_amount(pair) + if not stake_amount: + logger.warning("Stake amount is 0, ignoring trade") + continue + logger.info(f"Buy signal found: about create a new trade with stake_amount: " f"{stake_amount} ...") From fc98cf00372b8b5f0d8e9cdd6ea8dc3b182f3f4a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 06:25:45 +0100 Subject: [PATCH 0077/1106] Address PR feedback - change output to show Filename only --- docs/utils.md | 8 ++++---- freqtrade/utils.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index f7501ae9d..18deeac54 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -110,7 +110,7 @@ freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt ## List Strategies -Use the `list-strategies` subcommand to see all strategies in one particular folder. +Use the `list-strategies` subcommand to see all strategies in one particular directory. ``` freqtrade list-strategies --help @@ -135,12 +135,12 @@ Common arguments: ``` !!! Warning - Using this command will try to load all python files from a folder. This can be a security risk if untrusted files reside in this folder, since all module-level code is executed. + Using this command will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed. -Example: search default strategy folder within userdir +Example: search default strategy directory within userdir ``` bash -freqtrade list-strategies --user-data ~/.freqtrade/ +freqtrade list-strategies --userdir ~/.freqtrade/ ``` Example: search dedicated strategy path diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 06a62172a..f6e251154 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -226,7 +226,7 @@ def start_download_data(args: Dict[str, Any]) -> None: def start_list_strategies(args: Dict[str, Any]) -> None: """ - Print Strategies available in a folder + Print Strategies available in a directory """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) @@ -234,7 +234,7 @@ def start_list_strategies(args: Dict[str, Any]) -> None: strategies = StrategyResolver.search_all_objects(directory) # Sort alphabetically strategies = sorted(strategies, key=lambda x: x['name']) - strats_to_print = [{'name': s['name'], 'location': s['location']} for s in strategies] + strats_to_print = [{'name': s['name'], 'location': s['location'].name} for s in strategies] if args['print_one_column']: print('\n'.join([s['name'] for s in strategies])) From b2fb28453f460f89bfaef57a2ac5edae90749585 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 06:39:25 +0100 Subject: [PATCH 0078/1106] Fix tests after changing output --- tests/test_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 185425efc..4cf7b5f23 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -644,7 +644,7 @@ def test_start_list_strategies(mocker, caplog, capsys): start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacy" in captured.out - assert str(Path("strategy/legacy_strategy.py")) not in captured.out + assert "legacy_strategy.py" not in captured.out assert "DefaultStrategy" in captured.out # Test regular output @@ -658,7 +658,7 @@ def test_start_list_strategies(mocker, caplog, capsys): start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacy" in captured.out - assert str(Path("strategy/legacy_strategy.py")) in captured.out + assert "legacy_strategy.py" in captured.out assert "DefaultStrategy" in captured.out From 2496aa8e3f027cfb95a6628204442ca464739121 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 10:59:26 +0100 Subject: [PATCH 0079/1106] Add convert-data template subcommands --- freqtrade/configuration/arguments.py | 13 ++++++++++++- freqtrade/utils.py | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index b2197619d..396b55ef5 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -47,6 +47,8 @@ ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] +ARGS_CONVERT_DATA = [] + ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", "timeframes", "erase"] @@ -131,7 +133,7 @@ class Arguments: self._build_args(optionlist=['version'], parser=self.parser) from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge - from freqtrade.utils import (start_create_userdir, start_download_data, + from freqtrade.utils import (start_create_userdir, start_convert_data, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, start_list_strategies, start_new_hyperopt, @@ -251,6 +253,15 @@ class Arguments: download_data_cmd.set_defaults(func=start_download_data) self._build_args(optionlist=ARGS_DOWNLOAD_DATA, parser=download_data_cmd) + # Add convert-data subcommand + convert_data_cmd = subparsers.add_parser( + 'convert-data', + help='Convert data from one format to another.', + parents=[_common_parser], + ) + convert_data_cmd.set_defaults(func=start_convert_data) + self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_data_cmd) + # Add Plotting subcommand plot_dataframe_cmd = subparsers.add_parser( 'plot-dataframe', diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 5a5662e4b..59a8dcbb3 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -241,6 +241,14 @@ def start_list_strategies(args: Dict[str, Any]) -> None: print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) +def start_convert_data(args: Dict[str, Any]) -> None: + """ + Convert data from one format to another + """ + config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) + print(config) + + def start_list_timeframes(args: Dict[str, Any]) -> None: """ Print ticker intervals (timeframes) available on Exchange From e5a61667ddf60061a5e5477fa3b97da9a6563a9a Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 14:56:48 +0100 Subject: [PATCH 0080/1106] Implement first version of jsondatahandler --- freqtrade/configuration/arguments.py | 6 +- freqtrade/data/datahandlers/__init__.py | 20 ++++ freqtrade/data/datahandlers/idatahandler.py | 97 ++++++++++++++++ .../data/datahandlers/jsondatahandler.py | 105 ++++++++++++++++++ 4 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 freqtrade/data/datahandlers/__init__.py create mode 100644 freqtrade/data/datahandlers/idatahandler.py create mode 100644 freqtrade/data/datahandlers/jsondatahandler.py diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 396b55ef5..44bc71038 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -65,9 +65,9 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "print_c ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] -NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs", - "list-strategies", "hyperopt-list", "hyperopt-show", "plot-dataframe", - "plot-profit"] +NO_CONF_REQURIED = ["convert-data", "download-data", "list-timeframes", "list-markets", + "list-pairs", "list-strategies", "hyperopt-list", "hyperopt-show", + "plot-dataframe", "plot-profit"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] diff --git a/freqtrade/data/datahandlers/__init__.py b/freqtrade/data/datahandlers/__init__.py new file mode 100644 index 000000000..b3aa2e3a4 --- /dev/null +++ b/freqtrade/data/datahandlers/__init__.py @@ -0,0 +1,20 @@ +from .idatahandler import IDataHandler + + +def get_datahandlerclass(datatype: str) -> IDataHandler: + """ + Get datahandler class. + Could be done using Resolvers, but since this may be called often and resolvers + are rather expensive, doing this directly should improve performance. + :param datatype: datatype to use. + :return: Datahandler class + """ + + if datatype == 'json': + from .jsondatahandler import JsonDataHandler + return JsonDataHandler + elif datatype == 'jsongz': + from .jsondatahandler import JsonGzDataHandler + return JsonGzDataHandler + else: + raise ValueError(f"No datahandler for datatype {datatype} available.") diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py new file mode 100644 index 000000000..ffe50b14e --- /dev/null +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -0,0 +1,97 @@ +""" +Abstract datahandler interface. +It's subclasses handle and storing data from disk. + +""" + +from abc import ABC, abstractmethod, abstractclassmethod +from pathlib import Path +from typing import Dict, List, Optional + +from pandas import DataFrame + +from freqtrade.configuration import TimeRange + + +class IDataHandler(ABC): + + def __init__(self, datadir: Path, pair: str) -> None: + self._datadir = datadir + self._pair = pair + + @abstractclassmethod + def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: + """ + Returns a list of all pairs available in this datadir + """ + + @abstractmethod + def ohlcv_store(self, timeframe: str, data: DataFrame): + """ + Store data + """ + + @abstractmethod + def ohlcv_append(self, timeframe: str, data: DataFrame): + """ + Append data to existing files + """ + + @abstractmethod + def ohlcv_load(self, timeframe: str, timerange: Optional[TimeRange] = None) -> DataFrame: + """ + Load data for one pair + :return: Dataframe + """ + + @abstractclassmethod + def trades_get_pairs(cls, datadir: Path) -> List[str]: + """ + Returns a list of all pairs available in this datadir + """ + + @abstractmethod + def trades_store(self, data: DataFrame): + """ + Store data + """ + + @abstractmethod + def trades_append(self, data: DataFrame): + """ + Append data to existing files + """ + + @abstractmethod + def trades_load(self, timerange: Optional[TimeRange] = None): + """ + Load data for one pair + :return: Dataframe + """ + + @staticmethod + def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]: + """ + TODO: investigate if this is needed ... we can probably cover this in a dataframe + Trim tickerlist based on given timerange + """ + if not tickerlist: + return tickerlist + + start_index = 0 + stop_index = len(tickerlist) + + if timerange.starttype == 'date': + while (start_index < len(tickerlist) and + tickerlist[start_index][0] < timerange.startts * 1000): + start_index += 1 + + if timerange.stoptype == 'date': + while (stop_index > 0 and + tickerlist[stop_index-1][0] > timerange.stopts * 1000): + stop_index -= 1 + + if start_index > stop_index: + raise ValueError(f'The timerange [{timerange.startts},{timerange.stopts}] is incorrect') + + return tickerlist[start_index:stop_index] diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py new file mode 100644 index 000000000..214958251 --- /dev/null +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -0,0 +1,105 @@ +import re +from pathlib import Path +from typing import Dict, List, Optional + +from pandas import DataFrame + +from freqtrade import misc +from freqtrade.configuration import TimeRange + +from .idatahandler import IDataHandler + + +class JsonDataHandler(IDataHandler): + + _use_zip = False + + @classmethod + def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: + """ + Returns a list of all pairs available in this datadir + """ + return [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name)[0].replace('_', ' /') + for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] + + def ohlcv_store(self, timeframe: str, data: DataFrame): + """ + Store data + """ + raise NotImplementedError() + + def ohlcv_append(self, timeframe: str, data: DataFrame): + """ + Append data to existing files + """ + raise NotImplementedError() + + def ohlcv_load(self, timeframe: str, timerange: Optional[TimeRange] = None) -> DataFrame: + """ + Load data for one pair + :return: Dataframe + """ + filename = JsonDataHandler._pair_data_filename(self.datadir, self._pair, + self._pair, timeframe) + pairdata = misc.file_load_json(filename) + if not pairdata: + return [] + + if timerange: + pairdata = IDataHandler.trim_tickerlist(pairdata, timerange) + return pairdata + + @classmethod + def trades_get_pairs(cls, datadir: Path) -> List[str]: + """ + Returns a list of all pairs available in this datadir + """ + return [re.search(r'^(\S+)(?=\-trades.json)', p.name)[0].replace('_', '/') + for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] + + def trades_store(self, data: List[Dict]): + """ + Store data + """ + filename = self._pair_trades_filename(self._datadir, self._pair) + misc.file_dump_json(filename, data, is_zip=self._use_zip) + + def trades_append(self, data: DataFrame): + """ + Append data to existing files + """ + raise NotImplementedError() + + def trades_load(self, timerange: Optional[TimeRange] = None) -> List[Dict]: + """ + Load a pair from file, either .json.gz or .json + # TODO: validate timerange ... + :return: List of trades + """ + filename = self._pair_trades_filename(self._datadir, self._pair) + tradesdata = misc.file_load_json(filename) + if not tradesdata: + return [] + + return tradesdata + + @classmethod + def _pair_data_filename(cls, datadir: Path, pair: str, timeframe: str) -> Path: + pair_s = pair.replace("/", "_") + filename = datadir.joinpath(f'{pair_s}-{timeframe}.{cls._get_file_extension()}') + return filename + + @classmethod + def _get_file_extension(cls): + return "json.gz" if cls._use_zip else "json" + + @classmethod + def _pair_trades_filename(cls, datadir: Path, pair: str) -> Path: + pair_s = pair.replace("/", "_") + filename = datadir.joinpath(f'{pair_s}-trades.{cls._get_file_extension()}') + return filename + + +class JsonGzDataHandler(JsonDataHandler): + + _use_zip = True From cd4466a62655dbec5c0e811af87fd530b3ea0b28 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 15:04:45 +0100 Subject: [PATCH 0081/1106] Add convert_* methods --- freqtrade/utils.py | 50 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 59a8dcbb3..82d781fe5 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -17,6 +17,7 @@ from freqtrade.configuration import (Configuration, TimeRange, from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY +from freqtrade.data.datahandlers import get_datahandlerclass from freqtrade.data.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data, refresh_backtest_trades_data) @@ -241,12 +242,53 @@ def start_list_strategies(args: Dict[str, Any]) -> None: print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) +def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str): + """ + TODO: move this to converter.py (?) + """ + SrcClass = get_datahandlerclass(convert_from) + TrgClass = get_datahandlerclass(convert_to) + + if 'pairs' not in config: + config['pairs'] = SrcClass.trades_get_pairs(config['datadir']) + logger.info(f"Converting trades for {config['pairs']}") + + for pair in config['pairs']: + src = SrcClass(config['datadir'], pair) + trg = TrgClass(config['datadir'], pair) + data = src.trades_load() + logger.info(f"Converting {len(data)} trades for {pair}") + trg.trades_store(data) + + +def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str): + """ + TODO: move this to converter.py (?) + """ + SrcClass = get_datahandlerclass(convert_from) + TrgClass = get_datahandlerclass(convert_to) + + if 'pairs' not in config: + config['pairs'] = SrcClass.ohclv_get_pairs(config['datadir'], config['ticker_interval']) + logger.info(f"Converting OHLCV for {config['pairs']}") + + for pair in config['pairs']: + src = SrcClass(config['datadir'], pair) + trg = TrgClass(config['datadir'], pair) + data = src.ohlcv_load() + logger.info(f"Converting {len(data)} candles for {pair}") + trg.ohlcv_store(data) + + def start_convert_data(args: Dict[str, Any]) -> None: """ Convert data from one format to another """ - config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - print(config) + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + from pprint import pprint + pprint(config) + + # convert_trades_format(config, 'json', 'jsongz') def start_list_timeframes(args: Dict[str, Any]) -> None: @@ -452,10 +494,10 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: n = config.get('hyperopt_show_index', -1) if n > trials_epochs: raise OperationalException( - f"The index of the epoch to show should be less than {trials_epochs + 1}.") + f"The index of the epoch to show should be less than {trials_epochs + 1}.") if n < -trials_epochs: raise OperationalException( - f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") + f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") # Translate epoch index from human-readable format to pythonic if n > 0: From c3064dfd2b56e8d74ef8c07219b0e119cd0626c6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Dec 2019 15:06:33 +0100 Subject: [PATCH 0082/1106] Enhance validation constants --- freqtrade/constants.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d7c6249d5..2f60bef2d 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -18,6 +18,7 @@ REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange'] ORDERTYPE_POSSIBILITIES = ['limit', 'market'] ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', 'PrecisionFilter', 'PriceFilter'] +AVAILABLE_DATAHANDLERS = ['json', 'jsongz'] DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons @@ -213,6 +214,16 @@ CONF_SCHEMA = { 'process_throttle_secs': {'type': 'integer'}, 'interval': {'type': 'integer'}, 'sd_notify': {'type': 'boolean'}, + 'dataformat_ohlcv': { + 'type': 'string', + 'enum': AVAILABLE_DATAHANDLERS, + 'default': 'json' + }, + 'dataformat_trades': { + 'type': 'string', + 'enum': AVAILABLE_DATAHANDLERS, + 'default': 'jsongz' + } } } }, @@ -280,5 +291,6 @@ CONF_SCHEMA = { 'unfilledtimeout', 'stoploss', 'minimal_roi', + 'internals', ] } From 2a6b542b098f4ada5fd75149437e9dcb14474450 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 09:59:01 +0100 Subject: [PATCH 0083/1106] Add second subcommand to allow conversation of ohlcv and trades data seprately --- freqtrade/configuration/arguments.py | 20 +++++++++++++++----- freqtrade/configuration/cli_options.py | 12 ++++++++++++ freqtrade/utils.py | 10 +++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 44bc71038..a20ecaa43 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -47,7 +47,7 @@ ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] -ARGS_CONVERT_DATA = [] +ARGS_CONVERT_DATA = ["format_from", "format_to"] ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", "timeframes", "erase"] @@ -65,8 +65,9 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "print_c ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] -NO_CONF_REQURIED = ["convert-data", "download-data", "list-timeframes", "list-markets", - "list-pairs", "list-strategies", "hyperopt-list", "hyperopt-show", +NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", + "list-timeframes", "list-markets", "list-pairs", + "list-strategies", "hyperopt-list", "hyperopt-show", "plot-dataframe", "plot-profit"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] @@ -256,10 +257,19 @@ class Arguments: # Add convert-data subcommand convert_data_cmd = subparsers.add_parser( 'convert-data', - help='Convert data from one format to another.', + help='Convert OHLCV data from one format to another.', parents=[_common_parser], ) - convert_data_cmd.set_defaults(func=start_convert_data) + convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=True)) + self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_data_cmd) + + # Add convert-data subcommand + convert_data_cmd = subparsers.add_parser( + 'convert-trade-data', + help='Convert trade-data from one format to another.', + parents=[_common_parser], + ) + convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False)) self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_data_cmd) # Add Plotting subcommand diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index 4b6429f20..ffaf9ea66 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -332,6 +332,18 @@ AVAILABLE_CLI_OPTIONS = { 'desired timeframe as specified as --timeframes/-t.', action='store_true', ), + "format_from": Arg( + '--format-from', + help='Source format for data conversation.', + choices=constants.AVAILABLE_DATAHANDLERS, + required=True, + ), + "format_to": Arg( + '--format-to', + help='Destination format for data conversation.', + choices=constants.AVAILABLE_DATAHANDLERS, + required=True, + ), "exchange": Arg( '--exchange', help=f'Exchange name (default: `{constants.DEFAULT_EXCHANGE}`). ' diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 82d781fe5..d02c80f7f 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -280,15 +280,19 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: trg.ohlcv_store(data) -def start_convert_data(args: Dict[str, Any]) -> None: +def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: """ Convert data from one format to another """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) from pprint import pprint pprint(config) - - # convert_trades_format(config, 'json', 'jsongz') + if ohlcv: + convert_ohlcv_format(config, + convert_from=args['format_from'], convert_to=args['format_to']) + else: + convert_trades_format(config, + convert_from=args['format_from'], convert_to=args['format_to']) def start_list_timeframes(args: Dict[str, Any]) -> None: From f8b8b9ac631dfe36083a3f0f7c1ccc086a81dad0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:01:39 +0100 Subject: [PATCH 0084/1106] Convert to Path temporarily --- freqtrade/utils.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index d02c80f7f..4661e84b2 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -245,17 +245,18 @@ def start_list_strategies(args: Dict[str, Any]) -> None: def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str): """ TODO: move this to converter.py (?) + TODO: remove Path conversation once PR is merged and this is rebased """ SrcClass = get_datahandlerclass(convert_from) TrgClass = get_datahandlerclass(convert_to) if 'pairs' not in config: - config['pairs'] = SrcClass.trades_get_pairs(config['datadir']) + config['pairs'] = SrcClass.trades_get_pairs(Path(config['datadir'])) logger.info(f"Converting trades for {config['pairs']}") for pair in config['pairs']: - src = SrcClass(config['datadir'], pair) - trg = TrgClass(config['datadir'], pair) + src = SrcClass(Path(config['datadir'], pair)) + trg = TrgClass(Path(config['datadir'], pair)) data = src.trades_load() logger.info(f"Converting {len(data)} trades for {pair}") trg.trades_store(data) @@ -264,17 +265,18 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str): """ TODO: move this to converter.py (?) + TODO: remove Path conversation once PR is merged and this is rebased """ SrcClass = get_datahandlerclass(convert_from) TrgClass = get_datahandlerclass(convert_to) if 'pairs' not in config: - config['pairs'] = SrcClass.ohclv_get_pairs(config['datadir'], config['ticker_interval']) + config['pairs'] = SrcClass.ohclv_get_pairs(Path(config['datadir']), config['ticker_interval']) logger.info(f"Converting OHLCV for {config['pairs']}") for pair in config['pairs']: - src = SrcClass(config['datadir'], pair) - trg = TrgClass(config['datadir'], pair) + src = SrcClass(Path(config['datadir']), pair) + trg = TrgClass(Path(config['datadir']), pair) data = src.ohlcv_load() logger.info(f"Converting {len(data)} candles for {pair}") trg.ohlcv_store(data) From ef0fcb0e0f5b82548b53380a0968d1750c64da69 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:21:30 +0100 Subject: [PATCH 0085/1106] Make data-finding safe --- freqtrade/data/datahandlers/jsondatahandler.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 214958251..fe01176ad 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -19,8 +19,11 @@ class JsonDataHandler(IDataHandler): """ Returns a list of all pairs available in this datadir """ - return [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name)[0].replace('_', ' /') + + _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] + # Check if regex found something and only return these results + return [match[0].replace('_', ' /') for match in _tmp if match] def ohlcv_store(self, timeframe: str, data: DataFrame): """ @@ -54,8 +57,10 @@ class JsonDataHandler(IDataHandler): """ Returns a list of all pairs available in this datadir """ - return [re.search(r'^(\S+)(?=\-trades.json)', p.name)[0].replace('_', '/') + _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] + # Check if regex found something and only return these results to avoid exceptions. + return [match[0].replace('_', ' /') for match in _tmp if match] def trades_store(self, data: List[Dict]): """ From 3d4f62081e1cc9306a7eceb33fc575c9fd354c5d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:21:47 +0100 Subject: [PATCH 0086/1106] Allow timeframes for convert-data --- freqtrade/configuration/arguments.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index a20ecaa43..888da4296 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -48,6 +48,7 @@ ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] ARGS_CONVERT_DATA = ["format_from", "format_to"] +ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"] ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", "timeframes", "erase"] @@ -261,7 +262,7 @@ class Arguments: parents=[_common_parser], ) convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=True)) - self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_data_cmd) + self._build_args(optionlist=ARGS_CONVERT_DATA_OHLCV, parser=convert_data_cmd) # Add convert-data subcommand convert_data_cmd = subparsers.add_parser( From 2a728ee68f669b0df51c70bf8e1f1a4cc52dcfc1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:25:30 +0100 Subject: [PATCH 0087/1106] fix bug in find-files --- freqtrade/data/datahandlers/jsondatahandler.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index fe01176ad..a6caf137d 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -23,7 +23,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] # Check if regex found something and only return these results - return [match[0].replace('_', ' /') for match in _tmp if match] + return [match[0].replace('_', '/') for match in _tmp if match] def ohlcv_store(self, timeframe: str, data: DataFrame): """ @@ -42,8 +42,7 @@ class JsonDataHandler(IDataHandler): Load data for one pair :return: Dataframe """ - filename = JsonDataHandler._pair_data_filename(self.datadir, self._pair, - self._pair, timeframe) + filename = JsonDataHandler._pair_data_filename(self._datadir, self._pair, timeframe) pairdata = misc.file_load_json(filename) if not pairdata: return [] @@ -60,7 +59,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] # Check if regex found something and only return these results to avoid exceptions. - return [match[0].replace('_', ' /') for match in _tmp if match] + return [match[0].replace('_', '/') for match in _tmp if match] def trades_store(self, data: List[Dict]): """ From 018e2703368459d06d0aab0b8e320321a12c6e2c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:28:11 +0100 Subject: [PATCH 0088/1106] Allow --pairs for convert arguments --- freqtrade/configuration/arguments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 888da4296..cefa86927 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -47,7 +47,7 @@ ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] -ARGS_CONVERT_DATA = ["format_from", "format_to"] +ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to"] ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"] ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", From d804372d74ad0a38a66ca6588abc2b01af04b341 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:28:25 +0100 Subject: [PATCH 0089/1106] Enhance ohlcv_convert method --- freqtrade/utils.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 4661e84b2..0805f0011 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -252,11 +252,12 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: if 'pairs' not in config: config['pairs'] = SrcClass.trades_get_pairs(Path(config['datadir'])) - logger.info(f"Converting trades for {config['pairs']}") + logger.info(f"Converting trades for {config['pairs']}") for pair in config['pairs']: - src = SrcClass(Path(config['datadir'], pair)) - trg = TrgClass(Path(config['datadir'], pair)) + print(pair) + src = SrcClass(Path(config['datadir']), pair) + trg = TrgClass(Path(config['datadir']), pair) data = src.trades_load() logger.info(f"Converting {len(data)} trades for {pair}") trg.trades_store(data) @@ -269,17 +270,25 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: """ SrcClass = get_datahandlerclass(convert_from) TrgClass = get_datahandlerclass(convert_to) + timeframes = config.get('timeframes', [config.get('ticker_interval')]) + logger.info(f"Converting OHLCV for timeframe {timeframes}") if 'pairs' not in config: - config['pairs'] = SrcClass.ohclv_get_pairs(Path(config['datadir']), config['ticker_interval']) - logger.info(f"Converting OHLCV for {config['pairs']}") + config['pairs'] = [] + # Check timeframes or fall back to ticker_interval. + for timeframe in timeframes: + config['pairs'].extend(SrcClass.ohlcv_get_pairs(Path(config['datadir']), + timeframe)) + logger.info(f"Converting OHLCV for {config['pairs']}") - for pair in config['pairs']: - src = SrcClass(Path(config['datadir']), pair) - trg = TrgClass(Path(config['datadir']), pair) - data = src.ohlcv_load() - logger.info(f"Converting {len(data)} candles for {pair}") - trg.ohlcv_store(data) + for timeframe in timeframes: + + for pair in config['pairs']: + src = SrcClass(Path(config['datadir']), pair) + trg = TrgClass(Path(config['datadir']), pair) + data = src.ohlcv_load(timeframe) + logger.info(f"Converting {len(data)} candles for {pair}") + # trg.ohlcv_store(data) def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: From abc6b9459a8133c4c66f3a2c9f7afc407af35a9c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:30:35 +0100 Subject: [PATCH 0090/1106] Add ohlcv_store call to convert_ohlcv --- freqtrade/data/datahandlers/jsondatahandler.py | 4 ++-- freqtrade/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index a6caf137d..747d80c54 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -25,13 +25,13 @@ class JsonDataHandler(IDataHandler): # Check if regex found something and only return these results return [match[0].replace('_', '/') for match in _tmp if match] - def ohlcv_store(self, timeframe: str, data: DataFrame): + def ohlcv_store(self, timeframe: str, data: DataFrame) -> None: """ Store data """ raise NotImplementedError() - def ohlcv_append(self, timeframe: str, data: DataFrame): + def ohlcv_append(self, timeframe: str, data: DataFrame) -> None: """ Append data to existing files """ diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 0805f0011..72b2afc8e 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -286,9 +286,9 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: for pair in config['pairs']: src = SrcClass(Path(config['datadir']), pair) trg = TrgClass(Path(config['datadir']), pair) - data = src.ohlcv_load(timeframe) + data = src.ohlcv_load(timeframe=timeframe) logger.info(f"Converting {len(data)} candles for {pair}") - # trg.ohlcv_store(data) + trg.ohlcv_store(timeframe=timeframe, data=data) def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: From 8f214aec891a862dab943de5f3561025852ac1fd Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:35:23 +0100 Subject: [PATCH 0091/1106] Fix "dumping" message to work correctly for .gz files --- freqtrade/misc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index bcba78cf0..ed37ace3a 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -47,14 +47,16 @@ def file_dump_json(filename: Path, data, is_zip=False) -> None: :param data: JSON Data to save :return: """ - logger.info(f'dumping json to "{filename}"') if is_zip: if filename.suffix != '.gz': filename = filename.with_suffix('.gz') + logger.info(f'dumping json to "{filename}"') + with gzip.open(filename, 'w') as fp: rapidjson.dump(data, fp, default=str, number_mode=rapidjson.NM_NATIVE) else: + logger.info(f'dumping json to "{filename}"') with open(filename, 'w') as fp: rapidjson.dump(data, fp, default=str, number_mode=rapidjson.NM_NATIVE) From c6d6dbfdb1646279fb439197e40716780bd99867 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:37:31 +0100 Subject: [PATCH 0092/1106] Implement jsondatahandler file store --- freqtrade/data/datahandlers/jsondatahandler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 747d80c54..ec4e41ae8 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -29,7 +29,8 @@ class JsonDataHandler(IDataHandler): """ Store data """ - raise NotImplementedError() + filename = JsonDataHandler._pair_data_filename(self._datadir, self._pair, timeframe) + misc.file_dump_json(filename, data, is_zip=self._use_zip) def ohlcv_append(self, timeframe: str, data: DataFrame) -> None: """ From eff5cc0568b5a3464eb1326afccb3b0eac3a84fc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 10:41:04 +0100 Subject: [PATCH 0093/1106] Add default to internals --- freqtrade/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 2f60bef2d..9c7e3db63 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -210,6 +210,7 @@ CONF_SCHEMA = { 'forcebuy_enable': {'type': 'boolean'}, 'internals': { 'type': 'object', + 'default': {}, 'properties': { 'process_throttle_secs': {'type': 'integer'}, 'interval': {'type': 'integer'}, From e529a4c261e0762056bb2c685170a3a9e3f5b653 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 11:08:11 +0100 Subject: [PATCH 0094/1106] Fix typehint for get_datahandlerclass --- freqtrade/data/datahandlers/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/datahandlers/__init__.py b/freqtrade/data/datahandlers/__init__.py index b3aa2e3a4..b22b61417 100644 --- a/freqtrade/data/datahandlers/__init__.py +++ b/freqtrade/data/datahandlers/__init__.py @@ -1,7 +1,9 @@ +from typing import Type + from .idatahandler import IDataHandler -def get_datahandlerclass(datatype: str) -> IDataHandler: +def get_datahandlerclass(datatype: str) -> Type[IDataHandler]: """ Get datahandler class. Could be done using Resolvers, but since this may be called often and resolvers From 48728e2d666d3cddafc654b87a0b1e21cc1ea58c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 11:08:49 +0100 Subject: [PATCH 0095/1106] Change DataProvider interface to accept pair per method --- .../data/datahandlers/jsondatahandler.py | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index ec4e41ae8..ca6f94c5e 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -6,6 +6,7 @@ from pandas import DataFrame from freqtrade import misc from freqtrade.configuration import TimeRange +from freqtrade.data.converter import parse_ticker_dataframe from .idatahandler import IDataHandler @@ -25,31 +26,40 @@ class JsonDataHandler(IDataHandler): # Check if regex found something and only return these results return [match[0].replace('_', '/') for match in _tmp if match] - def ohlcv_store(self, timeframe: str, data: DataFrame) -> None: + def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: """ Store data """ - filename = JsonDataHandler._pair_data_filename(self._datadir, self._pair, timeframe) + filename = JsonDataHandler._pair_data_filename(self._datadir, pair, timeframe) misc.file_dump_json(filename, data, is_zip=self._use_zip) - def ohlcv_append(self, timeframe: str, data: DataFrame) -> None: + def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: """ Append data to existing files """ raise NotImplementedError() - def ohlcv_load(self, timeframe: str, timerange: Optional[TimeRange] = None) -> DataFrame: + def _ohlcv_load(self, pair: str, timeframe: str, + timerange: Optional[TimeRange] = None, + fill_up_missing: bool = True, + drop_incomplete: bool = True, + ) -> DataFrame: """ - Load data for one pair + Load data for one pair from disk. + Implements the loading and conversation to a Pandas dataframe. :return: Dataframe """ - filename = JsonDataHandler._pair_data_filename(self._datadir, self._pair, timeframe) + filename = JsonDataHandler._pair_data_filename(self._datadir, pair, timeframe) pairdata = misc.file_load_json(filename) if not pairdata: - return [] + return DataFrame() if timerange: pairdata = IDataHandler.trim_tickerlist(pairdata, timerange) + return parse_ticker_dataframe(pairdata, timeframe, + pair=self._pair, + fill_missing=fill_up_missing, + drop_incomplete=drop_incomplete) return pairdata @classmethod @@ -62,26 +72,26 @@ class JsonDataHandler(IDataHandler): # Check if regex found something and only return these results to avoid exceptions. return [match[0].replace('_', '/') for match in _tmp if match] - def trades_store(self, data: List[Dict]): + def trades_store(self, pair: str, data: List[Dict]): """ Store data """ - filename = self._pair_trades_filename(self._datadir, self._pair) + filename = self._pair_trades_filename(self._datadir, pair) misc.file_dump_json(filename, data, is_zip=self._use_zip) - def trades_append(self, data: DataFrame): + def trades_append(self, pair: str, data: DataFrame): """ Append data to existing files """ raise NotImplementedError() - def trades_load(self, timerange: Optional[TimeRange] = None) -> List[Dict]: + def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> List[Dict]: """ Load a pair from file, either .json.gz or .json # TODO: validate timerange ... :return: List of trades """ - filename = self._pair_trades_filename(self._datadir, self._pair) + filename = self._pair_trades_filename(self._datadir, pair) tradesdata = misc.file_load_json(filename) if not tradesdata: return [] From d923bab8288f65a4c97bf3340883f1cb11f60523 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 11:09:29 +0100 Subject: [PATCH 0096/1106] Remove abstract interface for now --- freqtrade/data/datahandlers/idatahandler.py | 106 +++++++++++--------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index ffe50b14e..b82898353 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -3,71 +3,77 @@ Abstract datahandler interface. It's subclasses handle and storing data from disk. """ - +import logging from abc import ABC, abstractmethod, abstractclassmethod from pathlib import Path from typing import Dict, List, Optional - +from copy import deepcopy from pandas import DataFrame from freqtrade.configuration import TimeRange +from freqtrade.exchange import timeframe_to_seconds +from freqtrade.data.converter import parse_ticker_dataframe + +logger = logging.getLogger(__name__) class IDataHandler(ABC): - def __init__(self, datadir: Path, pair: str) -> None: + def __init__(self, datadir: Path) -> None: self._datadir = datadir - self._pair = pair - @abstractclassmethod - def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: + # TODO: create abstract interface + + def ohlcv_load(self, pair, timeframe: str, + timerange: Optional[TimeRange] = None, + fill_up_missing: bool = True, + drop_incomplete: bool = True, + startup_candles: int = 0, + ) -> DataFrame: """ - Returns a list of all pairs available in this datadir + Load cached ticker history for the given pair. + + :param pair: Pair to load data for + :param timeframe: Ticker timeframe (e.g. "5m") + :param timerange: Limit data to be loaded to this timerange + :param fill_up_missing: Fill missing values with "No action"-candles + :param drop_incomplete: Drop last candle assuming it may be incomplete. + :param startup_candles: Additional candles to load at the start of the period + :return: DataFrame with ohlcv data, or empty DataFrame + """ + # Fix startup period + timerange_startup = deepcopy(timerange) + if startup_candles > 0 and timerange_startup: + timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles) + + pairdf = self._ohlcv_load(pair, timeframe, + timerange=timerange_startup, + fill_missing=fill_up_missing, + drop_incomplete=drop_incomplete) + if pairdf.empty(): + logger.warning( + f'No history data for pair: "{pair}", timeframe: {timeframe}. ' + 'Use `freqtrade download-data` to download the data' + ) + return pairdf + else: + if timerange_startup: + self._validate_pairdata(pair, pairdf, timerange_startup) + return pairdf + + def _validate_pairdata(pair, pairdata: DataFrame, timerange: TimeRange): + """ + Validates pairdata for missing data at start end end and logs warnings. + :param pairdata: Dataframe to validate + :param timerange: Timerange specified for start and end dates """ - @abstractmethod - def ohlcv_store(self, timeframe: str, data: DataFrame): - """ - Store data - """ - - @abstractmethod - def ohlcv_append(self, timeframe: str, data: DataFrame): - """ - Append data to existing files - """ - - @abstractmethod - def ohlcv_load(self, timeframe: str, timerange: Optional[TimeRange] = None) -> DataFrame: - """ - Load data for one pair - :return: Dataframe - """ - - @abstractclassmethod - def trades_get_pairs(cls, datadir: Path) -> List[str]: - """ - Returns a list of all pairs available in this datadir - """ - - @abstractmethod - def trades_store(self, data: DataFrame): - """ - Store data - """ - - @abstractmethod - def trades_append(self, data: DataFrame): - """ - Append data to existing files - """ - - @abstractmethod - def trades_load(self, timerange: Optional[TimeRange] = None): - """ - Load data for one pair - :return: Dataframe - """ + if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000: + logger.warning('Missing data at start for pair %s, data starts at %s', + pair, arrow.get(pairdata[0][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) + if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000: + logger.warning('Missing data at end for pair %s, data ends at %s', + pair, arrow.get(pairdata[-1][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) @staticmethod def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]: From 1b90ec58b9bf621b9a6b2941597d5d8efbb118ee Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 11:09:59 +0100 Subject: [PATCH 0097/1106] Use changed pair-handling for providers --- freqtrade/data/datahandlers/idatahandler.py | 15 ++++++++------- freqtrade/utils.py | 20 +++++++++----------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index b82898353..a1413fe98 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -4,15 +4,16 @@ It's subclasses handle and storing data from disk. """ import logging -from abc import ABC, abstractmethod, abstractclassmethod +from abc import ABC, abstractclassmethod, abstractmethod +from copy import deepcopy from pathlib import Path from typing import Dict, List, Optional -from copy import deepcopy + +import arrow from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.exchange import timeframe_to_seconds -from freqtrade.data.converter import parse_ticker_dataframe logger = logging.getLogger(__name__) @@ -26,7 +27,7 @@ class IDataHandler(ABC): def ohlcv_load(self, pair, timeframe: str, timerange: Optional[TimeRange] = None, - fill_up_missing: bool = True, + fill_missing: bool = True, drop_incomplete: bool = True, startup_candles: int = 0, ) -> DataFrame: @@ -48,9 +49,9 @@ class IDataHandler(ABC): pairdf = self._ohlcv_load(pair, timeframe, timerange=timerange_startup, - fill_missing=fill_up_missing, + fill_missing=fill_missing, drop_incomplete=drop_incomplete) - if pairdf.empty(): + if pairdf.empty: logger.warning( f'No history data for pair: "{pair}", timeframe: {timeframe}. ' 'Use `freqtrade download-data` to download the data' @@ -61,7 +62,7 @@ class IDataHandler(ABC): self._validate_pairdata(pair, pairdf, timerange_startup) return pairdf - def _validate_pairdata(pair, pairdata: DataFrame, timerange: TimeRange): + def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange): """ Validates pairdata for missing data at start end end and logs warnings. :param pairdata: Dataframe to validate diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 72b2afc8e..25f10f71a 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -253,14 +253,12 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: if 'pairs' not in config: config['pairs'] = SrcClass.trades_get_pairs(Path(config['datadir'])) logger.info(f"Converting trades for {config['pairs']}") - + src = SrcClass(Path(config['datadir'])) + trg = TrgClass(Path(config['datadir'])) for pair in config['pairs']: - print(pair) - src = SrcClass(Path(config['datadir']), pair) - trg = TrgClass(Path(config['datadir']), pair) - data = src.trades_load() + data = src.trades_load(pair=pair) logger.info(f"Converting {len(data)} trades for {pair}") - trg.trades_store(data) + trg.trades_store(pair, data) def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str): @@ -281,14 +279,14 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: timeframe)) logger.info(f"Converting OHLCV for {config['pairs']}") - for timeframe in timeframes: + src = SrcClass(Path(config['datadir'])) + trg = TrgClass(Path(config['datadir'])) + for timeframe in timeframes: for pair in config['pairs']: - src = SrcClass(Path(config['datadir']), pair) - trg = TrgClass(Path(config['datadir']), pair) - data = src.ohlcv_load(timeframe=timeframe) + data = src.ohlcv_load(pair=pair, timeframe=timeframe) logger.info(f"Converting {len(data)} candles for {pair}") - trg.ohlcv_store(timeframe=timeframe, data=data) + trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data) def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: From d9e7d64f33149d26f8517ba594f044a9cc07ca5b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 13:24:09 +0100 Subject: [PATCH 0098/1106] Split parse_ticker_dataframe some logic to clean_ohlcv_dataframe. --- freqtrade/data/converter.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index e45dd451e..6b44a6b20 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -37,9 +37,29 @@ def parse_ticker_dataframe(ticker: list, timeframe: str, pair: str, *, # and fail with exception... frame = frame.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float', 'volume': 'float'}) + return clean_ohlcv_dataframe(frame, timeframe, pair, + fill_missing=fill_missing, + drop_incomplete=drop_incomplete) + +def clean_ohlcv_dataframe(data: DataFrame, timeframe: str, pair: str, *, + fill_missing: bool = True, + drop_incomplete: bool = True) -> DataFrame: + """ + Clense a ohlcv dataframe by + * Grouping it by date (removes duplicate tics) + * dropping last candles if requested + * Filling up missing data (if requested) + :param data: DataFrame containing ohlcv data. + :param timeframe: timeframe (e.g. 5m). Used to fill up eventual missing data + :param pair: Pair this data is for (used to warn if fillup was necessary) + :param fill_missing: fill up missing candles with 0 candles + (see ohlcv_fill_up_missing_data for details) + :param drop_incomplete: Drop the last candle of the dataframe, assuming it's incomplete + :return: DataFrame + """ # group by index and aggregate results to eliminate duplicate ticks - frame = frame.groupby(by='date', as_index=False, sort=True).agg({ + data = data.groupby(by='date', as_index=False, sort=True).agg({ 'open': 'first', 'high': 'max', 'low': 'min', @@ -48,13 +68,13 @@ def parse_ticker_dataframe(ticker: list, timeframe: str, pair: str, *, }) # eliminate partial candle if drop_incomplete: - frame.drop(frame.tail(1).index, inplace=True) + data.drop(data.tail(1).index, inplace=True) logger.debug('Dropping last candle') if fill_missing: - return ohlcv_fill_up_missing_data(frame, timeframe, pair) + return ohlcv_fill_up_missing_data(data, timeframe, pair) else: - return frame + return data def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) -> DataFrame: From 377d59abe70fb93b1d644a39412d859853b97cf0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:04:45 +0100 Subject: [PATCH 0099/1106] Be selective how to load ohclv data for conversation --- freqtrade/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 25f10f71a..877e4825c 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -284,7 +284,10 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: for timeframe in timeframes: for pair in config['pairs']: - data = src.ohlcv_load(pair=pair, timeframe=timeframe) + data = src.ohlcv_load(pair=pair, timeframe=timeframe, + fill_missing=False, + drop_incomplete=False, + startup_candles=0) logger.info(f"Converting {len(data)} candles for {pair}") trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data) @@ -294,8 +297,6 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: Convert data from one format to another """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - from pprint import pprint - pprint(config) if ohlcv: convert_ohlcv_format(config, convert_from=args['format_from'], convert_to=args['format_to']) From 866908d2ca3a2a5caa2792c23f720b4097acced8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:05:01 +0100 Subject: [PATCH 0100/1106] Load and save using pandas internal function --- .../data/datahandlers/jsondatahandler.py | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index ca6f94c5e..3e64885a7 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -2,11 +2,12 @@ import re from pathlib import Path from typing import Dict, List, Optional -from pandas import DataFrame +import numpy as np +from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import clean_ohlcv_dataframe from .idatahandler import IDataHandler @@ -14,6 +15,7 @@ from .idatahandler import IDataHandler class JsonDataHandler(IDataHandler): _use_zip = False + _columns = ['date', 'open', 'high', 'low', 'close', 'volume'] @classmethod def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: @@ -28,20 +30,27 @@ class JsonDataHandler(IDataHandler): def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: """ - Store data + Store data in json format "values". + format looks as follows: + [[,,,,]] + :param pair: Pair - used to generate filename + :timeframe: Timeframe - used to generate filename + :data: Dataframe containing OHLCV data + :return: None """ - filename = JsonDataHandler._pair_data_filename(self._datadir, pair, timeframe) - misc.file_dump_json(filename, data, is_zip=self._use_zip) + filename = self._pair_data_filename(self._datadir, pair, timeframe) + _data = data.copy() + # Convert date to int + _data['date'] = _data['date'].astype(np.int64) // 1000 // 1000 - def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: - """ - Append data to existing files - """ - raise NotImplementedError() + # Reset index, select only appropriate columns and save as json + _data.reset_index(drop=True).loc[:, self._columns].to_json( + filename, orient="values", + compression='gzip' if self._use_zip else None) def _ohlcv_load(self, pair: str, timeframe: str, timerange: Optional[TimeRange] = None, - fill_up_missing: bool = True, + fill_missing: bool = True, drop_incomplete: bool = True, ) -> DataFrame: """ @@ -49,18 +58,31 @@ class JsonDataHandler(IDataHandler): Implements the loading and conversation to a Pandas dataframe. :return: Dataframe """ - filename = JsonDataHandler._pair_data_filename(self._datadir, pair, timeframe) - pairdata = misc.file_load_json(filename) - if not pairdata: - return DataFrame() + filename = self._pair_data_filename(self._datadir, pair, timeframe) + pairdata = read_json(filename, orient='values') + pairdata.columns = self._columns + pairdata['date'] = to_datetime(pairdata['date'], + unit='ms', + utc=True, + infer_datetime_format=True) if timerange: pairdata = IDataHandler.trim_tickerlist(pairdata, timerange) - return parse_ticker_dataframe(pairdata, timeframe, - pair=self._pair, - fill_missing=fill_up_missing, - drop_incomplete=drop_incomplete) - return pairdata + + return clean_ohlcv_dataframe(pairdata, timeframe, + pair=pair, + fill_missing=fill_missing, + drop_incomplete=drop_incomplete) + + def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: + """ + Append data to existing data structures + :param pair: Pair + :param timeframe: Timeframe this ohlcv data is for + :param data: Data to append. + + """ + raise NotImplementedError() @classmethod def trades_get_pairs(cls, datadir: Path) -> List[str]: From db520a09ee1f3ef44d29e98dad7225be17112ec5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:07:49 +0100 Subject: [PATCH 0101/1106] Trim dataframe, not tickerlist --- freqtrade/data/datahandlers/idatahandler.py | 29 +------------------ .../data/datahandlers/jsondatahandler.py | 13 +++++++-- freqtrade/utils.py | 1 + 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index a1413fe98..b9d11f243 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -37,7 +37,7 @@ class IDataHandler(ABC): :param pair: Pair to load data for :param timeframe: Ticker timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange - :param fill_up_missing: Fill missing values with "No action"-candles + :param fill_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. :param startup_candles: Additional candles to load at the start of the period :return: DataFrame with ohlcv data, or empty DataFrame @@ -75,30 +75,3 @@ class IDataHandler(ABC): if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000: logger.warning('Missing data at end for pair %s, data ends at %s', pair, arrow.get(pairdata[-1][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) - - @staticmethod - def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]: - """ - TODO: investigate if this is needed ... we can probably cover this in a dataframe - Trim tickerlist based on given timerange - """ - if not tickerlist: - return tickerlist - - start_index = 0 - stop_index = len(tickerlist) - - if timerange.starttype == 'date': - while (start_index < len(tickerlist) and - tickerlist[start_index][0] < timerange.startts * 1000): - start_index += 1 - - if timerange.stoptype == 'date': - while (stop_index > 0 and - tickerlist[stop_index-1][0] > timerange.stopts * 1000): - stop_index -= 1 - - if start_index > stop_index: - raise ValueError(f'The timerange [{timerange.startts},{timerange.stopts}] is incorrect') - - return tickerlist[start_index:stop_index] diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 3e64885a7..215aa003a 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -8,6 +8,7 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange from freqtrade.data.converter import clean_ohlcv_dataframe +from freqtrade.data.history import trim_dataframe from .idatahandler import IDataHandler @@ -54,9 +55,15 @@ class JsonDataHandler(IDataHandler): drop_incomplete: bool = True, ) -> DataFrame: """ - Load data for one pair from disk. + Internal method used to load data for one pair from disk. Implements the loading and conversation to a Pandas dataframe. - :return: Dataframe + :param pair: Pair to load data for + :param timeframe: Ticker timeframe (e.g. "5m") + :param timerange: Limit data to be loaded to this timerange + :param fill_missing: Fill missing values with "No action"-candles + :param drop_incomplete: Drop last candle assuming it may be incomplete. + :param startup_candles: Additional candles to load at the start of the period + :return: DataFrame with ohlcv data, or empty DataFrame """ filename = self._pair_data_filename(self._datadir, pair, timeframe) pairdata = read_json(filename, orient='values') @@ -67,7 +74,7 @@ class JsonDataHandler(IDataHandler): infer_datetime_format=True) if timerange: - pairdata = IDataHandler.trim_tickerlist(pairdata, timerange) + pairdata = trim_dataframe(pairdata, timerange) return clean_ohlcv_dataframe(pairdata, timeframe, pair=pair, diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 877e4825c..5f646cc7a 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -285,6 +285,7 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: for timeframe in timeframes: for pair in config['pairs']: data = src.ohlcv_load(pair=pair, timeframe=timeframe, + timerange=None, fill_missing=False, drop_incomplete=False, startup_candles=0) From 873f5dbe6bbe73e6c155dd451d6fa553894276fc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:13:17 +0100 Subject: [PATCH 0102/1106] Revrite validate_pairdata to work with pandas --- freqtrade/data/datahandlers/idatahandler.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index b9d11f243..9508e022e 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -8,8 +8,7 @@ from abc import ABC, abstractclassmethod, abstractmethod from copy import deepcopy from pathlib import Path from typing import Dict, List, Optional - -import arrow +from datetime import datetime, timezone from pandas import DataFrame from freqtrade.configuration import TimeRange @@ -70,8 +69,12 @@ class IDataHandler(ABC): """ if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000: - logger.warning('Missing data at start for pair %s, data starts at %s', - pair, arrow.get(pairdata[0][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) + start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) + if pairdata.iloc[0]['date'] > start: + logger.warning(f"Missing data at start for pair {pair}, " + f"data starts at {pairdata.iloc[0]['date']}") if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000: - logger.warning('Missing data at end for pair %s, data ends at %s', - pair, arrow.get(pairdata[-1][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) + stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc) + if pairdata.iloc[-1]['date'] < stop: + logger.warning(f"Missing data at end for pair {pair}," + f"data ends at {pairdata.iloc[-1]['date']}") From 53ee636fa02880d12ef3c32430e62d1af3f7a92f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:24:53 +0100 Subject: [PATCH 0103/1106] Check if file exists before loading --- freqtrade/data/datahandlers/jsondatahandler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 215aa003a..2893393b1 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -66,6 +66,8 @@ class JsonDataHandler(IDataHandler): :return: DataFrame with ohlcv data, or empty DataFrame """ filename = self._pair_data_filename(self._datadir, pair, timeframe) + if not filename.is_file(): + return DataFrame(columns=self._columns) pairdata = read_json(filename, orient='values') pairdata.columns = self._columns pairdata['date'] = to_datetime(pairdata['date'], From 88fa7fc24cd0688b0d0d58d6fa572e2f0f45b869 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:35:59 +0100 Subject: [PATCH 0104/1106] Simplify validate dataframe method --- freqtrade/data/datahandlers/idatahandler.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index 9508e022e..c28d03930 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -68,13 +68,13 @@ class IDataHandler(ABC): :param timerange: Timerange specified for start and end dates """ - if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000: + if timerange.starttype == 'date': start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) if pairdata.iloc[0]['date'] > start: logger.warning(f"Missing data at start for pair {pair}, " - f"data starts at {pairdata.iloc[0]['date']}") - if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000: + f"data starts at {pairdata.iloc[0]['date']:%Y-%m-%d %H:%M:%S}") + if timerange.stoptype == 'date': stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc) if pairdata.iloc[-1]['date'] < stop: - logger.warning(f"Missing data at end for pair {pair}," - f"data ends at {pairdata.iloc[-1]['date']}") + logger.warning(f"Missing data at end for pair {pair}, " + f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}") From 9d8ea2f13be579e44a03b93c35b307a09f7fc98e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:40:42 +0100 Subject: [PATCH 0105/1106] Replace calls to load_tickerdata_file with DataHandler calls --- freqtrade/data/history.py | 37 +++++++++++++++---------------------- tests/data/test_history.py | 9 +++++---- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 4c5c0521f..f09fe3d6a 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -8,7 +8,6 @@ Includes: import logging import operator -from copy import deepcopy from datetime import datetime, timezone from pathlib import Path from typing import Any, Dict, List, Optional, Tuple @@ -18,8 +17,9 @@ from pandas import DataFrame from freqtrade import OperationalException, misc from freqtrade.configuration import TimeRange -from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv -from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_seconds +from freqtrade.data.converter import trades_to_ohlcv +from freqtrade.exchange import Exchange, timeframe_to_minutes +from .datahandlers import get_datahandlerclass logger = logging.getLogger(__name__) @@ -126,11 +126,12 @@ def _validate_pairdata(pair, pairdata, timerange: TimeRange): def load_pair_history(pair: str, timeframe: str, - datadir: Path, + datadir: Path, *, timerange: Optional[TimeRange] = None, fill_up_missing: bool = True, drop_incomplete: bool = True, startup_candles: int = 0, + data_format: str = 'json' ) -> DataFrame: """ Load cached ticker history for the given pair. @@ -142,26 +143,18 @@ def load_pair_history(pair: str, :param fill_up_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. :param startup_candles: Additional candles to load at the start of the period + :param data_format: Format of the data :return: DataFrame with ohlcv data, or empty DataFrame """ - timerange_startup = deepcopy(timerange) - if startup_candles > 0 and timerange_startup: - timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles) - - pairdata = load_tickerdata_file(datadir, pair, timeframe, timerange=timerange_startup) - - if pairdata: - if timerange_startup: - _validate_pairdata(pair, pairdata, timerange_startup) - return parse_ticker_dataframe(pairdata, timeframe, pair=pair, - fill_missing=fill_up_missing, - drop_incomplete=drop_incomplete) - else: - logger.warning( - f'No history data for pair: "{pair}", timeframe: {timeframe}. ' - 'Use `freqtrade download-data` to download the data' - ) - return DataFrame() + HandlerClass = get_datahandlerclass(data_format) + loader = HandlerClass(datadir) + return loader.ohlcv_load(pair=pair, + timeframe=timeframe, + timerange=timerange, + fill_missing=fill_up_missing, + drop_incomplete=drop_incomplete, + startup_candles=startup_candles, + ) def load_data(datadir: Path, diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 7b3143db9..f13e386f8 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -96,8 +96,9 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog, testdatadir) -> N def test_load_data_startup_candles(mocker, caplog, default_conf, testdatadir) -> None: - ltfmock = mocker.patch('freqtrade.data.history.load_tickerdata_file', - MagicMock(return_value=None)) + ltfmock = mocker.patch( + 'freqtrade.data.datahandlers.jsondatahandler.JsonDataHandler._ohlcv_load', + MagicMock(return_value=DataFrame())) timerange = TimeRange('date', None, 1510639620, 0) load_pair_history(pair='UNITTEST/BTC', timeframe='1m', datadir=testdatadir, timerange=timerange, @@ -361,8 +362,8 @@ def test_load_partial_missing(testdatadir, caplog) -> None: # timedifference in 5 minutes td = ((end - start).total_seconds() // 60 // 5) + 1 assert td != len(tickerdata['UNITTEST/BTC']) - # Shift endtime with +5 - as last candle is dropped (partial candle) - end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5) + # This validation happens now after parsing to pandas. + end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]) assert log_has(f'Missing data at end for pair ' f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}', caplog) From 416517b0c901f3438dcdc1af54fe5b32a77e38ba Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:47:04 +0100 Subject: [PATCH 0106/1106] Move trim_dataframe from history to converter --- freqtrade/data/converter.py | 19 ++++++++ .../data/datahandlers/jsondatahandler.py | 3 +- freqtrade/data/history.py | 26 ---------- freqtrade/optimize/backtesting.py | 3 +- freqtrade/optimize/hyperopt.py | 3 +- freqtrade/plot/plotting.py | 3 +- tests/data/test_converter.py | 47 ++++++++++++++++++- tests/data/test_history.py | 46 +----------------- 8 files changed, 73 insertions(+), 77 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 6b44a6b20..52ce3c593 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -2,10 +2,12 @@ Functions to convert data from one format to another """ import logging +from datetime import datetime, timezone import pandas as pd from pandas import DataFrame, to_datetime +from freqtrade.configuration.timerange import TimeRange logger = logging.getLogger(__name__) @@ -112,6 +114,23 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) return df +def trim_dataframe(df: DataFrame, timerange: TimeRange, df_date_col: str = 'date') -> DataFrame: + """ + Trim dataframe based on given timerange + :param df: Dataframe to trim + :param timerange: timerange (use start and end date if available) + :param: df_date_col: Column in the dataframe to use as Date column + :return: trimmed dataframe + """ + if timerange.starttype == 'date': + start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) + df = df.loc[df[df_date_col] >= start, :] + if timerange.stoptype == 'date': + stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc) + df = df.loc[df[df_date_col] <= stop, :] + return df + + def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: """ Gets order book list, returns dataframe with below format per suggested by creslin diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 2893393b1..c799784d0 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -7,8 +7,7 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange -from freqtrade.data.converter import clean_ohlcv_dataframe -from freqtrade.data.history import trim_dataframe +from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe from .idatahandler import IDataHandler diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index f09fe3d6a..cc82217a0 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -50,23 +50,6 @@ def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]: return tickerlist[start_index:stop_index] -def trim_dataframe(df: DataFrame, timerange: TimeRange, df_date_col: str = 'date') -> DataFrame: - """ - Trim dataframe based on given timerange - :param df: Dataframe to trim - :param timerange: timerange (use start and end date if available) - :param: df_date_col: Column in the dataframe to use as Date column - :return: trimmed dataframe - """ - if timerange.starttype == 'date': - start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) - df = df.loc[df[df_date_col] >= start, :] - if timerange.stoptype == 'date': - stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc) - df = df.loc[df[df_date_col] <= stop, :] - return df - - def load_tickerdata_file(datadir: Path, pair: str, timeframe: str, timerange: Optional[TimeRange] = None) -> List[Dict]: """ @@ -115,15 +98,6 @@ def store_trades_file(datadir: Path, pair: str, misc.file_dump_json(filename, data, is_zip=is_zip) -def _validate_pairdata(pair, pairdata, timerange: TimeRange): - if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000: - logger.warning('Missing data at start for pair %s, data starts at %s', - pair, arrow.get(pairdata[0][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) - if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000: - logger.warning('Missing data at end for pair %s, data ends at %s', - pair, arrow.get(pairdata[-1][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) - - def load_pair_history(pair: str, timeframe: str, datadir: Path, *, diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index a8fe90a06..98ee71a60 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -16,6 +16,7 @@ from freqtrade import OperationalException from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) from freqtrade.data import history +from freqtrade.data.converter import trim_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json @@ -482,7 +483,7 @@ class Backtesting: # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): - preprocessed[pair] = history.trim_dataframe(df, timerange) + preprocessed[pair] = trim_dataframe(df, timerange) min_date, max_date = history.get_timerange(preprocessed) logger.info( diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 48f883ac5..d29508b49 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -23,7 +23,8 @@ from joblib import (Parallel, cpu_count, delayed, dump, load, from pandas import DataFrame from freqtrade import OperationalException -from freqtrade.data.history import get_timerange, trim_dataframe +from freqtrade.data.history import get_timerange +from freqtrade.data.converter import trim_dataframe from freqtrade.misc import plural, round_dict from freqtrade.optimize.backtesting import Backtesting # Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index db4637ee5..0ef71ed82 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -5,6 +5,7 @@ from typing import Any, Dict, List import pandas as pd from freqtrade.configuration import TimeRange from freqtrade.data import history +from freqtrade.data.converter import trim_dataframe from freqtrade.data.btanalysis import (combine_tickers_with_mean, create_cum_profit, extract_trades_of_period, load_trades) @@ -47,7 +48,7 @@ def init_plotscript(config): db_url=config.get('db_url'), exportfilename=config.get('exportfilename'), ) - trades = history.trim_dataframe(trades, timerange, 'open_time') + trades = trim_dataframe(trades, timerange, 'open_time') return {"tickers": tickers, "trades": trades, "pairs": pairs, diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index 414551c95..eb8a8e513 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -1,8 +1,11 @@ # pragma pylint: disable=missing-docstring, C0103 import logging -from freqtrade.data.converter import parse_ticker_dataframe, ohlcv_fill_up_missing_data -from freqtrade.data.history import load_pair_history, validate_backtest_data, get_timerange +from freqtrade.configuration.timerange import TimeRange +from freqtrade.data.converter import (ohlcv_fill_up_missing_data, + parse_ticker_dataframe, trim_dataframe) +from freqtrade.data.history import (get_timerange, load_data, + load_pair_history, validate_backtest_data) from tests.conftest import log_has @@ -145,3 +148,43 @@ def test_ohlcv_drop_incomplete(caplog): assert len(data) == 3 assert log_has("Dropping last candle", caplog) + + +def test_trim_dataframe(testdatadir) -> None: + data = load_data( + datadir=testdatadir, + timeframe='1m', + pairs=['UNITTEST/BTC'] + )['UNITTEST/BTC'] + min_date = int(data.iloc[0]['date'].timestamp()) + max_date = int(data.iloc[-1]['date'].timestamp()) + data_modify = data.copy() + + # Remove first 30 minutes (1800 s) + tr = TimeRange('date', None, min_date + 1800, 0) + data_modify = trim_dataframe(data_modify, tr) + assert not data_modify.equals(data) + assert len(data_modify) < len(data) + assert len(data_modify) == len(data) - 30 + assert all(data_modify.iloc[-1] == data.iloc[-1]) + assert all(data_modify.iloc[0] == data.iloc[30]) + + data_modify = data.copy() + # Remove last 30 minutes (1800 s) + tr = TimeRange(None, 'date', 0, max_date - 1800) + data_modify = trim_dataframe(data_modify, tr) + assert not data_modify.equals(data) + assert len(data_modify) < len(data) + assert len(data_modify) == len(data) - 30 + assert all(data_modify.iloc[0] == data.iloc[0]) + assert all(data_modify.iloc[-1] == data.iloc[-31]) + + data_modify = data.copy() + # Remove first 25 and last 30 minutes (1800 s) + tr = TimeRange('date', 'date', min_date + 1500, max_date - 1800) + data_modify = trim_dataframe(data_modify, tr) + assert not data_modify.equals(data) + assert len(data_modify) < len(data) + assert len(data_modify) == len(data) - 55 + # first row matches 25th original row + assert all(data_modify.iloc[0] == data.iloc[25]) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index f13e386f8..5f7d0f5a2 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -18,10 +18,8 @@ from freqtrade.data.history import (_download_pair_history, load_tickerdata_file, pair_data_filename, pair_trades_filename, refresh_backtest_ohlcv_data, - refresh_backtest_trades_data, - refresh_data, - trim_dataframe, trim_tickerlist, - validate_backtest_data) + refresh_backtest_trades_data, refresh_data, + trim_tickerlist, validate_backtest_data) from freqtrade.exchange import timeframe_to_minutes from freqtrade.misc import file_dump_json from freqtrade.strategy.default_strategy import DefaultStrategy @@ -444,46 +442,6 @@ def test_trim_tickerlist(testdatadir) -> None: assert not ticker -def test_trim_dataframe(testdatadir) -> None: - data = load_data( - datadir=testdatadir, - timeframe='1m', - pairs=['UNITTEST/BTC'] - )['UNITTEST/BTC'] - min_date = int(data.iloc[0]['date'].timestamp()) - max_date = int(data.iloc[-1]['date'].timestamp()) - data_modify = data.copy() - - # Remove first 30 minutes (1800 s) - tr = TimeRange('date', None, min_date + 1800, 0) - data_modify = trim_dataframe(data_modify, tr) - assert not data_modify.equals(data) - assert len(data_modify) < len(data) - assert len(data_modify) == len(data) - 30 - assert all(data_modify.iloc[-1] == data.iloc[-1]) - assert all(data_modify.iloc[0] == data.iloc[30]) - - data_modify = data.copy() - # Remove last 30 minutes (1800 s) - tr = TimeRange(None, 'date', 0, max_date - 1800) - data_modify = trim_dataframe(data_modify, tr) - assert not data_modify.equals(data) - assert len(data_modify) < len(data) - assert len(data_modify) == len(data) - 30 - assert all(data_modify.iloc[0] == data.iloc[0]) - assert all(data_modify.iloc[-1] == data.iloc[-31]) - - data_modify = data.copy() - # Remove first 25 and last 30 minutes (1800 s) - tr = TimeRange('date', 'date', min_date + 1500, max_date - 1800) - data_modify = trim_dataframe(data_modify, tr) - assert not data_modify.equals(data) - assert len(data_modify) < len(data) - assert len(data_modify) == len(data) - 55 - # first row matches 25th original row - assert all(data_modify.iloc[0] == data.iloc[25]) - - def test_file_dump_json_tofile(testdatadir) -> None: file = testdatadir / 'test_{id}.json'.format(id=str(uuid.uuid4())) data = {'bar': 'foo'} From 5fca17d7e1fc89f30e90156d2fc88f954d9faf82 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 15:55:28 +0100 Subject: [PATCH 0107/1106] Allow initializing handler-class just once --- freqtrade/data/history.py | 40 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index cc82217a0..7c5cf482d 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -8,7 +8,7 @@ Includes: import logging import operator -from datetime import datetime, timezone +from datetime import datetime from pathlib import Path from typing import Any, Dict, List, Optional, Tuple @@ -18,6 +18,7 @@ from pandas import DataFrame from freqtrade import OperationalException, misc from freqtrade.configuration import TimeRange from freqtrade.data.converter import trades_to_ohlcv +from freqtrade.data.datahandlers.idatahandler import IDataHandler from freqtrade.exchange import Exchange, timeframe_to_minutes from .datahandlers import get_datahandlerclass @@ -105,7 +106,8 @@ def load_pair_history(pair: str, fill_up_missing: bool = True, drop_incomplete: bool = True, startup_candles: int = 0, - data_format: str = 'json' + data_format: str = 'json', + data_handler: IDataHandler, ) -> DataFrame: """ Load cached ticker history for the given pair. @@ -117,18 +119,21 @@ def load_pair_history(pair: str, :param fill_up_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. :param startup_candles: Additional candles to load at the start of the period - :param data_format: Format of the data + :param data_format: Format of the data. Ignored if data_handler is set. + :param data_handler: Initialized data-handler to use. + Will be initialized from data_format if not set :return: DataFrame with ohlcv data, or empty DataFrame """ - HandlerClass = get_datahandlerclass(data_format) - loader = HandlerClass(datadir) - return loader.ohlcv_load(pair=pair, - timeframe=timeframe, - timerange=timerange, - fill_missing=fill_up_missing, - drop_incomplete=drop_incomplete, - startup_candles=startup_candles, - ) + if not data_handler: + HandlerClass = get_datahandlerclass(data_format) + data_handler = HandlerClass(datadir) + return data_handler.ohlcv_load(pair=pair, + timeframe=timeframe, + timerange=timerange, + fill_missing=fill_up_missing, + drop_incomplete=drop_incomplete, + startup_candles=startup_candles, + ) def load_data(datadir: Path, @@ -137,7 +142,8 @@ def load_data(datadir: Path, timerange: Optional[TimeRange] = None, fill_up_missing: bool = True, startup_candles: int = 0, - fail_without_data: bool = False + fail_without_data: bool = False, + data_format: str = 'json', ) -> Dict[str, DataFrame]: """ Load ticker history data for a list of pairs. @@ -149,17 +155,23 @@ def load_data(datadir: Path, :param fill_up_missing: Fill missing values with "No action"-candles :param startup_candles: Additional candles to load at the start of the period :param fail_without_data: Raise OperationalException if no data is found. + :param data_handler: Initialized data-handler to use. :return: dict(:) """ result: Dict[str, DataFrame] = {} if startup_candles > 0 and timerange: logger.info(f'Using indicator startup period: {startup_candles} ...') + HandlerClass = get_datahandlerclass(data_format) + data_handler = HandlerClass(datadir) + for pair in pairs: hist = load_pair_history(pair=pair, timeframe=timeframe, datadir=datadir, timerange=timerange, fill_up_missing=fill_up_missing, - startup_candles=startup_candles) + startup_candles=startup_candles, + data_handler=data_handler + ) if not hist.empty: result[pair] = hist From 9547d47ae2f58bc416454bb0b5212c79da8845e5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 16:12:20 +0100 Subject: [PATCH 0108/1106] Initialize datahandlers --- freqtrade/data/datahandlers/__init__.py | 16 +++++++++++- freqtrade/data/history.py | 34 ++++++++++++++----------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/freqtrade/data/datahandlers/__init__.py b/freqtrade/data/datahandlers/__init__.py index b22b61417..a21dd832d 100644 --- a/freqtrade/data/datahandlers/__init__.py +++ b/freqtrade/data/datahandlers/__init__.py @@ -1,5 +1,5 @@ from typing import Type - +from pathlib import Path from .idatahandler import IDataHandler @@ -20,3 +20,17 @@ def get_datahandlerclass(datatype: str) -> Type[IDataHandler]: return JsonGzDataHandler else: raise ValueError(f"No datahandler for datatype {datatype} available.") + + +def get_datahandler(datadir: Path, data_format: str = None, + data_handler: IDataHandler = None) -> IDataHandler: + """ + :param datadir: Folder to save data + :data_format: dataformat to use + :data_handler: returns this datahandler if it exists or initializes a new one + """ + + if not data_handler: + HandlerClass = get_datahandlerclass(data_format or 'json') + data_handler = HandlerClass(datadir) + return data_handler diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 7c5cf482d..4f31ebd60 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -18,9 +18,9 @@ from pandas import DataFrame from freqtrade import OperationalException, misc from freqtrade.configuration import TimeRange from freqtrade.data.converter import trades_to_ohlcv +from freqtrade.data.datahandlers import get_datahandler, get_datahandlerclass from freqtrade.data.datahandlers.idatahandler import IDataHandler from freqtrade.exchange import Exchange, timeframe_to_minutes -from .datahandlers import get_datahandlerclass logger = logging.getLogger(__name__) @@ -106,8 +106,8 @@ def load_pair_history(pair: str, fill_up_missing: bool = True, drop_incomplete: bool = True, startup_candles: int = 0, - data_format: str = 'json', - data_handler: IDataHandler, + data_format: str = None, + data_handler: IDataHandler = None, ) -> DataFrame: """ Load cached ticker history for the given pair. @@ -115,18 +115,17 @@ def load_pair_history(pair: str, :param pair: Pair to load data for :param timeframe: Ticker timeframe (e.g. "5m") :param datadir: Path to the data storage location. + :param data_format: Format of the data. Ignored if data_handler is set. :param timerange: Limit data to be loaded to this timerange :param fill_up_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. :param startup_candles: Additional candles to load at the start of the period - :param data_format: Format of the data. Ignored if data_handler is set. :param data_handler: Initialized data-handler to use. Will be initialized from data_format if not set :return: DataFrame with ohlcv data, or empty DataFrame """ - if not data_handler: - HandlerClass = get_datahandlerclass(data_format) - data_handler = HandlerClass(datadir) + data_handler = get_datahandler(datadir, data_format, data_handler) + return data_handler.ohlcv_load(pair=pair, timeframe=timeframe, timerange=timerange, @@ -138,7 +137,7 @@ def load_pair_history(pair: str, def load_data(datadir: Path, timeframe: str, - pairs: List[str], + pairs: List[str], *, timerange: Optional[TimeRange] = None, fill_up_missing: bool = True, startup_candles: int = 0, @@ -162,8 +161,7 @@ def load_data(datadir: Path, if startup_candles > 0 and timerange: logger.info(f'Using indicator startup period: {startup_candles} ...') - HandlerClass = get_datahandlerclass(data_format) - data_handler = HandlerClass(datadir) + data_handler = get_datahandler(datadir, data_format) for pair in pairs: hist = load_pair_history(pair=pair, timeframe=timeframe, @@ -184,6 +182,7 @@ def refresh_data(datadir: Path, timeframe: str, pairs: List[str], exchange: Exchange, + data_format: str = None, timerange: Optional[TimeRange] = None, ) -> None: """ @@ -195,10 +194,11 @@ def refresh_data(datadir: Path, :param exchange: Exchange object :param timerange: Limit data to be loaded to this timerange """ + data_handler = get_datahandler(datadir, data_format) for pair in pairs: _download_pair_history(pair=pair, timeframe=timeframe, datadir=datadir, timerange=timerange, - exchange=exchange) + exchange=exchange, data_handler=data_handler) def pair_data_filename(datadir: Path, pair: str, timeframe: str) -> Path: @@ -256,9 +256,10 @@ def _load_cached_data_for_updating(datadir: Path, pair: str, timeframe: str, def _download_pair_history(datadir: Path, exchange: Exchange, - pair: str, + pair: str, *, timeframe: str = '5m', - timerange: Optional[TimeRange] = None) -> bool: + timerange: Optional[TimeRange] = None, + data_handler: IDataHandler = None) -> bool: """ Download latest candles from the exchange for the pair and timeframe passed in parameters The data is downloaded starting from the last correct data that @@ -272,6 +273,8 @@ def _download_pair_history(datadir: Path, :param timerange: range of time to download :return: bool with success state """ + data_handler = get_datahandler(datadir) + try: logger.info( f'Download history data for pair: "{pair}", timeframe: {timeframe} ' @@ -308,13 +311,14 @@ def _download_pair_history(datadir: Path, def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str], datadir: Path, timerange: Optional[TimeRange] = None, - erase=False) -> List[str]: + erase=False, data_format: str = None) -> List[str]: """ Refresh stored ohlcv data for backtesting and hyperopt operations. Used by freqtrade download-data subcommand. :return: List of pairs that are not available. """ pairs_not_available = [] + data_handler = get_datahandler(datadir, data_format) for pair in pairs: if pair not in exchange.markets: pairs_not_available.append(pair) @@ -331,7 +335,7 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes logger.info(f'Downloading pair {pair}, interval {timeframe}.') _download_pair_history(datadir=datadir, exchange=exchange, pair=pair, timeframe=str(timeframe), - timerange=timerange) + timerange=timerange, data_handler=data_handler) return pairs_not_available From 9876d126ca0add61c853a99a0a8a531445046dae Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 16:34:27 +0100 Subject: [PATCH 0109/1106] Use handler for trades --- freqtrade/data/converter.py | 9 ++++----- freqtrade/data/history.py | 38 ++++++++++++++++++------------------- tests/data/test_history.py | 7 ++++--- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 52ce3c593..09f7e3278 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -155,12 +155,12 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: return frame -def trades_to_ohlcv(trades: list, timeframe: str) -> list: +def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: """ Converts trades list to ohlcv list :param trades: List of trades, as returned by ccxt.fetch_trades. :param timeframe: Ticker timeframe to resample data to - :return: ohlcv timeframe as list (as returned by ccxt.fetch_ohlcv) + :return: ohlcv Dataframe. """ from freqtrade.exchange import timeframe_to_minutes ticker_minutes = timeframe_to_minutes(timeframe) @@ -170,8 +170,7 @@ def trades_to_ohlcv(trades: list, timeframe: str) -> list: df_new = df['price'].resample(f'{ticker_minutes}min').ohlc() df_new['volume'] = df['amount'].resample(f'{ticker_minutes}min').sum() - df_new['date'] = df_new.index.astype("int64") // 10 ** 6 + df_new['date'] = df_new.index # Drop 0 volume rows df_new = df_new.dropna() - columns = ["date", "open", "high", "low", "close", "volume"] - return list(zip(*[df_new[x].values.tolist() for x in columns])) + return df_new[['date', 'open', 'high', 'low', 'close', 'volume']] diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 4f31ebd60..1970f05d5 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -18,7 +18,7 @@ from pandas import DataFrame from freqtrade import OperationalException, misc from freqtrade.configuration import TimeRange from freqtrade.data.converter import trades_to_ohlcv -from freqtrade.data.datahandlers import get_datahandler, get_datahandlerclass +from freqtrade.data.datahandlers import get_datahandler from freqtrade.data.datahandlers.idatahandler import IDataHandler from freqtrade.exchange import Exchange, timeframe_to_minutes @@ -90,15 +90,6 @@ def load_trades_file(datadir: Path, pair: str, return tradesdata -def store_trades_file(datadir: Path, pair: str, - data: list, is_zip: bool = True): - """ - Stores tickerdata to file - """ - filename = pair_trades_filename(datadir, pair) - misc.file_dump_json(filename, data, is_zip=is_zip) - - def load_pair_history(pair: str, timeframe: str, datadir: Path, *, @@ -339,10 +330,11 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes return pairs_not_available -def _download_trades_history(datadir: Path, - exchange: Exchange, - pair: str, - timerange: Optional[TimeRange] = None) -> bool: +def _download_trades_history(exchange: Exchange, + pair: str, *, + timerange: Optional[TimeRange] = None, + data_handler: IDataHandler + ) -> bool: """ Download trade history from the exchange. Appends to previously downloaded trades data. @@ -351,7 +343,7 @@ def _download_trades_history(datadir: Path, since = timerange.startts * 1000 if timerange and timerange.starttype == 'date' else None - trades = load_trades_file(datadir, pair) + trades = data_handler.trades_load(pair) from_id = trades[-1]['id'] if trades else None @@ -366,7 +358,7 @@ def _download_trades_history(datadir: Path, from_id=from_id, ) trades.extend(new_trades[1]) - store_trades_file(datadir, pair, trades) + data_handler.trades_store(pair, data=trades) logger.debug("New Start: %s", trades[0]['datetime']) logger.debug("New End: %s", trades[-1]['datetime']) @@ -382,13 +374,15 @@ def _download_trades_history(datadir: Path, def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: Path, - timerange: TimeRange, erase=False) -> List[str]: + timerange: TimeRange, erase=False, + data_format: str = 'jsongz') -> List[str]: """ Refresh stored trades data for backtesting and hyperopt operations. Used by freqtrade download-data subcommand. :return: List of pairs that are not available. """ pairs_not_available = [] + data_handler = get_datahandler(datadir, data_format=data_format) for pair in pairs: if pair not in exchange.markets: pairs_not_available.append(pair) @@ -404,7 +398,8 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: logger.info(f'Downloading trades for pair {pair}.') _download_trades_history(datadir=datadir, exchange=exchange, pair=pair, - timerange=timerange) + timerange=timerange, + data_handler=data_handler) return pairs_not_available @@ -413,8 +408,11 @@ def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], """ Convert stored trades data to ohlcv data """ + data_handler_trades = get_datahandler(datadir, data_format='jsongz') + data_handler_ohlcv = get_datahandler(datadir, data_format='json') + for pair in pairs: - trades = load_trades_file(datadir, pair) + trades = data_handler_trades.trades_load(pair) for timeframe in timeframes: ohlcv_file = pair_data_filename(datadir, pair, timeframe) if erase and ohlcv_file.exists(): @@ -422,7 +420,7 @@ def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], ohlcv_file.unlink() ohlcv = trades_to_ohlcv(trades, timeframe) # Store ohlcv - store_tickerdata_file(datadir, pair, timeframe, data=ohlcv) + data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv) def get_timerange(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]: diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 5f7d0f5a2..77cb6a565 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -10,6 +10,7 @@ import arrow from pandas import DataFrame from freqtrade.configuration import TimeRange +from freqtrade.data.datahandlers import get_datahandler from freqtrade.data.history import (_download_pair_history, _download_trades_history, _load_cached_data_for_updating, @@ -597,12 +598,12 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad ght_mock) exchange = get_patched_exchange(mocker, default_conf) file1 = testdatadir / 'ETH_BTC-trades.json.gz' - + data_handler = get_datahandler(testdatadir, data_format='jsongz') _backup_file(file1) assert not file1.is_file() - assert _download_trades_history(datadir=testdatadir, exchange=exchange, + assert _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC') assert log_has("New Amount of trades: 5", caplog) assert file1.is_file() @@ -613,7 +614,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', MagicMock(side_effect=ValueError)) - assert not _download_trades_history(datadir=testdatadir, exchange=exchange, + assert not _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC') assert log_has_re('Failed to download historic trades for pair: "ETH/BTC".*', caplog) From b7c1d5549179ecd39f4e2c5b269b90df1e6a1be9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 16:41:52 +0100 Subject: [PATCH 0110/1106] Modify tests to point to datahandlers --- freqtrade/data/history.py | 20 -------------------- tests/data/test_history.py | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 1970f05d5..c83e91bac 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -76,20 +76,6 @@ def store_tickerdata_file(datadir: Path, pair: str, misc.file_dump_json(filename, data, is_zip=is_zip) -def load_trades_file(datadir: Path, pair: str, - timerange: Optional[TimeRange] = None) -> List[Dict]: - """ - Load a pair from file, either .json.gz or .json - :return: tradelist or empty list if unsuccesful - """ - filename = pair_trades_filename(datadir, pair) - tradesdata = misc.file_load_json(filename) - if not tradesdata: - return [] - - return tradesdata - - def load_pair_history(pair: str, timeframe: str, datadir: Path, *, @@ -198,12 +184,6 @@ def pair_data_filename(datadir: Path, pair: str, timeframe: str) -> Path: return filename -def pair_trades_filename(datadir: Path, pair: str) -> Path: - pair_s = pair.replace("/", "_") - filename = datadir.joinpath(f'{pair_s}-trades.json.gz') - return filename - - def _load_cached_data_for_updating(datadir: Path, pair: str, timeframe: str, timerange: Optional[TimeRange]) -> Tuple[List[Any], Optional[int]]: diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 77cb6a565..fef7a3149 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -11,13 +11,14 @@ from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.data.datahandlers import get_datahandler +from freqtrade.data.datahandlers.jsondatahandler import (JsonDataHandler, + JsonGzDataHandler) from freqtrade.data.history import (_download_pair_history, _download_trades_history, _load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange, load_data, load_pair_history, - load_tickerdata_file, pair_data_filename, - pair_trades_filename, + load_tickerdata_file, refresh_backtest_ohlcv_data, refresh_backtest_trades_data, refresh_data, trim_tickerlist, validate_backtest_data) @@ -143,14 +144,21 @@ def test_testdata_path(testdatadir) -> None: assert str(Path('tests') / 'testdata') in str(testdatadir) -def test_pair_data_filename(): - fn = pair_data_filename(Path('freqtrade/hello/world'), 'ETH/BTC', '5m') +def test_json_pair_data_filename(): + fn = JsonDataHandler._pair_data_filename(Path('freqtrade/hello/world'), 'ETH/BTC', '5m') assert isinstance(fn, Path) assert fn == Path('freqtrade/hello/world/ETH_BTC-5m.json') + fn = JsonGzDataHandler._pair_data_filename(Path('freqtrade/hello/world'), 'ETH/BTC', '5m') + assert isinstance(fn, Path) + assert fn == Path('freqtrade/hello/world/ETH_BTC-5m.json.gz') -def test_pair_trades_filename(): - fn = pair_trades_filename(Path('freqtrade/hello/world'), 'ETH/BTC') +def test_json_pair_trades_filename(): + fn = JsonDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), 'ETH/BTC') + assert isinstance(fn, Path) + assert fn == Path('freqtrade/hello/world/ETH_BTC-trades.json') + + fn = JsonGzDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), 'ETH/BTC') assert isinstance(fn, Path) assert fn == Path('freqtrade/hello/world/ETH_BTC-trades.json.gz') From 552c93abf08239108b5b64baec0d37618152a3a1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Dec 2019 19:53:52 +0100 Subject: [PATCH 0111/1106] Improve some docstrings --- .../data/datahandlers/jsondatahandler.py | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index c799784d0..0b6327017 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -20,7 +20,11 @@ class JsonDataHandler(IDataHandler): @classmethod def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: """ - Returns a list of all pairs available in this datadir + Returns a list of all pairs with ohlcv data available in this datadir + for the specified timeframe + :param datadir: Directory to search for ohlcv files + :param timeframe: Timeframe to search pairs for + :return: List of Pairs """ _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) @@ -56,7 +60,7 @@ class JsonDataHandler(IDataHandler): """ Internal method used to load data for one pair from disk. Implements the loading and conversation to a Pandas dataframe. - :param pair: Pair to load data for + :param pair: Pair to load data :param timeframe: Ticker timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange :param fill_missing: Fill missing values with "No action"-candles @@ -95,16 +99,20 @@ class JsonDataHandler(IDataHandler): @classmethod def trades_get_pairs(cls, datadir: Path) -> List[str]: """ - Returns a list of all pairs available in this datadir + Returns a list of all pairs for which trade data is available in this + :param datadir: Directory to search for ohlcv files + :return: List of Pairs """ _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] # Check if regex found something and only return these results to avoid exceptions. return [match[0].replace('_', '/') for match in _tmp if match] - def trades_store(self, pair: str, data: List[Dict]): + def trades_store(self, pair: str, data: List[Dict]) -> None: """ - Store data + Store trades data (list of Dicts) to file + :param pair: Pair - used for filename + :param data: List of Dicts containing trade data """ filename = self._pair_trades_filename(self._datadir, pair) misc.file_dump_json(filename, data, is_zip=self._use_zip) @@ -112,13 +120,17 @@ class JsonDataHandler(IDataHandler): def trades_append(self, pair: str, data: DataFrame): """ Append data to existing files + :param pair: Pair - used for filename + :param data: List of Dicts containing trade data """ raise NotImplementedError() def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> List[Dict]: """ Load a pair from file, either .json.gz or .json - # TODO: validate timerange ... + # TODO: respect timerange ... + :param pair: Load trades for this pair + :param timerange: Timerange to load trades for - currently not implemented :return: List of trades """ filename = self._pair_trades_filename(self._datadir, pair) From e861f05b75fd333d21ab63b57cbd189e405ff27f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Dec 2019 09:51:03 +0100 Subject: [PATCH 0112/1106] Move dataframe trim to within jsondatahandler --- freqtrade/data/datahandlers/idatahandler.py | 6 +----- .../data/datahandlers/jsondatahandler.py | 19 ++++++++++++++++++- freqtrade/data/history.py | 8 +++----- tests/data/test_history.py | 5 +++-- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index c28d03930..8e61829b6 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -55,11 +55,7 @@ class IDataHandler(ABC): f'No history data for pair: "{pair}", timeframe: {timeframe}. ' 'Use `freqtrade download-data` to download the data' ) - return pairdf - else: - if timerange_startup: - self._validate_pairdata(pair, pairdf, timerange_startup) - return pairdf + return pairdf def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange): """ diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 0b6327017..42fbaf51b 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -78,13 +78,18 @@ class JsonDataHandler(IDataHandler): utc=True, infer_datetime_format=True) + enddate = pairdata.iloc[-1]['date'] + if timerange: + self._validate_pairdata(pair, pairdata, timerange) pairdata = trim_dataframe(pairdata, timerange) + # incomplete candles should only be dropped if we didn't trim the end beforehand. return clean_ohlcv_dataframe(pairdata, timeframe, pair=pair, fill_missing=fill_missing, - drop_incomplete=drop_incomplete) + drop_incomplete=(drop_incomplete and + enddate == pairdata.iloc[-1]['date'])) def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: """ @@ -140,6 +145,18 @@ class JsonDataHandler(IDataHandler): return tradesdata + def trades_purge(self, pair: str) -> bool: + """ + Remove data for this pair + :param pair: Delete data for this pair. + :return: True when deleted, false if file did not exist. + """ + filename = self._pair_trades_filename(self._datadir, pair) + if filename.is_file(): + filename.unlink() + return True + return False + @classmethod def _pair_data_filename(cls, datadir: Path, pair: str, timeframe: str) -> Path: pair_s = pair.replace("/", "_") diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index c83e91bac..e71d9f36c 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -369,11 +369,9 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: logger.info(f"Skipping pair {pair}...") continue - dl_file = pair_trades_filename(datadir, pair) - if erase and dl_file.exists(): - logger.info( - f'Deleting existing data for pair {pair}.') - dl_file.unlink() + if erase: + if data_handler.trades_purge(pair): + logger.info(f'Deleting existing data for pair {pair}.') logger.info(f'Downloading trades for pair {pair}.') _download_trades_history(datadir=datadir, exchange=exchange, diff --git a/tests/data/test_history.py b/tests/data/test_history.py index fef7a3149..973c83a46 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -369,8 +369,9 @@ def test_load_partial_missing(testdatadir, caplog) -> None: # timedifference in 5 minutes td = ((end - start).total_seconds() // 60 // 5) + 1 assert td != len(tickerdata['UNITTEST/BTC']) - # This validation happens now after parsing to pandas. - end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]) + + # Shift endtime with +5 - as last candle is dropped (partial candle) + end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5) assert log_has(f'Missing data at end for pair ' f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}', caplog) From 37c5b689877958fbf80478e792e50b77d0183148 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Dec 2019 09:56:42 +0100 Subject: [PATCH 0113/1106] Move dataframe validation to abstract class --- freqtrade/data/datahandlers/idatahandler.py | 20 ++++++++++++---- .../data/datahandlers/jsondatahandler.py | 23 +++---------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index 8e61829b6..ebf399358 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -10,6 +10,7 @@ from pathlib import Path from typing import Dict, List, Optional from datetime import datetime, timezone from pandas import DataFrame +from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe from freqtrade.configuration import TimeRange from freqtrade.exchange import timeframe_to_seconds @@ -47,15 +48,26 @@ class IDataHandler(ABC): timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles) pairdf = self._ohlcv_load(pair, timeframe, - timerange=timerange_startup, - fill_missing=fill_missing, - drop_incomplete=drop_incomplete) + timerange=timerange_startup) if pairdf.empty: logger.warning( f'No history data for pair: "{pair}", timeframe: {timeframe}. ' 'Use `freqtrade download-data` to download the data' ) - return pairdf + return pairdf + else: + enddate = pairdf.iloc[-1]['date'] + + if timerange_startup: + self._validate_pairdata(pair, pairdf, timerange_startup) + pairdf = trim_dataframe(pairdf, timerange_startup) + + # incomplete candles should only be dropped if we didn't trim the end beforehand. + return clean_ohlcv_dataframe(pairdf, timeframe, + pair=pair, + fill_missing=fill_missing, + drop_incomplete=(drop_incomplete and + enddate == pairdf.iloc[-1]['date'])) def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange): """ diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 42fbaf51b..7d780a48d 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -7,7 +7,6 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange -from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe from .idatahandler import IDataHandler @@ -54,18 +53,14 @@ class JsonDataHandler(IDataHandler): def _ohlcv_load(self, pair: str, timeframe: str, timerange: Optional[TimeRange] = None, - fill_missing: bool = True, - drop_incomplete: bool = True, ) -> DataFrame: """ Internal method used to load data for one pair from disk. Implements the loading and conversation to a Pandas dataframe. + Timerange trimming and dataframe validation happens outside of this method. :param pair: Pair to load data :param timeframe: Ticker timeframe (e.g. "5m") - :param timerange: Limit data to be loaded to this timerange - :param fill_missing: Fill missing values with "No action"-candles - :param drop_incomplete: Drop last candle assuming it may be incomplete. - :param startup_candles: Additional candles to load at the start of the period + :param timerange: Limit data to be loaded to this timerange. :return: DataFrame with ohlcv data, or empty DataFrame """ filename = self._pair_data_filename(self._datadir, pair, timeframe) @@ -77,19 +72,7 @@ class JsonDataHandler(IDataHandler): unit='ms', utc=True, infer_datetime_format=True) - - enddate = pairdata.iloc[-1]['date'] - - if timerange: - self._validate_pairdata(pair, pairdata, timerange) - pairdata = trim_dataframe(pairdata, timerange) - - # incomplete candles should only be dropped if we didn't trim the end beforehand. - return clean_ohlcv_dataframe(pairdata, timeframe, - pair=pair, - fill_missing=fill_missing, - drop_incomplete=(drop_incomplete and - enddate == pairdata.iloc[-1]['date'])) + return pairdata def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: """ From 91c70a0e9c3d4299973fca60a3a922bf6f275307 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Dec 2019 10:22:38 +0100 Subject: [PATCH 0114/1106] Change to use ohlcv_purge --- freqtrade/data/datahandlers/jsondatahandler.py | 13 +++++++++++++ freqtrade/data/history.py | 9 ++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 7d780a48d..e76fee2b9 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -74,6 +74,19 @@ class JsonDataHandler(IDataHandler): infer_datetime_format=True) return pairdata + def ohlcv_purge(self, pair: str, timeframe: str) -> bool: + """ + Remove data for this pair + :param pair: Delete data for this pair. + :param timeframe: Ticker timeframe (e.g. "5m") + :return: True when deleted, false if file did not exist. + """ + filename = self._pair_data_filename(self._datadir, pair, timeframe) + if filename.is_file(): + filename.unlink() + return True + return False + def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: """ Append data to existing data structures diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index e71d9f36c..9347e7ee5 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -374,7 +374,7 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: logger.info(f'Deleting existing data for pair {pair}.') logger.info(f'Downloading trades for pair {pair}.') - _download_trades_history(datadir=datadir, exchange=exchange, + _download_trades_history(exchange=exchange, pair=pair, timerange=timerange, data_handler=data_handler) @@ -392,10 +392,9 @@ def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], for pair in pairs: trades = data_handler_trades.trades_load(pair) for timeframe in timeframes: - ohlcv_file = pair_data_filename(datadir, pair, timeframe) - if erase and ohlcv_file.exists(): - logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.') - ohlcv_file.unlink() + if erase: + if data_handler_ohlcv.ohlcv_purge(pair, timeframe): + logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.') ohlcv = trades_to_ohlcv(trades, timeframe) # Store ohlcv data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv) From dbe8f727cb1e58b3c5139e18e5df05cfe397d760 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Dec 2019 10:26:19 +0100 Subject: [PATCH 0115/1106] Fix typehint --- freqtrade/strategy/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4f2e990d2..74097286a 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -434,7 +434,7 @@ class IStrategy(ABC): else: return current_profit > roi - def tickerdata_to_dataframe(self, tickerdata: Dict[str, List]) -> Dict[str, DataFrame]: + def tickerdata_to_dataframe(self, tickerdata: Dict[str, DataFrame]) -> Dict[str, DataFrame]: """ Creates a dataframe and populates indicators for given ticker data Used by optimize operations only, not during dry / live runs. From b83487a70d32d71b3fea8998f619bfd984383887 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 26 Dec 2019 19:52:08 +0100 Subject: [PATCH 0116/1106] Extract default dataframe columns to constant --- freqtrade/constants.py | 1 + freqtrade/data/converter.py | 5 +++-- freqtrade/data/datahandlers/jsondatahandler.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 9c7e3db63..8d9cde98b 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -21,6 +21,7 @@ AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', 'PrecisionFilter', 'P AVAILABLE_DATAHANDLERS = ['json', 'jsongz'] DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons +DEFAULT_DATAFRAME_COLUMNS = ['date', 'open', 'high', 'low', 'close', 'volume'] USERPATH_HYPEROPTS = 'hyperopts' USERPATH_STRATEGY = 'strategies' diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 09f7e3278..41a843e36 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -8,6 +8,7 @@ import pandas as pd from pandas import DataFrame, to_datetime from freqtrade.configuration.timerange import TimeRange +from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS logger = logging.getLogger(__name__) @@ -26,7 +27,7 @@ def parse_ticker_dataframe(ticker: list, timeframe: str, pair: str, *, :return: DataFrame """ logger.debug("Parsing tickerlist to dataframe") - cols = ['date', 'open', 'high', 'low', 'close', 'volume'] + cols = DEFAULT_DATAFRAME_COLUMNS frame = DataFrame(ticker, columns=cols) frame['date'] = to_datetime(frame['date'], @@ -173,4 +174,4 @@ def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: df_new['date'] = df_new.index # Drop 0 volume rows df_new = df_new.dropna() - return df_new[['date', 'open', 'high', 'low', 'close', 'volume']] + return df_new[DEFAULT_DATAFRAME_COLUMNS] diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index e76fee2b9..1a26671b9 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -7,6 +7,7 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange +from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS from .idatahandler import IDataHandler @@ -14,7 +15,7 @@ from .idatahandler import IDataHandler class JsonDataHandler(IDataHandler): _use_zip = False - _columns = ['date', 'open', 'high', 'low', 'close', 'volume'] + _columns = DEFAULT_DATAFRAME_COLUMNS @classmethod def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: From ec8fb5f30894ef55fc388e7c6767e17d3c24d57b Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 06:58:29 +0100 Subject: [PATCH 0117/1106] Make no-data warning optional --- freqtrade/data/datahandlers/idatahandler.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/datahandlers/idatahandler.py index ebf399358..b80b8cfcc 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/datahandlers/idatahandler.py @@ -30,6 +30,7 @@ class IDataHandler(ABC): fill_missing: bool = True, drop_incomplete: bool = True, startup_candles: int = 0, + warn_no_data: bool = True ) -> DataFrame: """ Load cached ticker history for the given pair. @@ -40,6 +41,7 @@ class IDataHandler(ABC): :param fill_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. :param startup_candles: Additional candles to load at the start of the period + :param warn_no_data: Log a warning message when no data is found :return: DataFrame with ohlcv data, or empty DataFrame """ # Fix startup period @@ -50,10 +52,11 @@ class IDataHandler(ABC): pairdf = self._ohlcv_load(pair, timeframe, timerange=timerange_startup) if pairdf.empty: - logger.warning( - f'No history data for pair: "{pair}", timeframe: {timeframe}. ' - 'Use `freqtrade download-data` to download the data' - ) + if warn_no_data: + logger.warning( + f'No history data for pair: "{pair}", timeframe: {timeframe}. ' + 'Use `freqtrade download-data` to download the data' + ) return pairdf else: enddate = pairdf.iloc[-1]['date'] From c648d973c18015270d9196c3d9abc73eed09b13b Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 06:58:50 +0100 Subject: [PATCH 0118/1106] Implement new "load_data_for_updating" method based on dataframes --- freqtrade/data/history.py | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 9347e7ee5..80a846e87 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -8,7 +8,7 @@ Includes: import logging import operator -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path from typing import Any, Dict, List, Optional, Tuple @@ -17,7 +17,8 @@ from pandas import DataFrame from freqtrade import OperationalException, misc from freqtrade.configuration import TimeRange -from freqtrade.data.converter import trades_to_ohlcv +from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS +from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv from freqtrade.data.datahandlers import get_datahandler from freqtrade.data.datahandlers.idatahandler import IDataHandler from freqtrade.exchange import Exchange, timeframe_to_minutes @@ -184,9 +185,9 @@ def pair_data_filename(datadir: Path, pair: str, timeframe: str) -> Path: return filename -def _load_cached_data_for_updating(datadir: Path, pair: str, timeframe: str, - timerange: Optional[TimeRange]) -> Tuple[List[Any], - Optional[int]]: +def _load_cached_data_for_updating_old(datadir: Path, pair: str, timeframe: str, + timerange: Optional[TimeRange]) -> Tuple[List[Any], + Optional[int]]: """ Load cached data to download more data. If timerange is passed in, checks whether data from an before the stored data will be @@ -225,6 +226,27 @@ def _load_cached_data_for_updating(datadir: Path, pair: str, timeframe: str, return (data, since_ms) +def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange], + data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]: + start = None + if timerange: + if timerange.starttype == 'date': + # TODO: convert to date for conversation + start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) + + # Intentionally don't pass timerange in - since we need to load the full dataset. + data = data_handler.ohlcv_load(pair, timeframe=timeframe, + timerange=None, fill_missing=False, + drop_incomplete=True, warn_no_data=False) + if not data.empty: + if start < data.iloc[0]['date']: + # Earlier data than existing data requested, redownload all + return DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS), None + start = data.iloc[-1]['date'] + start_ms = int(start.timestamp() * 1000) if start else None + return data, start_ms + + def _download_pair_history(datadir: Path, exchange: Exchange, pair: str, *, @@ -252,10 +274,14 @@ def _download_pair_history(datadir: Path, f'and store in {datadir}.' ) - data, since_ms = _load_cached_data_for_updating(datadir, pair, timeframe, timerange) + # data, since_ms = _load_cached_data_for_updating_old(datadir, pair, timeframe, timerange) + data, since_ms = _load_cached_data_for_updating(pair, timeframe, timerange, + data_handler=data_handler) - logger.debug("Current Start: %s", misc.format_ms_time(data[1][0]) if data else 'None') - logger.debug("Current End: %s", misc.format_ms_time(data[-1][0]) if data else 'None') + logger.debug("Current Start: %s", + f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') + logger.debug("Current End: %s", + f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') # Default since_ms to 30 days if nothing is given new_data = exchange.get_historic_ohlcv(pair=pair, @@ -264,12 +290,20 @@ def _download_pair_history(datadir: Path, int(arrow.utcnow().shift( days=-30).float_timestamp) * 1000 ) - data.extend(new_data) + # TODO: Maybe move parsing to exchange class (?) + new_dataframe = parse_ticker_dataframe(new_data, timeframe, pair, + fill_missing=False, drop_incomplete=True) + if data.empty: + data = new_dataframe + else: + data = data.append(new_dataframe) - logger.debug("New Start: %s", misc.format_ms_time(data[0][0])) - logger.debug("New End: %s", misc.format_ms_time(data[-1][0])) + logger.debug("New Start: %s", + f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') + logger.debug("New End: %s", + f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') - store_tickerdata_file(datadir, pair, timeframe, data=data) + data_handler.ohlcv_store(pair, timeframe, data=data) return True except Exception as e: From df085a6f1560d00f90dcbc69e16ff4ce9e021473 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 07:07:27 +0100 Subject: [PATCH 0119/1106] Fix small bug and test --- freqtrade/data/history.py | 4 +++- tests/data/test_history.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 80a846e87..189f51594 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -239,10 +239,12 @@ def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optiona timerange=None, fill_missing=False, drop_incomplete=True, warn_no_data=False) if not data.empty: - if start < data.iloc[0]['date']: + if start and start < data.iloc[0]['date']: # Earlier data than existing data requested, redownload all return DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS), None + start = data.iloc[-1]['date'] + start_ms = int(start.timestamp() * 1000) if start else None return data, start_ms diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 973c83a46..c626e27e8 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -301,7 +301,9 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None: [1509836520000, 0.00162008, 0.00162008, 0.00162008, 0.00162008, 108.14853839], [1509836580000, 0.00161, 0.00161, 0.00161, 0.00161, 82.390199] ] - json_dump_mock = mocker.patch('freqtrade.misc.file_dump_json', return_value=None) + json_dump_mock = mocker.patch( + 'freqtrade.data.datahandlers.jsondatahandler.JsonDataHandler.ohlcv_store', + return_value=None) mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=tick) exchange = get_patched_exchange(mocker, default_conf) _download_pair_history(testdatadir, exchange, pair="UNITTEST/BTC", timeframe='1m') From e4f185f3579fe60e497c3efc5a416f45c2ad0d67 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 07:08:50 +0100 Subject: [PATCH 0120/1106] Remove 'line' from load_cached_data tests Users are unable to use line anyway, it's only there for tests --- tests/data/test_history.py | 38 ------------------------------ tests/optimize/test_backtesting.py | 1 - 2 files changed, 39 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index c626e27e8..4281eee8c 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -171,7 +171,6 @@ def test_load_cached_data_for_updating(mocker) -> None: with open(test_filename, "rt") as file: test_data = json.load(file) - # change now time to test 'line' cases # now = last cached item + 1 hour now_ts = test_data[-1][0] / 1000 + 60 * 60 mocker.patch('arrow.utcnow', return_value=arrow.get(now_ts)) @@ -183,13 +182,6 @@ def test_load_cached_data_for_updating(mocker) -> None: assert data == [] assert start_ts == test_data[0][0] - 1000 - # same with 'line' timeframe - num_lines = (test_data[-1][0] - test_data[1][0]) / 1000 / 60 + 120 - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', - TimeRange(None, 'line', 0, -num_lines)) - assert data == [] - assert start_ts < test_data[0][0] - 1 - # timeframe starts in the center of the cached data # should return the chached data w/o the last item timerange = TimeRange('date', None, test_data[0][0] / 1000 + 1, 0) @@ -197,13 +189,6 @@ def test_load_cached_data_for_updating(mocker) -> None: assert data == test_data[:-1] assert test_data[-2][0] < start_ts < test_data[-1][0] - # same with 'line' timeframe - num_lines = (test_data[-1][0] - test_data[1][0]) / 1000 / 60 + 30 - timerange = TimeRange(None, 'line', 0, -num_lines) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == test_data[:-1] - assert test_data[-2][0] < start_ts < test_data[-1][0] - # timeframe starts after the chached data # should return the chached data w/o the last item timerange = TimeRange('date', None, test_data[-1][0] / 1000 + 1, 0) @@ -211,22 +196,6 @@ def test_load_cached_data_for_updating(mocker) -> None: assert data == test_data[:-1] assert test_data[-2][0] < start_ts < test_data[-1][0] - # Try loading last 30 lines. - # Not supported by _load_cached_data_for_updating, we always need to get the full data. - num_lines = 30 - timerange = TimeRange(None, 'line', 0, -num_lines) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == test_data[:-1] - assert test_data[-2][0] < start_ts < test_data[-1][0] - - # no timeframe is set - # should return the chached data w/o the last item - num_lines = 30 - timerange = TimeRange(None, 'line', 0, -num_lines) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == test_data[:-1] - assert test_data[-2][0] < start_ts < test_data[-1][0] - # no datafile exist # should return timestamp start time timerange = TimeRange('date', None, now_ts - 10000, 0) @@ -234,13 +203,6 @@ def test_load_cached_data_for_updating(mocker) -> None: assert data == [] assert start_ts == (now_ts - 10000) * 1000 - # same with 'line' timeframe - num_lines = 30 - timerange = TimeRange(None, 'line', 0, -num_lines) - data, start_ts = _load_cached_data_for_updating(datadir, 'NONEXIST/BTC', '1m', timerange) - assert data == [] - assert start_ts == (now_ts - num_lines * 60) * 1000 - # no datafile exist, no timeframe is set # should return an empty array and None data, start_ts = _load_cached_data_for_updating(datadir, 'NONEXIST/BTC', '1m', None) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 8a27c591f..c4670a331 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -342,7 +342,6 @@ def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None: def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: patch_exchange(mocker) - # timerange = TimeRange(None, 'line', 0, -100) timerange = TimeRange.parse_timerange('1510694220-1510700340') tick = history.load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m', timerange=timerange) tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", From 7a6476c9ba979efb37d73ec2856e15e01b9e7535 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:11:49 +0100 Subject: [PATCH 0121/1106] Update tests --- freqtrade/data/history.py | 6 +++--- tests/data/test_history.py | 38 ++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 189f51594..99dde67c1 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -241,9 +241,9 @@ def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optiona if not data.empty: if start and start < data.iloc[0]['date']: # Earlier data than existing data requested, redownload all - return DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS), None - - start = data.iloc[-1]['date'] + data = DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS) + else: + start = data.iloc[-1]['date'] start_ms = int(start.timestamp() * 1000) if start else None return data, start_ms diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 4281eee8c..12c6d3630 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -8,8 +8,10 @@ from unittest.mock import MagicMock, PropertyMock import arrow from pandas import DataFrame +from pandas.testing import assert_frame_equal from freqtrade.configuration import TimeRange +from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.datahandlers import get_datahandler from freqtrade.data.datahandlers.jsondatahandler import (JsonDataHandler, JsonGzDataHandler) @@ -163,14 +165,17 @@ def test_json_pair_trades_filename(): assert fn == Path('freqtrade/hello/world/ETH_BTC-trades.json.gz') -def test_load_cached_data_for_updating(mocker) -> None: - datadir = Path(__file__).parent.parent.joinpath('testdata') +def test_load_cached_data_for_updating(mocker, testdatadir) -> None: + + data_handler = get_datahandler(testdatadir, 'json') test_data = None - test_filename = datadir.joinpath('UNITTEST_BTC-1m.json') + test_filename = testdatadir.joinpath('UNITTEST_BTC-1m.json') with open(test_filename, "rt") as file: test_data = json.load(file) + test_data_df = parse_ticker_dataframe(test_data, '1m', 'UNITTEST/BTC', + fill_missing=False, drop_incomplete=False) # now = last cached item + 1 hour now_ts = test_data[-1][0] / 1000 + 60 * 60 mocker.patch('arrow.utcnow', return_value=arrow.get(now_ts)) @@ -178,35 +183,36 @@ def test_load_cached_data_for_updating(mocker) -> None: # timeframe starts earlier than the cached data # should fully update data timerange = TimeRange('date', None, test_data[0][0] / 1000 - 1, 0) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == [] + data, start_ts = _load_cached_data_for_updating('UNITTEST/BTC', '1m', timerange, data_handler) + assert data.empty assert start_ts == test_data[0][0] - 1000 # timeframe starts in the center of the cached data # should return the chached data w/o the last item timerange = TimeRange('date', None, test_data[0][0] / 1000 + 1, 0) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == test_data[:-1] - assert test_data[-2][0] < start_ts < test_data[-1][0] + data, start_ts = _load_cached_data_for_updating('UNITTEST/BTC', '1m', timerange, data_handler) + + assert_frame_equal(data, test_data_df.iloc[:-1]) + assert test_data[-2][0] <= start_ts < test_data[-1][0] # timeframe starts after the chached data # should return the chached data w/o the last item - timerange = TimeRange('date', None, test_data[-1][0] / 1000 + 1, 0) - data, start_ts = _load_cached_data_for_updating(datadir, 'UNITTEST/BTC', '1m', timerange) - assert data == test_data[:-1] - assert test_data[-2][0] < start_ts < test_data[-1][0] + timerange = TimeRange('date', None, test_data[-1][0] / 1000 + 100, 0) + data, start_ts = _load_cached_data_for_updating('UNITTEST/BTC', '1m', timerange, data_handler) + assert_frame_equal(data, test_data_df.iloc[:-1]) + assert test_data[-2][0] <= start_ts < test_data[-1][0] # no datafile exist # should return timestamp start time timerange = TimeRange('date', None, now_ts - 10000, 0) - data, start_ts = _load_cached_data_for_updating(datadir, 'NONEXIST/BTC', '1m', timerange) - assert data == [] + data, start_ts = _load_cached_data_for_updating('NONEXIST/BTC', '1m', timerange, data_handler) + assert data.empty assert start_ts == (now_ts - 10000) * 1000 # no datafile exist, no timeframe is set # should return an empty array and None - data, start_ts = _load_cached_data_for_updating(datadir, 'NONEXIST/BTC', '1m', None) - assert data == [] + data, start_ts = _load_cached_data_for_updating('NONEXIST/BTC', '1m', None, data_handler) + assert data.empty assert start_ts is None From d06777b8ce4021d0e378765f0bb484ecff567b87 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:12:56 +0100 Subject: [PATCH 0122/1106] Remove old "load_cached_data" method --- freqtrade/data/history.py | 41 ++++----------------------------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 99dde67c1..93fe635a2 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -185,49 +185,16 @@ def pair_data_filename(datadir: Path, pair: str, timeframe: str) -> Path: return filename -def _load_cached_data_for_updating_old(datadir: Path, pair: str, timeframe: str, - timerange: Optional[TimeRange]) -> Tuple[List[Any], - Optional[int]]: +def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange], + data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]: """ Load cached data to download more data. If timerange is passed in, checks whether data from an before the stored data will be downloaded. If that's the case then what's available should be completely overwritten. - Only used by download_pair_history(). + Otherwise downloads always start at the end of the available data to avoid data gaps. + Note: Only used by download_pair_history(). """ - - since_ms = None - - # user sets timerange, so find the start time - if timerange: - if timerange.starttype == 'date': - since_ms = timerange.startts * 1000 - elif timerange.stoptype == 'line': - num_minutes = timerange.stopts * timeframe_to_minutes(timeframe) - since_ms = arrow.utcnow().shift(minutes=num_minutes).timestamp * 1000 - - # read the cached file - # Intentionally don't pass timerange in - since we need to load the full dataset. - data = load_tickerdata_file(datadir, pair, timeframe) - # remove the last item, could be incomplete candle - if data: - data.pop() - else: - data = [] - - if data: - if since_ms and since_ms < data[0][0]: - # Earlier data than existing data requested, redownload all - data = [] - else: - # a part of the data was already downloaded, so download unexist data only - since_ms = data[-1][0] + 1 - - return (data, since_ms) - - -def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange], - data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]: start = None if timerange: if timerange.starttype == 'date': From d1b52809ac79370023a47db66ee6474ee3b5ca9d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:25:17 +0100 Subject: [PATCH 0123/1106] Cleanup history --- freqtrade/data/history.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 93fe635a2..59695da2e 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -10,7 +10,7 @@ import logging import operator from datetime import datetime, timezone from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple +from typing import Dict, List, Optional, Tuple import arrow from pandas import DataFrame @@ -21,7 +21,7 @@ from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv from freqtrade.data.datahandlers import get_datahandler from freqtrade.data.datahandlers.idatahandler import IDataHandler -from freqtrade.exchange import Exchange, timeframe_to_minutes +from freqtrade.exchange import Exchange logger = logging.getLogger(__name__) @@ -68,15 +68,6 @@ def load_tickerdata_file(datadir: Path, pair: str, timeframe: str, return pairdata -def store_tickerdata_file(datadir: Path, pair: str, - timeframe: str, data: list, is_zip: bool = False): - """ - Stores tickerdata to file - """ - filename = pair_data_filename(datadir, pair, timeframe) - misc.file_dump_json(filename, data, is_zip=is_zip) - - def load_pair_history(pair: str, timeframe: str, datadir: Path, *, From a2567bea645c2d124423c2a7d4ff71f6c21a4abf Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:25:27 +0100 Subject: [PATCH 0124/1106] Remove unnecessary mock --- tests/optimize/test_backtesting.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index c4670a331..3b7b18f52 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -116,14 +116,6 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None: assert len(results) == num_results -def mocked_load_data(datadir, pairs=[], timeframe='0m', - timerange=None, *args, **kwargs): - tickerdata = history.load_tickerdata_file(datadir, 'UNITTEST/BTC', '1m', timerange=timerange) - pairdata = {'UNITTEST/BTC': parse_ticker_dataframe(tickerdata, '1m', pair="UNITTEST/BTC", - fill_missing=True)} - return pairdata - - # use for mock ccxt.fetch_ohlvc' def _load_pair_as_ticks(pair, tickfreq): ticks = history.load_tickerdata_file(None, timeframe=tickfreq, pair=pair) @@ -460,7 +452,6 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: def get_timerange(input1): return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) - mocker.patch('freqtrade.data.history.load_data', mocked_load_data) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) From aa39f2160bf095b1edecabc3243b72eed952cb69 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:25:38 +0100 Subject: [PATCH 0125/1106] Use load_data instead of a sequence of calls in tests which don't test this --- tests/optimize/test_hyperopt.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index fb492be35..ddafabe71 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -10,8 +10,7 @@ from arrow import Arrow from filelock import Timeout from freqtrade import OperationalException -from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.history import load_tickerdata_file +from freqtrade.data.history import load_data from freqtrade.optimize import setup_configuration, start_hyperopt from freqtrade.optimize.default_hyperopt import DefaultHyperOpt from freqtrade.optimize.default_hyperopt_loss import DefaultHyperOptLoss @@ -543,9 +542,7 @@ def test_has_space(hyperopt, spaces, expected_results): def test_populate_indicators(hyperopt, testdatadir) -> None: - tick = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m') - tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", - fill_missing=True)} + tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist) dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'}) @@ -557,9 +554,7 @@ def test_populate_indicators(hyperopt, testdatadir) -> None: def test_buy_strategy_generator(hyperopt, testdatadir) -> None: - tick = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m') - tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", - fill_missing=True)} + tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist) dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'}) From 80dbba12801fbf7f030600de18d88d30c70a3014 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:29:06 +0100 Subject: [PATCH 0126/1106] Remove unnecessary mocks --- tests/optimize/test_backtesting.py | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 3b7b18f52..a10ce5254 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -116,13 +116,6 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None: assert len(results) == num_results -# use for mock ccxt.fetch_ohlvc' -def _load_pair_as_ticks(pair, tickfreq): - ticks = history.load_tickerdata_file(None, timeframe=tickfreq, pair=pair) - ticks = ticks[-201:] - return ticks - - # FIX: fixturize this? def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC', record=None): data = history.load_data(datadir=datadir, timeframe='1m', pairs=[pair]) @@ -795,13 +788,7 @@ def test_backtest_record(default_conf, fee, mocker): def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] - async def load_pairs(pair, timeframe, since): - return _load_pair_as_ticks(pair, timeframe) - - api_mock = MagicMock() - api_mock.fetch_ohlcv = load_pairs - - patch_exchange(mocker, api_mock) + patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock()) patched_configuration_load_config_file(mocker, default_conf) @@ -840,12 +827,7 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] - async def load_pairs(pair, timeframe, since): - return _load_pair_as_ticks(pair, timeframe) - api_mock = MagicMock() - api_mock.fetch_ohlcv = load_pairs - - patch_exchange(mocker, api_mock) + patch_exchange(mocker) backtestmock = MagicMock() mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) gen_table_mock = MagicMock() From 5479c6717833ffff66a165b835ff20863f44ad48 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:40:14 +0100 Subject: [PATCH 0127/1106] Clean up some codes which use list-based tests --- tests/optimize/test_backtesting.py | 65 +++++++++++------------------- 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index a10ce5254..447f0052b 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -1,6 +1,5 @@ # pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument -import math import random from pathlib import Path from unittest.mock import MagicMock @@ -14,7 +13,7 @@ from freqtrade import DependencyException, OperationalException, constants from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import evaluate_result_multi -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import clean_ohlcv_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.optimize import setup_configuration, start_backtesting @@ -50,47 +49,33 @@ def trim_dictlist(dict_list, num): def load_data_test(what, testdatadir): timerange = TimeRange.parse_timerange('1510694220-1510700340') - pair = history.load_tickerdata_file(testdatadir, timeframe='1m', - pair='UNITTEST/BTC', timerange=timerange) - datalen = len(pair) + data = history.load_pair_history(pair='UNITTEST/BTC', datadir=testdatadir, + timeframe='1m', timerange=timerange, + drop_incomplete=False, + fill_up_missing=False) base = 0.001 if what == 'raise': - data = [ - [ - pair[x][0], # Keep old dates - x * base, # But replace O,H,L,C - x * base + 0.0001, - x * base - 0.0001, - x * base, - pair[x][5], # Keep old volume - ] for x in range(0, datalen) - ] + data.loc[:, 'open'] = data.index * base + data.loc[:, 'high'] = data.index * base + 0.0001 + data.loc[:, 'low'] = data.index * base - 0.0001 + data.loc[:, 'close'] = data.index * base + if what == 'lower': - data = [ - [ - pair[x][0], # Keep old dates - 1 - x * base, # But replace O,H,L,C - 1 - x * base + 0.0001, - 1 - x * base - 0.0001, - 1 - x * base, - pair[x][5] # Keep old volume - ] for x in range(0, datalen) - ] + data.loc[:, 'open'] = 1 - data.index * base + data.loc[:, 'high'] = 1 - data.index * base + 0.0001 + data.loc[:, 'low'] = 1 - data.index * base - 0.0001 + data.loc[:, 'close'] = 1 - data.index * base + if what == 'sine': hz = 0.1 # frequency - data = [ - [ - pair[x][0], # Keep old dates - math.sin(x * hz) / 1000 + base, # But replace O,H,L,C - math.sin(x * hz) / 1000 + base + 0.0001, - math.sin(x * hz) / 1000 + base - 0.0001, - math.sin(x * hz) / 1000 + base, - pair[x][5] # Keep old volume - ] for x in range(0, datalen) - ] - return {'UNITTEST/BTC': parse_ticker_dataframe(data, '1m', pair="UNITTEST/BTC", - fill_missing=True)} + data.loc[:, 'open'] = np.sin(data.index * hz) / 1000 + base + data.loc[:, 'high'] = np.sin(data.index * hz) / 1000 + base + 0.0001 + data.loc[:, 'low'] = np.sin(data.index * hz) / 1000 + base - 0.0001 + data.loc[:, 'close'] = np.sin(data.index * hz) / 1000 + base + + return {'UNITTEST/BTC': clean_ohlcv_dataframe(data, timeframe='1m', pair='UNITTEST/BTC', + fill_missing=True)} def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None: @@ -328,10 +313,8 @@ def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None: def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: patch_exchange(mocker) timerange = TimeRange.parse_timerange('1510694220-1510700340') - tick = history.load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m', timerange=timerange) - tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", - fill_missing=True)} - + tickerlist = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) backtesting = Backtesting(default_conf) data = backtesting.strategy.tickerdata_to_dataframe(tickerlist) assert len(data['UNITTEST/BTC']) == 102 From 4b277afc52c3ffbcfd668deac649e39515f3b428 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:41:19 +0100 Subject: [PATCH 0128/1106] Remove test for load_tickerdata --- tests/data/test_history.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 12c6d3630..969e58223 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -20,7 +20,6 @@ from freqtrade.data.history import (_download_pair_history, _load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange, load_data, load_pair_history, - load_tickerdata_file, refresh_backtest_ohlcv_data, refresh_backtest_trades_data, refresh_data, trim_tickerlist, validate_backtest_data) @@ -303,17 +302,6 @@ def test_download_backtesting_data_exception(ticker_history, mocker, caplog, ) -def test_load_tickerdata_file(testdatadir) -> None: - # 7 does not exist in either format. - assert not load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '7m') - # 1 exists only as a .json - tickerdata = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m') - assert _BTC_UNITTEST_LENGTH == len(tickerdata) - # 8 .json is empty and will fail if it's loaded. .json.gz is a copy of 1.json - tickerdata = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '8m') - assert _BTC_UNITTEST_LENGTH == len(tickerdata) - - def test_load_partial_missing(testdatadir, caplog) -> None: # Make sure we start fresh - test missing data at start start = arrow.get('2018-01-01T00:00:00') From 32c2ce146ebcbea093e32f66de3bedfcd0b28f01 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:44:08 +0100 Subject: [PATCH 0129/1106] Remove last usage of load_tickerlist --- tests/strategy/test_interface.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 89c38bda1..647344653 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -7,8 +7,7 @@ import arrow from pandas import DataFrame from freqtrade.configuration import TimeRange -from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.history import load_tickerdata_file +from freqtrade.data.history import load_data from freqtrade.persistence import Trade from tests.conftest import get_patched_exchange, log_has from freqtrade.strategy.default_strategy import DefaultStrategy @@ -107,9 +106,8 @@ def test_tickerdata_to_dataframe(default_conf, testdatadir) -> None: strategy = DefaultStrategy(default_conf) timerange = TimeRange.parse_timerange('1510694220-1510700340') - tick = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m', timerange=timerange) - tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", - fill_missing=True)} + tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) data = strategy.tickerdata_to_dataframe(tickerlist) assert len(data['UNITTEST/BTC']) == 102 # partial candle was removed From baa942ff989adb86c35228454887cd624d38a6c1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:49:01 +0100 Subject: [PATCH 0130/1106] Don't use function to resolve pairname for test --- tests/test_misc.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 23231e2f0..c5bf06311 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -5,7 +5,6 @@ from pathlib import Path from unittest.mock import MagicMock from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.history import pair_data_filename from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, file_load_json, format_ms_time, plural, shorten_date) @@ -48,13 +47,13 @@ def test_file_dump_json(mocker) -> None: def test_file_load_json(mocker, testdatadir) -> None: # 7m .json does not exist - ret = file_load_json(pair_data_filename(testdatadir, 'UNITTEST/BTC', '7m')) + ret = file_load_json(testdatadir / 'UNITTEST_BTC-7m.json') assert not ret # 1m json exists (but no .gz exists) - ret = file_load_json(pair_data_filename(testdatadir, 'UNITTEST/BTC', '1m')) + ret = file_load_json(testdatadir / 'UNITTEST_BTC-1m.json') assert ret # 8 .json is empty and will fail if it's loaded. .json.gz is a copy of 1.json - ret = file_load_json(pair_data_filename(testdatadir, 'UNITTEST/BTC', '8m')) + ret = file_load_json(testdatadir / 'UNITTEST_BTC-8m.json') assert ret From a3144cb2f0c07c777f566326f0df9246dfbc36d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 10:49:30 +0100 Subject: [PATCH 0131/1106] remove trim_tickerlist --- freqtrade/data/history.py | 59 ++++---------------------------------- tests/data/test_history.py | 54 +--------------------------------- 2 files changed, 6 insertions(+), 107 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 59695da2e..9dad90864 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -15,7 +15,7 @@ from typing import Dict, List, Optional, Tuple import arrow from pandas import DataFrame -from freqtrade import OperationalException, misc +from freqtrade import OperationalException from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv @@ -26,48 +26,6 @@ from freqtrade.exchange import Exchange logger = logging.getLogger(__name__) -def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]: - """ - Trim tickerlist based on given timerange - """ - if not tickerlist: - return tickerlist - - start_index = 0 - stop_index = len(tickerlist) - - if timerange.starttype == 'date': - while (start_index < len(tickerlist) and - tickerlist[start_index][0] < timerange.startts * 1000): - start_index += 1 - - if timerange.stoptype == 'date': - while (stop_index > 0 and - tickerlist[stop_index-1][0] > timerange.stopts * 1000): - stop_index -= 1 - - if start_index > stop_index: - raise ValueError(f'The timerange [{timerange.startts},{timerange.stopts}] is incorrect') - - return tickerlist[start_index:stop_index] - - -def load_tickerdata_file(datadir: Path, pair: str, timeframe: str, - timerange: Optional[TimeRange] = None) -> List[Dict]: - """ - Load a pair from file, either .json.gz or .json - :return: tickerlist or None if unsuccessful - """ - filename = pair_data_filename(datadir, pair, timeframe) - pairdata = misc.file_load_json(filename) - if not pairdata: - return [] - - if timerange: - pairdata = trim_tickerlist(pairdata, timerange) - return pairdata - - def load_pair_history(pair: str, timeframe: str, datadir: Path, *, @@ -170,12 +128,6 @@ def refresh_data(datadir: Path, exchange=exchange, data_handler=data_handler) -def pair_data_filename(datadir: Path, pair: str, timeframe: str) -> Path: - pair_s = pair.replace("/", "_") - filename = datadir.joinpath(f'{pair_s}-{timeframe}.json') - return filename - - def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange], data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]: """ @@ -291,11 +243,10 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes continue for timeframe in timeframes: - dl_file = pair_data_filename(datadir, pair, timeframe) - if erase and dl_file.exists(): - logger.info( - f'Deleting existing data for pair {pair}, interval {timeframe}.') - dl_file.unlink() + if erase: + if data_handler.ohlcv_purge(pair, timeframe): + logger.info( + f'Deleting existing data for pair {pair}, interval {timeframe}.') logger.info(f'Downloading pair {pair}, interval {timeframe}.') _download_pair_history(datadir=datadir, exchange=exchange, diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 969e58223..7e030b523 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -22,7 +22,7 @@ from freqtrade.data.history import (_download_pair_history, load_data, load_pair_history, refresh_backtest_ohlcv_data, refresh_backtest_trades_data, refresh_data, - trim_tickerlist, validate_backtest_data) + validate_backtest_data) from freqtrade.exchange import timeframe_to_minutes from freqtrade.misc import file_dump_json from freqtrade.strategy.default_strategy import DefaultStrategy @@ -358,58 +358,6 @@ def test_init_with_refresh(default_conf, mocker) -> None: ) -def test_trim_tickerlist(testdatadir) -> None: - file = testdatadir / 'UNITTEST_BTC-1m.json' - with open(file) as data_file: - ticker_list = json.load(data_file) - ticker_list_len = len(ticker_list) - - # Test the pattern ^(\d{8})-(\d{8})$ - # This pattern extract a window between the dates - timerange = TimeRange('date', 'date', ticker_list[5][0] / 1000, ticker_list[10][0] / 1000 - 1) - ticker = trim_tickerlist(ticker_list, timerange) - ticker_len = len(ticker) - - assert ticker_len == 5 - assert ticker_list[0] is not ticker[0] # The first element should be different - assert ticker_list[5] is ticker[0] # The list starts at the index 5 - assert ticker_list[9] is ticker[-1] # The list ends at the index 9 (5 elements) - - # Test the pattern ^-(\d{8})$ - # This pattern extracts elements from the start to the date - timerange = TimeRange(None, 'date', 0, ticker_list[10][0] / 1000 - 1) - ticker = trim_tickerlist(ticker_list, timerange) - ticker_len = len(ticker) - - assert ticker_len == 10 - assert ticker_list[0] is ticker[0] # The start of the list is included - assert ticker_list[9] is ticker[-1] # The element 10 is not included - - # Test the pattern ^(\d{8})-$ - # This pattern extracts elements from the date to now - timerange = TimeRange('date', None, ticker_list[10][0] / 1000 - 1, None) - ticker = trim_tickerlist(ticker_list, timerange) - ticker_len = len(ticker) - - assert ticker_len == ticker_list_len - 10 - assert ticker_list[10] is ticker[0] # The first element is element #10 - assert ticker_list[-1] is ticker[-1] # The last element is the same - - # Test a wrong pattern - # This pattern must return the list unchanged - timerange = TimeRange(None, None, None, 5) - ticker = trim_tickerlist(ticker_list, timerange) - ticker_len = len(ticker) - - assert ticker_list_len == ticker_len - - # passing empty list - timerange = TimeRange(None, None, None, 5) - ticker = trim_tickerlist([], timerange) - assert 0 == len(ticker) - assert not ticker - - def test_file_dump_json_tofile(testdatadir) -> None: file = testdatadir / 'test_{id}.json'.format(id=str(uuid.uuid4())) data = {'bar': 'foo'} From 8a030e7fc01566191ce747767efb2a6a1b83974f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 11:08:47 +0100 Subject: [PATCH 0132/1106] Use exists instead of is_file --- freqtrade/data/datahandlers/jsondatahandler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 1a26671b9..9f3468d30 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -65,7 +65,7 @@ class JsonDataHandler(IDataHandler): :return: DataFrame with ohlcv data, or empty DataFrame """ filename = self._pair_data_filename(self._datadir, pair, timeframe) - if not filename.is_file(): + if not filename.exists(): return DataFrame(columns=self._columns) pairdata = read_json(filename, orient='values') pairdata.columns = self._columns @@ -149,7 +149,7 @@ class JsonDataHandler(IDataHandler): :return: True when deleted, false if file did not exist. """ filename = self._pair_trades_filename(self._datadir, pair) - if filename.is_file(): + if filename.exists(): filename.unlink() return True return False From d65c1eea7aff4b730771a8d1a7d8d98755e9ba86 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 13:16:53 +0100 Subject: [PATCH 0133/1106] Add some tests for datahandler --- .../data/datahandlers/jsondatahandler.py | 4 +- tests/data/test_history.py | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/datahandlers/jsondatahandler.py index 9f3468d30..f40cf969f 100644 --- a/freqtrade/data/datahandlers/jsondatahandler.py +++ b/freqtrade/data/datahandlers/jsondatahandler.py @@ -83,7 +83,7 @@ class JsonDataHandler(IDataHandler): :return: True when deleted, false if file did not exist. """ filename = self._pair_data_filename(self._datadir, pair, timeframe) - if filename.is_file(): + if filename.exists(): filename.unlink() return True return False @@ -119,7 +119,7 @@ class JsonDataHandler(IDataHandler): filename = self._pair_trades_filename(self._datadir, pair) misc.file_dump_json(filename, data, is_zip=self._use_zip) - def trades_append(self, pair: str, data: DataFrame): + def trades_append(self, pair: str, data: List[Dict]): """ Append data to existing files :param pair: Pair - used for filename diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 7e030b523..8787a35b2 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -7,6 +7,7 @@ from shutil import copyfile from unittest.mock import MagicMock, PropertyMock import arrow +import pytest from pandas import DataFrame from pandas.testing import assert_frame_equal @@ -561,3 +562,52 @@ def test_convert_trades_to_ohlcv(mocker, default_conf, testdatadir, caplog): _clean_test_file(file1) _clean_test_file(file5) + + +def test_jsondatahandler_ohlcv_get_pairs(testdatadir): + pairs = JsonDataHandler.ohlcv_get_pairs(testdatadir, '5m') + # Convert to set to avoid failures due to sorting + assert set(pairs) == {'UNITTEST/BTC', 'XLM/BTC', 'ETH/BTC', 'TRX/BTC', 'LTC/BTC', + 'XMR/BTC', 'ZEC/BTC', 'ADA/BTC', 'ETC/BTC', 'NXT/BTC', + 'DASH/BTC', 'XRP/ETH'} + + pairs = JsonGzDataHandler.ohlcv_get_pairs(testdatadir, '8m') + assert set(pairs) == {'UNITTEST/BTC'} + + +def test_jsondatahandler_trades_get_pairs(testdatadir): + pairs = JsonGzDataHandler.trades_get_pairs(testdatadir) + # Convert to set to avoid failures due to sorting + assert set(pairs) == {'XRP/ETH'} + + +def test_jsondatahandler_ohlcv_purge(mocker, testdatadir): + mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + mocker.patch.object(Path, "unlink", MagicMock()) + dh = JsonGzDataHandler(testdatadir) + assert not dh.ohlcv_purge('UNITTEST/NONEXIST', '5m') + + mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + assert dh.ohlcv_purge('UNITTEST/NONEXIST', '5m') + + +def test_jsondatahandler_trades_purge(mocker, testdatadir): + mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + mocker.patch.object(Path, "unlink", MagicMock()) + dh = JsonGzDataHandler(testdatadir) + assert not dh.trades_purge('UNITTEST/NONEXIST') + + mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + assert dh.trades_purge('UNITTEST/NONEXIST') + + +def test_jsondatahandler_ohlcv_append(testdatadir): + dh = JsonGzDataHandler(testdatadir) + with pytest.raises(NotImplementedError): + dh.ohlcv_append('UNITTEST/ETH', '5m', DataFrame()) + + +def test_jsondatahandler_trades_append(testdatadir): + dh = JsonGzDataHandler(testdatadir) + with pytest.raises(NotImplementedError): + dh.trades_append('UNITTEST/ETH', []) From 65f539e9d8bb0631237c6dc3c44cf42eb8d94e87 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 13:25:34 +0100 Subject: [PATCH 0134/1106] More tests for datahandler --- tests/data/test_history.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 8787a35b2..726b6d3a7 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -13,7 +13,8 @@ from pandas.testing import assert_frame_equal from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.datahandlers import get_datahandler +from freqtrade.data.datahandlers import get_datahandler, get_datahandlerclass +from freqtrade.data.datahandlers.idatahandler import IDataHandler from freqtrade.data.datahandlers.jsondatahandler import (JsonDataHandler, JsonGzDataHandler) from freqtrade.data.history import (_download_pair_history, @@ -611,3 +612,24 @@ def test_jsondatahandler_trades_append(testdatadir): dh = JsonGzDataHandler(testdatadir) with pytest.raises(NotImplementedError): dh.trades_append('UNITTEST/ETH', []) + + +def test_gethandlerclass(): + cl = get_datahandlerclass('json') + assert cl == JsonDataHandler + assert issubclass(cl, IDataHandler) + cl = get_datahandlerclass('jsongz') + assert cl == JsonGzDataHandler + assert issubclass(cl, IDataHandler) + assert issubclass(cl, JsonDataHandler) + with pytest.raises(ValueError, match=r"No datahandler for .*"): + get_datahandlerclass('DeadBeef') + + +def test_get_datahandler(testdatadir): + dh = get_datahandler(testdatadir, 'json') + assert type(dh) == JsonDataHandler + dh = get_datahandler(testdatadir, 'jsongz') + assert type(dh) == JsonGzDataHandler + dh1 = get_datahandler(testdatadir, 'jsongz', dh) + assert id(dh1) == id(dh) From 9c5b94adf506f2e726b2e497655a424c2cc6f4f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 27 Dec 2019 13:46:25 +0100 Subject: [PATCH 0135/1106] Pass data_format to methods --- docs/configuration.md | 2 ++ freqtrade/configuration/arguments.py | 2 +- freqtrade/configuration/cli_options.py | 12 ++++++++++++ freqtrade/configuration/configuration.py | 7 +++++++ freqtrade/constants.py | 14 +++++++------- freqtrade/data/history.py | 10 ++++++---- freqtrade/utils.py | 12 +++++++++--- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 90f0aa791..002e3ab5d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -106,6 +106,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
***Datatype:*** *Boolean* | `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file.
***Datatype:*** *String* | `user_data_dir` | Directory containing user data.
*Defaults to `./user_data/`*.
***Datatype:*** *String* +| `dataformat_ohlcv` | Data format to use to store OHLCV historic data.
*Defaults to `json`*.
***Datatype:*** *String* +| `dataformat_trades` | Data format to use to store trades historic data.
*Defaults to `jsongz`*.
***Datatype:*** *String* ### Parameters in the strategy diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index cefa86927..121bd23b4 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -51,7 +51,7 @@ ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to"] ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"] ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", - "timeframes", "erase"] + "timeframes", "erase", "dataformat_ohlcv", "dataformat_trades"] ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", "db_url", "trade_source", "export", "exportfilename", diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index ffaf9ea66..c80bea393 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -344,6 +344,18 @@ AVAILABLE_CLI_OPTIONS = { choices=constants.AVAILABLE_DATAHANDLERS, required=True, ), + "dataformat_ohlcv": Arg( + '--data-format', + help='Storage format for downloaded ohlcv data. (default: `%(default)s`).', + choices=constants.AVAILABLE_DATAHANDLERS, + default='json' + ), + "dataformat_trades": Arg( + '--data-format-trades', + help='Storage format for downloaded trades data. (default: `%(default)s`).', + choices=constants.AVAILABLE_DATAHANDLERS, + default='jsongz' + ), "exchange": Arg( '--exchange', help=f'Exchange name (default: `{constants.DEFAULT_EXCHANGE}`). ' diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index f73b52c10..aa453a392 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -339,9 +339,16 @@ class Configuration: self._args_to_config(config, argname='days', logstring='Detected --days: {}') + self._args_to_config(config, argname='download_trades', logstring='Detected --dl-trades: {}') + self._args_to_config(config, argname='dataformat_ohlcv', + logstring='Using "{}" to store OHLCV data.') + + self._args_to_config(config, argname='dataformat_trade', + logstring='Using "{}" to store trades data.') + def _process_runmode(self, config: Dict[str, Any]) -> None: if not self.runmode: diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 8d9cde98b..95ec71552 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -216,17 +216,17 @@ CONF_SCHEMA = { 'process_throttle_secs': {'type': 'integer'}, 'interval': {'type': 'integer'}, 'sd_notify': {'type': 'boolean'}, - 'dataformat_ohlcv': { - 'type': 'string', + } + }, + 'dataformat_ohlcv': { + 'type': 'string', 'enum': AVAILABLE_DATAHANDLERS, 'default': 'json' - }, - 'dataformat_trades': { - 'type': 'string', + }, + 'dataformat_trades': { + 'type': 'string', 'enum': AVAILABLE_DATAHANDLERS, 'default': 'jsongz' - } - } } }, 'definitions': { diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 9dad90864..c06b14b4a 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -178,7 +178,7 @@ def _download_pair_history(datadir: Path, :param timerange: range of time to download :return: bool with success state """ - data_handler = get_datahandler(datadir) + data_handler = get_datahandler(datadir, data_handler=data_handler) try: logger.info( @@ -327,12 +327,14 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], - datadir: Path, timerange: TimeRange, erase=False) -> None: + datadir: Path, timerange: TimeRange, erase=False, + data_format_ohlcv: str = 'json', + data_format_trades: str = 'jsongz') -> None: """ Convert stored trades data to ohlcv data """ - data_handler_trades = get_datahandler(datadir, data_format='jsongz') - data_handler_ohlcv = get_datahandler(datadir, data_format='json') + data_handler_trades = get_datahandler(datadir, data_format=data_format_trades) + data_handler_ohlcv = get_datahandler(datadir, data_format=data_format_ohlcv) for pair in pairs: trades = data_handler_trades.trades_load(pair) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 5f646cc7a..81d41f28a 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -204,16 +204,22 @@ def start_download_data(args: Dict[str, Any]) -> None: if config.get('download_trades'): pairs_not_available = refresh_backtest_trades_data( exchange, pairs=config["pairs"], datadir=config['datadir'], - timerange=timerange, erase=config.get("erase")) + timerange=timerange, erase=config.get("erase"), + data_format=config['dataformat_trades']) # Convert downloaded trade data to different timeframes convert_trades_to_ohlcv( pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, erase=config.get("erase"), + data_format_ohlcv=config['dataformat_ohlcv'], + data_format_trades=config['dataformat_trades'], + ) + else: pairs_not_available = refresh_backtest_ohlcv_data( exchange, pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, erase=config.get("erase"), + data_format=config['dataformat_ohlcv']) except KeyboardInterrupt: sys.exit("SIGINT received, aborting ...") From b37b5c3d90440d8d3afe098f8668d463a67c33c2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 07:02:46 +0100 Subject: [PATCH 0136/1106] Remove Explicit datadir conversation --- freqtrade/utils.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 81d41f28a..f5865f1db 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -251,16 +251,15 @@ def start_list_strategies(args: Dict[str, Any]) -> None: def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str): """ TODO: move this to converter.py (?) - TODO: remove Path conversation once PR is merged and this is rebased """ SrcClass = get_datahandlerclass(convert_from) TrgClass = get_datahandlerclass(convert_to) if 'pairs' not in config: - config['pairs'] = SrcClass.trades_get_pairs(Path(config['datadir'])) + config['pairs'] = SrcClass.trades_get_pairs(config['datadir']) logger.info(f"Converting trades for {config['pairs']}") - src = SrcClass(Path(config['datadir'])) - trg = TrgClass(Path(config['datadir'])) + src = SrcClass(config['datadir']) + trg = TrgClass(config['datadir']) for pair in config['pairs']: data = src.trades_load(pair=pair) logger.info(f"Converting {len(data)} trades for {pair}") @@ -270,7 +269,6 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str): """ TODO: move this to converter.py (?) - TODO: remove Path conversation once PR is merged and this is rebased """ SrcClass = get_datahandlerclass(convert_from) TrgClass = get_datahandlerclass(convert_to) @@ -281,12 +279,12 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: config['pairs'] = [] # Check timeframes or fall back to ticker_interval. for timeframe in timeframes: - config['pairs'].extend(SrcClass.ohlcv_get_pairs(Path(config['datadir']), + config['pairs'].extend(SrcClass.ohlcv_get_pairs(config['datadir'], timeframe)) logger.info(f"Converting OHLCV for {config['pairs']}") - src = SrcClass(Path(config['datadir'])) - trg = TrgClass(Path(config['datadir'])) + src = SrcClass(config['datadir']) + trg = TrgClass(config['datadir']) for timeframe in timeframes: for pair in config['pairs']: From 68604911891d7f0f9eaf2d9f2636f2110cc806c3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 09:59:47 +0100 Subject: [PATCH 0137/1106] Rename datahandler module to history module Also move previous history.py into this module - so everything is bundled --- freqtrade/data/datahandlers/__init__.py | 36 ----------------- freqtrade/data/history/__init__.py | 14 +++++++ .../{history.py => history/history_utils.py} | 11 +---- .../{datahandlers => history}/idatahandler.py | 40 +++++++++++++++++-- .../jsondatahandler.py | 0 freqtrade/utils.py | 2 +- tests/data/test_history.py | 33 ++++++++------- tests/optimize/test_backtesting.py | 3 +- 8 files changed, 71 insertions(+), 68 deletions(-) delete mode 100644 freqtrade/data/datahandlers/__init__.py create mode 100644 freqtrade/data/history/__init__.py rename freqtrade/data/{history.py => history/history_utils.py} (98%) rename freqtrade/data/{datahandlers => history}/idatahandler.py (76%) rename freqtrade/data/{datahandlers => history}/jsondatahandler.py (100%) diff --git a/freqtrade/data/datahandlers/__init__.py b/freqtrade/data/datahandlers/__init__.py deleted file mode 100644 index a21dd832d..000000000 --- a/freqtrade/data/datahandlers/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Type -from pathlib import Path -from .idatahandler import IDataHandler - - -def get_datahandlerclass(datatype: str) -> Type[IDataHandler]: - """ - Get datahandler class. - Could be done using Resolvers, but since this may be called often and resolvers - are rather expensive, doing this directly should improve performance. - :param datatype: datatype to use. - :return: Datahandler class - """ - - if datatype == 'json': - from .jsondatahandler import JsonDataHandler - return JsonDataHandler - elif datatype == 'jsongz': - from .jsondatahandler import JsonGzDataHandler - return JsonGzDataHandler - else: - raise ValueError(f"No datahandler for datatype {datatype} available.") - - -def get_datahandler(datadir: Path, data_format: str = None, - data_handler: IDataHandler = None) -> IDataHandler: - """ - :param datadir: Folder to save data - :data_format: dataformat to use - :data_handler: returns this datahandler if it exists or initializes a new one - """ - - if not data_handler: - HandlerClass = get_datahandlerclass(data_format or 'json') - data_handler = HandlerClass(datadir) - return data_handler diff --git a/freqtrade/data/history/__init__.py b/freqtrade/data/history/__init__.py new file mode 100644 index 000000000..572c063fc --- /dev/null +++ b/freqtrade/data/history/__init__.py @@ -0,0 +1,14 @@ +""" +Handle historic data (ohlcv). + +Includes: +* load data for a pair (or a list of pairs) from disk +* download data from exchange and store to disk +""" + +from .history_utils import (convert_trades_to_ohlcv, # noqa: F401 + get_timerange, load_data, load_pair_history, + refresh_backtest_ohlcv_data, + refresh_backtest_trades_data, refresh_data, + validate_backtest_data) +from .idatahandler import get_datahandler, get_datahandlerclass # noqa: F401 diff --git a/freqtrade/data/history.py b/freqtrade/data/history/history_utils.py similarity index 98% rename from freqtrade/data/history.py rename to freqtrade/data/history/history_utils.py index c06b14b4a..42f1c9be7 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history/history_utils.py @@ -1,11 +1,3 @@ -""" -Handle historic data (ohlcv). - -Includes: -* load data for a pair (or a list of pairs) from disk -* download data from exchange and store to disk -""" - import logging import operator from datetime import datetime, timezone @@ -19,8 +11,7 @@ from freqtrade import OperationalException from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv -from freqtrade.data.datahandlers import get_datahandler -from freqtrade.data.datahandlers.idatahandler import IDataHandler +from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler from freqtrade.exchange import Exchange logger = logging.getLogger(__name__) diff --git a/freqtrade/data/datahandlers/idatahandler.py b/freqtrade/data/history/idatahandler.py similarity index 76% rename from freqtrade/data/datahandlers/idatahandler.py rename to freqtrade/data/history/idatahandler.py index b80b8cfcc..cee43dcef 100644 --- a/freqtrade/data/datahandlers/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -6,13 +6,14 @@ It's subclasses handle and storing data from disk. import logging from abc import ABC, abstractclassmethod, abstractmethod from copy import deepcopy -from pathlib import Path -from typing import Dict, List, Optional from datetime import datetime, timezone +from pathlib import Path +from typing import Dict, List, Optional, Type + from pandas import DataFrame -from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe from freqtrade.configuration import TimeRange +from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe from freqtrade.exchange import timeframe_to_seconds logger = logging.getLogger(__name__) @@ -89,3 +90,36 @@ class IDataHandler(ABC): if pairdata.iloc[-1]['date'] < stop: logger.warning(f"Missing data at end for pair {pair}, " f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}") + + +def get_datahandlerclass(datatype: str) -> Type[IDataHandler]: + """ + Get datahandler class. + Could be done using Resolvers, but since this may be called often and resolvers + are rather expensive, doing this directly should improve performance. + :param datatype: datatype to use. + :return: Datahandler class + """ + + if datatype == 'json': + from .jsondatahandler import JsonDataHandler + return JsonDataHandler + elif datatype == 'jsongz': + from .jsondatahandler import JsonGzDataHandler + return JsonGzDataHandler + else: + raise ValueError(f"No datahandler for datatype {datatype} available.") + + +def get_datahandler(datadir: Path, data_format: str = None, + data_handler: IDataHandler = None) -> IDataHandler: + """ + :param datadir: Folder to save data + :data_format: dataformat to use + :data_handler: returns this datahandler if it exists or initializes a new one + """ + + if not data_handler: + HandlerClass = get_datahandlerclass(data_format or 'json') + data_handler = HandlerClass(datadir) + return data_handler diff --git a/freqtrade/data/datahandlers/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py similarity index 100% rename from freqtrade/data/datahandlers/jsondatahandler.py rename to freqtrade/data/history/jsondatahandler.py diff --git a/freqtrade/utils.py b/freqtrade/utils.py index f5865f1db..1bb0f611a 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -17,8 +17,8 @@ from freqtrade.configuration import (Configuration, TimeRange, from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY -from freqtrade.data.datahandlers import get_datahandlerclass from freqtrade.data.history import (convert_trades_to_ohlcv, + get_datahandlerclass, refresh_backtest_ohlcv_data, refresh_backtest_trades_data) from freqtrade.exchange import (available_exchanges, ccxt_exchanges, diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 726b6d3a7..f84e819ad 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -13,18 +13,15 @@ from pandas.testing import assert_frame_equal from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.datahandlers import get_datahandler, get_datahandlerclass -from freqtrade.data.datahandlers.idatahandler import IDataHandler -from freqtrade.data.datahandlers.jsondatahandler import (JsonDataHandler, - JsonGzDataHandler) -from freqtrade.data.history import (_download_pair_history, - _download_trades_history, - _load_cached_data_for_updating, - convert_trades_to_ohlcv, get_timerange, - load_data, load_pair_history, - refresh_backtest_ohlcv_data, - refresh_backtest_trades_data, refresh_data, - validate_backtest_data) +from freqtrade.data.history import get_datahandler, get_datahandlerclass +from freqtrade.data.history.history_utils import ( + _download_pair_history, _download_trades_history, + _load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange, + load_data, load_pair_history, refresh_backtest_ohlcv_data, + refresh_backtest_trades_data, refresh_data, validate_backtest_data) +from freqtrade.data.history.idatahandler import IDataHandler +from freqtrade.data.history.jsondatahandler import (JsonDataHandler, + JsonGzDataHandler) from freqtrade.exchange import timeframe_to_minutes from freqtrade.misc import file_dump_json from freqtrade.strategy.default_strategy import DefaultStrategy @@ -100,7 +97,7 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog, testdatadir) -> N def test_load_data_startup_candles(mocker, caplog, default_conf, testdatadir) -> None: ltfmock = mocker.patch( - 'freqtrade.data.datahandlers.jsondatahandler.JsonDataHandler._ohlcv_load', + 'freqtrade.data.history.jsondatahandler.JsonDataHandler._ohlcv_load', MagicMock(return_value=DataFrame())) timerange = TimeRange('date', None, 1510639620, 0) load_pair_history(pair='UNITTEST/BTC', timeframe='1m', @@ -271,7 +268,7 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None: [1509836580000, 0.00161, 0.00161, 0.00161, 0.00161, 82.390199] ] json_dump_mock = mocker.patch( - 'freqtrade.data.datahandlers.jsondatahandler.JsonDataHandler.ohlcv_store', + 'freqtrade.data.history.jsondatahandler.JsonDataHandler.ohlcv_store', return_value=None) mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=tick) exchange = get_patched_exchange(mocker, default_conf) @@ -444,7 +441,8 @@ def test_validate_backtest_data(default_conf, mocker, caplog, testdatadir) -> No def test_refresh_backtest_ohlcv_data(mocker, default_conf, markets, caplog, testdatadir): - dl_mock = mocker.patch('freqtrade.data.history._download_pair_history', MagicMock()) + dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_pair_history', + MagicMock()) mocker.patch( 'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets) ) @@ -465,7 +463,7 @@ def test_refresh_backtest_ohlcv_data(mocker, default_conf, markets, caplog, test def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir): - dl_mock = mocker.patch('freqtrade.data.history._download_pair_history', MagicMock()) + dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_pair_history', MagicMock()) ex = get_patched_exchange(mocker, default_conf) mocker.patch( @@ -485,7 +483,8 @@ def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir): def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, testdatadir): - dl_mock = mocker.patch('freqtrade.data.history._download_trades_history', MagicMock()) + dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_trades_history', + MagicMock()) mocker.patch( 'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets) ) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 447f0052b..427e6c422 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -460,7 +460,8 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> def get_timerange(input1): return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) - mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=pd.DataFrame())) + mocker.patch('freqtrade.data.history.history_utils.load_pair_history', + MagicMock(return_value=pd.DataFrame())) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) From 525550e4c75af8ae2c863e16a8fc0c47c367ae70 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 10:01:54 +0100 Subject: [PATCH 0138/1106] Fix typo in parameter transition --- freqtrade/configuration/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index aa453a392..99ca84f34 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -346,7 +346,7 @@ class Configuration: self._args_to_config(config, argname='dataformat_ohlcv', logstring='Using "{}" to store OHLCV data.') - self._args_to_config(config, argname='dataformat_trade', + self._args_to_config(config, argname='dataformat_trades', logstring='Using "{}" to store trades data.') def _process_runmode(self, config: Dict[str, Any]) -> None: From 28787a001ce03790bb4848ca55b09ebdf817aa17 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 10:27:49 +0100 Subject: [PATCH 0139/1106] Move convert functions to convert module --- freqtrade/configuration/arguments.py | 2 +- freqtrade/data/converter.py | 62 +++++++++++++++++++++++ freqtrade/data/history/jsondatahandler.py | 2 + freqtrade/utils.py | 58 +++------------------ tests/data/test_history.py | 3 +- 5 files changed, 73 insertions(+), 54 deletions(-) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 121bd23b4..2b9b362bf 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -47,7 +47,7 @@ ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] -ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to"] +ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to", "erase"] ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"] ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange", diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 41a843e36..c6ec4fa2b 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -3,6 +3,7 @@ Functions to convert data from one format to another """ import logging from datetime import datetime, timezone +from typing import Any, Dict import pandas as pd from pandas import DataFrame, to_datetime @@ -175,3 +176,64 @@ def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: # Drop 0 volume rows df_new = df_new.dropna() return df_new[DEFAULT_DATAFRAME_COLUMNS] + + +def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool): + """ + Convert trades from one format to another format. + :param config: Config dictionary + :param convert_from: Source format + :param convert_to: Target format + :param erase: Erase souce data (does not apply if source and target format are identical) + """ + from freqtrade.data.history.idatahandler import get_datahandler + src = get_datahandler(config['datadir'], convert_from) + trg = get_datahandler(config['datadir'], convert_to) + + if 'pairs' not in config: + config['pairs'] = src.trades_get_pairs(config['datadir']) + logger.info(f"Converting trades for {config['pairs']}") + + for pair in config['pairs']: + data = src.trades_load(pair=pair) + logger.info(f"Converting {len(data)} trades for {pair}") + trg.trades_store(pair, data) + if erase and convert_from != convert_to: + logger.info(f"Deleting source Trade data for {pair}.") + src.trades_purge(pair=pair) + + +def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool): + """ + Convert ohlcv from one format to another format. + :param config: Config dictionary + :param convert_from: Source format + :param convert_to: Target format + :param erase: Erase souce data (does not apply if source and target format are identical) + """ + from freqtrade.data.history.idatahandler import get_datahandler + src = get_datahandler(config['datadir'], convert_from) + trg = get_datahandler(config['datadir'], convert_to) + timeframes = config.get('timeframes', [config.get('ticker_interval')]) + logger.info(f"Converting OHLCV for timeframe {timeframes}") + + if 'pairs' not in config: + config['pairs'] = [] + # Check timeframes or fall back to ticker_interval. + for timeframe in timeframes: + config['pairs'].extend(src.ohlcv_get_pairs(config['datadir'], + timeframe)) + logger.info(f"Converting OHLCV for {config['pairs']}") + + for timeframe in timeframes: + for pair in config['pairs']: + data = src.ohlcv_load(pair=pair, timeframe=timeframe, + timerange=None, + fill_missing=False, + drop_incomplete=False, + startup_candles=0) + logger.info(f"Converting {len(data)} candles for {pair}") + trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data) + if erase and convert_from != convert_to: + logger.info(f"Deleting source data for {pair} / {timeframe}") + src.ohlcv_purge(pair=pair, timeframe=timeframe) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index f40cf969f..14f643705 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -62,6 +62,8 @@ class JsonDataHandler(IDataHandler): :param pair: Pair to load data :param timeframe: Ticker timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange. + Optionally implemented by subclasses to avoid loading + all data where possible. :return: DataFrame with ohlcv data, or empty DataFrame """ filename = self._pair_data_filename(self._datadir, pair, timeframe) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 1bb0f611a..b0ef7241b 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -17,8 +17,9 @@ from freqtrade.configuration import (Configuration, TimeRange, from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY +from freqtrade.data.converter import (convert_ohlcv_format, + convert_trades_format) from freqtrade.data.history import (convert_trades_to_ohlcv, - get_datahandlerclass, refresh_backtest_ohlcv_data, refresh_backtest_trades_data) from freqtrade.exchange import (available_exchanges, ccxt_exchanges, @@ -248,55 +249,6 @@ def start_list_strategies(args: Dict[str, Any]) -> None: print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) -def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str): - """ - TODO: move this to converter.py (?) - """ - SrcClass = get_datahandlerclass(convert_from) - TrgClass = get_datahandlerclass(convert_to) - - if 'pairs' not in config: - config['pairs'] = SrcClass.trades_get_pairs(config['datadir']) - logger.info(f"Converting trades for {config['pairs']}") - src = SrcClass(config['datadir']) - trg = TrgClass(config['datadir']) - for pair in config['pairs']: - data = src.trades_load(pair=pair) - logger.info(f"Converting {len(data)} trades for {pair}") - trg.trades_store(pair, data) - - -def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str): - """ - TODO: move this to converter.py (?) - """ - SrcClass = get_datahandlerclass(convert_from) - TrgClass = get_datahandlerclass(convert_to) - timeframes = config.get('timeframes', [config.get('ticker_interval')]) - logger.info(f"Converting OHLCV for timeframe {timeframes}") - - if 'pairs' not in config: - config['pairs'] = [] - # Check timeframes or fall back to ticker_interval. - for timeframe in timeframes: - config['pairs'].extend(SrcClass.ohlcv_get_pairs(config['datadir'], - timeframe)) - logger.info(f"Converting OHLCV for {config['pairs']}") - - src = SrcClass(config['datadir']) - trg = TrgClass(config['datadir']) - - for timeframe in timeframes: - for pair in config['pairs']: - data = src.ohlcv_load(pair=pair, timeframe=timeframe, - timerange=None, - fill_missing=False, - drop_incomplete=False, - startup_candles=0) - logger.info(f"Converting {len(data)} candles for {pair}") - trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data) - - def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: """ Convert data from one format to another @@ -304,10 +256,12 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) if ohlcv: convert_ohlcv_format(config, - convert_from=args['format_from'], convert_to=args['format_to']) + convert_from=args['format_from'], convert_to=args['format_to'], + erase=args['erase']) else: convert_trades_format(config, - convert_from=args['format_from'], convert_to=args['format_to']) + convert_from=args['format_from'], convert_to=args['format_to'], + erase=args['erase']) def start_list_timeframes(args: Dict[str, Any]) -> None: diff --git a/tests/data/test_history.py b/tests/data/test_history.py index f84e819ad..404f52e87 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -463,7 +463,8 @@ def test_refresh_backtest_ohlcv_data(mocker, default_conf, markets, caplog, test def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir): - dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_pair_history', MagicMock()) + dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_pair_history', + MagicMock()) ex = get_patched_exchange(mocker, default_conf) mocker.patch( From e7054adc496d54b060ea579d650e6d208f2be12a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 10:37:34 +0100 Subject: [PATCH 0140/1106] Add tests for start_convert_data --- tests/test_utils.py | 58 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 4cf7b5f23..e384a7633 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -6,13 +6,13 @@ import pytest from freqtrade import OperationalException from freqtrade.state import RunMode -from freqtrade.utils import (setup_utils_configuration, start_create_userdir, - start_download_data, start_hyperopt_list, - start_hyperopt_show, start_list_exchanges, - start_list_markets, start_list_strategies, - start_list_timeframes, start_new_hyperopt, - start_new_strategy, start_test_pairlist, - start_trading) +from freqtrade.utils import (setup_utils_configuration, start_convert_data, + start_create_userdir, start_download_data, + start_hyperopt_list, start_hyperopt_show, + start_list_exchanges, start_list_markets, + start_list_strategies, start_list_timeframes, + start_new_hyperopt, start_new_strategy, + start_test_pairlist, start_trading) from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) @@ -821,3 +821,47 @@ def test_hyperopt_show(mocker, capsys, hyperopt_results): with pytest.raises(OperationalException, match="The index of the epoch to show should be less than 4."): start_hyperopt_show(pargs) + + +def test_convert_data(mocker, testdatadir): + ohlcv_mock = mocker.patch("freqtrade.utils.convert_ohlcv_format", MagicMock()) + trades_mock = mocker.patch("freqtrade.utils.convert_trades_format", MagicMock()) + args = [ + "convert-data", + "--format-from", + "json", + "--format-to", + "jsongz", + "--datadir", + str(testdatadir), + ] + pargs = get_args(args) + pargs['config'] = None + start_convert_data(pargs, True) + assert trades_mock.call_count == 0 + assert ohlcv_mock.call_count == 1 + assert ohlcv_mock.call_args[1]['convert_from'] == 'json' + assert ohlcv_mock.call_args[1]['convert_to'] == 'jsongz' + assert ohlcv_mock.call_args[1]['erase'] is False + + +def test_convert_data_trades(mocker, testdatadir): + ohlcv_mock = mocker.patch("freqtrade.utils.convert_ohlcv_format", MagicMock()) + trades_mock = mocker.patch("freqtrade.utils.convert_trades_format", MagicMock()) + args = [ + "convert-trade-data", + "--format-from", + "jsongz", + "--format-to", + "json", + "--datadir", + str(testdatadir), + ] + pargs = get_args(args) + pargs['config'] = None + start_convert_data(pargs, False) + assert ohlcv_mock.call_count == 0 + assert trades_mock.call_count == 1 + assert trades_mock.call_args[1]['convert_from'] == 'jsongz' + assert trades_mock.call_args[1]['convert_to'] == 'json' + assert trades_mock.call_args[1]['erase'] is False From 70f3ff046128491ca2310f967020308b92319c68 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 10:45:26 +0100 Subject: [PATCH 0141/1106] Add test for convert_trades_Format --- tests/data/test_converter.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index eb8a8e513..ac5472221 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -2,11 +2,13 @@ import logging from freqtrade.configuration.timerange import TimeRange -from freqtrade.data.converter import (ohlcv_fill_up_missing_data, +from freqtrade.data.converter import (convert_trades_format, + ohlcv_fill_up_missing_data, parse_ticker_dataframe, trim_dataframe) from freqtrade.data.history import (get_timerange, load_data, load_pair_history, validate_backtest_data) from tests.conftest import log_has +from tests.data.test_history import _backup_file, _clean_test_file def test_dataframe_correct_columns(result): @@ -188,3 +190,31 @@ def test_trim_dataframe(testdatadir) -> None: assert len(data_modify) == len(data) - 55 # first row matches 25th original row assert all(data_modify.iloc[0] == data.iloc[25]) + + +def test_convert_trades_format(mocker, default_conf, testdatadir): + file = testdatadir / "XRP_ETH-trades.json.gz" + file_new = testdatadir / "XRP_ETH-trades.json" + _backup_file(file, copy_file=True) + default_conf['datadir'] = testdatadir + + assert not file_new.exists() + + convert_trades_format(default_conf, convert_from='jsongz', + convert_to='json', erase=False) + + assert file_new.exists() + assert file.exists() + + # Remove original file + file.unlink() + # Convert back + convert_trades_format(default_conf, convert_from='json', + convert_to='jsongz', erase=True) + + assert file.exists() + assert not file_new.exists() + + _clean_test_file(file) + if file_new.exists(): + file_new.unlink() From 9e4fc00a0ffcc80dc5ddb91c2961f5cbc81d48a7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 10:54:10 +0100 Subject: [PATCH 0142/1106] Add test for convert_ohlcv --- freqtrade/data/converter.py | 2 ++ tests/data/test_converter.py | 45 +++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index c6ec4fa2b..abc754df0 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -135,6 +135,7 @@ def trim_dataframe(df: DataFrame, timerange: TimeRange, df_date_col: str = 'date def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: """ + TODO: This should get a dedicated test Gets order book list, returns dataframe with below format per suggested by creslin ------------------------------------------------------------------- b_sum b_size bids asks a_size a_sum @@ -160,6 +161,7 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: """ Converts trades list to ohlcv list + TODO: This should get a dedicated test :param trades: List of trades, as returned by ccxt.fetch_trades. :param timeframe: Ticker timeframe to resample data to :return: ohlcv Dataframe. diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index ac5472221..a0ec2f46f 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -2,7 +2,8 @@ import logging from freqtrade.configuration.timerange import TimeRange -from freqtrade.data.converter import (convert_trades_format, +from freqtrade.data.converter import (convert_ohlcv_format, + convert_trades_format, ohlcv_fill_up_missing_data, parse_ticker_dataframe, trim_dataframe) from freqtrade.data.history import (get_timerange, load_data, @@ -218,3 +219,45 @@ def test_convert_trades_format(mocker, default_conf, testdatadir): _clean_test_file(file) if file_new.exists(): file_new.unlink() + + +def test_convert_ohlcv_format(mocker, default_conf, testdatadir): + file1 = testdatadir / "XRP_ETH-5m.json" + file1_new = testdatadir / "XRP_ETH-5m.json.gz" + file2 = testdatadir / "XRP_ETH-1m.json" + file2_new = testdatadir / "XRP_ETH-1m.json.gz" + _backup_file(file1, copy_file=True) + _backup_file(file2, copy_file=True) + default_conf['datadir'] = testdatadir + default_conf['pairs'] = ['XRP_ETH'] + default_conf['timeframes'] = ['1m', '5m'] + + assert not file1_new.exists() + assert not file2_new.exists() + + convert_ohlcv_format(default_conf, convert_from='json', + convert_to='jsongz', erase=False) + + assert file1_new.exists() + assert file2_new.exists() + assert file1.exists() + assert file2.exists() + + # Remove original files + file1.unlink() + file2.unlink() + # Convert back + convert_ohlcv_format(default_conf, convert_from='jsongz', + convert_to='json', erase=True) + + assert file1.exists() + assert file2.exists() + assert not file1_new.exists() + assert not file2_new.exists() + + _clean_test_file(file1) + _clean_test_file(file2) + if file1_new.exists(): + file1_new.unlink() + if file2_new.exists(): + file2_new.unlink() From 66d18575a741057ac9a763b4b72a3e8cd91e7883 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 11:10:31 +0100 Subject: [PATCH 0143/1106] Implement abstract interface --- freqtrade/data/history/idatahandler.py | 97 ++++++++++++++++++++++- freqtrade/data/history/jsondatahandler.py | 1 - 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index cee43dcef..20022fc38 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -24,7 +24,102 @@ class IDataHandler(ABC): def __init__(self, datadir: Path) -> None: self._datadir = datadir - # TODO: create abstract interface + @abstractclassmethod + def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: + """ + Returns a list of all pairs with ohlcv data available in this datadir + for the specified timeframe + :param datadir: Directory to search for ohlcv files + :param timeframe: Timeframe to search pairs for + :return: List of Pairs + """ + + @abstractmethod + def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: + """ + Store data in json format "values". + format looks as follows: + [[,,,,]] + :param pair: Pair - used to generate filename + :timeframe: Timeframe - used to generate filename + :data: Dataframe containing OHLCV data + :return: None + """ + + @abstractmethod + def _ohlcv_load(self, pair: str, timeframe: str, + timerange: Optional[TimeRange] = None, + ) -> DataFrame: + """ + Internal method used to load data for one pair from disk. + Implements the loading and conversation to a Pandas dataframe. + Timerange trimming and dataframe validation happens outside of this method. + :param pair: Pair to load data + :param timeframe: Ticker timeframe (e.g. "5m") + :param timerange: Limit data to be loaded to this timerange. + Optionally implemented by subclasses to avoid loading + all data where possible. + :return: DataFrame with ohlcv data, or empty DataFrame + """ + + @abstractmethod + def ohlcv_purge(self, pair: str, timeframe: str) -> bool: + """ + Remove data for this pair + :param pair: Delete data for this pair. + :param timeframe: Ticker timeframe (e.g. "5m") + :return: True when deleted, false if file did not exist. + """ + + @abstractmethod + def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: + """ + Append data to existing data structures + :param pair: Pair + :param timeframe: Timeframe this ohlcv data is for + :param data: Data to append. + """ + + @abstractclassmethod + def trades_get_pairs(cls, datadir: Path) -> List[str]: + """ + Returns a list of all pairs for which trade data is available in this + :param datadir: Directory to search for ohlcv files + :return: List of Pairs + """ + + @abstractmethod + def trades_store(self, pair: str, data: List[Dict]) -> None: + """ + Store trades data (list of Dicts) to file + :param pair: Pair - used for filename + :param data: List of Dicts containing trade data + """ + + @abstractmethod + def trades_append(self, pair: str, data: List[Dict]): + """ + Append data to existing files + :param pair: Pair - used for filename + :param data: List of Dicts containing trade data + """ + + @abstractmethod + def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> List[Dict]: + """ + Load a pair from file, either .json.gz or .json + :param pair: Load trades for this pair + :param timerange: Timerange to load trades for - currently not implemented + :return: List of trades + """ + + @abstractmethod + def trades_purge(self, pair: str) -> bool: + """ + Remove data for this pair + :param pair: Delete data for this pair. + :return: True when deleted, false if file did not exist. + """ def ohlcv_load(self, pair, timeframe: str, timerange: Optional[TimeRange] = None, diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 14f643705..dcfc249aa 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -96,7 +96,6 @@ class JsonDataHandler(IDataHandler): :param pair: Pair :param timeframe: Timeframe this ohlcv data is for :param data: Data to append. - """ raise NotImplementedError() From e2a00c03d626fb6242968c19402ccc5ebf7e505b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 11:24:37 +0100 Subject: [PATCH 0144/1106] Document convert options --- config_full.json.example | 4 +- docs/data-download.md | 146 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) diff --git a/config_full.json.example b/config_full.json.example index b9631f63d..108fdd534 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -127,5 +127,7 @@ "heartbeat_interval": 60 }, "strategy": "DefaultStrategy", - "strategy_path": "user_data/strategies/" + "strategy_path": "user_data/strategies/", + "dataformat_ohlcv": "json", + "dataformat_trades": "jsongz" } diff --git a/docs/data-download.md b/docs/data-download.md index 1f03b124a..c5fb744ab 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -12,6 +12,152 @@ Otherwise `--exchange` becomes mandatory. If you already have backtesting data available in your data-directory and would like to refresh this data up to today, use `--days xx` with a number slightly higher than the missing number of days. Freqtrade will keep the available data and only download the missing data. Be carefull though: If the number is too small (which would result in a few missing days), the whole dataset will be removed and only xx days will be downloaded. +### Usage + +``` +usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-p PAIRS [PAIRS ...]] + [--pairs-file FILE] [--days INT] [--dl-trades] [--exchange EXCHANGE] + [-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]] + [--erase] [--data-format {json,jsongz}] [--data-format-trades {json,jsongz}] + +optional arguments: + -h, --help show this help message and exit + -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] + Show profits for only these pairs. Pairs are space-separated. + --pairs-file FILE File containing a list of pairs to download. + --days INT Download data for given number of days. + --dl-trades Download trades instead of OHLCV data. The bot will resample trades to the desired timeframe as specified as + --timeframes/-t. + --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided. + -t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...] + Specify which tickers to download. Space-separated list. Default: `1m 5m`. + --erase Clean all existing data for the selected exchange/pairs/timeframes. + --data-format {json,jsongz} + Storage format for downloaded ohlcv data. (default: `json`). + --data-format-trades {json,jsongz} + Storage format for downloaded trades data. (default: `jsongz`). + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. +``` + +### Data format + +Freqtrade currently supports 2 dataformats, `json` and `jsongz`, a zipped version of json files. +By default, OHLCV data is stored as json data, while trades data is stored as `jsongz` data. + +This can be changed via the `--data-format` and `--data-format-trades` parameters respectivly. + +If the default dataformat has been changed during download, then the keys `dataformat_ohlcv` and `dataformat_trades` in the configuration file need to be adjusted to the selected dataformat as well. + +!!! Note + You can convert between data-formats using the [convert-data](#subcommand-convert-data) and [convert-trade-data](#subcommand-convert-trade-data) methods. + +#### Subcommand convert data + +``` +usage: freqtrade convert-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] + [-p PAIRS [PAIRS ...]] --format-from + {json,jsongz} --format-to {json,jsongz} + [--erase] + [-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]] + +optional arguments: + -h, --help show this help message and exit + -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] + Show profits for only these pairs. Pairs are space- + separated. + --format-from {json,jsongz} + Source format for data conversation. + --format-to {json,jsongz} + Destination format for data conversation. + --erase Clean all existing data for the selected + exchange/pairs/timeframes. + -t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...] + Specify which tickers to download. Space-separated + list. Default: `1m 5m`. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. +``` + +##### Example converting data + +The following command will convert all Candle data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process. +It'll also remove source files (`--erase` parameter). + +``` bash +freqtrade convert-data --format-from json --format-to jsongz --data-dir ~/.freqtrade/data/binance -t 5m 15m --erase +``` + +#### Subcommand convert-trade data + +``` +usage: freqtrade convert-trade-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] + [-p PAIRS [PAIRS ...]] --format-from + {json,jsongz} --format-to {json,jsongz} + [--erase] + +optional arguments: + -h, --help show this help message and exit + -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] + Show profits for only these pairs. Pairs are space- + separated. + --format-from {json,jsongz} + Source format for data conversation. + --format-to {json,jsongz} + Destination format for data conversation. + --erase Clean all existing data for the selected + exchange/pairs/timeframes. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. +``` + +##### Example converting trades + +The following command will convert all available trade-data in `~/.freqtrade/data/kraken` from json to jsongz, saving diskspace in the process. +It'll also remove source files (`--erase` parameter). + +``` bash +freqtrade convert-trade-data --format-from jsongz --format-to json --data-dir ~/.freqtrade/data/kraken --erase +``` + ### Pairs file In alternative to the whitelist from `config.json`, a `pairs.json` file can be used. From 5c39ebd0a0d9dea455762086d78a3ea5cbf3c995 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 28 Dec 2019 13:59:40 +0300 Subject: [PATCH 0145/1106] Adjust logging --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9c18d2d95..1cc7f32f4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -331,12 +331,12 @@ class FreqtradeBot: if buy and not sell: if not self.get_free_open_trades(): - logger.warning("Can't open a new trade: max number of trades is reached") + logger.debug("Can't open a new trade: max number of trades is reached") continue stake_amount = self.get_trade_stake_amount(pair) if not stake_amount: - logger.warning("Stake amount is 0, ignoring trade") + logger.debug("Stake amount is 0, ignoring possible trade for {pair}.") continue logger.info(f"Buy signal found: about create a new trade with stake_amount: " From ae1b28aab756adbef0fc64b0194a3b38a2ad0686 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 14:32:11 +0100 Subject: [PATCH 0146/1106] Remove get_datahandlerclass from package exposes --- freqtrade/data/history/__init__.py | 2 +- tests/data/test_history.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/history/__init__.py b/freqtrade/data/history/__init__.py index 572c063fc..23f635a98 100644 --- a/freqtrade/data/history/__init__.py +++ b/freqtrade/data/history/__init__.py @@ -11,4 +11,4 @@ from .history_utils import (convert_trades_to_ohlcv, # noqa: F401 refresh_backtest_ohlcv_data, refresh_backtest_trades_data, refresh_data, validate_backtest_data) -from .idatahandler import get_datahandler, get_datahandlerclass # noqa: F401 +from .idatahandler import get_datahandler # noqa: F401 diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 404f52e87..2341673db 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -13,13 +13,13 @@ from pandas.testing import assert_frame_equal from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe -from freqtrade.data.history import get_datahandler, get_datahandlerclass from freqtrade.data.history.history_utils import ( _download_pair_history, _download_trades_history, _load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange, load_data, load_pair_history, refresh_backtest_ohlcv_data, refresh_backtest_trades_data, refresh_data, validate_backtest_data) -from freqtrade.data.history.idatahandler import IDataHandler +from freqtrade.data.history.idatahandler import (IDataHandler, get_datahandler, + get_datahandlerclass) from freqtrade.data.history.jsondatahandler import (JsonDataHandler, JsonGzDataHandler) from freqtrade.exchange import timeframe_to_minutes From 6b5983339d8d94d90c51f0dbb51f1948fed4bbea Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 14:47:30 +0100 Subject: [PATCH 0147/1106] Require dataformat entries in configuration --- freqtrade/constants.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 95ec71552..a7f569f63 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -294,5 +294,7 @@ CONF_SCHEMA = { 'stoploss', 'minimal_roi', 'internals', + 'dataformat_ohlcv', + 'dataformat_trades', ] } From f4a532ef6d3ed63751de5c688338af1036741d7f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 14:57:39 +0100 Subject: [PATCH 0148/1106] Pass format to load_data --- freqtrade/data/history/history_utils.py | 2 +- freqtrade/edge/__init__.py | 1 + freqtrade/optimize/backtesting.py | 1 + freqtrade/plot/plotting.py | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 42f1c9be7..1f0459379 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -72,7 +72,7 @@ def load_data(datadir: Path, :param fill_up_missing: Fill missing values with "No action"-candles :param startup_candles: Additional candles to load at the start of the period :param fail_without_data: Raise OperationalException if no data is found. - :param data_handler: Initialized data-handler to use. + :param data_format: Data format which should be used. Defaults to json :return: dict(:) """ result: Dict[str, DataFrame] = {} diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 9ad2485ef..44eaad717 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -108,6 +108,7 @@ class Edge: timeframe=self.strategy.ticker_interval, timerange=self._timerange, startup_candles=self.strategy.startup_candle_count, + data_format=self.config.get('dataformat_ohlcv', 'json'), ) if not data: diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 98ee71a60..e49c0bd80 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -116,6 +116,7 @@ class Backtesting: timerange=timerange, startup_candles=self.required_startup, fail_without_data=True, + data_format=self.config.get('dataformat_ohlcv', 'json'), ) min_date, max_date = history.get_timerange(data) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 0ef71ed82..7c7f10fdc 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -42,6 +42,7 @@ def init_plotscript(config): pairs=pairs, timeframe=config.get('ticker_interval', '5m'), timerange=timerange, + data_format=config.get('dataformat_ohlcv', 'json'), ) trades = load_trades(config['trade_source'], From 814cc20c6b94ea0c34b8303dbb14c373f6f0290f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 28 Dec 2019 19:58:41 +0100 Subject: [PATCH 0149/1106] Remove potential circular import --- freqtrade/data/converter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index abc754df0..49a2a25bc 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -8,7 +8,6 @@ from typing import Any, Dict import pandas as pd from pandas import DataFrame, to_datetime -from freqtrade.configuration.timerange import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS logger = logging.getLogger(__name__) @@ -116,7 +115,7 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) return df -def trim_dataframe(df: DataFrame, timerange: TimeRange, df_date_col: str = 'date') -> DataFrame: +def trim_dataframe(df: DataFrame, timerange, df_date_col: str = 'date') -> DataFrame: """ Trim dataframe based on given timerange :param df: Dataframe to trim From 762604300f26afb5712d0ac92f01a57048a63f9e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 29 Dec 2019 04:17:49 +0300 Subject: [PATCH 0150/1106] Refactor create_trades() --- freqtrade/freqtradebot.py | 104 ++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 90eb7beba..d15624e9f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -294,65 +294,48 @@ class FreqtradeBot: # See also #2575 at github. return max(min_stake_amounts) / amount_reserve_percent - def create_trades(self) -> bool: + def create_trade(self, pair: str) -> bool: """ - Checks the implemented trading strategy for buy-signals, using the active pair whitelist. - If a pair triggers the buy_signal a new trade record gets created. - Checks pairs as long as the open trade count is below `max_open_trades`. - :return: True if at least one trade has been created. + Check the implemented trading strategy for buy-signals. + If the pair triggers the buy_signal a new trade record gets created. + :return: True if a trade has been created. """ - whitelist = copy.deepcopy(self.active_pair_whitelist) + logger.debug(f"create_trade for pair {pair}") - if not whitelist: - logger.info("Active pair whitelist is empty.") + if self.strategy.is_pair_locked(pair): + logger.info(f"Pair {pair} is currently locked.") return False - # Remove currently opened and latest pairs from whitelist - for trade in Trade.get_open_trades(): - if trade.pair in whitelist: - whitelist.remove(trade.pair) - logger.debug('Ignoring %s in pair whitelist', trade.pair) - - if not whitelist: - logger.info("No currency pair in active pair whitelist, " - "but checking to sell open trades.") - return False - - buycount = 0 # running get_signal on historical data fetched - for pair in whitelist: - if self.strategy.is_pair_locked(pair): - logger.info(f"Pair {pair} is currently locked.") - continue + (buy, sell) = self.strategy.get_signal( + pair, self.strategy.ticker_interval, + self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) - (buy, sell) = self.strategy.get_signal( - pair, self.strategy.ticker_interval, - self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) + if buy and not sell: + if not self.get_free_open_trades(): + logger.debug("Can't open a new trade: max number of trades is reached") + return False - if buy and not sell: - if not self.get_free_open_trades(): - logger.debug("Can't open a new trade: max number of trades is reached") - continue + stake_amount = self.get_trade_stake_amount(pair) + if not stake_amount: + logger.debug("Stake amount is 0, ignoring possible trade for {pair}.") + return False - stake_amount = self.get_trade_stake_amount(pair) - if not stake_amount: - logger.debug("Stake amount is 0, ignoring possible trade for {pair}.") - continue + logger.info(f"Buy signal found: about create a new trade with stake_amount: " + f"{stake_amount} ...") - logger.info(f"Buy signal found: about create a new trade with stake_amount: " - f"{stake_amount} ...") + bidstrat_check_depth_of_market = self.config.get('bid_strategy', {}).\ + get('check_depth_of_market', {}) + if (bidstrat_check_depth_of_market.get('enabled', False)) and\ + (bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0): + if self._check_depth_of_market_buy(pair, bidstrat_check_depth_of_market): + return self.execute_buy(pair, stake_amount) + else: + return False - bidstrat_check_depth_of_market = self.config.get('bid_strategy', {}).\ - get('check_depth_of_market', {}) - if (bidstrat_check_depth_of_market.get('enabled', False)) and\ - (bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0): - if self._check_depth_of_market_buy(pair, bidstrat_check_depth_of_market): - buycount += self.execute_buy(pair, stake_amount) - continue - - buycount += self.execute_buy(pair, stake_amount) - - return buycount > 0 + return self.execute_buy(pair, stake_amount) + else: + return False def _check_depth_of_market_buy(self, pair: str, conf: Dict) -> bool: """ @@ -479,10 +462,31 @@ class FreqtradeBot: """ Tries to execute buy orders for trades in a safe way """ + result = False try: - # Create entity and execute trade - if not self.create_trades(): + whitelist = copy.deepcopy(self.active_pair_whitelist) + + if not whitelist: + logger.info("Active pair whitelist is empty.") + else: + # Remove currently opened and latest pairs from whitelist + for trade in Trade.get_open_trades(): + if trade.pair in whitelist: + whitelist.remove(trade.pair) + logger.debug('Ignoring %s in pair whitelist', trade.pair) + + if not whitelist: + logger.info("No currency pair in active pair whitelist, " + "but checking to sell open trades.") + else: + # Create entity and execute trade for each pair from whitelist + for pair in whitelist: + if self.create_trade(pair): + result = True + + if not result: logger.debug('Found no buy signals for whitelisted currencies. Trying again...') + except DependencyException as exception: logger.warning('Unable to create trade: %s', exception) From ce84f74528de4ee06977967a859722b68a1f6b31 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 29 Dec 2019 04:38:28 +0300 Subject: [PATCH 0151/1106] Adjust tests --- tests/rpc/test_rpc.py | 22 ++--- tests/rpc/test_rpc_apiserver.py | 8 +- tests/rpc/test_rpc_telegram.py | 22 ++--- tests/test_freqtradebot.py | 151 ++++++++++++++++---------------- tests/test_integration.py | 4 +- 5 files changed, 105 insertions(+), 102 deletions(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 3b897572c..a9f73e98d 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -41,7 +41,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() results = rpc._rpc_trade_status() assert { 'trade_id': 1, @@ -116,7 +116,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: with pytest.raises(RPCException, match=r'.*no active order*'): rpc._rpc_status_table(default_conf['stake_currency'], 'USD') - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert "Since" in headers @@ -162,7 +162,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -217,7 +217,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -231,7 +231,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, trade.close_date = datetime.utcnow() trade.is_open = False - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -299,7 +299,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, rpc = RPC(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -529,7 +529,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: msg = rpc._rpc_forcesell('all') assert msg == {'result': 'Created sell orders for all open trades.'} - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() msg = rpc._rpc_forcesell('all') assert msg == {'result': 'Created sell orders for all open trades.'} @@ -563,7 +563,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 1 assert trade.amount == filled_amount - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.filter(Trade.id == '2').first() amount = trade.amount # make an limit-buy open trade, if there is no 'filled', don't sell it @@ -582,7 +582,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 2 assert trade.amount == amount - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() # make an limit-sell open trade mocker.patch( 'freqtrade.exchange.Exchange.get_order', @@ -613,7 +613,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee, rpc = RPC(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -649,7 +649,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None: assert counts["current"] == 0 # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() counts = rpc._rpc_count() assert counts["current"] == 1 diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 36bb81e41..94af85349 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -267,7 +267,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets): assert rc.json["max"] == 1.0 # Create some test data - ftbot.create_trades() + ftbot.process_maybe_execute_buys() rc = client_get(client, f"{BASE_URI}/count") assert_response(rc) assert rc.json["current"] == 1.0 @@ -333,7 +333,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li assert len(rc.json) == 1 assert rc.json == {"error": "Error querying _profit: no closed trade"} - ftbot.create_trades() + ftbot.process_maybe_execute_buys() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade @@ -422,7 +422,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets): assert_response(rc, 200) assert rc.json == [] - ftbot.create_trades() + ftbot.process_maybe_execute_buys() rc = client_get(client, f"{BASE_URI}/status") assert_response(rc) assert len(rc.json) == 1 @@ -552,7 +552,7 @@ def test_api_forcesell(botclient, mocker, ticker, fee, markets): assert_response(rc, 502) assert rc.json == {"error": "Error querying _forcesell: invalid argument"} - ftbot.create_trades() + ftbot.process_maybe_execute_buys() rc = client_post(client, f"{BASE_URI}/forcesell", data='{"tradeid": "1"}') diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index f8b9ca8ab..d9a7e2f5b 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -189,7 +189,7 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: # Create some test data for _ in range(3): - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() telegram._status(update=update, context=MagicMock()) assert msg_mock.call_count == 1 @@ -236,7 +236,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None: msg_mock.reset_mock() # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() # Trigger status while we have a fulfilled order for the open trade telegram._status(update=update, context=MagicMock()) @@ -285,7 +285,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: msg_mock.reset_mock() # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() telegram._status_table(update=update, context=MagicMock()) @@ -322,7 +322,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -352,7 +352,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, msg_mock.reset_mock() freqtradebot.config['max_open_trades'] = 2 # Add two other trades - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trades = Trade.query.all() for trade in trades: @@ -431,7 +431,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, msg_mock.reset_mock() # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade @@ -709,7 +709,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -764,7 +764,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() # Decrease the price and sell it mocker.patch.multiple( @@ -821,7 +821,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() rpc_mock.reset_mock() # /forcesell all @@ -971,7 +971,7 @@ def test_performance_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -1014,7 +1014,7 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: freqtradebot.state = State.RUNNING # Create some test data - freqtradebot.create_trades() + freqtradebot.process_maybe_execute_buys() msg_mock.reset_mock() telegram._count(update=update, context=MagicMock()) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 2f8c786fd..be6a9b392 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -247,7 +247,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf freqtrade.active_pair_whitelist = ['NEO/BTC'] patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) ############################################# @@ -287,7 +287,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, freqtrade.active_pair_whitelist = ['NEO/BTC'] patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) ############################################# @@ -310,7 +310,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker, ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade is not None @@ -318,7 +318,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker, assert trade.is_open assert trade.open_date is not None - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.order_by(Trade.id.desc()).first() assert trade is not None @@ -462,7 +462,7 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: assert round(result, 8) == round(max(0.0001, 0.001 * 0.020405) / 0.9, 8) -def test_create_trades(default_conf, ticker, limit_buy_order, fee, mocker) -> None: +def test_create_trade(default_conf, ticker, limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -476,7 +476,7 @@ def test_create_trades(default_conf, ticker, limit_buy_order, fee, mocker) -> No whitelist = deepcopy(default_conf['exchange']['pair_whitelist']) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.create_trade('ETH/BTC') trade = Trade.query.first() assert trade is not None @@ -494,8 +494,8 @@ def test_create_trades(default_conf, ticker, limit_buy_order, fee, mocker) -> No assert whitelist == default_conf['exchange']['pair_whitelist'] -def test_create_trades_no_stake_amount(default_conf, ticker, limit_buy_order, - fee, mocker) -> None: +def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order, + fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) patch_wallet(mocker, free=default_conf['stake_amount'] * 0.5) @@ -509,11 +509,11 @@ def test_create_trades_no_stake_amount(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade) with pytest.raises(DependencyException, match=r'.*stake amount.*'): - freqtrade.create_trades() + freqtrade.create_trade('ETH/BTC') -def test_create_trades_minimal_amount(default_conf, ticker, limit_buy_order, - fee, mocker) -> None: +def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order, + fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) buy_mock = MagicMock(return_value={'id': limit_buy_order['id']}) @@ -527,13 +527,13 @@ def test_create_trades_minimal_amount(default_conf, ticker, limit_buy_order, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.create_trade('ETH/BTC') rate, amount = buy_mock.call_args[1]['rate'], buy_mock.call_args[1]['amount'] assert rate * amount >= default_conf['stake_amount'] -def test_create_trades_too_small_stake_amount(default_conf, ticker, limit_buy_order, - fee, mocker) -> None: +def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_order, + fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) buy_mock = MagicMock(return_value={'id': limit_buy_order['id']}) @@ -549,11 +549,11 @@ def test_create_trades_too_small_stake_amount(default_conf, ticker, limit_buy_or patch_get_signal(freqtrade) - assert not freqtrade.create_trades() + assert not freqtrade.create_trade('ETH/BTC') -def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order, - fee, markets, mocker) -> None: +def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, + fee, markets, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -569,12 +569,13 @@ def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - assert not freqtrade.create_trades() + assert not freqtrade.create_trade('ETH/BTC') assert freqtrade.get_trade_stake_amount('ETH/BTC') is None -def test_create_trades_no_pairs_let(default_conf, ticker, limit_buy_order, fee, - mocker, caplog) -> None: +def test_process_maybe_execute_buys_no_pairs_let(default_conf, ticker, + limit_buy_order, fee, + mocker, caplog) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -588,14 +589,15 @@ def test_create_trades_no_pairs_let(default_conf, ticker, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - assert freqtrade.create_trades() - assert not freqtrade.create_trades() - assert log_has("No currency pair in active pair whitelist, " - "but checking to sell open trades.", caplog) + freqtrade.process_maybe_execute_buys() + assert not log_has_re(r"No currency pair in active pair whitelist.*", caplog) + freqtrade.process_maybe_execute_buys() + assert log_has_re(r"No currency pair in active pair whitelist.*", caplog) -def test_create_trades_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee, - mocker, caplog) -> None: +def test_process_maybe_execute_buys_no_pairs_in_whitelist(default_conf, ticker, + limit_buy_order, fee, + mocker, caplog) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -608,11 +610,11 @@ def test_create_trades_no_pairs_in_whitelist(default_conf, ticker, limit_buy_ord freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - assert not freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() assert log_has("Active pair whitelist is empty.", caplog) -def test_create_trades_no_signal(default_conf, fee, mocker) -> None: +def test_create_trade_no_signal(default_conf, fee, mocker) -> None: default_conf['dry_run'] = True patch_RPCManager(mocker) @@ -628,7 +630,7 @@ def test_create_trades_no_signal(default_conf, fee, mocker) -> None: Trade.query = MagicMock() Trade.query.filter = MagicMock() - assert not freqtrade.create_trades() + assert not freqtrade.create_trade('ETH/BTC') @pytest.mark.parametrize("max_open", range(0, 5)) @@ -646,7 +648,7 @@ def test_create_trades_multiple_trades(default_conf, ticker, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trades = Trade.get_open_trades() assert len(trades) == max_open @@ -672,7 +674,8 @@ def test_create_trades_preopen(default_conf, ticker, fee, mocker) -> None: assert len(Trade.get_open_trades()) == 2 # Create 2 new trades using create_trades - assert freqtrade.create_trades() + assert freqtrade.create_trade('ETH/BTC') + assert freqtrade.create_trade('NEO/BTC') trades = Trade.get_open_trades() assert len(trades) == 4 @@ -1056,7 +1059,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # should unset stoploss_order_id and return true # as a trade actually happened caplog.clear() - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1114,7 +1117,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True trade.open_order_id = '12345' @@ -1149,7 +1152,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee, patch_get_signal(freqtrade) freqtrade.strategy.order_types['stoploss_on_exchange'] = True - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() caplog.clear() freqtrade.create_stoploss_order(trade, 200, 199) @@ -1207,7 +1210,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1295,7 +1298,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c # setting stoploss_on_exchange_interval to 60 seconds freqtrade.strategy.order_types['stoploss_on_exchange_interval'] = 60 patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1376,7 +1379,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, freqtrade.active_pair_whitelist = freqtrade.edge.adjust(freqtrade.active_pair_whitelist) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1444,7 +1447,7 @@ def test_process_maybe_execute_buys(mocker, default_conf, caplog) -> None: caplog.set_level(logging.DEBUG) freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trades', MagicMock(return_value=False)) + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(return_value=False)) freqtrade.process_maybe_execute_buys() assert log_has('Found no buy signals for whitelisted currencies. Trying again...', caplog) @@ -1453,7 +1456,7 @@ def test_process_maybe_execute_buys_exception(mocker, default_conf, caplog) -> N freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch( - 'freqtrade.freqtradebot.FreqtradeBot.create_trades', + 'freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(side_effect=DependencyException) ) freqtrade.process_maybe_execute_buys() @@ -1674,7 +1677,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -1711,7 +1714,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, patch_get_signal(freqtrade, value=(True, True)) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() # Buy and Sell triggering, so doing nothing ... trades = Trade.query.all() @@ -1720,7 +1723,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, # Buy is triggering, so buying ... patch_get_signal(freqtrade, value=(True, False)) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trades = Trade.query.all() nb_trades = len(trades) assert nb_trades == 1 @@ -1764,7 +1767,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade, value=(True, False)) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True @@ -1795,7 +1798,7 @@ def test_handle_trade_use_sell_signal( freqtrade = get_patched_freqtradebot(mocker, default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.is_open = True @@ -1823,7 +1826,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, patch_get_signal(freqtrade) # Create trade and sell it - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2183,7 +2186,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2231,7 +2234,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2281,7 +2284,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2339,7 +2342,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, c freqtrade.strategy.order_types['stoploss_on_exchange'] = True patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() Trade.session = MagicMock() @@ -2382,7 +2385,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2432,7 +2435,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trades = [trade] freqtrade.process_maybe_execute_sells(trades) @@ -2484,7 +2487,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2546,7 +2549,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2577,7 +2580,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2608,7 +2611,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker patch_get_signal(freqtrade) freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple( sell_flag=False, sell_type=SellType.NONE)) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2638,7 +2641,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2667,7 +2670,7 @@ def test_sell_not_enough_balance(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() amnt = trade.amount @@ -2735,7 +2738,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -2754,7 +2757,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo # reinit - should buy other pair. caplog.clear() - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() assert log_has(f"Pair {trade.pair} is currently locked.", caplog) @@ -2779,7 +2782,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2812,7 +2815,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert freqtrade.handle_trade(trade) is False @@ -2867,7 +2870,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2924,7 +2927,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2987,7 +2990,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -3046,7 +3049,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trade.update(limit_buy_order) @@ -3377,7 +3380,7 @@ def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee, whitelist = deepcopy(default_conf['exchange']['pair_whitelist']) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade is not None @@ -3412,7 +3415,7 @@ def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_o # Save state of current whitelist freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade is None @@ -3514,7 +3517,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trade = Trade.query.first() assert trade @@ -3604,7 +3607,7 @@ def test_process_i_am_alive(default_conf, mocker, caplog): @pytest.mark.usefixtures("init_persistence") -def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order): +def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, caplog): default_conf['dry_run'] = True # Initialize to 2 times stake amount default_conf['dry_run_wallet'] = 0.002 @@ -3621,12 +3624,12 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order) patch_get_signal(bot) assert bot.wallets.get_free('BTC') == 0.002 - bot.create_trades() + bot.process_maybe_execute_buys() trades = Trade.query.all() assert len(trades) == 2 bot.config['max_open_trades'] = 3 - with pytest.raises( - DependencyException, - match=r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)"): - bot.create_trades() + bot.process_maybe_execute_buys() + assert log_has_re(r"Unable to create trade: " + r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)", + caplog) diff --git a/tests/test_integration.py b/tests/test_integration.py index 11dbca225..2c95bc6e3 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -80,7 +80,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, patch_get_signal(freqtrade) # Create some test data - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() wallets_mock.reset_mock() Trade.session = MagicMock() @@ -153,7 +153,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc patch_get_signal(freqtrade) # Create 4 trades - freqtrade.create_trades() + freqtrade.process_maybe_execute_buys() trades = Trade.query.all() assert len(trades) == 4 From 04f28ed9bcd337e6f0dbdddd0c1d51f62e67c613 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 29 Dec 2019 05:03:10 +0300 Subject: [PATCH 0152/1106] Refactor try/except: handle DependencyException for each pair separately --- freqtrade/freqtradebot.py | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d15624e9f..e47a4a85c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -463,32 +463,32 @@ class FreqtradeBot: Tries to execute buy orders for trades in a safe way """ result = False - try: - whitelist = copy.deepcopy(self.active_pair_whitelist) + + whitelist = copy.deepcopy(self.active_pair_whitelist) + if not whitelist: + logger.info("Active pair whitelist is empty.") + else: + # Remove currently opened and latest pairs from whitelist + for trade in Trade.get_open_trades(): + if trade.pair in whitelist: + whitelist.remove(trade.pair) + logger.debug('Ignoring %s in pair whitelist', trade.pair) if not whitelist: - logger.info("Active pair whitelist is empty.") + logger.info("No currency pair in active pair whitelist, " + "but checking to sell open trades.") else: - # Remove currently opened and latest pairs from whitelist - for trade in Trade.get_open_trades(): - if trade.pair in whitelist: - whitelist.remove(trade.pair) - logger.debug('Ignoring %s in pair whitelist', trade.pair) - - if not whitelist: - logger.info("No currency pair in active pair whitelist, " - "but checking to sell open trades.") - else: - # Create entity and execute trade for each pair from whitelist - for pair in whitelist: + # Create entity and execute trade for each pair from whitelist + for pair in whitelist: + try: if self.create_trade(pair): result = True + except DependencyException as exception: + logger.warning('Unable to create trade: %s', exception) - if not result: - logger.debug('Found no buy signals for whitelisted currencies. Trying again...') - - except DependencyException as exception: - logger.warning('Unable to create trade: %s', exception) + if not result: + logger.debug("Found no buy signals for whitelisted currencies. " + "Trying again...") def process_maybe_execute_sells(self, trades: List[Any]) -> None: """ From d1c45cf3f869968523f5b84e7949efd8130e166d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Dec 2019 13:07:51 +0100 Subject: [PATCH 0153/1106] Update analysis documentation to include kernel installation --- docs/data-analysis.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/data-analysis.md b/docs/data-analysis.md index 115ce1916..8786a1199 100644 --- a/docs/data-analysis.md +++ b/docs/data-analysis.md @@ -8,6 +8,27 @@ You can analyze the results of backtests and trading history easily using Jupyte * Don't forget to start a Jupyter notebook server from within your conda or venv environment or use [nb_conda_kernels](https://github.com/Anaconda-Platform/nb_conda_kernels)* * Copy the example notebook before use so your changes don't get clobbered with the next freqtrade update. +### Using virtual environment with System jupyter + +Sometimes it can be desired to use a system-wide installation of Jupyter notebook, and use a jupyter kernel from the virtual environment. +This prevents you from installing the full jupyter suite multiple times per system, and provides an easy way to switch between tasks (freqtrade / other analytics tasks). + +For this to work, first activate your virtual environment and run the following commands: + +``` bash +# Activate virtual environment +source .env/bin/activate + +pip install ipykernel +ipython kernel install --user --name=freqtrade +# Restart jupyter (lab / notebook) +# select kernel "freqtrade" in the notebook +``` + +!!! Note + This section is provided for completeness, the Freqtrade Team won't provide full support for problems with this setup and will recommend to install Jupyter in the virtual environment directly, as that is the easiest way to get up and running. For help with this setup please refer to the [Project Jupyter](https://jupyter.org/) [documentation](https://jupyter.org/documentation) or [help channels](https://jupyter.org/community). + + ## Fine print Some tasks don't work especially well in notebooks. For example, anything using asynchronous execution is a problem for Jupyter. Also, freqtrade's primary entry point is the shell cli, so using pure python in a notebook bypasses arguments that provide required objects and parameters to helper functions. You may need to set those values or create expected objects manually. From 304d15e23694d1dc3ac1f85760dbc3af9996710a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Dec 2019 19:35:42 +0100 Subject: [PATCH 0154/1106] Small corrections --- docs/data-analysis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data-analysis.md b/docs/data-analysis.md index 8786a1199..fc4693b17 100644 --- a/docs/data-analysis.md +++ b/docs/data-analysis.md @@ -8,7 +8,7 @@ You can analyze the results of backtests and trading history easily using Jupyte * Don't forget to start a Jupyter notebook server from within your conda or venv environment or use [nb_conda_kernels](https://github.com/Anaconda-Platform/nb_conda_kernels)* * Copy the example notebook before use so your changes don't get clobbered with the next freqtrade update. -### Using virtual environment with System jupyter +### Using virtual environment with system-wide Jupyter installation Sometimes it can be desired to use a system-wide installation of Jupyter notebook, and use a jupyter kernel from the virtual environment. This prevents you from installing the full jupyter suite multiple times per system, and provides an easy way to switch between tasks (freqtrade / other analytics tasks). @@ -26,7 +26,7 @@ ipython kernel install --user --name=freqtrade ``` !!! Note - This section is provided for completeness, the Freqtrade Team won't provide full support for problems with this setup and will recommend to install Jupyter in the virtual environment directly, as that is the easiest way to get up and running. For help with this setup please refer to the [Project Jupyter](https://jupyter.org/) [documentation](https://jupyter.org/documentation) or [help channels](https://jupyter.org/community). + This section is provided for completeness, the Freqtrade Team won't provide full support for problems with this setup and will recommend to install Jupyter in the virtual environment directly, as that is the easiest way to get jupyter notebooks up and running. For help with this setup please refer to the [Project Jupyter](https://jupyter.org/) [documentation](https://jupyter.org/documentation) or [help channels](https://jupyter.org/community). ## Fine print From df7ceb4ccbbfd35fe7eaec2d37dea273b89a4873 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Dec 2019 19:51:47 +0100 Subject: [PATCH 0155/1106] Fix misinformation in /status table --- freqtrade/rpc/rpc.py | 2 +- tests/rpc/test_rpc.py | 2 +- tests/rpc/test_rpc_telegram.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 35c312743..0a79d350b 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -142,7 +142,7 @@ class RPC: def _rpc_status_table(self, stake_currency, fiat_display_currency: str) -> Tuple[List, List]: trades = Trade.get_open_trades() if not trades: - raise RPCException('no active order') + raise RPCException('no active trade') else: trades_list = [] for trade in trades: diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 3b897572c..c5bb0ca2c 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -113,7 +113,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: rpc = RPC(freqtradebot) freqtradebot.state = State.RUNNING - with pytest.raises(RPCException, match=r'.*no active order*'): + with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_status_table(default_conf['stake_currency'], 'USD') freqtradebot.create_trades() diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index f8b9ca8ab..ddbc35bd5 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -275,13 +275,13 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: # Status table is also enabled when stopped telegram._status_table(update=update, context=MagicMock()) assert msg_mock.call_count == 1 - assert 'no active order' in msg_mock.call_args_list[0][0][0] + assert 'no active trade' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() freqtradebot.state = State.RUNNING telegram._status_table(update=update, context=MagicMock()) assert msg_mock.call_count == 1 - assert 'no active order' in msg_mock.call_args_list[0][0][0] + assert 'no active trade' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() # Create some test data From 20a132651f460b3ab00f4e4032173b8c58eb7bba Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2019 07:34:49 +0000 Subject: [PATCH 0156/1106] Bump ccxt from 1.21.12 to 1.21.23 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.12 to 1.21.23. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.12...1.21.23) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 9d0fd4756..add1ea0fd 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.12 +ccxt==1.21.23 SQLAlchemy==1.3.12 python-telegram-bot==12.2.0 arrow==0.15.4 From de23f3928de5639a01efe424e5040354196c59e8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 09:56:42 +0100 Subject: [PATCH 0157/1106] Add trailing_only_offset to template and sample --- freqtrade/templates/base_strategy.py.j2 | 1 + freqtrade/templates/sample_strategy.py | 1 + 2 files changed, 2 insertions(+) diff --git a/freqtrade/templates/base_strategy.py.j2 b/freqtrade/templates/base_strategy.py.j2 index 73a4c7a5a..32573ec9e 100644 --- a/freqtrade/templates/base_strategy.py.j2 +++ b/freqtrade/templates/base_strategy.py.j2 @@ -47,6 +47,7 @@ class {{ strategy }}(IStrategy): # Trailing stoploss trailing_stop = False + # trailing_only_offset_is_reached = False # trailing_stop_positive = 0.01 # trailing_stop_positive_offset = 0.0 # Disabled / not configured diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index 02bf24e7e..228e56b82 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -48,6 +48,7 @@ class SampleStrategy(IStrategy): # Trailing stoploss trailing_stop = False + # trailing_only_offset_is_reached = False # trailing_stop_positive = 0.01 # trailing_stop_positive_offset = 0.0 # Disabled / not configured From 4c9295fe2d657fdf373601ea8d2350fb1990ebc8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 14:00:34 +0100 Subject: [PATCH 0158/1106] Rename Bid-strategy helpervariable to something shorter avoids unnecessary wrapping... --- freqtrade/freqtradebot.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e47a4a85c..68091ed76 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -313,7 +313,7 @@ class FreqtradeBot: if buy and not sell: if not self.get_free_open_trades(): - logger.debug("Can't open a new trade: max number of trades is reached") + logger.debug("Can't open a new trade: max number of trades is reached.") return False stake_amount = self.get_trade_stake_amount(pair) @@ -324,11 +324,10 @@ class FreqtradeBot: logger.info(f"Buy signal found: about create a new trade with stake_amount: " f"{stake_amount} ...") - bidstrat_check_depth_of_market = self.config.get('bid_strategy', {}).\ - get('check_depth_of_market', {}) - if (bidstrat_check_depth_of_market.get('enabled', False)) and\ - (bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0): - if self._check_depth_of_market_buy(pair, bidstrat_check_depth_of_market): + bid_check_dom = self.config.get('bid_strategy', {}).get('check_depth_of_market', {}) + if ((bid_check_dom.get('enabled', False)) and + (bid_check_dom.get('bids_to_ask_delta', 0) > 0)): + if self._check_depth_of_market_buy(pair, bid_check_dom): return self.execute_buy(pair, stake_amount) else: return False From fb3a53b8af27c49eb4c8a26c271437a581dd187e Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 14:28:34 +0100 Subject: [PATCH 0159/1106] Use ExchangeResolver for edge_cli too --- freqtrade/optimize/edge_cli.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index ea5cc663d..4944f1dbb 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -12,8 +12,7 @@ from freqtrade import constants from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) from freqtrade.edge import Edge -from freqtrade.exchange import Exchange -from freqtrade.resolvers import StrategyResolver +from freqtrade.resolvers import StrategyResolver, ExchangeResolver logger = logging.getLogger(__name__) @@ -33,7 +32,7 @@ class EdgeCli: # Reset keys for edge remove_credentials(self.config) self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT - self.exchange = Exchange(self.config) + self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) self.strategy = StrategyResolver.load_strategy(self.config) validate_config_consistency(self.config) From 20abf67779a1c9f778e6339df0abd0af63433154 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 14:29:36 +0100 Subject: [PATCH 0160/1106] Add Debug "code" for randomly failing test --- tests/test_utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_utils.py b/tests/test_utils.py index 4cf7b5f23..8545eb817 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -448,6 +448,9 @@ def test_create_datadir(caplog, mocker): # Ensure that caplog is empty before starting ... # Should prevent random failures. caplog.clear() + # Added assert here to analyze random test-failures ... + assert len(caplog.record_tuples) == 0 + cud = mocker.patch("freqtrade.utils.create_userdata_dir", MagicMock()) csf = mocker.patch("freqtrade.utils.copy_sample_files", MagicMock()) args = [ From 024aa3ab6b6e5e0ba11bf7cfe0035cb83423bbf3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 14:57:26 +0100 Subject: [PATCH 0161/1106] Move exceptions to seperate module --- freqtrade/__init__.py | 31 ------------------------------- freqtrade/exceptions.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 freqtrade/exceptions.py diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 83fee0b0d..e1f65d4fe 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -11,34 +11,3 @@ if __version__ == 'develop': except Exception: # git not available, ignore pass - - -class DependencyException(Exception): - """ - Indicates that an assumed dependency is not met. - This could happen when there is currently not enough money on the account. - """ - - -class OperationalException(Exception): - """ - Requires manual intervention and will usually stop the bot. - This happens when an exchange returns an unexpected error during runtime - or given configuration is invalid. - """ - - -class InvalidOrderException(Exception): - """ - This is returned when the order is not valid. Example: - If stoploss on exchange order is hit, then trying to cancel the order - should return this exception. - """ - - -class TemporaryError(Exception): - """ - Temporary network or exchange related error. - This could happen when an exchange is congested, unavailable, or the user - has networking problems. Usually resolves itself after a time. - """ diff --git a/freqtrade/exceptions.py b/freqtrade/exceptions.py new file mode 100644 index 000000000..80d45dd86 --- /dev/null +++ b/freqtrade/exceptions.py @@ -0,0 +1,31 @@ + + +class DependencyException(Exception): + """ + Indicates that an assumed dependency is not met. + This could happen when there is currently not enough money on the account. + """ + + +class OperationalException(Exception): + """ + Requires manual intervention and will usually stop the bot. + This happens when an exchange returns an unexpected error during runtime + or given configuration is invalid. + """ + + +class InvalidOrderException(Exception): + """ + This is returned when the order is not valid. Example: + If stoploss on exchange order is hit, then trying to cancel the order + should return this exception. + """ + + +class TemporaryError(Exception): + """ + Temporary network or exchange related error. + This could happen when an exchange is congested, unavailable, or the user + has networking problems. Usually resolves itself after a time. + """ From 1ffda29fd2aeb95cffedfaded274c4d07e404436 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 15:02:17 +0100 Subject: [PATCH 0162/1106] Adjust improts to new exception location --- freqtrade/configuration/check_exchange.py | 4 ++-- freqtrade/configuration/config_validation.py | 3 ++- freqtrade/configuration/configuration.py | 5 +++-- freqtrade/configuration/deprecated_settings.py | 2 +- freqtrade/configuration/directory_operations.py | 2 +- freqtrade/configuration/load_config.py | 2 +- freqtrade/data/history.py | 6 ++++-- freqtrade/edge/__init__.py | 4 ++-- freqtrade/exchange/binance.py | 4 ++-- freqtrade/exchange/common.py | 2 +- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/exchange/kraken.py | 2 +- freqtrade/freqtradebot.py | 6 +++--- freqtrade/loggers.py | 2 +- freqtrade/main.py | 2 +- freqtrade/optimize/__init__.py | 4 ++-- freqtrade/optimize/backtesting.py | 2 +- freqtrade/optimize/hyperopt.py | 6 +++--- freqtrade/optimize/hyperopt_interface.py | 6 ++---- freqtrade/pairlist/VolumePairList.py | 2 +- freqtrade/pairlist/pairlistmanager.py | 5 +++-- freqtrade/persistence.py | 2 +- freqtrade/plot/plot_utils.py | 2 +- freqtrade/resolvers/hyperopt_resolver.py | 2 +- freqtrade/resolvers/iresolver.py | 2 +- freqtrade/resolvers/strategy_resolver.py | 2 +- freqtrade/rpc/rpc.py | 2 +- freqtrade/utils.py | 2 +- freqtrade/worker.py | 4 ++-- tests/edge/test_edge.py | 2 +- tests/exchange/test_binance.py | 4 ++-- tests/exchange/test_exchange.py | 4 ++-- tests/optimize/test_backtesting.py | 4 ++-- tests/optimize/test_hyperopt.py | 2 +- tests/pairlist/test_pairlist.py | 2 +- tests/rpc/test_rpc.py | 4 ++-- tests/strategy/test_strategy.py | 2 +- tests/test_configuration.py | 2 +- tests/test_directory_operations.py | 2 +- tests/test_freqtradebot.py | 10 +++++----- tests/test_main.py | 2 +- tests/test_persistence.py | 3 ++- tests/test_plotting.py | 6 +++--- tests/test_utils.py | 2 +- 44 files changed, 74 insertions(+), 70 deletions(-) diff --git a/freqtrade/configuration/check_exchange.py b/freqtrade/configuration/check_exchange.py index c739de692..0076b1c5d 100644 --- a/freqtrade/configuration/check_exchange.py +++ b/freqtrade/configuration/check_exchange.py @@ -1,9 +1,9 @@ import logging from typing import Any, Dict -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason, - is_exchange_known_ccxt, is_exchange_bad, + is_exchange_bad, is_exchange_known_ccxt, is_exchange_officially_supported) from freqtrade.state import RunMode diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 068364884..43eead46a 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -4,7 +4,8 @@ from typing import Any, Dict from jsonschema import Draft4Validator, validators from jsonschema.exceptions import ValidationError, best_match -from freqtrade import constants, OperationalException +from freqtrade import constants +from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode logger = logging.getLogger(__name__) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index f73b52c10..a8b7638c8 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -7,15 +7,16 @@ from copy import deepcopy from pathlib import Path from typing import Any, Callable, Dict, List, Optional -from freqtrade import OperationalException, constants +from freqtrade import constants from freqtrade.configuration.check_exchange import check_exchange from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings from freqtrade.configuration.directory_operations import (create_datadir, create_userdata_dir) from freqtrade.configuration.load_config import load_config_file +from freqtrade.exceptions import OperationalException from freqtrade.loggers import setup_logging from freqtrade.misc import deep_merge_dicts, json_load -from freqtrade.state import RunMode, TRADING_MODES, NON_UTIL_MODES +from freqtrade.state import NON_UTIL_MODES, TRADING_MODES, RunMode logger = logging.getLogger(__name__) diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index b1e3535a3..260aae419 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -5,7 +5,7 @@ Functions to handle deprecated settings import logging from typing import Any, Dict -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index 556f27742..43a209483 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -3,7 +3,7 @@ import shutil from pathlib import Path from typing import Any, Dict, Optional -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.constants import USER_DATA_FILES logger = logging.getLogger(__name__) diff --git a/freqtrade/configuration/load_config.py b/freqtrade/configuration/load_config.py index 7a3ca1798..19179c6c3 100644 --- a/freqtrade/configuration/load_config.py +++ b/freqtrade/configuration/load_config.py @@ -6,7 +6,7 @@ import logging import sys from typing import Any, Dict -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 4c5c0521f..30d168f78 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -16,10 +16,12 @@ from typing import Any, Dict, List, Optional, Tuple import arrow from pandas import DataFrame -from freqtrade import OperationalException, misc +from freqtrade import misc from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv -from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_seconds +from freqtrade.exceptions import OperationalException +from freqtrade.exchange import (Exchange, timeframe_to_minutes, + timeframe_to_seconds) logger = logging.getLogger(__name__) diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 9ad2485ef..19d65d9d7 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -8,12 +8,12 @@ import numpy as np import utils_find_1st as utf1st from pandas import DataFrame -from freqtrade import constants, OperationalException +from freqtrade import constants from freqtrade.configuration import TimeRange from freqtrade.data import history +from freqtrade.exceptions import OperationalException from freqtrade.strategy.interface import SellType - logger = logging.getLogger(__name__) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index b5507981f..96f72fcf5 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -4,8 +4,8 @@ from typing import Dict import ccxt -from freqtrade import (DependencyException, InvalidOrderException, - OperationalException, TemporaryError) +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from freqtrade.exchange import Exchange logger = logging.getLogger(__name__) diff --git a/freqtrade/exchange/common.py b/freqtrade/exchange/common.py index ed30b95c7..b38ed35a3 100644 --- a/freqtrade/exchange/common.py +++ b/freqtrade/exchange/common.py @@ -1,6 +1,6 @@ import logging -from freqtrade import DependencyException, TemporaryError +from freqtrade.exceptions import DependencyException, TemporaryError logger = logging.getLogger(__name__) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 01e84c06e..3ef32db62 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -17,9 +17,9 @@ import ccxt.async_support as ccxt_async from ccxt.base.decimal_to_precision import ROUND_DOWN, ROUND_UP from pandas import DataFrame -from freqtrade import (DependencyException, InvalidOrderException, - OperationalException, TemporaryError) from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async from freqtrade.misc import deep_merge_dicts diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index f548489bc..9bcd9cc1f 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -4,7 +4,7 @@ from typing import Dict import ccxt -from freqtrade import OperationalException, TemporaryError +from freqtrade.exceptions import OperationalException, TemporaryError from freqtrade.exchange import Exchange from freqtrade.exchange.exchange import retrier diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 90eb7beba..f33a8cd03 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -12,17 +12,17 @@ from typing import Any, Dict, List, Optional, Tuple import arrow from requests.exceptions import RequestException -from freqtrade import (DependencyException, InvalidOrderException, __version__, - constants, persistence) +from freqtrade import __version__, constants, persistence from freqtrade.configuration import validate_config_consistency from freqtrade.data.converter import order_book_to_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.edge import Edge +from freqtrade.exceptions import DependencyException, InvalidOrderException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date +from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.rpc import RPCManager, RPCMessageType -from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.state import State from freqtrade.strategy.interface import IStrategy, SellType from freqtrade.wallets import Wallets diff --git a/freqtrade/loggers.py b/freqtrade/loggers.py index 27f16ecc3..c69388430 100644 --- a/freqtrade/loggers.py +++ b/freqtrade/loggers.py @@ -5,7 +5,7 @@ from logging import Formatter from logging.handlers import RotatingFileHandler, SysLogHandler from typing import Any, Dict, List -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) diff --git a/freqtrade/main.py b/freqtrade/main.py index 7afaeb1a2..62d2fc05d 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -13,8 +13,8 @@ if sys.version_info < (3, 6): import logging from typing import Any, List -from freqtrade import OperationalException from freqtrade.configuration import Arguments +from freqtrade.exceptions import OperationalException logger = logging.getLogger('freqtrade') diff --git a/freqtrade/optimize/__init__.py b/freqtrade/optimize/__init__.py index 1f2f588ef..34760372f 100644 --- a/freqtrade/optimize/__init__.py +++ b/freqtrade/optimize/__init__.py @@ -1,11 +1,11 @@ import logging from typing import Any, Dict -from freqtrade import DependencyException, constants, OperationalException +from freqtrade import constants +from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.state import RunMode from freqtrade.utils import setup_utils_configuration - logger = logging.getLogger(__name__) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index a8fe90a06..9bd0327e0 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -12,11 +12,11 @@ from typing import Any, Dict, List, NamedTuple, Optional from pandas import DataFrame from tabulate import tabulate -from freqtrade import OperationalException from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) from freqtrade.data import history from freqtrade.data.dataprovider import DataProvider +from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json from freqtrade.persistence import Trade diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 48f883ac5..a8f1a71ef 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -22,13 +22,13 @@ from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame -from freqtrade import OperationalException from freqtrade.data.history import get_timerange, trim_dataframe +from freqtrade.exceptions import OperationalException from freqtrade.misc import plural, round_dict from freqtrade.optimize.backtesting import Backtesting # Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules -from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F4 -from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4 +from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F401 +from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F401 from freqtrade.resolvers.hyperopt_resolver import (HyperOptLossResolver, HyperOptResolver) diff --git a/freqtrade/optimize/hyperopt_interface.py b/freqtrade/optimize/hyperopt_interface.py index 856f3eee7..d7d917c19 100644 --- a/freqtrade/optimize/hyperopt_interface.py +++ b/freqtrade/optimize/hyperopt_interface.py @@ -4,17 +4,15 @@ This module defines the interface to apply for hyperopt """ import logging import math - from abc import ABC -from typing import Dict, Any, Callable, List +from typing import Any, Callable, Dict, List from skopt.space import Categorical, Dimension, Integer, Real -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes from freqtrade.misc import round_dict - logger = logging.getLogger(__name__) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 2df9ba691..4ac9935ba 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -8,7 +8,7 @@ import logging from datetime import datetime from typing import Dict, List -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.pairlist.IPairList import IPairList logger = logging.getLogger(__name__) diff --git a/freqtrade/pairlist/pairlistmanager.py b/freqtrade/pairlist/pairlistmanager.py index 1530710d2..55828c6ef 100644 --- a/freqtrade/pairlist/pairlistmanager.py +++ b/freqtrade/pairlist/pairlistmanager.py @@ -4,11 +4,12 @@ Static List provider Provides lists as configured in config.json """ -from cachetools import TTLCache, cached import logging from typing import Dict, List -from freqtrade import OperationalException +from cachetools import TTLCache, cached + +from freqtrade.exceptions import OperationalException from freqtrade.pairlist.IPairList import IPairList from freqtrade.resolvers import PairListResolver diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 993b68bc7..75116f1e3 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -16,7 +16,7 @@ from sqlalchemy.orm.scoping import scoped_session from sqlalchemy.orm.session import sessionmaker from sqlalchemy.pool import StaticPool -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) diff --git a/freqtrade/plot/plot_utils.py b/freqtrade/plot/plot_utils.py index 8de0eb9e7..9eff08396 100644 --- a/freqtrade/plot/plot_utils.py +++ b/freqtrade/plot/plot_utils.py @@ -1,6 +1,6 @@ from typing import Any, Dict -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode from freqtrade.utils import setup_utils_configuration diff --git a/freqtrade/resolvers/hyperopt_resolver.py b/freqtrade/resolvers/hyperopt_resolver.py index c26fd09f2..ddf461252 100644 --- a/freqtrade/resolvers/hyperopt_resolver.py +++ b/freqtrade/resolvers/hyperopt_resolver.py @@ -7,8 +7,8 @@ import logging from pathlib import Path from typing import Dict -from freqtrade import OperationalException from freqtrade.constants import DEFAULT_HYPEROPT_LOSS, USERPATH_HYPEROPTS +from freqtrade.exceptions import OperationalException from freqtrade.optimize.hyperopt_interface import IHyperOpt from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss from freqtrade.resolvers import IResolver diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index e3c0d1ad0..5a844097c 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -9,7 +9,7 @@ import logging from pathlib import Path from typing import Any, Dict, Generator, List, Optional, Tuple, Type, Union -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 4fd5c586a..9e64f38df 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -11,9 +11,9 @@ from inspect import getfullargspec from pathlib import Path from typing import Dict, Optional -from freqtrade import OperationalException from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, USERPATH_STRATEGY) +from freqtrade.exceptions import OperationalException from freqtrade.resolvers import IResolver from freqtrade.strategy.interface import IStrategy diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 0a79d350b..c187dae4f 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple import arrow from numpy import NAN, mean -from freqtrade import DependencyException, TemporaryError +from freqtrade.exceptions import DependencyException, TemporaryError from freqtrade.misc import shorten_date from freqtrade.persistence import Trade from freqtrade.rpc.fiat_convert import CryptoToFiatConverter diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 5a5662e4b..45520ecf7 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -11,7 +11,6 @@ import rapidjson from colorama import init as colorama_init from tabulate import tabulate -from freqtrade import OperationalException from freqtrade.configuration import (Configuration, TimeRange, remove_credentials) from freqtrade.configuration.directory_operations import (copy_sample_files, @@ -20,6 +19,7 @@ from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY from freqtrade.data.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data, refresh_backtest_trades_data) +from freqtrade.exceptions import OperationalException from freqtrade.exchange import (available_exchanges, ccxt_exchanges, market_is_active, symbol_is_pair) from freqtrade.misc import plural, render_template diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 8e4be9d43..22651d269 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -8,9 +8,9 @@ from typing import Any, Callable, Dict, Optional import sdnotify -from freqtrade import (OperationalException, TemporaryError, __version__, - constants) +from freqtrade import __version__, constants from freqtrade.configuration import Configuration +from freqtrade.exceptions import OperationalException, TemporaryError from freqtrade.freqtradebot import FreqtradeBot from freqtrade.rpc import RPCMessageType from freqtrade.state import State diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index 3a866c0a8..ef1280fa4 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -10,7 +10,7 @@ import numpy as np import pytest from pandas import DataFrame, to_datetime -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.edge import Edge, PairInfo from freqtrade.strategy.interface import SellType diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 7720a7d2e..0a12c1cb1 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -4,8 +4,8 @@ from unittest.mock import MagicMock import ccxt import pytest -from freqtrade import (DependencyException, InvalidOrderException, - OperationalException, TemporaryError) +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from tests.conftest import get_patched_exchange diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 2f95e4e01..cb40bdbd9 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -11,8 +11,8 @@ import ccxt import pytest from pandas import DataFrame -from freqtrade import (DependencyException, InvalidOrderException, - OperationalException, TemporaryError) +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from freqtrade.exchange import Binance, Exchange, Kraken from freqtrade.exchange.common import API_RETRY_COUNT from freqtrade.exchange.exchange import (market_is_active, symbol_is_pair, diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 8a27c591f..4e2fd01cf 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -10,13 +10,14 @@ import pandas as pd import pytest from arrow import Arrow -from freqtrade import DependencyException, OperationalException, constants +from freqtrade import constants from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import evaluate_result_multi from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange +from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize import setup_configuration, start_backtesting from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode @@ -25,7 +26,6 @@ from freqtrade.strategy.interface import SellType from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) - ORDER_TYPES = [ { 'buy': 'limit', diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index fb492be35..473d760ac 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -9,7 +9,7 @@ import pytest from arrow import Arrow from filelock import Timeout -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.optimize import setup_configuration, start_hyperopt diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 21929de2b..ac4cbc813 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -4,7 +4,7 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.constants import AVAILABLE_PAIRLISTS from freqtrade.resolvers import PairListResolver from freqtrade.pairlist.pairlistmanager import PairListManager diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index c5bb0ca2c..31632bd70 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -7,13 +7,13 @@ from unittest.mock import ANY, MagicMock, PropertyMock import pytest from numpy import isnan -from freqtrade import DependencyException, TemporaryError from freqtrade.edge import PairInfo +from freqtrade.exceptions import DependencyException, TemporaryError from freqtrade.persistence import Trade from freqtrade.rpc import RPC, RPCException from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.state import State -from tests.conftest import patch_get_signal, get_patched_freqtradebot +from tests.conftest import get_patched_freqtradebot, patch_get_signal # Functions for recurrent object patching diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 10b9f3466..d3977ae44 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -8,7 +8,7 @@ from pathlib import Path import pytest from pandas import DataFrame -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.resolvers import StrategyResolver from freqtrade.strategy.interface import IStrategy from tests.conftest import log_has, log_has_re diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 6564417b3..ee3d23131 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -10,7 +10,6 @@ from unittest.mock import MagicMock import pytest from jsonschema import ValidationError -from freqtrade import OperationalException from freqtrade.configuration import (Arguments, Configuration, check_exchange, remove_credentials, validate_config_consistency) @@ -20,6 +19,7 @@ from freqtrade.configuration.deprecated_settings import ( process_temporary_deprecated_settings) from freqtrade.configuration.load_config import load_config_file from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL +from freqtrade.exceptions import OperationalException from freqtrade.loggers import _set_loggers, setup_logging from freqtrade.state import RunMode from tests.conftest import (log_has, log_has_re, diff --git a/tests/test_directory_operations.py b/tests/test_directory_operations.py index db41e2da2..889338a64 100644 --- a/tests/test_directory_operations.py +++ b/tests/test_directory_operations.py @@ -4,10 +4,10 @@ from unittest.mock import MagicMock import pytest -from freqtrade import OperationalException from freqtrade.configuration.directory_operations import (copy_sample_files, create_datadir, create_userdata_dir) +from freqtrade.exceptions import OperationalException from tests.conftest import log_has, log_has_re diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 2f8c786fd..3f5b7bd54 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -11,9 +11,9 @@ import arrow import pytest import requests -from freqtrade import (DependencyException, InvalidOrderException, - OperationalException, TemporaryError, constants) -from freqtrade.constants import MATH_CLOSE_PREC +from freqtrade.constants import MATH_CLOSE_PREC, UNLIMITED_STAKE_AMOUNT +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from freqtrade.freqtradebot import FreqtradeBot from freqtrade.persistence import Trade from freqtrade.rpc import RPCMessageType @@ -163,7 +163,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, ) conf = deepcopy(default_conf) - conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT + conf['stake_amount'] = UNLIMITED_STAKE_AMOUNT conf['max_open_trades'] = 2 freqtrade = FreqtradeBot(conf) @@ -564,7 +564,7 @@ def test_create_trades_limit_reached(default_conf, ticker, limit_buy_order, get_fee=fee, ) default_conf['max_open_trades'] = 0 - default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT + default_conf['stake_amount'] = UNLIMITED_STAKE_AMOUNT freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) diff --git a/tests/test_main.py b/tests/test_main.py index 03e6a7ce9..83be01999 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -5,8 +5,8 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade import OperationalException from freqtrade.configuration import Arguments +from freqtrade.exceptions import OperationalException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.main import main from freqtrade.state import State diff --git a/tests/test_persistence.py b/tests/test_persistence.py index b9a636e1a..6bd7971a7 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -6,7 +6,8 @@ import arrow import pytest from sqlalchemy import create_engine -from freqtrade import OperationalException, constants +from freqtrade import constants +from freqtrade.exceptions import OperationalException from freqtrade.persistence import Trade, clean_dry_run_db, init from tests.conftest import log_has diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 31502cafc..9934d2493 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -7,17 +7,17 @@ import plotly.graph_objects as go import pytest from plotly.subplots import make_subplots -from freqtrade import OperationalException from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data +from freqtrade.exceptions import OperationalException from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit from freqtrade.plot.plotting import (add_indicators, add_profit, - load_and_plot_trades, generate_candlestick_graph, generate_plot_filename, generate_profit_graph, init_plotscript, - plot_profit, plot_trades, store_plot_file) + load_and_plot_trades, plot_profit, + plot_trades, store_plot_file) from freqtrade.strategy.default_strategy import DefaultStrategy from tests.conftest import get_args, log_has, log_has_re diff --git a/tests/test_utils.py b/tests/test_utils.py index 4cf7b5f23..2e2499337 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -4,7 +4,7 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade import OperationalException +from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode from freqtrade.utils import (setup_utils_configuration, start_create_userdir, start_download_data, start_hyperopt_list, From 8e9a3e8fc8e5de762455ca7472c81e5ad15f8591 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Dec 2019 15:11:07 +0100 Subject: [PATCH 0163/1106] Capture FtBaseException at the outermost level --- freqtrade/exceptions.py | 28 +++++++++++++++++----------- freqtrade/main.py | 4 ++-- tests/test_main.py | 4 ++-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/freqtrade/exceptions.py b/freqtrade/exceptions.py index 80d45dd86..2f05ddb57 100644 --- a/freqtrade/exceptions.py +++ b/freqtrade/exceptions.py @@ -1,21 +1,27 @@ -class DependencyException(Exception): +class FreqtradeException(Exception): + """ + Freqtrade base exception. Handled at the outermost level. + All other exception types are subclasses of this exception type. + """ + + +class OperationalException(FreqtradeException): + """ + Requires manual intervention and will stop the bot. + Most of the time, this is caused by an invalid Configuration. + """ + + +class DependencyException(FreqtradeException): """ Indicates that an assumed dependency is not met. This could happen when there is currently not enough money on the account. """ -class OperationalException(Exception): - """ - Requires manual intervention and will usually stop the bot. - This happens when an exchange returns an unexpected error during runtime - or given configuration is invalid. - """ - - -class InvalidOrderException(Exception): +class InvalidOrderException(FreqtradeException): """ This is returned when the order is not valid. Example: If stoploss on exchange order is hit, then trying to cancel the order @@ -23,7 +29,7 @@ class InvalidOrderException(Exception): """ -class TemporaryError(Exception): +class TemporaryError(FreqtradeException): """ Temporary network or exchange related error. This could happen when an exchange is congested, unavailable, or the user diff --git a/freqtrade/main.py b/freqtrade/main.py index 62d2fc05d..811e29864 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -4,6 +4,7 @@ Main Freqtrade bot script. Read the documentation to know what cli arguments you need. """ +from freqtrade.exceptions import FreqtradeException, OperationalException import sys # check min. python version if sys.version_info < (3, 6): @@ -14,7 +15,6 @@ import logging from typing import Any, List from freqtrade.configuration import Arguments -from freqtrade.exceptions import OperationalException logger = logging.getLogger('freqtrade') @@ -50,7 +50,7 @@ def main(sysargv: List[str] = None) -> None: except KeyboardInterrupt: logger.info('SIGINT received, aborting ...') return_code = 0 - except OperationalException as e: + except FreqtradeException as e: logger.error(str(e)) return_code = 2 except Exception: diff --git a/tests/test_main.py b/tests/test_main.py index 83be01999..76b1bf658 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,7 +6,7 @@ from unittest.mock import MagicMock, PropertyMock import pytest from freqtrade.configuration import Arguments -from freqtrade.exceptions import OperationalException +from freqtrade.exceptions import OperationalException, FreqtradeException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.main import main from freqtrade.state import State @@ -96,7 +96,7 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None: mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock()) mocker.patch( 'freqtrade.worker.Worker._worker', - MagicMock(side_effect=OperationalException('Oh snap!')) + MagicMock(side_effect=FreqtradeException('Oh snap!')) ) patched_configuration_load_config_file(mocker, default_conf) mocker.patch('freqtrade.wallets.Wallets.update', MagicMock()) From 4d56e3b36e02d2fb8bd41bde5cbf0fabc0cd7a28 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 30 Dec 2019 20:54:32 +0300 Subject: [PATCH 0164/1106] Address some comments made in the review --- freqtrade/freqtradebot.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 68091ed76..3bfa74005 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -296,8 +296,11 @@ class FreqtradeBot: def create_trade(self, pair: str) -> bool: """ - Check the implemented trading strategy for buy-signals. - If the pair triggers the buy_signal a new trade record gets created. + Check the implemented trading strategy for buy signals. + + If the pair triggers the buy signal a new trade record gets created + and the buy-order opening the trade gets issued towards the exchange. + :return: True if a trade has been created. """ logger.debug(f"create_trade for pair {pair}") @@ -467,7 +470,7 @@ class FreqtradeBot: if not whitelist: logger.info("Active pair whitelist is empty.") else: - # Remove currently opened and latest pairs from whitelist + # Remove pairs for currently opened trades from the whitelist for trade in Trade.get_open_trades(): if trade.pair in whitelist: whitelist.remove(trade.pair) From b00406a7eb0e73f2b104598441958782d4c95497 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 30 Dec 2019 21:09:35 +0300 Subject: [PATCH 0165/1106] Make process_maybe_execute_*() returning integers --- freqtrade/freqtradebot.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 3bfa74005..e6f51e5fa 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -460,11 +460,11 @@ class FreqtradeBot: return True - def process_maybe_execute_buys(self) -> None: + def process_maybe_execute_buys(self) -> int: """ Tries to execute buy orders for trades in a safe way """ - result = False + trades_created = 0 whitelist = copy.deepcopy(self.active_pair_whitelist) if not whitelist: @@ -483,39 +483,42 @@ class FreqtradeBot: # Create entity and execute trade for each pair from whitelist for pair in whitelist: try: - if self.create_trade(pair): - result = True + trades_created += self.create_trade(pair) except DependencyException as exception: logger.warning('Unable to create trade: %s', exception) - if not result: + if not trades_created: logger.debug("Found no buy signals for whitelisted currencies. " "Trying again...") - def process_maybe_execute_sells(self, trades: List[Any]) -> None: + return trades_created + + def process_maybe_execute_sells(self, trades: List[Any]) -> int: """ Tries to execute sell orders for trades in a safe way """ - result = False + trades_closed = 0 for trade in trades: try: self.update_trade_state(trade) if (self.strategy.order_types.get('stoploss_on_exchange') and self.handle_stoploss_on_exchange(trade)): - result = True + trades_closed += 1 continue # Check if we can sell our current pair if trade.open_order_id is None and self.handle_trade(trade): - result = True + trades_closed += 1 except DependencyException as exception: logger.warning('Unable to sell trade: %s', exception) # Updating wallets if any trade occured - if result: + if trades_closed: self.wallets.update() + return trades_closed + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Get real amount for the trade From 84918ad42481a7558bd935a1639b29de5f317931 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 30 Dec 2019 22:08:36 +0300 Subject: [PATCH 0166/1106] Rename process_maybe_execute_sells() --> exit_positions() --- freqtrade/freqtradebot.py | 8 ++++---- tests/test_freqtradebot.py | 22 ++++++++++++---------- tests/test_integration.py | 6 ++++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e6f51e5fa..695302bf9 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -132,8 +132,8 @@ class FreqtradeBot: self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist), self.strategy.informative_pairs()) - # First process current opened trades - self.process_maybe_execute_sells(trades) + # First process current opened trades (positions) + self.exit_positions(trades) # Then looking for buy opportunities if self.get_free_open_trades(): @@ -493,9 +493,9 @@ class FreqtradeBot: return trades_created - def process_maybe_execute_sells(self, trades: List[Any]) -> int: + def exit_positions(self, trades: List[Any]) -> int: """ - Tries to execute sell orders for trades in a safe way + Tries to execute sell orders for open trades (positions) """ trades_closed = 0 for trade in trades: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index be6a9b392..22110dd1c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -990,7 +990,7 @@ def test_add_stoploss_on_exchange(mocker, default_conf, limit_buy_order) -> None trade.is_open = True trades = [trade] - freqtrade.process_maybe_execute_sells(trades) + freqtrade.exit_positions(trades) assert trade.stoploss_order_id == '13434334' assert stoploss_limit.call_count == 1 assert trade.is_open is True @@ -1463,7 +1463,7 @@ def test_process_maybe_execute_buys_exception(mocker, default_conf, caplog) -> N assert log_has('Unable to create trade: ', caplog) -def test_process_maybe_execute_sells(mocker, default_conf, limit_buy_order, caplog) -> None: +def test_exit_positions(mocker, default_conf, limit_buy_order, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True)) @@ -1476,7 +1476,8 @@ def test_process_maybe_execute_sells(mocker, default_conf, limit_buy_order, capl trade.open_order_id = '123' trade.open_fee = 0.001 trades = [trade] - assert not freqtrade.process_maybe_execute_sells(trades) + n = freqtrade.exit_positions(trades) + assert n == 0 # Test amount not modified by fee-logic assert not log_has( 'Applying fee to amount for Trade {} from 90.99181073 to 90.81'.format(trade), caplog @@ -1484,11 +1485,11 @@ def test_process_maybe_execute_sells(mocker, default_conf, limit_buy_order, capl mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81) # test amount modified by fee-logic - assert not freqtrade.process_maybe_execute_sells(trades) + n = freqtrade.exit_positions(trades) + assert n == 0 -def test_process_maybe_execute_sells_exception(mocker, default_conf, - limit_buy_order, caplog) -> None: +def test_exit_positions_exception(mocker, default_conf, limit_buy_order, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.get_order', return_value=limit_buy_order) @@ -1502,7 +1503,8 @@ def test_process_maybe_execute_sells_exception(mocker, default_conf, 'freqtrade.freqtradebot.FreqtradeBot.update_trade_state', side_effect=DependencyException() ) - freqtrade.process_maybe_execute_sells(trades) + n = freqtrade.exit_positions(trades) + assert n == 0 assert log_has('Unable to sell trade: ', caplog) @@ -2391,7 +2393,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke assert trade trades = [trade] - freqtrade.process_maybe_execute_sells(trades) + freqtrade.exit_positions(trades) # Increase the price and sell it mocker.patch.multiple( @@ -2438,7 +2440,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f freqtrade.process_maybe_execute_buys() trade = Trade.query.first() trades = [trade] - freqtrade.process_maybe_execute_sells(trades) + freqtrade.exit_positions(trades) assert trade assert trade.stoploss_order_id == '123' assert trade.open_order_id is None @@ -2466,7 +2468,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f }) mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_limit_executed) - freqtrade.process_maybe_execute_sells(trades) + freqtrade.exit_positions(trades) assert trade.stoploss_order_id is None assert trade.is_open is False assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value diff --git a/tests/test_integration.py b/tests/test_integration.py index 2c95bc6e3..a73beeabe 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -90,7 +90,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, trade.stoploss_order_id = 3 trade.open_order_id = None - freqtrade.process_maybe_execute_sells(trades) + n = freqtrade.exit_positions(trades) + assert n == 2 assert should_sell_mock.call_count == 2 # Only order for 3rd trade needs to be cancelled @@ -170,7 +171,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc assert len(trades) == 5 bals = freqtrade.wallets.get_all_balances() - freqtrade.process_maybe_execute_sells(trades) + n = freqtrade.exit_positions(trades) + assert n == 1 trades = Trade.get_open_trades() # One trade sold assert len(trades) == 4 From fd7af587da29851de854fdd2be7a7d697cdcdbe2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 30 Dec 2019 22:50:56 +0300 Subject: [PATCH 0167/1106] Rename process_maybe_execute_buys() --> enter_positions() --- freqtrade/freqtradebot.py | 6 +- tests/rpc/test_rpc.py | 22 +++--- tests/rpc/test_rpc_apiserver.py | 8 +-- tests/rpc/test_rpc_telegram.py | 25 +++---- tests/test_freqtradebot.py | 118 +++++++++++++++++--------------- tests/test_integration.py | 5 +- 6 files changed, 96 insertions(+), 88 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 695302bf9..c595150ac 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -137,7 +137,7 @@ class FreqtradeBot: # Then looking for buy opportunities if self.get_free_open_trades(): - self.process_maybe_execute_buys() + self.enter_positions() # Check and handle any timed out open orders self.check_handle_timedout() @@ -460,9 +460,9 @@ class FreqtradeBot: return True - def process_maybe_execute_buys(self) -> int: + def enter_positions(self) -> int: """ - Tries to execute buy orders for trades in a safe way + Tries to execute buy orders for new trades (positions) """ trades_created = 0 diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index a9f73e98d..3581e3d18 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -41,7 +41,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() results = rpc._rpc_trade_status() assert { 'trade_id': 1, @@ -116,7 +116,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: with pytest.raises(RPCException, match=r'.*no active order*'): rpc._rpc_status_table(default_conf['stake_currency'], 'USD') - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert "Since" in headers @@ -162,7 +162,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() assert trade @@ -217,7 +217,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -231,7 +231,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, trade.close_date = datetime.utcnow() trade.is_open = False - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -299,7 +299,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, rpc = RPC(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) @@ -529,7 +529,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: msg = rpc._rpc_forcesell('all') assert msg == {'result': 'Created sell orders for all open trades.'} - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() msg = rpc._rpc_forcesell('all') assert msg == {'result': 'Created sell orders for all open trades.'} @@ -563,7 +563,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 1 assert trade.amount == filled_amount - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.filter(Trade.id == '2').first() amount = trade.amount # make an limit-buy open trade, if there is no 'filled', don't sell it @@ -582,7 +582,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: assert cancel_order_mock.call_count == 2 assert trade.amount == amount - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() # make an limit-sell open trade mocker.patch( 'freqtrade.exchange.Exchange.get_order', @@ -613,7 +613,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee, rpc = RPC(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() assert trade @@ -649,7 +649,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None: assert counts["current"] == 0 # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() counts = rpc._rpc_count() assert counts["current"] == 1 diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 94af85349..25c971bf7 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -267,7 +267,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets): assert rc.json["max"] == 1.0 # Create some test data - ftbot.process_maybe_execute_buys() + ftbot.enter_positions() rc = client_get(client, f"{BASE_URI}/count") assert_response(rc) assert rc.json["current"] == 1.0 @@ -333,7 +333,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li assert len(rc.json) == 1 assert rc.json == {"error": "Error querying _profit: no closed trade"} - ftbot.process_maybe_execute_buys() + ftbot.enter_positions() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade @@ -422,7 +422,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets): assert_response(rc, 200) assert rc.json == [] - ftbot.process_maybe_execute_buys() + ftbot.enter_positions() rc = client_get(client, f"{BASE_URI}/status") assert_response(rc) assert len(rc.json) == 1 @@ -552,7 +552,7 @@ def test_api_forcesell(botclient, mocker, ticker, fee, markets): assert_response(rc, 502) assert rc.json == {"error": "Error querying _forcesell: invalid argument"} - ftbot.process_maybe_execute_buys() + ftbot.enter_positions() rc = client_post(client, f"{BASE_URI}/forcesell", data='{"tradeid": "1"}') diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index d9a7e2f5b..44e51514e 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -188,8 +188,8 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: telegram = Telegram(freqtradebot) # Create some test data - for _ in range(3): - freqtradebot.process_maybe_execute_buys() + n = freqtradebot.enter_positions() + assert n == 1 telegram._status(update=update, context=MagicMock()) assert msg_mock.call_count == 1 @@ -236,7 +236,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None: msg_mock.reset_mock() # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() # Trigger status while we have a fulfilled order for the open trade telegram._status(update=update, context=MagicMock()) @@ -285,7 +285,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: msg_mock.reset_mock() # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() telegram._status_table(update=update, context=MagicMock()) @@ -322,7 +322,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() assert trade @@ -352,7 +352,8 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, msg_mock.reset_mock() freqtradebot.config['max_open_trades'] = 2 # Add two other trades - freqtradebot.process_maybe_execute_buys() + n = freqtradebot.enter_positions() + assert n == 2 trades = Trade.query.all() for trade in trades: @@ -431,7 +432,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee, msg_mock.reset_mock() # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade @@ -709,7 +710,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() assert trade @@ -764,7 +765,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() # Decrease the price and sell it mocker.patch.multiple( @@ -821,7 +822,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() rpc_mock.reset_mock() # /forcesell all @@ -971,7 +972,7 @@ def test_performance_handle(default_conf, update, ticker, fee, telegram = Telegram(freqtradebot) # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() trade = Trade.query.first() assert trade @@ -1014,7 +1015,7 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: freqtradebot.state = State.RUNNING # Create some test data - freqtradebot.process_maybe_execute_buys() + freqtradebot.enter_positions() msg_mock.reset_mock() telegram._count(update=update, context=MagicMock()) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 22110dd1c..f99b14286 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -247,7 +247,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf freqtrade.active_pair_whitelist = ['NEO/BTC'] patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) ############################################# @@ -287,7 +287,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, freqtrade.active_pair_whitelist = ['NEO/BTC'] patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) ############################################# @@ -310,7 +310,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker, ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade is not None @@ -318,7 +318,7 @@ def test_total_open_trades_stakes(mocker, default_conf, ticker, assert trade.is_open assert trade.open_date is not None - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.order_by(Trade.id.desc()).first() assert trade is not None @@ -573,9 +573,8 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, assert freqtrade.get_trade_stake_amount('ETH/BTC') is None -def test_process_maybe_execute_buys_no_pairs_let(default_conf, ticker, - limit_buy_order, fee, - mocker, caplog) -> None: +def test_enter_positions_no_pairs_left(default_conf, ticker, limit_buy_order, fee, + mocker, caplog) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -589,15 +588,16 @@ def test_process_maybe_execute_buys_no_pairs_let(default_conf, ticker, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 1 assert not log_has_re(r"No currency pair in active pair whitelist.*", caplog) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 0 assert log_has_re(r"No currency pair in active pair whitelist.*", caplog) -def test_process_maybe_execute_buys_no_pairs_in_whitelist(default_conf, ticker, - limit_buy_order, fee, - mocker, caplog) -> None: +def test_enter_positions_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee, + mocker, caplog) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -610,7 +610,8 @@ def test_process_maybe_execute_buys_no_pairs_in_whitelist(default_conf, ticker, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 0 assert log_has("Active pair whitelist is empty.", caplog) @@ -648,7 +649,8 @@ def test_create_trades_multiple_trades(default_conf, ticker, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == max_open trades = Trade.get_open_trades() assert len(trades) == max_open @@ -1059,7 +1061,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # should unset stoploss_order_id and return true # as a trade actually happened caplog.clear() - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1117,7 +1119,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True trade.open_order_id = '12345' @@ -1152,7 +1154,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee, patch_get_signal(freqtrade) freqtrade.strategy.order_types['stoploss_on_exchange'] = True - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() caplog.clear() freqtrade.create_stoploss_order(trade, 200, 199) @@ -1210,7 +1212,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1298,7 +1300,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c # setting stoploss_on_exchange_interval to 60 seconds freqtrade.strategy.order_types['stoploss_on_exchange_interval'] = 60 patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1379,7 +1381,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, freqtrade.active_pair_whitelist = freqtrade.edge.adjust(freqtrade.active_pair_whitelist) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True trade.open_order_id = None @@ -1443,23 +1445,25 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, stop_price=0.00002344 * 0.99) -def test_process_maybe_execute_buys(mocker, default_conf, caplog) -> None: +def test_enter_positions(mocker, default_conf, caplog) -> None: caplog.set_level(logging.DEBUG) freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(return_value=False)) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 0 assert log_has('Found no buy signals for whitelisted currencies. Trying again...', caplog) -def test_process_maybe_execute_buys_exception(mocker, default_conf, caplog) -> None: +def test_enter_positions_exception(mocker, default_conf, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch( 'freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(side_effect=DependencyException) ) - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 0 assert log_has('Unable to create trade: ', caplog) @@ -1679,7 +1683,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -1702,7 +1706,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock assert trade.close_date is not None -def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, mocker) -> None: +def test_handle_overlapping_signals(default_conf, ticker, limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -1716,7 +1720,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, patch_get_signal(freqtrade, value=(True, True)) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() # Buy and Sell triggering, so doing nothing ... trades = Trade.query.all() @@ -1725,7 +1729,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, # Buy is triggering, so buying ... patch_get_signal(freqtrade, value=(True, False)) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trades = Trade.query.all() nb_trades = len(trades) assert nb_trades == 1 @@ -1769,7 +1773,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade, value=(True, False)) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True @@ -1800,7 +1804,7 @@ def test_handle_trade_use_sell_signal( freqtrade = get_patched_freqtradebot(mocker, default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True @@ -1828,7 +1832,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, patch_get_signal(freqtrade) # Create trade and sell it - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2188,7 +2192,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2236,7 +2240,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2286,7 +2290,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2344,7 +2348,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee, c freqtrade.strategy.order_types['stoploss_on_exchange'] = True patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() Trade.session = MagicMock() @@ -2387,7 +2391,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2437,7 +2441,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trades = [trade] freqtrade.exit_positions(trades) @@ -2489,7 +2493,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2551,7 +2555,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2582,7 +2586,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2613,7 +2617,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker patch_get_signal(freqtrade) freqtrade.strategy.stop_loss_reached = MagicMock(return_value=SellCheckTuple( sell_flag=False, sell_type=SellType.NONE)) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2643,7 +2647,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2672,7 +2676,7 @@ def test_sell_not_enough_balance(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() amnt = trade.amount @@ -2740,7 +2744,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -2759,7 +2763,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplo # reinit - should buy other pair. caplog.clear() - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() assert log_has(f"Pair {trade.pair} is currently locked.", caplog) @@ -2784,7 +2788,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2817,7 +2821,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert freqtrade.handle_trade(trade) is False @@ -2872,7 +2876,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2929,7 +2933,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -2992,7 +2996,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=False) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -3051,7 +3055,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order, patch_get_signal(freqtrade) freqtrade.strategy.min_roi_reached = MagicMock(return_value=True) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() trade.update(limit_buy_order) @@ -3382,7 +3386,7 @@ def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee, whitelist = deepcopy(default_conf['exchange']['pair_whitelist']) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade is not None @@ -3417,7 +3421,7 @@ def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_o # Save state of current whitelist freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade is None @@ -3519,7 +3523,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() trade = Trade.query.first() assert trade @@ -3626,12 +3630,14 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, patch_get_signal(bot) assert bot.wallets.get_free('BTC') == 0.002 - bot.process_maybe_execute_buys() + n = bot.enter_positions() + assert n == 2 trades = Trade.query.all() assert len(trades) == 2 bot.config['max_open_trades'] = 3 - bot.process_maybe_execute_buys() + n = bot.enter_positions() + assert n == 0 assert log_has_re(r"Unable to create trade: " r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)", caplog) diff --git a/tests/test_integration.py b/tests/test_integration.py index a73beeabe..1108969ad 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -80,7 +80,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, patch_get_signal(freqtrade) # Create some test data - freqtrade.process_maybe_execute_buys() + freqtrade.enter_positions() wallets_mock.reset_mock() Trade.session = MagicMock() @@ -154,7 +154,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc patch_get_signal(freqtrade) # Create 4 trades - freqtrade.process_maybe_execute_buys() + n = freqtrade.enter_positions() + assert n == 4 trades = Trade.query.all() assert len(trades) == 4 From a88464de3a5ffb4c6802040c6463d4079c5dc868 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Dec 2019 07:01:58 +0100 Subject: [PATCH 0168/1106] Improve some test code --- tests/rpc/test_rpc_telegram.py | 10 ---------- tests/test_freqtradebot.py | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 44e51514e..9a39f2119 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -148,11 +148,6 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: default_conf['telegram']['enabled'] = False default_conf['telegram']['chat_id'] = "123" - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - fetch_ticker=ticker, - get_fee=fee, - ) msg_mock = MagicMock() status_table = MagicMock() mocker.patch.multiple( @@ -184,13 +179,8 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: ) freqtradebot = get_patched_freqtradebot(mocker, default_conf) - patch_get_signal(freqtradebot, (True, False)) telegram = Telegram(freqtradebot) - # Create some test data - n = freqtradebot.enter_positions() - assert n == 1 - telegram._status(update=update, context=MagicMock()) assert msg_mock.call_count == 1 diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index f99b14286..434633f5f 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1458,12 +1458,13 @@ def test_enter_positions(mocker, default_conf, caplog) -> None: def test_enter_positions_exception(mocker, default_conf, caplog) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch( + mock_ct = mocker.patch( 'freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(side_effect=DependencyException) ) n = freqtrade.enter_positions() assert n == 0 + assert mock_ct.call_count == len(default_conf['exchange']['pair_whitelist']) assert log_has('Unable to create trade: ', caplog) From 6ebb9017c7bc0b0d39d8f83d663a7218d776c48a Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Dec 2019 07:03:57 +0100 Subject: [PATCH 0169/1106] Improve test enter_positions --- tests/test_freqtradebot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 434633f5f..812ba4e3e 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1449,10 +1449,12 @@ def test_enter_positions(mocker, default_conf, caplog) -> None: caplog.set_level(logging.DEBUG) freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', MagicMock(return_value=False)) + mock_ct = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.create_trade', + MagicMock(return_value=False)) n = freqtrade.enter_positions() assert n == 0 assert log_has('Found no buy signals for whitelisted currencies. Trying again...', caplog) + assert mock_ct.call_count == 4 def test_enter_positions_exception(mocker, default_conf, caplog) -> None: From 9d518b9d29cdcf90ccdc8efc4117ccff0ba5c380 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Dec 2019 07:05:21 +0100 Subject: [PATCH 0170/1106] Add comment and don't hardcode 4 in test --- tests/test_freqtradebot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 812ba4e3e..6527554be 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1454,7 +1454,8 @@ def test_enter_positions(mocker, default_conf, caplog) -> None: n = freqtrade.enter_positions() assert n == 0 assert log_has('Found no buy signals for whitelisted currencies. Trying again...', caplog) - assert mock_ct.call_count == 4 + # create_trade should be called once for every pair in the whitelist. + assert mock_ct.call_count == len(default_conf['exchange']['pair_whitelist']) def test_enter_positions_exception(mocker, default_conf, caplog) -> None: From 26a2395aebd0b1ed39aaadb63e674dcf64a592bc Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Dec 2019 07:11:09 +0100 Subject: [PATCH 0171/1106] Include Pair name in exception log message --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c595150ac..a642e6ea7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -485,7 +485,7 @@ class FreqtradeBot: try: trades_created += self.create_trade(pair) except DependencyException as exception: - logger.warning('Unable to create trade: %s', exception) + logger.warning('Unable to create trade for %s: %s', pair, exception) if not trades_created: logger.debug("Found no buy signals for whitelisted currencies. " diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6527554be..cf395ef39 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1468,7 +1468,7 @@ def test_enter_positions_exception(mocker, default_conf, caplog) -> None: n = freqtrade.enter_positions() assert n == 0 assert mock_ct.call_count == len(default_conf['exchange']['pair_whitelist']) - assert log_has('Unable to create trade: ', caplog) + assert log_has('Unable to create trade for ETH/BTC: ', caplog) def test_exit_positions(mocker, default_conf, limit_buy_order, caplog) -> None: @@ -3642,6 +3642,6 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, bot.config['max_open_trades'] = 3 n = bot.enter_positions() assert n == 0 - assert log_has_re(r"Unable to create trade: " + assert log_has_re(r"Unable to create trade for XRP/BTC: " r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)", caplog) From 0ea44b014347d3541bb1b125ee1ebda88e8464f7 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 02:36:59 +0300 Subject: [PATCH 0172/1106] Fix message in setup.sh --- setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index c4b6e074a..fb5102e12 100755 --- a/setup.sh +++ b/setup.sh @@ -263,7 +263,7 @@ function install() { echo "-------------------------" echo "Run the bot !" echo "-------------------------" - echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade'." + echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade trade'." } function plot() { From 4475110df85265cd2ba1172ebe3bf9df592addaf Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 02:53:25 +0300 Subject: [PATCH 0173/1106] Cosmetics in freqtradebot --- freqtrade/freqtradebot.py | 73 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c4991a31c..4a207b087 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -27,6 +27,7 @@ from freqtrade.state import State from freqtrade.strategy.interface import IStrategy, SellType from freqtrade.wallets import Wallets + logger = logging.getLogger(__name__) @@ -181,6 +182,43 @@ class FreqtradeBot: open_trades = len(Trade.get_open_trades()) return max(0, self.config['max_open_trades'] - open_trades) +# +# BUY / enter positions / open trades part +# + + def enter_positions(self) -> int: + """ + Tries to execute buy orders for new trades (positions) + """ + trades_created = 0 + + whitelist = copy.deepcopy(self.active_pair_whitelist) + if not whitelist: + logger.info("Active pair whitelist is empty.") + else: + # Remove pairs for currently opened trades from the whitelist + for trade in Trade.get_open_trades(): + if trade.pair in whitelist: + whitelist.remove(trade.pair) + logger.debug('Ignoring %s in pair whitelist', trade.pair) + + if not whitelist: + logger.info("No currency pair in active pair whitelist, " + "but checking to sell open trades.") + else: + # Create entity and execute trade for each pair from whitelist + for pair in whitelist: + try: + trades_created += self.create_trade(pair) + except DependencyException as exception: + logger.warning('Unable to create trade for %s: %s', pair, exception) + + if not trades_created: + logger.debug("Found no buy signals for whitelisted currencies. " + "Trying again...") + + return trades_created + def get_target_bid(self, pair: str, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price @@ -460,38 +498,9 @@ class FreqtradeBot: return True - def enter_positions(self) -> int: - """ - Tries to execute buy orders for new trades (positions) - """ - trades_created = 0 - - whitelist = copy.deepcopy(self.active_pair_whitelist) - if not whitelist: - logger.info("Active pair whitelist is empty.") - else: - # Remove pairs for currently opened trades from the whitelist - for trade in Trade.get_open_trades(): - if trade.pair in whitelist: - whitelist.remove(trade.pair) - logger.debug('Ignoring %s in pair whitelist', trade.pair) - - if not whitelist: - logger.info("No currency pair in active pair whitelist, " - "but checking to sell open trades.") - else: - # Create entity and execute trade for each pair from whitelist - for pair in whitelist: - try: - trades_created += self.create_trade(pair) - except DependencyException as exception: - logger.warning('Unable to create trade for %s: %s', pair, exception) - - if not trades_created: - logger.debug("Found no buy signals for whitelisted currencies. " - "Trying again...") - - return trades_created +# +# SELL / exit positions / close trades part +# def exit_positions(self, trades: List[Any]) -> int: """ From 21418e298828e78576fffae4b973fe5c3723079a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 03:16:18 +0300 Subject: [PATCH 0174/1106] Minor: fix comment --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4a207b087..774e001c8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -407,7 +407,7 @@ class FreqtradeBot: if price: buy_limit_requested = price else: - # Calculate amount + # Calculate price buy_limit_requested = self.get_target_bid(pair) min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested) From 18a53f446762016b42b15d0adb90181c69a80027 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 07:26:43 +0100 Subject: [PATCH 0175/1106] Extract generate_text_table from backtesting class --- freqtrade/optimize/backtest_reports.py | 53 +++++++++++++++++++++++ freqtrade/optimize/backtesting.py | 60 ++++---------------------- tests/optimize/test_backtesting.py | 9 ++-- 3 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 freqtrade/optimize/backtest_reports.py diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/backtest_reports.py new file mode 100644 index 000000000..501d22228 --- /dev/null +++ b/freqtrade/optimize/backtest_reports.py @@ -0,0 +1,53 @@ +from datetime import timedelta +from typing import Dict + +from pandas import DataFrame +from tabulate import tabulate + + +def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, + results: DataFrame, skip_nan: bool = False) -> str: + """ + Generates and returns a text table for the given backtest data and the results dataframe + :return: pretty printed table with tabulate as str + """ + + floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') + tabular_data = [] + headers = ['pair', 'buy count', 'avg profit %', 'cum profit %', + f'tot profit {stake_currency}', 'tot profit %', 'avg duration', + 'profit', 'loss'] + for pair in data: + result = results[results.pair == pair] + if skip_nan and result.profit_abs.isnull().all(): + continue + + tabular_data.append([ + pair, + len(result.index), + result.profit_percent.mean() * 100.0, + result.profit_percent.sum() * 100.0, + result.profit_abs.sum(), + result.profit_percent.sum() * 100.0 / max_open_trades, + str(timedelta( + minutes=round(result.trade_duration.mean()))) if not result.empty else '0:00', + len(result[result.profit_abs > 0]), + len(result[result.profit_abs < 0]) + ]) + + # Append Total + tabular_data.append([ + 'TOTAL', + len(results.index), + results.profit_percent.mean() * 100.0, + results.profit_percent.sum() * 100.0, + results.profit_abs.sum(), + results.profit_percent.sum() * 100.0 / max_open_trades, + str(timedelta( + minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', + len(results[results.profit_abs > 0]), + len(results[results.profit_abs < 0]) + ]) + # Ignore type as floatfmt does allow tuples but mypy does not know that + return tabulate(tabular_data, headers=headers, + floatfmt=floatfmt, tablefmt="pipe") # type: ignore diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 9bd0327e0..e90a4c7ea 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -14,6 +14,7 @@ from tabulate import tabulate from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) +from freqtrade.optimize.backtest_reports import generate_text_table from freqtrade.data import history from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException @@ -129,55 +130,6 @@ class Backtesting: return data, timerange - def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame, - skip_nan: bool = False) -> str: - """ - Generates and returns a text table for the given backtest data and the results dataframe - :return: pretty printed table with tabulate as str - """ - stake_currency = str(self.config.get('stake_currency')) - max_open_trades = self.config.get('max_open_trades') - - floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') - tabular_data = [] - headers = ['pair', 'buy count', 'avg profit %', 'cum profit %', - 'tot profit ' + stake_currency, 'tot profit %', 'avg duration', - 'profit', 'loss'] - for pair in data: - result = results[results.pair == pair] - if skip_nan and result.profit_abs.isnull().all(): - continue - - tabular_data.append([ - pair, - len(result.index), - result.profit_percent.mean() * 100.0, - result.profit_percent.sum() * 100.0, - result.profit_abs.sum(), - result.profit_percent.sum() * 100.0 / max_open_trades, - str(timedelta( - minutes=round(result.trade_duration.mean()))) if not result.empty else '0:00', - len(result[result.profit_abs > 0]), - len(result[result.profit_abs < 0]) - ]) - - # Append Total - tabular_data.append([ - 'TOTAL', - len(results.index), - results.profit_percent.mean() * 100.0, - results.profit_percent.sum() * 100.0, - results.profit_abs.sum(), - results.profit_percent.sum() * 100.0 / max_open_trades, - str(timedelta( - minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', - len(results[results.profit_abs > 0]), - len(results[results.profit_abs < 0]) - ]) - # Ignore type as floatfmt does allow tuples but mypy does not know that - return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore - def _generate_text_table_sell_reason(self, data: Dict[str, Dict], results: DataFrame) -> str: """ Generate small table outlining Backtest results @@ -509,13 +461,19 @@ class Backtesting: print(f"Result for strategy {strategy}") print(' BACKTESTING REPORT '.center(133, '=')) - print(self._generate_text_table(data, results)) + print(generate_text_table(data, + stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results)) print(' SELL REASON STATS '.center(133, '=')) print(self._generate_text_table_sell_reason(data, results)) print(' LEFT OPEN TRADES REPORT '.center(133, '=')) - print(self._generate_text_table(data, results.loc[results.open_at_end], True)) + print(generate_text_table(data, + stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results.loc[results.open_at_end], skip_nan=True)) print() if len(all_results) > 1: # Print Strategy summary table diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 4e2fd01cf..67332c10a 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -19,6 +19,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize import setup_configuration, start_backtesting +from freqtrade.optimize.backtest_reports import generate_text_table from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy @@ -360,8 +361,8 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: def test_generate_text_table(default_conf, mocker): patch_exchange(mocker) - default_conf['max_open_trades'] = 2 - backtesting = Backtesting(default_conf) + # default_conf['max_open_trades'] = 2 + # backtesting = Backtesting(default_conf) results = pd.DataFrame( { @@ -384,7 +385,9 @@ def test_generate_text_table(default_conf, mocker): '| TOTAL | 2 | 15.00 | 30.00 | ' '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |' ) - assert backtesting._generate_text_table(data={'ETH/BTC': {}}, results=results) == result_str + assert generate_text_table(data={'ETH/BTC': {}}, + stake_currency='BTC', max_open_trades=2, + results=results) == result_str def test_generate_text_table_sell_reason(default_conf, mocker): From caec345c0b77364412ae0ec2c524ff2eab9ef316 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 07:28:30 +0100 Subject: [PATCH 0176/1106] Extract generate_text_table_sell_reason from backtesting class --- freqtrade/optimize/backtest_reports.py | 13 +++++++++++++ freqtrade/optimize/backtesting.py | 17 ++++------------- tests/optimize/test_backtesting.py | 8 +++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/backtest_reports.py index 501d22228..8912af22a 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/backtest_reports.py @@ -51,3 +51,16 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, floatfmt=floatfmt, tablefmt="pipe") # type: ignore + + +def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) -> str: + """ + Generate small table outlining Backtest results + """ + tabular_data = [] + headers = ['Sell Reason', 'Count', 'Profit', 'Loss'] + for reason, count in results['sell_reason'].value_counts().iteritems(): + profit = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] >= 0)]) + loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)]) + tabular_data.append([reason.value, count, profit, loss]) + return tabulate(tabular_data, headers=headers, tablefmt="pipe") diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index e90a4c7ea..1c92860a8 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -14,12 +14,13 @@ from tabulate import tabulate from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) -from freqtrade.optimize.backtest_reports import generate_text_table from freqtrade.data import history from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json +from freqtrade.optimize.backtest_reports import ( + generate_text_table, generate_text_table_sell_reason) from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode @@ -130,17 +131,7 @@ class Backtesting: return data, timerange - def _generate_text_table_sell_reason(self, data: Dict[str, Dict], results: DataFrame) -> str: - """ - Generate small table outlining Backtest results - """ - tabular_data = [] - headers = ['Sell Reason', 'Count', 'Profit', 'Loss'] - for reason, count in results['sell_reason'].value_counts().iteritems(): - profit = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] >= 0)]) - loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)]) - tabular_data.append([reason.value, count, profit, loss]) - return tabulate(tabular_data, headers=headers, tablefmt="pipe") + def _generate_text_table_strategy(self, all_results: dict) -> str: """ @@ -467,7 +458,7 @@ class Backtesting: results=results)) print(' SELL REASON STATS '.center(133, '=')) - print(self._generate_text_table_sell_reason(data, results)) + print(generate_text_table_sell_reason(data, results)) print(' LEFT OPEN TRADES REPORT '.center(133, '=')) print(generate_text_table(data, diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 67332c10a..554d8974b 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -19,7 +19,8 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize import setup_configuration, start_backtesting -from freqtrade.optimize.backtest_reports import generate_text_table +from freqtrade.optimize.backtest_reports import ( + generate_text_table, generate_text_table_sell_reason) from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy @@ -361,8 +362,6 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: def test_generate_text_table(default_conf, mocker): patch_exchange(mocker) - # default_conf['max_open_trades'] = 2 - # backtesting = Backtesting(default_conf) results = pd.DataFrame( { @@ -392,7 +391,6 @@ def test_generate_text_table(default_conf, mocker): def test_generate_text_table_sell_reason(default_conf, mocker): patch_exchange(mocker) - backtesting = Backtesting(default_conf) results = pd.DataFrame( { @@ -412,7 +410,7 @@ def test_generate_text_table_sell_reason(default_conf, mocker): '| roi | 2 | 2 | 0 |\n' '| stop_loss | 1 | 0 | 1 |' ) - assert backtesting._generate_text_table_sell_reason( + assert generate_text_table_sell_reason( data={'ETH/BTC': {}}, results=results) == result_str From 904e1647e1579f2bc0ff396937ea6982afd4ccd7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 07:32:12 +0100 Subject: [PATCH 0177/1106] Extract generate_text_table_strategy to seperate module --- freqtrade/optimize/backtest_reports.py | 29 +++++++++++++++++++ freqtrade/optimize/backtesting.py | 39 ++++---------------------- tests/optimize/test_backtesting.py | 15 +++------- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/backtest_reports.py index 8912af22a..8f0436563 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/backtest_reports.py @@ -64,3 +64,32 @@ def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) - loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)]) tabular_data.append([reason.value, count, profit, loss]) return tabulate(tabular_data, headers=headers, tablefmt="pipe") + + +def generate_text_table_strategy(stake_currency: str, max_open_trades: str, + all_results: Dict) -> str: + """ + Generate summary table per strategy + """ + + floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') + tabular_data = [] + headers = ['Strategy', 'buy count', 'avg profit %', 'cum profit %', + f'tot profit {stake_currency}', 'tot profit %', 'avg duration', + 'profit', 'loss'] + for strategy, results in all_results.items(): + tabular_data.append([ + strategy, + len(results.index), + results.profit_percent.mean() * 100.0, + results.profit_percent.sum() * 100.0, + results.profit_abs.sum(), + results.profit_percent.sum() * 100.0 / max_open_trades, + str(timedelta( + minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', + len(results[results.profit_abs > 0]), + len(results[results.profit_abs < 0]) + ]) + # Ignore type as floatfmt does allow tuples but mypy does not know that + return tabulate(tabular_data, headers=headers, + floatfmt=floatfmt, tablefmt="pipe") # type: ignore diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 1c92860a8..ae3fbed0a 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -10,7 +10,6 @@ from pathlib import Path from typing import Any, Dict, List, NamedTuple, Optional from pandas import DataFrame -from tabulate import tabulate from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) @@ -20,7 +19,8 @@ from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json from freqtrade.optimize.backtest_reports import ( - generate_text_table, generate_text_table_sell_reason) + generate_text_table, generate_text_table_sell_reason, + generate_text_table_strategy) from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode @@ -131,37 +131,6 @@ class Backtesting: return data, timerange - - - def _generate_text_table_strategy(self, all_results: dict) -> str: - """ - Generate summary table per strategy - """ - stake_currency = str(self.config.get('stake_currency')) - max_open_trades = self.config.get('max_open_trades') - - floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') - tabular_data = [] - headers = ['Strategy', 'buy count', 'avg profit %', 'cum profit %', - 'tot profit ' + stake_currency, 'tot profit %', 'avg duration', - 'profit', 'loss'] - for strategy, results in all_results.items(): - tabular_data.append([ - strategy, - len(results.index), - results.profit_percent.mean() * 100.0, - results.profit_percent.sum() * 100.0, - results.profit_abs.sum(), - results.profit_percent.sum() * 100.0 / max_open_trades, - str(timedelta( - minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', - len(results[results.profit_abs > 0]), - len(results[results.profit_abs < 0]) - ]) - # Ignore type as floatfmt does allow tuples but mypy does not know that - return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore - def _store_backtest_result(self, recordfilename: Path, results: DataFrame, strategyname: Optional[str] = None) -> None: @@ -469,5 +438,7 @@ class Backtesting: if len(all_results) > 1: # Print Strategy summary table print(' Strategy Summary '.center(133, '=')) - print(self._generate_text_table_strategy(all_results)) + print(generate_text_table_strategy(self.config['stake_currency'], + self.config['max_open_trades'], + all_results=all_results)) print('\nFor more details, please look at the detail tables above') diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 554d8974b..57b80f837 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -20,7 +20,8 @@ from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize import setup_configuration, start_backtesting from freqtrade.optimize.backtest_reports import ( - generate_text_table, generate_text_table_sell_reason) + generate_text_table, generate_text_table_sell_reason, + generate_text_table_strategy) from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy @@ -361,7 +362,6 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: def test_generate_text_table(default_conf, mocker): - patch_exchange(mocker) results = pd.DataFrame( { @@ -390,7 +390,6 @@ def test_generate_text_table(default_conf, mocker): def test_generate_text_table_sell_reason(default_conf, mocker): - patch_exchange(mocker) results = pd.DataFrame( { @@ -414,13 +413,7 @@ def test_generate_text_table_sell_reason(default_conf, mocker): data={'ETH/BTC': {}}, results=results) == result_str -def test_generate_text_table_strategyn(default_conf, mocker): - """ - Test Backtesting.generate_text_table_sell_reason() method - """ - patch_exchange(mocker) - default_conf['max_open_trades'] = 2 - backtesting = Backtesting(default_conf) +def test_generate_text_table_strategy(default_conf, mocker): results = {} results['ETH/BTC'] = pd.DataFrame( { @@ -455,7 +448,7 @@ def test_generate_text_table_strategyn(default_conf, mocker): '| LTC/BTC | 3 | 30.00 | 90.00 ' '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' ) - assert backtesting._generate_text_table_strategy(all_results=results) == result_str + assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: From 10ee23622a34797170e2ad37b3389b7b1ea7ebfd Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 07:33:55 +0100 Subject: [PATCH 0178/1106] Extract tests for backtest_reports to their own test module --- tests/optimize/test_backtest_reports.py | 96 +++++++++++++++++++++++++ tests/optimize/test_backtesting.py | 93 ------------------------ 2 files changed, 96 insertions(+), 93 deletions(-) create mode 100644 tests/optimize/test_backtest_reports.py diff --git a/tests/optimize/test_backtest_reports.py b/tests/optimize/test_backtest_reports.py new file mode 100644 index 000000000..726202517 --- /dev/null +++ b/tests/optimize/test_backtest_reports.py @@ -0,0 +1,96 @@ +import pandas as pd + +from freqtrade.optimize.backtest_reports import ( + generate_text_table, generate_text_table_sell_reason, + generate_text_table_strategy) +from freqtrade.strategy.interface import SellType + + +def test_generate_text_table(default_conf, mocker): + + results = pd.DataFrame( + { + 'pair': ['ETH/BTC', 'ETH/BTC'], + 'profit_percent': [0.1, 0.2], + 'profit_abs': [0.2, 0.4], + 'trade_duration': [10, 30], + 'profit': [2, 0], + 'loss': [0, 0] + } + ) + + result_str = ( + '| pair | buy count | avg profit % | cum profit % | ' + 'tot profit BTC | tot profit % | avg duration | profit | loss |\n' + '|:--------|------------:|---------------:|---------------:|' + '-----------------:|---------------:|:---------------|---------:|-------:|\n' + '| ETH/BTC | 2 | 15.00 | 30.00 | ' + '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |\n' + '| TOTAL | 2 | 15.00 | 30.00 | ' + '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |' + ) + assert generate_text_table(data={'ETH/BTC': {}}, + stake_currency='BTC', max_open_trades=2, + results=results) == result_str + + +def test_generate_text_table_sell_reason(default_conf, mocker): + + results = pd.DataFrame( + { + 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], + 'profit_percent': [0.1, 0.2, -0.3], + 'profit_abs': [0.2, 0.4, -0.5], + 'trade_duration': [10, 30, 10], + 'profit': [2, 0, 0], + 'loss': [0, 0, 1], + 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] + } + ) + + result_str = ( + '| Sell Reason | Count | Profit | Loss |\n' + '|:--------------|--------:|---------:|-------:|\n' + '| roi | 2 | 2 | 0 |\n' + '| stop_loss | 1 | 0 | 1 |' + ) + assert generate_text_table_sell_reason( + data={'ETH/BTC': {}}, results=results) == result_str + + +def test_generate_text_table_strategy(default_conf, mocker): + results = {} + results['ETH/BTC'] = pd.DataFrame( + { + 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], + 'profit_percent': [0.1, 0.2, 0.3], + 'profit_abs': [0.2, 0.4, 0.5], + 'trade_duration': [10, 30, 10], + 'profit': [2, 0, 0], + 'loss': [0, 0, 1], + 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] + } + ) + results['LTC/BTC'] = pd.DataFrame( + { + 'pair': ['LTC/BTC', 'LTC/BTC', 'LTC/BTC'], + 'profit_percent': [0.4, 0.2, 0.3], + 'profit_abs': [0.4, 0.4, 0.5], + 'trade_duration': [15, 30, 15], + 'profit': [4, 1, 0], + 'loss': [0, 0, 1], + 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] + } + ) + + result_str = ( + '| Strategy | buy count | avg profit % | cum profit % ' + '| tot profit BTC | tot profit % | avg duration | profit | loss |\n' + '|:-----------|------------:|---------------:|---------------:' + '|-----------------:|---------------:|:---------------|---------:|-------:|\n' + '| ETH/BTC | 3 | 20.00 | 60.00 ' + '| 1.10000000 | 30.00 | 0:17:00 | 3 | 0 |\n' + '| LTC/BTC | 3 | 30.00 | 90.00 ' + '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' + ) + assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 57b80f837..9f31114b4 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -19,9 +19,6 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize import setup_configuration, start_backtesting -from freqtrade.optimize.backtest_reports import ( - generate_text_table, generate_text_table_sell_reason, - generate_text_table_strategy) from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy @@ -361,96 +358,6 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC']) -def test_generate_text_table(default_conf, mocker): - - results = pd.DataFrame( - { - 'pair': ['ETH/BTC', 'ETH/BTC'], - 'profit_percent': [0.1, 0.2], - 'profit_abs': [0.2, 0.4], - 'trade_duration': [10, 30], - 'profit': [2, 0], - 'loss': [0, 0] - } - ) - - result_str = ( - '| pair | buy count | avg profit % | cum profit % | ' - 'tot profit BTC | tot profit % | avg duration | profit | loss |\n' - '|:--------|------------:|---------------:|---------------:|' - '-----------------:|---------------:|:---------------|---------:|-------:|\n' - '| ETH/BTC | 2 | 15.00 | 30.00 | ' - '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |\n' - '| TOTAL | 2 | 15.00 | 30.00 | ' - '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |' - ) - assert generate_text_table(data={'ETH/BTC': {}}, - stake_currency='BTC', max_open_trades=2, - results=results) == result_str - - -def test_generate_text_table_sell_reason(default_conf, mocker): - - results = pd.DataFrame( - { - 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], - 'profit_percent': [0.1, 0.2, -0.3], - 'profit_abs': [0.2, 0.4, -0.5], - 'trade_duration': [10, 30, 10], - 'profit': [2, 0, 0], - 'loss': [0, 0, 1], - 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] - } - ) - - result_str = ( - '| Sell Reason | Count | Profit | Loss |\n' - '|:--------------|--------:|---------:|-------:|\n' - '| roi | 2 | 2 | 0 |\n' - '| stop_loss | 1 | 0 | 1 |' - ) - assert generate_text_table_sell_reason( - data={'ETH/BTC': {}}, results=results) == result_str - - -def test_generate_text_table_strategy(default_conf, mocker): - results = {} - results['ETH/BTC'] = pd.DataFrame( - { - 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], - 'profit_percent': [0.1, 0.2, 0.3], - 'profit_abs': [0.2, 0.4, 0.5], - 'trade_duration': [10, 30, 10], - 'profit': [2, 0, 0], - 'loss': [0, 0, 1], - 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] - } - ) - results['LTC/BTC'] = pd.DataFrame( - { - 'pair': ['LTC/BTC', 'LTC/BTC', 'LTC/BTC'], - 'profit_percent': [0.4, 0.2, 0.3], - 'profit_abs': [0.4, 0.4, 0.5], - 'trade_duration': [15, 30, 15], - 'profit': [4, 1, 0], - 'loss': [0, 0, 1], - 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] - } - ) - - result_str = ( - '| Strategy | buy count | avg profit % | cum profit % ' - '| tot profit BTC | tot profit % | avg duration | profit | loss |\n' - '|:-----------|------------:|---------------:|---------------:' - '|-----------------:|---------------:|:---------------|---------:|-------:|\n' - '| ETH/BTC | 3 | 20.00 | 60.00 ' - '| 1.10000000 | 30.00 | 0:17:00 | 3 | 0 |\n' - '| LTC/BTC | 3 | 30.00 | 90.00 ' - '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' - ) - assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str - - def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: def get_timerange(input1): return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) From 8cc48cf4b042f4b47ad3902addd2fafc5e433762 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 09:31:35 +0100 Subject: [PATCH 0179/1106] Fix tests where mocks fail now --- tests/optimize/test_backtesting.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 9f31114b4..83d212e3d 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -366,11 +366,8 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: mocker.patch('freqtrade.data.history.get_timerange', get_timerange) mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) - mocker.patch.multiple( - 'freqtrade.optimize.backtesting.Backtesting', - backtest=MagicMock(), - _generate_text_table=MagicMock(return_value='1'), - ) + mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) + mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = '1m' @@ -399,11 +396,8 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> mocker.patch('freqtrade.data.history.get_timerange', get_timerange) mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) - mocker.patch.multiple( - 'freqtrade.optimize.backtesting.Backtesting', - backtest=MagicMock(), - _generate_text_table=MagicMock(return_value='1'), - ) + mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) + mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = "1m" @@ -714,7 +708,8 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): patch_exchange(mocker, api_mock) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) - mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock()) + mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock()) + patched_configuration_load_config_file(mocker, default_conf) args = [ @@ -760,10 +755,9 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): backtestmock = MagicMock() mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) gen_table_mock = MagicMock() - mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', gen_table_mock) + mocker.patch('freqtrade.optimize.backtesting.generate_text_table', gen_table_mock) gen_strattable_mock = MagicMock() - mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table_strategy', - gen_strattable_mock) + mocker.patch('freqtrade.optimize.backtesting.generate_text_table_strategy', gen_strattable_mock) patched_configuration_load_config_file(mocker, default_conf) args = [ From a9fbad0741fe7475a2d0b90c22788a42a24e3a05 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 09:37:54 +0100 Subject: [PATCH 0180/1106] Improve docstrings --- freqtrade/optimize/backtest_reports.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/backtest_reports.py index 8f0436563..5778747cf 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/backtest_reports.py @@ -9,7 +9,12 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra results: DataFrame, skip_nan: bool = False) -> str: """ Generates and returns a text table for the given backtest data and the results dataframe - :return: pretty printed table with tabulate as str + :param data: Dict of containing data that was used during backtesting. + :param stake_currency: stake-currency - used to correctly name headers + :param max_open_trades: Maximum allowed open trades + :param results: Dataframe containing the backtest results + :param skip_nan: Print "left open" open trades + :return: pretty printed table with tabulate as string """ floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') @@ -56,6 +61,9 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) -> str: """ Generate small table outlining Backtest results + :param data: Dict of containing data that was used during backtesting. + :param results: Dataframe containing the backtest results + :return: pretty printed table with tabulate as string """ tabular_data = [] headers = ['Sell Reason', 'Count', 'Profit', 'Loss'] @@ -70,6 +78,10 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, all_results: Dict) -> str: """ Generate summary table per strategy + :param stake_currency: stake-currency - used to correctly name headers + :param max_open_trades: Maximum allowed open trades used for backtest + :param all_results: Dict of containing results for all strategies + :return: pretty printed table with tabulate as string """ floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') From e89fa44680e795f5a52067406526e41c6a1ae756 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 11:50:54 +0300 Subject: [PATCH 0181/1106] Arrange common section for update trade state methods --- freqtrade/freqtradebot.py | 170 +++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 83 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 774e001c8..d5d918585 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -183,7 +183,7 @@ class FreqtradeBot: return max(0, self.config['max_open_trades'] - open_trades) # -# BUY / enter positions / open trades part +# BUY / enter positions / open trades logic and methods # def enter_positions(self) -> int: @@ -499,7 +499,7 @@ class FreqtradeBot: return True # -# SELL / exit positions / close trades part +# SELL / exit positions / close trades logic and methods # def exit_positions(self, trades: List[Any]) -> int: @@ -528,87 +528,6 @@ class FreqtradeBot: return trades_closed - def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: - """ - Get real amount for the trade - Necessary for exchanges which charge fees in base currency (e.g. binance) - """ - if order_amount is None: - order_amount = order['amount'] - # Only run for closed orders - if trade.fee_open == 0 or order['status'] == 'open': - return order_amount - - # use fee from order-dict if possible - if ('fee' in order and order['fee'] is not None and - (order['fee'].keys() >= {'currency', 'cost'})): - if (order['fee']['currency'] is not None and - order['fee']['cost'] is not None and - trade.pair.startswith(order['fee']['currency'])): - new_amount = order_amount - order['fee']['cost'] - logger.info("Applying fee on amount for %s (from %s to %s) from Order", - trade, order['amount'], new_amount) - return new_amount - - # Fallback to Trades - trades = self.exchange.get_trades_for_order(trade.open_order_id, trade.pair, - trade.open_date) - - if len(trades) == 0: - logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade) - return order_amount - amount = 0 - fee_abs = 0 - for exectrade in trades: - amount += exectrade['amount'] - if ("fee" in exectrade and exectrade['fee'] is not None and - (exectrade['fee'].keys() >= {'currency', 'cost'})): - # only applies if fee is in quote currency! - if (exectrade['fee']['currency'] is not None and - exectrade['fee']['cost'] is not None and - trade.pair.startswith(exectrade['fee']['currency'])): - fee_abs += exectrade['fee']['cost'] - - if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): - logger.warning(f"Amount {amount} does not match amount {trade.amount}") - raise DependencyException("Half bought? Amounts don't match") - real_amount = amount - fee_abs - if fee_abs != 0: - logger.info(f"Applying fee on amount for {trade} " - f"(from {order_amount} to {real_amount}) from Trades") - return real_amount - - def update_trade_state(self, trade, action_order: dict = None): - """ - Checks trades with open orders and updates the amount if necessary - """ - # Get order details for actual price per unit - if trade.open_order_id: - # Update trade with order values - logger.info('Found open order for %s', trade) - try: - order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) - except InvalidOrderException as exception: - logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception) - return - # Try update amount (binance-fix) - try: - new_amount = self.get_real_amount(trade, order) - if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): - order['amount'] = new_amount - # Fee was applied, so set to 0 - trade.fee_open = 0 - trade.recalc_open_trade_price() - - except DependencyException as exception: - logger.warning("Could not update trade amount: %s", exception) - - trade.update(order) - - # Updating wallets when order is closed - if not trade.is_open: - self.wallets.update() - def get_sell_rate(self, pair: str, refresh: bool) -> float: """ Get sell rate - either using get-ticker bid or first bid based on orderbook @@ -1047,3 +966,88 @@ class FreqtradeBot: # Send the message self.rpc.send_msg(msg) + +# +# Common update trade state methods +# + + def update_trade_state(self, trade, action_order: dict = None): + """ + Checks trades with open orders and updates the amount if necessary + """ + # Get order details for actual price per unit + if trade.open_order_id: + # Update trade with order values + logger.info('Found open order for %s', trade) + try: + order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) + except InvalidOrderException as exception: + logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception) + return + # Try update amount (binance-fix) + try: + new_amount = self.get_real_amount(trade, order) + if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): + order['amount'] = new_amount + # Fee was applied, so set to 0 + trade.fee_open = 0 + trade.recalc_open_trade_price() + + except DependencyException as exception: + logger.warning("Could not update trade amount: %s", exception) + + trade.update(order) + + # Updating wallets when order is closed + if not trade.is_open: + self.wallets.update() + + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: + """ + Get real amount for the trade + Necessary for exchanges which charge fees in base currency (e.g. binance) + """ + if order_amount is None: + order_amount = order['amount'] + # Only run for closed orders + if trade.fee_open == 0 or order['status'] == 'open': + return order_amount + + # use fee from order-dict if possible + if ('fee' in order and order['fee'] is not None and + (order['fee'].keys() >= {'currency', 'cost'})): + if (order['fee']['currency'] is not None and + order['fee']['cost'] is not None and + trade.pair.startswith(order['fee']['currency'])): + new_amount = order_amount - order['fee']['cost'] + logger.info("Applying fee on amount for %s (from %s to %s) from Order", + trade, order['amount'], new_amount) + return new_amount + + # Fallback to Trades + trades = self.exchange.get_trades_for_order(trade.open_order_id, trade.pair, + trade.open_date) + + if len(trades) == 0: + logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade) + return order_amount + amount = 0 + fee_abs = 0 + for exectrade in trades: + amount += exectrade['amount'] + if ("fee" in exectrade and exectrade['fee'] is not None and + (exectrade['fee'].keys() >= {'currency', 'cost'})): + # only applies if fee is in quote currency! + if (exectrade['fee']['currency'] is not None and + exectrade['fee']['cost'] is not None and + trade.pair.startswith(exectrade['fee']['currency'])): + fee_abs += exectrade['fee']['cost'] + + if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): + logger.warning(f"Amount {amount} does not match amount {trade.amount}") + raise DependencyException("Half bought? Amounts don't match") + real_amount = amount - fee_abs + if fee_abs != 0: + logger.info(f"Applying fee on amount for {trade} " + f"(from {order_amount} to {real_amount}) from Trades") + return real_amount From 6fbdd6bee9520afc13450cb63c3fba4591537ce3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 09:51:24 +0100 Subject: [PATCH 0182/1106] Remove unused directory from user_data --- user_data/backtest_data/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 user_data/backtest_data/.gitkeep diff --git a/user_data/backtest_data/.gitkeep b/user_data/backtest_data/.gitkeep deleted file mode 100644 index e69de29bb..000000000 From 2c8e8d8ef65021fbb3ee3446768fe3e3fa34c36f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 09:51:47 +0100 Subject: [PATCH 0183/1106] Align columns for btanalysis loading --- freqtrade/data/btanalysis.py | 2 +- tests/data/test_btanalysis.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 2fc931a9b..04b2ca980 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -47,7 +47,7 @@ def load_backtest_data(filename) -> pd.DataFrame: utc=True, infer_datetime_format=True ) - df['profitabs'] = df['close_rate'] - df['open_rate'] + df['profit'] = df['close_rate'] - df['open_rate'] df = df.sort_values("open_time").reset_index(drop=True) return df diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 13711c63e..60d9c3ea5 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -20,7 +20,7 @@ def test_load_backtest_data(testdatadir): filename = testdatadir / "backtest-result_test.json" bt_data = load_backtest_data(filename) assert isinstance(bt_data, DataFrame) - assert list(bt_data.columns) == BT_DATA_COLUMNS + ["profitabs"] + assert list(bt_data.columns) == BT_DATA_COLUMNS + ["profit"] assert len(bt_data) == 179 # Test loading from string (must yield same result) From 9325880fe5c84973a6553f47993639042f574ac9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:38:59 +0100 Subject: [PATCH 0184/1106] Split config-validation requires --- freqtrade/configuration/config_validation.py | 11 +++++-- freqtrade/constants.py | 30 ++++++++++++-------- tests/test_configuration.py | 1 + 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 43eead46a..9afa39ca7 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -1,4 +1,5 @@ import logging +from copy import deepcopy from typing import Any, Dict from jsonschema import Draft4Validator, validators @@ -42,15 +43,21 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]: :param conf: Config in JSON format :return: Returns the config if valid, otherwise throw an exception """ + conf_schema = deepcopy(constants.CONF_SCHEMA) + if conf.get('runmode', RunMode.OTHER) in (RunMode.DRY_RUN, RunMode.LIVE): + conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED + else: + conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED + try: - FreqtradeValidator(constants.CONF_SCHEMA).validate(conf) + FreqtradeValidator(conf_schema).validate(conf) return conf except ValidationError as e: logger.critical( f"Invalid configuration. See config.json.example. Reason: {e}" ) raise ValidationError( - best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message + best_match(Draft4Validator(conf_schema).iter_errors(conf)).message ) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d7c6249d5..b21279bb4 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -269,16 +269,22 @@ CONF_SCHEMA = { 'required': ['process_throttle_secs', 'allowed_risk', 'capital_available_percentage'] } }, - 'required': [ - 'exchange', - 'max_open_trades', - 'stake_currency', - 'stake_amount', - 'dry_run', - 'dry_run_wallet', - 'bid_strategy', - 'unfilledtimeout', - 'stoploss', - 'minimal_roi', - ] } + +SCHEMA_TRADE_REQUIRED = [ + 'exchange', + 'max_open_trades', + 'stake_currency', + 'stake_amount', + 'dry_run', + 'dry_run_wallet', + 'bid_strategy', + 'unfilledtimeout', + 'stoploss', + 'minimal_roi', +] + +SCHEMA_MINIMAL_REQUIRED = [ + 'exchange', + 'dry_run', +] diff --git a/tests/test_configuration.py b/tests/test_configuration.py index ee3d23131..531a88688 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -49,6 +49,7 @@ def test_load_config_missing_attributes(default_conf) -> None: conf = deepcopy(default_conf) conf.pop('stake_currency') + conf['runmode'] = RunMode.DRY_RUN with pytest.raises(ValidationError, match=r".*'stake_currency' is a required property.*"): validate_config_schema(conf) From 20fc3b7978d036da11a56df2b8c81622854e2a6e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:41:10 +0100 Subject: [PATCH 0185/1106] validate config for utils too --- freqtrade/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 45520ecf7..9fe15aea6 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -12,7 +12,8 @@ from colorama import init as colorama_init from tabulate import tabulate from freqtrade.configuration import (Configuration, TimeRange, - remove_credentials) + remove_credentials, + validate_config_consistency) from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY @@ -40,6 +41,7 @@ def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str # Ensure we do not use Exchange credentials remove_credentials(config) + validate_config_consistency(config) return config From 22fcf7b4dc64c82058e4eb1349422ac83199c043 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:47:37 +0100 Subject: [PATCH 0186/1106] Allow empty stake currency in certain cases --- freqtrade/configuration/config_validation.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 9afa39ca7..f7886eec2 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -48,6 +48,10 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]: conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED else: conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED + # Dynamically allow empty stake-currency + # Since the minimal config specifies this too. + # It's not allowed for Dry-run or live modes + conf_schema['properties']['stake_currency']['enum'] += [''] try: FreqtradeValidator(conf_schema).validate(conf) From 9382b38c41509e51495d48248b968d58bdf1e6df Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:56:00 +0100 Subject: [PATCH 0187/1106] Fix mypy error --- freqtrade/configuration/config_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index f7886eec2..6f56790f4 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -51,7 +51,7 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]: # Dynamically allow empty stake-currency # Since the minimal config specifies this too. # It's not allowed for Dry-run or live modes - conf_schema['properties']['stake_currency']['enum'] += [''] + conf_schema['properties']['stake_currency']['enum'] += [''] # type: ignore try: FreqtradeValidator(conf_schema).validate(conf) From 1b8943ac54fabbad046503efeac88f0425a6684a Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:59:10 +0100 Subject: [PATCH 0188/1106] Add documentation for tradable_balance_ratio --- config_full.json.example | 1 + docs/configuration.md | 7 +++++++ freqtrade/constants.py | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/config_full.json.example b/config_full.json.example index b9631f63d..4e692d371 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, "dry_run": false, diff --git a/docs/configuration.md b/docs/configuration.md index 90f0aa791..1acd6162c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,6 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.0` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -144,6 +145,12 @@ To allow the bot to trade all the available `stake_currency` in your account set "stake_amount" : "unlimited", ``` +When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. +This will keep 1% of your account balance "untradable" in your account. + +!!! Note: + This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). + In this case a trade amount is calculated as: ```python diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d7c6249d5..d5ba00cd5 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -73,6 +73,12 @@ CONF_SCHEMA = { 'minimum': 0.0001, 'pattern': UNLIMITED_STAKE_AMOUNT }, + 'tradable_balance_ratio': { + 'type': ['number'], + 'minimum': 0.1, + 'maximum': 1, + 'default': 0.99 + }, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, From f15e5e9d5715c233d49adbe692dd38215e71a769 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 13:51:25 +0300 Subject: [PATCH 0189/1106] Add _notify_buy() --- freqtrade/freqtradebot.py | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d5d918585..9570a80ef 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -400,8 +400,6 @@ class FreqtradeBot: :param pair: pair for which we want to create a LIMIT_BUY :return: None """ - stake_currency = self.config['stake_currency'] - fiat_currency = self.config.get('fiat_display_currency', None) time_in_force = self.strategy.order_time_in_force['buy'] if price: @@ -458,17 +456,6 @@ class FreqtradeBot: amount = order['amount'] buy_limit_filled_price = order['price'] - self.rpc.send_msg({ - 'type': RPCMessageType.BUY_NOTIFICATION, - 'exchange': self.exchange.name.capitalize(), - 'pair': pair, - 'limit': buy_limit_filled_price, - 'order_type': order_type, - 'stake_amount': stake_amount, - 'stake_currency': stake_currency, - 'fiat_currency': fiat_currency - }) - # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker') trade = Trade( @@ -486,6 +473,8 @@ class FreqtradeBot: ticker_interval=timeframe_to_minutes(self.config['ticker_interval']) ) + self._notify_buy(trade, order_type) + # Update fees if order is closed if order_status == 'closed': self.update_trade_state(trade, order) @@ -498,6 +487,30 @@ class FreqtradeBot: return True + def _notify_buy(self, trade: Trade, order_type: str): + """ + Sends rpc notification when a buy occured. + """ + msg = { + 'type': RPCMessageType.BUY_NOTIFICATION, + 'exchange': self.exchange.name.capitalize(), + 'pair': trade.pair, + 'limit': trade.open_rate, + 'order_type': order_type, + 'stake_amount': trade.stake_amount, + } + + if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: + stake_currency = self.config['stake_currency'] + fiat_currency = self.config['fiat_display_currency'] + msg.update({ + 'stake_currency': stake_currency, + 'fiat_currency': fiat_currency, + }) + + # Send the message + self.rpc.send_msg(msg) + # # SELL / exit positions / close trades logic and methods # @@ -952,10 +965,9 @@ class FreqtradeBot: 'profit_percent': profit_percent, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, - 'close_date': trade.close_date or datetime.utcnow() + 'close_date': trade.close_date or datetime.utcnow(), } - # For regular case, when the configuration exists if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: stake_currency = self.config['stake_currency'] fiat_currency = self.config['fiat_display_currency'] From 88efa4065bdcb222091d9594c2cb86a5a8b03461 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 13:56:16 +0300 Subject: [PATCH 0190/1106] Align the name of a variable to be same for buy and sell parts --- freqtrade/freqtradebot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9570a80ef..5e6ffbfde 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -913,16 +913,16 @@ class FreqtradeBot: except InvalidOrderException: logger.exception(f"Could not cancel stoploss order {trade.stoploss_order_id}") - ordertype = self.strategy.order_types[sell_type] + order_type = self.strategy.order_types[sell_type] if sell_reason == SellType.EMERGENCY_SELL: # Emergencysells (default to market!) - ordertype = self.strategy.order_types.get("emergencysell", "market") + order_type = self.strategy.order_types.get("emergencysell", "market") amount = self._safe_sell_amount(trade.pair, trade.amount) # Execute sell and update trade record order = self.exchange.sell(pair=str(trade.pair), - ordertype=ordertype, + ordertype=order_type, amount=amount, rate=limit, time_in_force=self.strategy.order_time_in_force['sell'] ) @@ -938,7 +938,7 @@ class FreqtradeBot: # Lock pair for one candle to prevent immediate rebuys self.strategy.lock_pair(trade.pair, timeframe_to_next_date(self.config['ticker_interval'])) - self._notify_sell(trade, ordertype) + self._notify_sell(trade, order_type) def _notify_sell(self, trade: Trade, order_type: str): """ From a47a25ca8889667bfec6cd948a2773b471cff87a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 2 Jan 2020 14:38:25 +0300 Subject: [PATCH 0191/1106] Refine passing msg params --- freqtrade/freqtradebot.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5e6ffbfde..c18d9131f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -498,16 +498,10 @@ class FreqtradeBot: 'limit': trade.open_rate, 'order_type': order_type, 'stake_amount': trade.stake_amount, + 'stake_currency': self.config['stake_currency'], + 'fiat_currency': self.config.get('fiat_display_currency', None), } - if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: - stake_currency = self.config['stake_currency'] - fiat_currency = self.config['fiat_display_currency'] - msg.update({ - 'stake_currency': stake_currency, - 'fiat_currency': fiat_currency, - }) - # Send the message self.rpc.send_msg(msg) @@ -966,13 +960,12 @@ class FreqtradeBot: 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, 'close_date': trade.close_date or datetime.utcnow(), + 'stake_currency': self.config['stake_currency'], } - if 'stake_currency' in self.config and 'fiat_display_currency' in self.config: - stake_currency = self.config['stake_currency'] + if 'fiat_display_currency' in self.config: fiat_currency = self.config['fiat_display_currency'] msg.update({ - 'stake_currency': stake_currency, 'fiat_currency': fiat_currency, }) From 64db1f67365b128e8a9d9eb04893cbb5c5a8dd9c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:16:18 +0100 Subject: [PATCH 0192/1106] Prepare tests to valiate reduced full amount. --- tests/test_freqtradebot.py | 15 ++++++++++----- tests/test_integration.py | 15 +++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 1c17ce735..dc17ddaaa 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -150,11 +150,14 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: freqtrade.get_trade_stake_amount('ETH/BTC') -def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, - limit_buy_order, fee, mocker) -> None: +@pytest.mark.parametrize("balance_ratio,result1,result2", [ + (1, 0.005, 0.005), + (0.99, 0.00495, 0.00495), + ]) +def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_ratio, result1, + result2, limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) - patch_wallet(mocker, free=default_conf['stake_amount']) mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, @@ -164,20 +167,22 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, conf = deepcopy(default_conf) conf['stake_amount'] = UNLIMITED_STAKE_AMOUNT + conf['dry_run_wallet'] = 0.01 conf['max_open_trades'] = 2 + conf['tradable_balance_ratio'] = balance_ratio freqtrade = FreqtradeBot(conf) patch_get_signal(freqtrade) # no open trades, order amount should be 'balance / max_open_trades' result = freqtrade.get_trade_stake_amount('ETH/BTC') - assert result == default_conf['stake_amount'] / conf['max_open_trades'] + assert result == result1 # create one trade, order amount should be 'balance / (max_open_trades - num_open_trades)' freqtrade.execute_buy('ETH/BTC', result) result = freqtrade.get_trade_stake_amount('LTC/BTC') - assert result == default_conf['stake_amount'] / (conf['max_open_trades'] - 1) + assert result == result2 # create 2 trades, order amount should be None freqtrade.execute_buy('LTC/BTC', result) diff --git a/tests/test_integration.py b/tests/test_integration.py index 1108969ad..d1be961cf 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,10 +1,11 @@ - from unittest.mock import MagicMock +import pytest + from freqtrade.persistence import Trade +from freqtrade.rpc.rpc import RPC from freqtrade.strategy.interface import SellCheckTuple, SellType from tests.conftest import get_patched_freqtradebot, patch_get_signal -from freqtrade.rpc.rpc import RPC def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, @@ -112,13 +113,19 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, assert not trade.is_open -def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker) -> None: +@pytest.mark.parametrize("balance_ratio,result1", [ + (1, 200), + (0.99, 198), +]) +def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, + result1) -> None: """ Tests workflow """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True default_conf['stake_amount'] = 'unlimited' + default_conf['tradable_balance_ratio'] = balance_ratio default_conf['dry_run_wallet'] = 1000 default_conf['exchange']['name'] = 'binance' default_conf['telegram']['enabled'] = True @@ -165,7 +172,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc assert len(trades) == 5 for trade in trades: - assert trade.stake_amount == 200 + assert trade.stake_amount == result1 # Reset trade open order id's trade.open_order_id = None trades = Trade.get_open_trades() From cba156dfff18d634440f1c4d7e46f95475f97f7f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:20:57 +0100 Subject: [PATCH 0193/1106] Add offset calculation for relative stake maximum limit --- freqtrade/freqtradebot.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d5d918585..6a6a14375 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -278,7 +278,15 @@ class FreqtradeBot: free_open_trades = self.get_free_open_trades() if not free_open_trades: return None - available_amount = self.wallets.get_free(self.config['stake_currency']) + + val_tied_up = Trade.total_open_trades_stakes() + + # Ensure 1% is used from the overall balance + # Otherwise we'd risk lowering stakes with each open trade. + # (tied up + current free) * ratio) - tied up + available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * + self.config['tradable_balance_ratio']) - val_tied_up + return available_amount / free_open_trades def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: From bfef3cf497425fad61f00382119938ea39357eb4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:37:35 +0100 Subject: [PATCH 0194/1106] Add additional test case for lower balance ratios --- tests/test_freqtradebot.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index dc17ddaaa..9ca54d003 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -150,12 +150,13 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: freqtrade.get_trade_stake_amount('ETH/BTC') -@pytest.mark.parametrize("balance_ratio,result1,result2", [ - (1, 0.005, 0.005), - (0.99, 0.00495, 0.00495), +@pytest.mark.parametrize("balance_ratio,result1", [ + (1, 0.005), + (0.99, 0.00495), + (0.50, 0.0025), ]) def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_ratio, result1, - result2, limit_buy_order, fee, mocker) -> None: + limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -182,7 +183,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r freqtrade.execute_buy('ETH/BTC', result) result = freqtrade.get_trade_stake_amount('LTC/BTC') - assert result == result2 + assert result == result1 # create 2 trades, order amount should be None freqtrade.execute_buy('LTC/BTC', result) From 94afb7cb1dff0c8d0d92d785fd9aed5854b17a66 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:45:03 +0100 Subject: [PATCH 0195/1106] Improve integration test with a few additional tests --- tests/test_integration.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index d1be961cf..98bf1862b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -120,7 +120,10 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, result1) -> None: """ - Tests workflow + Tests workflow unlimited stake-amount + Buy 4 trades, forcebuy a 5th trade + Sell one trade, calculated stake amount should now be lower than before since + one trade was sold at a loss. """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True @@ -166,6 +169,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc trades = Trade.query.all() assert len(trades) == 4 + assert freqtrade.get_trade_stake_amount('XRP/BTC') == result1 + rpc._rpc_forcebuy('TKN/BTC', None) trades = Trade.query.all() @@ -184,6 +189,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc trades = Trade.get_open_trades() # One trade sold assert len(trades) == 4 + # stake-amount should now be reduced, since one trade was sold at a loss. + assert freqtrade.get_trade_stake_amount('XRP/BTC') < result1 # Validate that balance of sold trade is not in dry-run balances anymore. bals2 = freqtrade.wallets.get_all_balances() assert bals != bals2 From 6e615998c07809a99f1a82598ec07f2d8925c645 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:52:35 +0100 Subject: [PATCH 0196/1106] Fix documentation typo --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 1acd6162c..594b79050 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -148,7 +148,7 @@ To allow the bot to trade all the available `stake_currency` in your account set When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. This will keep 1% of your account balance "untradable" in your account. -!!! Note: +!!! Note This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). In this case a trade amount is calculated as: From c13c11cfa19050ee430dcd31ba95b951eb32918e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 14:41:28 +0100 Subject: [PATCH 0197/1106] Type does not need to be a list --- freqtrade/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d5ba00cd5..dd3c07e69 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -74,7 +74,7 @@ CONF_SCHEMA = { 'pattern': UNLIMITED_STAKE_AMOUNT }, 'tradable_balance_ratio': { - 'type': ['number'], + 'type': 'number', 'minimum': 0.1, 'maximum': 1, 'default': 0.99 From b48bf035f6758bedf5773ec9b1b1ed98ca3477ae Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 14:52:34 +0100 Subject: [PATCH 0198/1106] Add note about MacOS installation --- docs/installation.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 27b7a94c5..f7dce8787 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -270,3 +270,19 @@ The easiest way is to download install Microsoft Visual Studio Community [here]( Now you have an environment ready, the next step is [Bot Configuration](configuration.md). + + +## Trouble shooting + +### MacOS installation error + +Newer versions of MacOS may have installation fail with errors like `error: command 'g++' failed with exit status 1`. + +This error will require an explicit installation of the SDK Headers, which are not installed by default in this version of MacOS. +For MacOS 10.14, this can be accomplished with the below command. + +``` bash +open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg +``` + +If this file is inexistant, then you're probably on a different version of MacOS, so you may need to consult the internet for specific resolution details. From 90744ff5abe262ef4d0731d966c5d8ad74ade076 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 19:36:31 +0100 Subject: [PATCH 0199/1106] show percent instead of ratio (!) --- freqtrade/plot/plotting.py | 4 ++-- tests/test_plotting.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index db4637ee5..e1989b249 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -120,8 +120,8 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: ) ) # Create description for sell summarizing the trade - desc = trades.apply(lambda row: f"{round(row['profitperc'], 3)}%, {row['sell_reason']}, " - f"{row['duration']} min", + desc = trades.apply(lambda row: f"{round(row['profitperc'] * 100, 1)}%, " + f"{row['sell_reason']}, {row['duration']} min", axis=1) trade_sells = go.Scatter( x=trades["close_time"], diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 9934d2493..271246517 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -119,6 +119,7 @@ def test_plot_trades(testdatadir, caplog): assert trade_sell.yaxis == 'y' assert len(trades) == len(trade_sell.x) assert trade_sell.marker.color == 'red' + assert trade_sell.text[0] == "4.0%, roi, 15 min" def test_generate_candlestick_graph_no_signals_no_trades(default_conf, mocker, testdatadir, caplog): From 560aea876efa6aaaec65f7def6c58a9c4613d33a Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 20:20:29 +0100 Subject: [PATCH 0200/1106] Remove fiat_currency temporary variable --- freqtrade/freqtradebot.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c18d9131f..373055165 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -964,9 +964,8 @@ class FreqtradeBot: } if 'fiat_display_currency' in self.config: - fiat_currency = self.config['fiat_display_currency'] msg.update({ - 'fiat_currency': fiat_currency, + 'fiat_currency': self.config['fiat_display_currency'], }) # Send the message From da1fea6582790e99b3cd69688dd6dfb7c3b57e00 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 06:37:36 +0100 Subject: [PATCH 0201/1106] Minor correction to wording of MacOS Specific install doc --- docs/installation.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index f7dce8787..267d91c8d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -271,14 +271,13 @@ The easiest way is to download install Microsoft Visual Studio Community [here]( Now you have an environment ready, the next step is [Bot Configuration](configuration.md). - -## Trouble shooting +## Troubleshooting ### MacOS installation error -Newer versions of MacOS may have installation fail with errors like `error: command 'g++' failed with exit status 1`. +Newer versions of MacOS may have installation failed with errors like `error: command 'g++' failed with exit status 1`. -This error will require an explicit installation of the SDK Headers, which are not installed by default in this version of MacOS. +This error will require explicit installation of the SDK Headers, which are not installed by default in this version of MacOS. For MacOS 10.14, this can be accomplished with the below command. ``` bash From 11059e532bf444c42daca77e31405d9e9b44f9a6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 06:39:47 +0100 Subject: [PATCH 0202/1106] Fix missed default minimum in documentation --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 594b79050..2f7ef9f29 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,7 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.0` and `1.0`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From a8d56b28503f62cae1f729cf27955fc98b7b6f39 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 07:07:59 +0100 Subject: [PATCH 0203/1106] IMplement check for unlimited settings verifying that either max_open_trades or stake_amount is set for operations without edge --- freqtrade/configuration/config_validation.py | 12 ++++++++++++ tests/test_configuration.py | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 43eead46a..02dee2afe 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -67,12 +67,24 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None: _validate_trailing_stoploss(conf) _validate_edge(conf) _validate_whitelist(conf) + _validate_unlimited_amount(conf) # validate configuration before returning logger.info('Validating configuration ...') validate_config_schema(conf) +def _validate_unlimited_amount(conf: Dict[str, Any]) -> None: + """ + If edge is disabled, either max_open_trades or stake_amount need to be set. + :raise: OperationalException if config validation failed + """ + if (not conf.get('edge', {}).get('enabled') + and conf.get('max_open_trades') == float('inf') + and conf.get('stake_amount') == constants.UNLIMITED_STAKE_AMOUNT): + raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.") + + def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None: if conf.get('stoploss') == 0.0: diff --git a/tests/test_configuration.py b/tests/test_configuration.py index ee3d23131..6c0035395 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -722,6 +722,14 @@ def test_validate_default_conf(default_conf) -> None: validate_config_schema(default_conf) +def test_validate_max_open_trades(default_conf): + default_conf['max_open_trades'] = float('inf') + default_conf['stake_amount'] = 'unlimited' + with pytest.raises(OperationalException, match='`max_open_trades` and `stake_amount` ' + 'cannot both be unlimited.'): + validate_config_consistency(default_conf) + + def test_validate_tsl(default_conf): default_conf['stoploss'] = 0.0 with pytest.raises(OperationalException, match='The config stoploss needs to be different ' From 4ac1ac7ef5c227eee989219e420fe46163f95622 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 09:56:06 +0100 Subject: [PATCH 0204/1106] Warn about tradable balance being applied to the current amount of the balance --- docs/configuration.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 2f7ef9f29..4448f4548 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -157,6 +157,9 @@ In this case a trade amount is calculated as: currency_balance / (max_open_trades - current_open_trades) ``` +!!! Warning + `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + !!! Note "When using Dry-Run Mode" When using `"stake_amount" : "unlimited",` in combination with Dry-Run, the balance will be simulated starting with a stake of `dry_run_wallet` which will evolve over time. It is therefore important to set `dry_run_wallet` to a sensible value (like 0.05 or 0.01 for BTC and 1000 or 100 for USDT, for example), otherwise it may simulate trades with 100 BTC (or more) or 0.05 USDT (or less) at once - which may not correspond to your real available balance or is less than the exchange minimal limit for the order amount for the stake currency. From 3c7981160c3407e8a5c0c5a8d02b5ec2d362d61d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:14:23 +0100 Subject: [PATCH 0205/1106] Extract `get_available_stake_amount` --- freqtrade/freqtradebot.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6a6a14375..bdba74215 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -270,6 +270,22 @@ class FreqtradeBot: return self._check_available_stake_amount(stake_amount) + def _get_available_stake_amount(self) -> float: + """ + Return the total currently available balance in stake currency, + respecting tradable_balance_ratio. + Calculated as + + free amount ) * tradable_balance_ratio - + """ + val_tied_up = Trade.total_open_trades_stakes() + + # Ensure % is used from the overall balance + # Otherwise we'd risk lowering stakes with each open trade. + # (tied up + current free) * ratio) - tied up + available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * + self.config['tradable_balance_ratio']) - val_tied_up + return available_amount + def _calculate_unlimited_stake_amount(self) -> Optional[float]: """ Calculate stake amount for "unlimited" stake amount @@ -279,13 +295,7 @@ class FreqtradeBot: if not free_open_trades: return None - val_tied_up = Trade.total_open_trades_stakes() - - # Ensure 1% is used from the overall balance - # Otherwise we'd risk lowering stakes with each open trade. - # (tied up + current free) * ratio) - tied up - available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * - self.config['tradable_balance_ratio']) - val_tied_up + available_amount = self._get_available_stake_amount() return available_amount / free_open_trades From 455838648da4dab24c1d5193764c880542faf406 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:41:10 +0100 Subject: [PATCH 0206/1106] Apply get_available_balance logic to regular trades, too --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index bdba74215..aa47adfd4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -305,7 +305,7 @@ class FreqtradeBot: for the stake currency :return: float: Stake amount """ - available_amount = self.wallets.get_free(self.config['stake_currency']) + available_amount = self._get_available_stake_amount() if stake_amount is not None and available_amount < stake_amount: raise DependencyException( diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 9ca54d003..a2e6789ef 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3628,6 +3628,7 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, # Initialize to 2 times stake amount default_conf['dry_run_wallet'] = 0.002 default_conf['max_open_trades'] = 2 + default_conf['tradable_balance_ratio'] = 1.0 patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -3649,5 +3650,5 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, n = bot.enter_positions() assert n == 0 assert log_has_re(r"Unable to create trade for XRP/BTC: " - r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)", + r"Available balance \(0.0 BTC\) is lower than stake amount \(0.001 BTC\)", caplog) From 6d01653bfec14900cd75fb0938a8c196f9ff8e20 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:41:34 +0100 Subject: [PATCH 0207/1106] Adapt test to test more cases with reduced tradable_balance --- tests/test_freqtradebot.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a2e6789ef..c8b627ca4 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -641,11 +641,15 @@ def test_create_trade_no_signal(default_conf, fee, mocker) -> None: @pytest.mark.parametrize("max_open", range(0, 5)) -def test_create_trades_multiple_trades(default_conf, ticker, - fee, mocker, max_open) -> None: +@pytest.mark.parametrize("tradable_balance_ratio,modifier", [(1.0, 1), (0.99, 0.8), (0.5, 0.5)]) +def test_create_trades_multiple_trades(default_conf, ticker, fee, mocker, + max_open, tradable_balance_ratio, modifier) -> None: patch_RPCManager(mocker) patch_exchange(mocker) default_conf['max_open_trades'] = max_open + default_conf['tradable_balance_ratio'] = tradable_balance_ratio + default_conf['dry_run_wallet'] = 0.001 * max_open + mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, @@ -656,10 +660,11 @@ def test_create_trades_multiple_trades(default_conf, ticker, patch_get_signal(freqtrade) n = freqtrade.enter_positions() - assert n == max_open - trades = Trade.get_open_trades() - assert len(trades) == max_open + # Expected trades should be max_open * a modified value + # depending on the configured tradable_balance + assert n == max(int(max_open * modifier), 0) + assert len(trades) == max(int(max_open * modifier), 0) def test_create_trades_preopen(default_conf, ticker, fee, mocker) -> None: From f3beaa3374eae8300b5f845cb68dca4e16b1f9a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:58:31 +0100 Subject: [PATCH 0208/1106] Deprecate capital_available_percentage --- config.json.example | 1 - config_binance.json.example | 1 - config_full.json.example | 1 - config_kraken.json.example | 1 - docs/configuration.md | 2 +- docs/edge.md | 2 +- freqtrade/configuration/deprecated_settings.py | 10 ++++++++++ freqtrade/constants.py | 2 +- freqtrade/edge/__init__.py | 4 +++- tests/conftest.py | 2 +- tests/test_configuration.py | 10 ++++++++++ 11 files changed, 27 insertions(+), 9 deletions(-) diff --git a/config.json.example b/config.json.example index a2add358f..d46582d2b 100644 --- a/config.json.example +++ b/config.json.example @@ -59,7 +59,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_binance.json.example b/config_binance.json.example index 8dc6f5c3a..11c309053 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -64,7 +64,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_full.json.example b/config_full.json.example index 4e692d371..981fc5209 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -97,7 +97,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_kraken.json.example b/config_kraken.json.example index 401ee7c9f..3cac29cef 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -70,7 +70,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/docs/configuration.md b/docs/configuration.md index 4448f4548..d0450f5c9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,7 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* diff --git a/docs/edge.md b/docs/edge.md index e7909594e..95f3de42e 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -148,7 +148,7 @@ Edge module has following configuration options: | `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* | `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* | `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* -| `capital_available_percentage` | This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* +| `capital_available_percentage` | **DEPRECATED - replaced with `tradable_balance_ratio`** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* | `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* | `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* | `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index 260aae419..a104bf6e3 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -80,3 +80,13 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: f"Using precision_filter setting is deprecated and has been replaced by" "PrecisionFilter. Please refer to the docs on configuration details") config['pairlists'].append({'method': 'PrecisionFilter'}) + + if (config.get('edge', {}.get('enabled', False)) + and config.get('edge', {}).get('capital_available_percentage')): + logger.warning( + "DEPRECATED: " + "Using 'edge.capital_available_percentage' has been deprecated in favor of " + "'tradable_balance_ratio'. Please migrate your configuration to " + "'tradable_balance_ratio' and remove 'capital_available_percentage' " + "from the edge configuration." + ) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index dd3c07e69..7dd75c438 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -272,7 +272,7 @@ CONF_SCHEMA = { 'max_trade_duration_minute': {'type': 'integer'}, 'remove_pumps': {'type': 'boolean'} }, - 'required': ['process_throttle_secs', 'allowed_risk', 'capital_available_percentage'] + 'required': ['process_throttle_secs', 'allowed_risk'] } }, 'required': [ diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 19d65d9d7..15883357b 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -57,7 +57,9 @@ class Edge: if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: raise OperationalException('Edge works only with unlimited stake amount') - self._capital_percentage: float = self.edge_config.get('capital_available_percentage') + # Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future. + self._capital_percentage: float = self.edge_config.get( + 'capital_available_percentage', self.config['tradable_balance_ratio']) self._allowed_risk: float = self.edge_config.get('allowed_risk') self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14) self._last_updated: int = 0 # Timestamp of pairs last updated time diff --git a/tests/conftest.py b/tests/conftest.py index 501f89fff..7bb4cf4c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1317,12 +1317,12 @@ def buy_order_fee(): def edge_conf(default_conf): conf = deepcopy(default_conf) conf['max_open_trades'] = -1 + conf['tradable_balance_ratio'] = 0.5 conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT conf['edge'] = { "enabled": True, "process_throttle_secs": 1800, "calculate_since_number_of_days": 14, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 6c0035395..3e7b51c0e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1036,6 +1036,16 @@ def test_process_deprecated_setting_pairlists(mocker, default_conf, caplog): assert log_has_re(r'DEPRECATED.*in pairlist is deprecated and must be moved*', caplog) +def test_process_deprecated_setting_edge(mocker, edge_conf, caplog): + patched_configuration_load_config_file(mocker, edge_conf) + edge_conf.update({'edge': { + 'capital_available_percentage': 0.5, + }}) + + process_temporary_deprecated_settings(edge_conf) + assert log_has_re(r"DEPRECATED.*Using 'edge.capital_available_percentage'*", caplog) + + def test_check_conflicting_settings(mocker, default_conf, caplog): patched_configuration_load_config_file(mocker, default_conf) From 0dd274917f820e6fc4892503ea7b09a4f5f42b7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:16:59 +0100 Subject: [PATCH 0209/1106] Update documentation regarding configuration of stake_amount --- docs/configuration.md | 56 +++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d0450f5c9..e9756e8ac 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,10 +40,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* +| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* -| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -130,26 +130,39 @@ Values set in the configuration file always overwrite values set in the strategy * `sell_profit_only` (ask_strategy) * `ignore_roi_if_buy_signal` (ask_strategy) -### Understand stake_amount +### Configuring amount per trade -The `stake_amount` configuration parameter is an amount of crypto-currency your bot will use for each trade. +There are several methods to configure how much of the stake currency the bot will use to enter a trade. All methods respect the [available balance configuration](#available-balance) as explained below. -The minimal configuration value is 0.0001. Please check your exchange's trading minimums to avoid problems. +#### Available balance + +By default, the bot assumes that the `complete amount - 1%` is at it's disposal, and when using [dynamic stake amount](#dynamic-stake-amount), it will split the complete balance into `max_open_trades` buckets per trade. +Freqtrade will reserve 1% for eventual fees when entering a trade and will therefore not touch that by default. + +You can configure the "untouched" amount by using the `tradable_balance_ratio` setting. + +For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. + +!!! Warning + `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + +#### Static Stake amount + +The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. + +The minimal configuration value is 0.0001, however, please check your exchange's trading minimums for the stake currency you're using to avoid problems. This setting works in combination with `max_open_trades`. The maximum capital engaged in trades is `stake_amount * max_open_trades`. For example, the bot will at most use (0.05 BTC x 3) = 0.15 BTC, assuming a configuration of `max_open_trades=3` and `stake_amount=0.05`. -To allow the bot to trade all the available `stake_currency` in your account set - -```json -"stake_amount" : "unlimited", -``` - -When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. -This will keep 1% of your account balance "untradable" in your account. - !!! Note - This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). + This setting respects the [available balance configuration](#available-balance). + +#### Dynamic stake amount + +Alternatively, you can use a dynamic stake amount, which will use the available balance on the exchange, and divide that equally by the amount of allowed trades (`max_open_trades`). + +To configure this, set `stake_amount="unlimited"`. We also recommend to set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. In this case a trade amount is calculated as: @@ -157,8 +170,15 @@ In this case a trade amount is calculated as: currency_balance / (max_open_trades - current_open_trades) ``` -!!! Warning - `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). +To allow the bot to trade all the available `stake_currency` in your account (minus `tradable_balance_ratio`) set + +```json +"stake_amount" : "unlimited", +"tradable_balance_ratio": 0.99, +``` + +!!! Note + This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). !!! Note "When using Dry-Run Mode" When using `"stake_amount" : "unlimited",` in combination with Dry-Run, the balance will be simulated starting with a stake of `dry_run_wallet` which will evolve over time. It is therefore important to set `dry_run_wallet` to a sensible value (like 0.05 or 0.01 for BTC and 1000 or 100 for USDT, for example), otherwise it may simulate trades with 100 BTC (or more) or 0.05 USDT (or less) at once - which may not correspond to your real available balance or is less than the exchange minimal limit for the order amount for the stake currency. From 55041878ae7da0758a8e58d2c1add3139e54fcbb Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:20:08 +0100 Subject: [PATCH 0210/1106] Update Backtesting fee documentation --- docs/backtesting.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index ac7c8e11a..c2359b370 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -79,12 +79,14 @@ Please also read about the [strategy startup period](strategy-customization.md#s Sometimes your account has certain fee rebates (fee reductions starting with a certain account size or monthly volume), which are not visible to ccxt. To account for this in backtesting, you can use `--fee 0.001` to supply this value to backtesting. -This fee must be a percentage, and will be applied twice (once for trade entry, and once for trade exit). +This fee must be a ratio, and will be applied twice (once for trade entry, and once for trade exit). ```bash freqtrade backtesting --fee 0.001 ``` +!!! Note + Only supply this parameter if you want to experiment with different fee values. By default, Backtesting fetches the exchange's default fee from the exchange. #### Running backtest with smaller testset by using timerange From 71dd0386640e675771881395e19163ce1131df41 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:23:06 +0100 Subject: [PATCH 0211/1106] add tradable_balance_ratio to to all config samples --- config.json.example | 1 + config_binance.json.example | 1 + config_kraken.json.example | 1 + 3 files changed, 3 insertions(+) diff --git a/config.json.example b/config.json.example index d46582d2b..8b85e71eb 100644 --- a/config.json.example +++ b/config.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "ticker_interval" : "5m", "dry_run": false, diff --git a/config_binance.json.example b/config_binance.json.example index 11c309053..0521a3a35 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "ticker_interval" : "5m", "dry_run": true, diff --git a/config_kraken.json.example b/config_kraken.json.example index 3cac29cef..a527b569d 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -2,6 +2,7 @@ "max_open_trades": 5, "stake_currency": "EUR", "stake_amount": 10, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "EUR", "ticker_interval" : "5m", "dry_run": true, From 7e7c82cf4a80cd7d70a3a0317cf7158cefd9c6f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:34:17 +0100 Subject: [PATCH 0212/1106] Small adjustments to relative_stake PR --- docs/configuration.md | 2 +- docs/edge.md | 2 +- freqtrade/configuration/deprecated_settings.py | 4 ++-- tests/test_configuration.py | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index e9756e8ac..3b8760366 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -146,7 +146,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr !!! Warning `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). -#### Static Stake amount +#### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/docs/edge.md b/docs/edge.md index 95f3de42e..dcefe7451 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -148,7 +148,7 @@ Edge module has following configuration options: | `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* | `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* | `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* -| `capital_available_percentage` | **DEPRECATED - replaced with `tradable_balance_ratio`** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* +| `capital_available_percentage` | **DEPRECATED - [replaced with `tradable_balance_ratio`](configuration.md#Available balance)** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* | `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* | `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* | `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index a104bf6e3..78d8218d4 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -81,8 +81,8 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: "PrecisionFilter. Please refer to the docs on configuration details") config['pairlists'].append({'method': 'PrecisionFilter'}) - if (config.get('edge', {}.get('enabled', False)) - and config.get('edge', {}).get('capital_available_percentage')): + if (config.get('edge', {}).get('enabled', False) + and 'capital_available_percentage' in config.get('edge', {})): logger.warning( "DEPRECATED: " "Using 'edge.capital_available_percentage' has been deprecated in favor of " diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 3e7b51c0e..a489875d9 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1039,6 +1039,7 @@ def test_process_deprecated_setting_pairlists(mocker, default_conf, caplog): def test_process_deprecated_setting_edge(mocker, edge_conf, caplog): patched_configuration_load_config_file(mocker, edge_conf) edge_conf.update({'edge': { + 'enabled': True, 'capital_available_percentage': 0.5, }}) From e1f89e3ad34187caf0385a841f13ec1c710fbd17 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 20:11:58 +0100 Subject: [PATCH 0213/1106] Reword Note in backtesting fee docs --- docs/backtesting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index c2359b370..45759e2aa 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -86,7 +86,7 @@ freqtrade backtesting --fee 0.001 ``` !!! Note - Only supply this parameter if you want to experiment with different fee values. By default, Backtesting fetches the exchange's default fee from the exchange. + Only supply this option (or the corresponding configuration parameter) if you want to experiment with different fee values. By default, Backtesting fetches the default fee from the exchange pair/market info. #### Running backtest with smaller testset by using timerange From 24aa596e3c956df3e3b8967e0334246574f8e434 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sat, 4 Jan 2020 01:08:37 +0300 Subject: [PATCH 0214/1106] Minor: Refine fee example in the docs Taken from https://github.com/freqtrade/freqtrade/issues/2738#issuecomment-570687230. slightly reworded. --- docs/backtesting.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 45759e2aa..41428085d 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -78,9 +78,11 @@ Please also read about the [strategy startup period](strategy-customization.md#s #### Supplying custom fee value Sometimes your account has certain fee rebates (fee reductions starting with a certain account size or monthly volume), which are not visible to ccxt. -To account for this in backtesting, you can use `--fee 0.001` to supply this value to backtesting. +To account for this in backtesting, you can use the `--fee` command line option to supply this value to backtesting. This fee must be a ratio, and will be applied twice (once for trade entry, and once for trade exit). +For example, if the buying and selling commission fee is 0.1% (i.e., 0.001 written as ratio), then you would run backtesting as the following: + ```bash freqtrade backtesting --fee 0.001 ``` From 84ef588163e95adaa3359200ddaa3a7ef64d0b8c Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 13:27:22 +0100 Subject: [PATCH 0215/1106] support dicts as indicators --- freqtrade/plot/plotting.py | 66 +++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index e1989b249..2bf4afcfb 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import Any, Dict, List +from typing import Any, Dict, List, Union import pandas as pd from freqtrade.configuration import TimeRange @@ -13,6 +13,8 @@ from freqtrade.resolvers import StrategyResolver logger = logging.getLogger(__name__) +IndicatorType = Union[List[str], Dict[str, Dict]] + try: from plotly.subplots import make_subplots from plotly.offline import plot @@ -54,9 +56,9 @@ def init_plotscript(config): } -def add_indicators(fig, row, indicators: List[str], data: pd.DataFrame) -> make_subplots: +def _add_indicators_list(fig, row, indicators: List[str], data: pd.DataFrame) -> make_subplots: """ - Generator all the indicator selected by the user for a specific row + Generate all the indicator selected by the user for a specific row :param fig: Plot figure to append to :param row: row number for this plot :param indicators: List of indicators present in the dataframe @@ -81,6 +83,51 @@ def add_indicators(fig, row, indicators: List[str], data: pd.DataFrame) -> make_ return fig +def _add_indicators_dict(fig, row, indicators: Dict[str, Dict], + data: pd.DataFrame) -> make_subplots: + """ + Generate all the indicators selected by the user for a specific row, based on the configuration + :param fig: Plot figure to append to + :param row: row number for this plot + :param indicators: Dict of Indicators with configuration options. + Dict key must correspond to dataframe column. + :param data: candlestick DataFrame + """ + for indicator, conf in indicators.items(): + print(conf) + if indicator in data: + scatter = go.Scatter( + x=data['date'], + y=data[indicator].values, + mode='lines', + name=indicator + ) + fig.add_trace(scatter, row, 1) + else: + logger.info( + 'Indicator "%s" ignored. Reason: This indicator is not found ' + 'in your strategy.', + indicator + ) + + return fig + + +def add_indicators(fig, row, indicators: IndicatorType, data: pd.DataFrame) -> make_subplots: + """ + Generate all the indicator selected by the user for a specific row + :param fig: Plot figure to append to + :param row: row number for this plot + :param indicators: List of indicators present in the dataframe, Or Dict of Indicators + with configuration options. Dict key must correspond to dataframe column. + :param data: candlestick DataFrame + """ + if isinstance(indicators, list): + _add_indicators_list(fig, row, indicators, data) + else: + _add_indicators_dict(fig, row, indicators, data) + + def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_subplots: """ Add profit-plot @@ -144,8 +191,8 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFrame = None, - indicators1: List[str] = [], - indicators2: List[str] = [],) -> go.Figure: + indicators1: IndicatorType = [], + indicators2: IndicatorType = [],) -> go.Figure: """ Generate the graph from the data generated by Backtesting or from DB Volume will always be ploted in row2, so Row 1 and 3 are to our disposal for custom indicators @@ -254,7 +301,7 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra name='Volume', marker_color='DarkSlateGrey', marker_line_color='DarkSlateGrey' - ) + ) fig.add_trace(volume, 2, 1) # Add indicators to separate row @@ -355,12 +402,15 @@ def load_and_plot_trades(config: Dict[str, Any]): trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) + indicators1 = config["indicators1"] + indicators2 = config["indicators2"] + fig = generate_candlestick_graph( pair=pair, data=dataframe, trades=trades_pair, - indicators1=config["indicators1"], - indicators2=config["indicators2"], + indicators1=indicators1, + indicators2=indicators2, ) store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), From 5d5074ac9c1af08034f283c39244a4e50b8652da Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 20:10:22 +0100 Subject: [PATCH 0216/1106] Implement first working version of plot_config --- freqtrade/plot/plotting.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 2bf4afcfb..cb5806f75 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -96,11 +96,15 @@ def _add_indicators_dict(fig, row, indicators: Dict[str, Dict], for indicator, conf in indicators.items(): print(conf) if indicator in data: + kwargs = {'x': data['date'], + 'y': data[indicator].values, + 'mode': 'lines', + 'name': indicator + } + if 'color' in conf: + kwargs.update({'line': {'color': conf['color']}}) scatter = go.Scatter( - x=data['date'], - y=data[indicator].values, - mode='lines', - name=indicator + **kwargs ) fig.add_trace(scatter, row, 1) else: @@ -123,9 +127,9 @@ def add_indicators(fig, row, indicators: IndicatorType, data: pd.DataFrame) -> m :param data: candlestick DataFrame """ if isinstance(indicators, list): - _add_indicators_list(fig, row, indicators, data) + return _add_indicators_list(fig, row, indicators, data) else: - _add_indicators_dict(fig, row, indicators, data) + return _add_indicators_dict(fig, row, indicators, data) def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_subplots: @@ -376,6 +380,17 @@ def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False logger.info(f"Stored plot as {_filename}") +def _get_plot_indicators(config, strategy): + + if hasattr(strategy, 'plot_config'): + indicators1 = strategy.plot_config['main_plot'] + indicators2 = strategy.plot_config['subplots'] + else: + indicators1 = config.get("indicators1") + indicators2 = config.get("indicators2") + return indicators1, indicators2 + + def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided @@ -402,8 +417,7 @@ def load_and_plot_trades(config: Dict[str, Any]): trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) - indicators1 = config["indicators1"] - indicators2 = config["indicators2"] + indicators1, indicators2 = _get_plot_indicators(config, strategy) fig = generate_candlestick_graph( pair=pair, From 5853b9904c2cefa163d6c6d3b8536b5170b74ad3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 11:13:45 +0100 Subject: [PATCH 0217/1106] make Plot_config the default approach --- freqtrade/plot/plotting.py | 128 ++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 72 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index cb5806f75..c11776fab 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -56,35 +56,7 @@ def init_plotscript(config): } -def _add_indicators_list(fig, row, indicators: List[str], data: pd.DataFrame) -> make_subplots: - """ - Generate all the indicator selected by the user for a specific row - :param fig: Plot figure to append to - :param row: row number for this plot - :param indicators: List of indicators present in the dataframe - :param data: candlestick DataFrame - """ - for indicator in indicators: - if indicator in data: - scatter = go.Scatter( - x=data['date'], - y=data[indicator].values, - mode='lines', - name=indicator - ) - fig.add_trace(scatter, row, 1) - else: - logger.info( - 'Indicator "%s" ignored. Reason: This indicator is not found ' - 'in your strategy.', - indicator - ) - - return fig - - -def _add_indicators_dict(fig, row, indicators: Dict[str, Dict], - data: pd.DataFrame) -> make_subplots: +def add_indicators(fig, row, indicators: Dict[str, Dict], data: pd.DataFrame) -> make_subplots: """ Generate all the indicators selected by the user for a specific row, based on the configuration :param fig: Plot figure to append to @@ -94,7 +66,7 @@ def _add_indicators_dict(fig, row, indicators: Dict[str, Dict], :param data: candlestick DataFrame """ for indicator, conf in indicators.items(): - print(conf) + logger.debug(f"indicator {indicator} with config {conf}") if indicator in data: kwargs = {'x': data['date'], 'y': data[indicator].values, @@ -117,21 +89,6 @@ def _add_indicators_dict(fig, row, indicators: Dict[str, Dict], return fig -def add_indicators(fig, row, indicators: IndicatorType, data: pd.DataFrame) -> make_subplots: - """ - Generate all the indicator selected by the user for a specific row - :param fig: Plot figure to append to - :param row: row number for this plot - :param indicators: List of indicators present in the dataframe, Or Dict of Indicators - with configuration options. Dict key must correspond to dataframe column. - :param data: candlestick DataFrame - """ - if isinstance(indicators, list): - return _add_indicators_list(fig, row, indicators, data) - else: - return _add_indicators_dict(fig, row, indicators, data) - - def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_subplots: """ Add profit-plot @@ -194,9 +151,39 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: return fig -def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFrame = None, - indicators1: IndicatorType = [], - indicators2: IndicatorType = [],) -> go.Figure: +def create_plotconfig(indicators1: List[str], indicators2: List[str], plot_config: Dict[str, Dict]) -> Dict[str, Dict]: + """ + Combines indicators 1 and indicators 2 into plot_config if necessary + :param indicators1: List containing Main plot indicators + :param indicators2: List containing Sub plot indicators + :param plot_config: Dict of Dicts containing advanced plot configuration + :return: plot_config - eventually with indicators 1 and 2 + """ + + if not plot_config: + # If no indicators and no plot-config given, use defaults. + if not indicators1: + indicators1 = ['sma', 'ema3', 'ema5'] + if not indicators2: + indicators1 = ['macd', 'macdsignal'] + + # Create subplot configuration if plot_config is not available. + plot_config = { + 'main_plot': {ind: {} for ind in indicators1}, + 'subplots': {'Other': {ind: {} for ind in indicators2}}, + } + if 'main_plot' not in plot_config: + plot_config['main_plot'] = {} + + if 'subplots' not in plot_config: + plot_config['subplots'] = {} + + +def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFrame = None, *, + indicators1: List[str] = [], + indicators2: List[str] = [], + plot_config: Dict[str, Dict] = {}, + ) -> go.Figure: """ Generate the graph from the data generated by Backtesting or from DB Volume will always be ploted in row2, so Row 1 and 3 are to our disposal for custom indicators @@ -205,21 +192,26 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra :param trades: All trades created :param indicators1: List containing Main plot indicators :param indicators2: List containing Sub plot indicators - :return: None + :param plot_config: Dict of Dicts containing advanced plot configuration + :return: Plotly figure """ + plot_config = create_plotconfig(indicators1, indicators2) + rows = 2 + len(plot_config['subplots']) + row_widths = [1 for _ in plot_config['subplots']] # Define the graph fig = make_subplots( - rows=3, + rows=rows, cols=1, shared_xaxes=True, - row_width=[1, 1, 4], + row_width=row_widths + [1, 4], vertical_spacing=0.0001, ) fig['layout'].update(title=pair) fig['layout']['yaxis1'].update(title='Price') fig['layout']['yaxis2'].update(title='Volume') - fig['layout']['yaxis3'].update(title='Other') + for i, name in enumerate(plot_config['subplots']): + fig['layout'][f'yaxis{3 + i}'].update(title=name) fig['layout']['xaxis']['rangeslider'].update(visible=False) # Common information @@ -289,12 +281,13 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra ) fig.add_trace(bb_lower, 1, 1) fig.add_trace(bb_upper, 1, 1) - if 'bb_upperband' in indicators1 and 'bb_lowerband' in indicators1: - indicators1.remove('bb_upperband') - indicators1.remove('bb_lowerband') + if ('bb_upperband' in plot_config['main_plot'] + and 'bb_lowerband' in plot_config['main_plot']): + del plot_config['main_plot']['bb_upperband'] + del plot_config['main_plot']['bb_lowerband'] # Add indicators to main plot - fig = add_indicators(fig=fig, row=1, indicators=indicators1, data=data) + fig = add_indicators(fig=fig, row=1, indicators=plot_config['main_plot'], data=data) fig = plot_trades(fig, trades) @@ -309,7 +302,10 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra fig.add_trace(volume, 2, 1) # Add indicators to separate row - fig = add_indicators(fig=fig, row=3, indicators=indicators2, data=data) + for i, name in enumerate(plot_config['subplots']): + fig = add_indicators(fig=fig, row=3 + i, + indicators=plot_config['subplots'][name], + data=data) return fig @@ -380,17 +376,6 @@ def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False logger.info(f"Stored plot as {_filename}") -def _get_plot_indicators(config, strategy): - - if hasattr(strategy, 'plot_config'): - indicators1 = strategy.plot_config['main_plot'] - indicators2 = strategy.plot_config['subplots'] - else: - indicators1 = config.get("indicators1") - indicators2 = config.get("indicators2") - return indicators1, indicators2 - - def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided @@ -417,14 +402,13 @@ def load_and_plot_trades(config: Dict[str, Any]): trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) - indicators1, indicators2 = _get_plot_indicators(config, strategy) - fig = generate_candlestick_graph( pair=pair, data=dataframe, trades=trades_pair, - indicators1=indicators1, - indicators2=indicators2, + indicators1=config["indicators1"], + indicators2=config["indicators2"], + plot_config=strategy.plot_config if hasattr(strategy, 'plot_config') else {} ) store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), From f04873b0b06df81bed51dfd59fb7db1e29422f55 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 11:14:00 +0100 Subject: [PATCH 0218/1106] Add plot_config to interface --- freqtrade/configuration/cli_options.py | 6 ++---- freqtrade/strategy/interface.py | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index 4b6429f20..1807cd591 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -363,15 +363,13 @@ AVAILABLE_CLI_OPTIONS = { "indicators1": Arg( '--indicators1', help='Set indicators from your strategy you want in the first row of the graph. ' - 'Space-separated list. Example: `ema3 ema5`. Default: `%(default)s`.', - default=['sma', 'ema3', 'ema5'], + "Space-separated list. Example: `ema3 ema5`. Default: `['sma', 'ema3', 'ema5']`.", nargs='+', ), "indicators2": Arg( '--indicators2', help='Set indicators from your strategy you want in the third row of the graph. ' - 'Space-separated list. Example: `fastd fastk`. Default: `%(default)s`.', - default=['macd', 'macdsignal'], + "Space-separated list. Example: `fastd fastk`. Default: `['macd', 'macdsignal']`.", nargs='+', ), "plot_limit": Arg( diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4f2e990d2..a2dee7837 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -112,6 +112,8 @@ class IStrategy(ABC): dp: Optional[DataProvider] = None wallets: Optional[Wallets] = None + plot_config: Dict + def __init__(self, config: dict) -> None: self.config = config # Dict to determine if analysis is necessary From 4628024de6e9d7c35977b9d2459651560fe75111 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 11:18:51 +0100 Subject: [PATCH 0219/1106] Adapt tests to new add_indicator methodology --- freqtrade/plot/plotting.py | 3 ++- tests/test_plotting.py | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index c11776fab..a79ec6b87 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -177,6 +177,7 @@ def create_plotconfig(indicators1: List[str], indicators2: List[str], plot_confi if 'subplots' not in plot_config: plot_config['subplots'] = {} + return plot_config def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFrame = None, *, @@ -195,7 +196,7 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra :param plot_config: Dict of Dicts containing advanced plot configuration :return: Plotly figure """ - plot_config = create_plotconfig(indicators1, indicators2) + plot_config = create_plotconfig(indicators1, indicators2, plot_config) rows = 2 + len(plot_config['subplots']) row_widths = [1 for _ in plot_config['subplots']] diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 271246517..048f9d60c 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -66,8 +66,8 @@ def test_add_indicators(default_conf, testdatadir, caplog): data = history.load_pair_history(pair=pair, timeframe='1m', datadir=testdatadir, timerange=timerange) - indicators1 = ["ema10"] - indicators2 = ["macd"] + indicators1 = {"ema10": {}} + indicators2 = {"macd": {"color": "red"}} # Generate buy/sell signals and indicators strat = DefaultStrategy(default_conf) @@ -86,9 +86,10 @@ def test_add_indicators(default_conf, testdatadir, caplog): macd = find_trace_in_fig_data(figure.data, "macd") assert isinstance(macd, go.Scatter) assert macd.yaxis == "y3" + assert macd.line.color == "red" # No indicator found - fig3 = add_indicators(fig=deepcopy(fig), row=3, indicators=['no_indicator'], data=data) + fig3 = add_indicators(fig=deepcopy(fig), row=3, indicators={'no_indicator': {}}, data=data) assert fig == fig3 assert log_has_re(r'Indicator "no_indicator" ignored\..*', caplog) From b5a806dec766301632dd4ccad169cba598f3bbd1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 11:30:21 +0100 Subject: [PATCH 0220/1106] Fix typo and add tests for create_plotconfig --- freqtrade/plot/plotting.py | 2 +- tests/test_plotting.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index a79ec6b87..1c8ad552f 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -165,7 +165,7 @@ def create_plotconfig(indicators1: List[str], indicators2: List[str], plot_confi if not indicators1: indicators1 = ['sma', 'ema3', 'ema5'] if not indicators2: - indicators1 = ['macd', 'macdsignal'] + indicators2 = ['macd', 'macdsignal'] # Create subplot configuration if plot_config is not available. plot_config = { diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 048f9d60c..908c90a0a 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -13,6 +13,7 @@ from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data from freqtrade.exceptions import OperationalException from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit from freqtrade.plot.plotting import (add_indicators, add_profit, + create_plotconfig, generate_candlestick_graph, generate_plot_filename, generate_profit_graph, init_plotscript, @@ -372,3 +373,26 @@ def test_plot_profit(default_conf, mocker, testdatadir, caplog): assert profit_mock.call_args_list[0][0][0] == default_conf['pairs'] assert store_mock.call_args_list[0][1]['auto_open'] is True + + +@pytest.mark.parametrize("ind1,ind2,plot_conf,exp", [ + ([], [], {}, + {'main_plot': {'sma': {}, 'ema3': {}, 'ema5': {}}, + 'subplots': {'Other': {'macd': {}, 'macdsignal': {}}}}), + (['sma', 'ema3'], ['macd'], {}, + {'main_plot': {'sma': {}, 'ema3': {}}, 'subplots': {'Other': {'macd': {}}}} + ), + ([], [], {'main_plot': {'sma': {}}}, + {'main_plot': {'sma': {}}, 'subplots': {}}), + ([], [], {'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, + {'main_plot': {}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}), +]) +def test_create_plotconfig(ind1, ind2, plot_conf, exp): + + res = create_plotconfig(ind1, ind2, plot_conf) + assert 'main_plot' in res + assert 'subplots' in res + assert isinstance(res['main_plot'], dict) + assert isinstance(res['subplots'], dict) + + assert res == exp From bdda62039752c967ae51e3717958bb282f825c18 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 12:54:58 +0100 Subject: [PATCH 0221/1106] add plot_config to startegy interface properly --- freqtrade/plot/plotting.py | 7 +++---- freqtrade/strategy/interface.py | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 1c8ad552f..39629fe21 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import Any, Dict, List, Union +from typing import Any, Dict, List import pandas as pd from freqtrade.configuration import TimeRange @@ -13,8 +13,6 @@ from freqtrade.resolvers import StrategyResolver logger = logging.getLogger(__name__) -IndicatorType = Union[List[str], Dict[str, Dict]] - try: from plotly.subplots import make_subplots from plotly.offline import plot @@ -151,7 +149,8 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: return fig -def create_plotconfig(indicators1: List[str], indicators2: List[str], plot_config: Dict[str, Dict]) -> Dict[str, Dict]: +def create_plotconfig(indicators1: List[str], indicators2: List[str], + plot_config: Dict[str, Dict]) -> Dict[str, Dict]: """ Combines indicators 1 and indicators 2 into plot_config if necessary :param indicators1: List containing Main plot indicators diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index a2dee7837..7bd6a9ac5 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -112,7 +112,8 @@ class IStrategy(ABC): dp: Optional[DataProvider] = None wallets: Optional[Wallets] = None - plot_config: Dict + # Definition of plot_config. See plotting documentation for more details. + plot_config: Dict = {} def __init__(self, config: dict) -> None: self.config = config From 53499e01dec6099a63bf1543f9b202f75d5d5d20 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 4 Jan 2020 20:27:27 +0100 Subject: [PATCH 0222/1106] Clearly differentiate trade buys sells (positive and negative) * Swap trade buys to cyan circles * Show sell-reason description on buy too * Green positive sells - red negative / 0 sells --- freqtrade/plot/plotting.py | 37 +++++++++++++++++++++++++++---------- tests/test_plotting.py | 25 ++++++++++++++++++------- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 39629fe21..1660371a1 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -113,11 +113,31 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: """ # Trades can be empty if trades is not None and len(trades) > 0: + # Create description for sell summarizing the trade + trades['desc'] = trades.apply(lambda row: f"{round(row['profitperc'] * 100, 1)}%, " + f"{row['sell_reason']}, {row['duration']} min", + axis=1) trade_buys = go.Scatter( x=trades["open_time"], y=trades["open_rate"], mode='markers', - name='trade_buy', + name='Trade buy', + text=trades["desc"], + marker=dict( + symbol='circle-open', + size=11, + line=dict(width=2), + color='cyan' + + ) + ) + + trade_sells = go.Scatter( + x=trades.loc[trades['profitperc'] > 0, "close_time"], + y=trades.loc[trades['profitperc'] > 0, "close_rate"], + text=trades.loc[trades['profitperc'] > 0, "desc"], + mode='markers', + name='Sell - Profit', marker=dict( symbol='square-open', size=11, @@ -125,16 +145,12 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: color='green' ) ) - # Create description for sell summarizing the trade - desc = trades.apply(lambda row: f"{round(row['profitperc'] * 100, 1)}%, " - f"{row['sell_reason']}, {row['duration']} min", - axis=1) - trade_sells = go.Scatter( - x=trades["close_time"], - y=trades["close_rate"], - text=desc, + trade_sells_loss = go.Scatter( + x=trades.loc[trades['profitperc'] <= 0, "close_time"], + y=trades.loc[trades['profitperc'] <= 0, "close_rate"], + text=trades.loc[trades['profitperc'] <= 0, "desc"], mode='markers', - name='trade_sell', + name='Sell - Loss', marker=dict( symbol='square-open', size=11, @@ -144,6 +160,7 @@ def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: ) fig.add_trace(trade_buys, 1, 1) fig.add_trace(trade_sells, 1, 1) + fig.add_trace(trade_sells_loss, 1, 1) else: logger.warning("No trades found.") return fig diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 908c90a0a..e5162bb17 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -110,18 +110,29 @@ def test_plot_trades(testdatadir, caplog): figure = fig1.layout.figure # Check buys - color, should be in first graph, ... - trade_buy = find_trace_in_fig_data(figure.data, "trade_buy") + trade_buy = find_trace_in_fig_data(figure.data, 'Trade buy') assert isinstance(trade_buy, go.Scatter) assert trade_buy.yaxis == 'y' assert len(trades) == len(trade_buy.x) - assert trade_buy.marker.color == 'green' + assert trade_buy.marker.color == 'cyan' + assert trade_buy.marker.symbol == 'circle-open' + assert trade_buy.text[0] == '4.0%, roi, 15 min' - trade_sell = find_trace_in_fig_data(figure.data, "trade_sell") + trade_sell = find_trace_in_fig_data(figure.data, 'Sell - Profit') assert isinstance(trade_sell, go.Scatter) assert trade_sell.yaxis == 'y' - assert len(trades) == len(trade_sell.x) - assert trade_sell.marker.color == 'red' - assert trade_sell.text[0] == "4.0%, roi, 15 min" + assert len(trades.loc[trades['profitperc'] > 0]) == len(trade_sell.x) + assert trade_sell.marker.color == 'green' + assert trade_sell.marker.symbol == 'square-open' + assert trade_sell.text[0] == '4.0%, roi, 15 min' + + trade_sell_loss = find_trace_in_fig_data(figure.data, 'Sell - Loss') + assert isinstance(trade_sell_loss, go.Scatter) + assert trade_sell_loss.yaxis == 'y' + assert len(trades.loc[trades['profitperc'] <= 0]) == len(trade_sell_loss.x) + assert trade_sell_loss.marker.color == 'red' + assert trade_sell_loss.marker.symbol == 'square-open' + assert trade_sell_loss.text[5] == '-10.4%, stop_loss, 720 min' def test_generate_candlestick_graph_no_signals_no_trades(default_conf, mocker, testdatadir, caplog): @@ -310,7 +321,7 @@ def test_load_and_plot_trades(default_conf, mocker, caplog, testdatadir): "freqtrade.plot.plotting", generate_candlestick_graph=candle_mock, store_plot_file=store_mock - ) + ) load_and_plot_trades(default_conf) # Both mocks should be called once per pair From f82c4346b6ce65c5ded54a63b3931780cd349a98 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 09:55:02 +0100 Subject: [PATCH 0223/1106] data conversion, not data conversation * we're not talking to the data yet ... --- docs/data-download.md | 8 ++++---- freqtrade/configuration/arguments.py | 8 ++++---- freqtrade/configuration/cli_options.py | 4 ++-- freqtrade/data/history/history_utils.py | 2 +- freqtrade/data/history/idatahandler.py | 2 +- freqtrade/data/history/jsondatahandler.py | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/data-download.md b/docs/data-download.md index c5fb744ab..f747123d0 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -78,9 +78,9 @@ optional arguments: Show profits for only these pairs. Pairs are space- separated. --format-from {json,jsongz} - Source format for data conversation. + Source format for data conversion. --format-to {json,jsongz} - Destination format for data conversation. + Destination format for data conversion. --erase Clean all existing data for the selected exchange/pairs/timeframes. -t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...] @@ -127,9 +127,9 @@ optional arguments: Show profits for only these pairs. Pairs are space- separated. --format-from {json,jsongz} - Source format for data conversation. + Source format for data conversion. --format-to {json,jsongz} - Destination format for data conversation. + Destination format for data conversion. --erase Clean all existing data for the selected exchange/pairs/timeframes. diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 2b9b362bf..718b6dedc 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -264,14 +264,14 @@ class Arguments: convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=True)) self._build_args(optionlist=ARGS_CONVERT_DATA_OHLCV, parser=convert_data_cmd) - # Add convert-data subcommand - convert_data_cmd = subparsers.add_parser( + # Add convert-trade-data subcommand + convert_trade_data_cmd = subparsers.add_parser( 'convert-trade-data', help='Convert trade-data from one format to another.', parents=[_common_parser], ) - convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False)) - self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_data_cmd) + convert_trade_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False)) + self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_trade_data_cmd) # Add Plotting subcommand plot_dataframe_cmd = subparsers.add_parser( diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index c80bea393..0289d3fd0 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -334,13 +334,13 @@ AVAILABLE_CLI_OPTIONS = { ), "format_from": Arg( '--format-from', - help='Source format for data conversation.', + help='Source format for data conversion.', choices=constants.AVAILABLE_DATAHANDLERS, required=True, ), "format_to": Arg( '--format-to', - help='Destination format for data conversation.', + help='Destination format for data conversion.', choices=constants.AVAILABLE_DATAHANDLERS, required=True, ), diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 2d11b229b..c0578a32b 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -132,7 +132,7 @@ def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optiona start = None if timerange: if timerange.starttype == 'date': - # TODO: convert to date for conversation + # TODO: convert to date for conversion start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) # Intentionally don't pass timerange in - since we need to load the full dataset. diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index 20022fc38..df03e7713 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -52,7 +52,7 @@ class IDataHandler(ABC): ) -> DataFrame: """ Internal method used to load data for one pair from disk. - Implements the loading and conversation to a Pandas dataframe. + Implements the loading and conversion to a Pandas dataframe. Timerange trimming and dataframe validation happens outside of this method. :param pair: Pair to load data :param timeframe: Ticker timeframe (e.g. "5m") diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index dcfc249aa..7f0643862 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -57,7 +57,7 @@ class JsonDataHandler(IDataHandler): ) -> DataFrame: """ Internal method used to load data for one pair from disk. - Implements the loading and conversation to a Pandas dataframe. + Implements the loading and conversion to a Pandas dataframe. Timerange trimming and dataframe validation happens outside of this method. :param pair: Pair to load data :param timeframe: Ticker timeframe (e.g. "5m") From bc6a10353bf4c704003a319fd953026896c33533 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 4 Jan 2020 05:07:51 +0300 Subject: [PATCH 0224/1106] Introduce pair_to_filename() --- freqtrade/misc.py | 6 ++++++ freqtrade/plot/plotting.py | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index ed37ace3a..e6ebc8d65 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -92,6 +92,12 @@ def file_load_json(file): return pairdata +def pair_to_filename(pair: str) -> str: + for ch in ['/', ' ', '.']: + pair = pair.replace(ch, '_') + return pair + + def format_ms_time(date: int) -> str: """ convert MS date to readable format. diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 6b2d426e7..7c9c9f985 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -3,12 +3,14 @@ from pathlib import Path from typing import Any, Dict, List import pandas as pd + from freqtrade.configuration import TimeRange -from freqtrade.data import history -from freqtrade.data.converter import trim_dataframe from freqtrade.data.btanalysis import (combine_tickers_with_mean, create_cum_profit, extract_trades_of_period, load_trades) +from freqtrade.data.converter import trim_dataframe +from freqtrade.data.history import load_data +from freqtrade.misc import pair_to_filename from freqtrade.resolvers import StrategyResolver logger = logging.getLogger(__name__) @@ -37,7 +39,7 @@ def init_plotscript(config): # Set timerange to use timerange = TimeRange.parse_timerange(config.get("timerange")) - tickers = history.load_data( + tickers = load_data( datadir=config.get("datadir"), pairs=pairs, timeframe=config.get('ticker_interval', '5m'), @@ -306,8 +308,8 @@ def generate_plot_filename(pair, timeframe) -> str: """ Generate filenames per pair/timeframe to be used for storing plots """ - pair_name = pair.replace("/", "_") - file_name = 'freqtrade-plot-' + pair_name + '-' + timeframe + '.html' + pair_s = pair_to_filename(pair) + file_name = 'freqtrade-plot-' + pair_s + '-' + timeframe + '.html' logger.info('Generate plot file for %s', pair) From 4eaaec9d1a0bee87a6ce2b60b2044b5bd52164b7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 10:36:08 +0100 Subject: [PATCH 0225/1106] Implement pair_to_filename to datahandler includes tests - taken from #2744 and modified to adapt to new structure --- freqtrade/data/history/jsondatahandler.py | 8 ++--- freqtrade/misc.py | 2 +- tests/data/test_history.py | 36 ++++++++++++++++------- tests/test_misc.py | 25 +++++++++++++++- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 7f0643862..7da1477af 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -30,7 +30,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] # Check if regex found something and only return these results - return [match[0].replace('_', '/') for match in _tmp if match] + return [misc.pair_to_filename(match[0]) for match in _tmp if match] def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: """ @@ -109,7 +109,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] # Check if regex found something and only return these results to avoid exceptions. - return [match[0].replace('_', '/') for match in _tmp if match] + return [misc.pair_to_filename(match[0]) for match in _tmp if match] def trades_store(self, pair: str, data: List[Dict]) -> None: """ @@ -157,7 +157,7 @@ class JsonDataHandler(IDataHandler): @classmethod def _pair_data_filename(cls, datadir: Path, pair: str, timeframe: str) -> Path: - pair_s = pair.replace("/", "_") + pair_s = misc.pair_to_filename(pair) filename = datadir.joinpath(f'{pair_s}-{timeframe}.{cls._get_file_extension()}') return filename @@ -167,7 +167,7 @@ class JsonDataHandler(IDataHandler): @classmethod def _pair_trades_filename(cls, datadir: Path, pair: str) -> Path: - pair_s = pair.replace("/", "_") + pair_s = misc.pair_to_filename(pair) filename = datadir.joinpath(f'{pair_s}-trades.{cls._get_file_extension()}') return filename diff --git a/freqtrade/misc.py b/freqtrade/misc.py index e6ebc8d65..f012400c4 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -93,7 +93,7 @@ def file_load_json(file): def pair_to_filename(pair: str) -> str: - for ch in ['/', ' ', '.']: + for ch in ['/', '-', ' ', '.', '@', '$', '+', ':']: pair = pair.replace(ch, '_') return pair diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 2341673db..39000e508 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -144,23 +144,39 @@ def test_testdata_path(testdatadir) -> None: assert str(Path('tests') / 'testdata') in str(testdatadir) -def test_json_pair_data_filename(): - fn = JsonDataHandler._pair_data_filename(Path('freqtrade/hello/world'), 'ETH/BTC', '5m') +@pytest.mark.parametrize("pair,expected_result", [ + ("ETH/BTC", 'freqtrade/hello/world/ETH_BTC-5m.json'), + ("Fabric Token/ETH", 'freqtrade/hello/world/Fabric_Token_ETH-5m.json'), + ("ETHH20", 'freqtrade/hello/world/ETHH20-5m.json'), + (".XBTBON2H", 'freqtrade/hello/world/_XBTBON2H-5m.json'), + ("ETHUSD.d", 'freqtrade/hello/world/ETHUSD_d-5m.json'), + ("ACC_OLD/BTC", 'freqtrade/hello/world/ACC_OLD_BTC-5m.json'), +]) +def test_json_pair_data_filename(pair, expected_result): + fn = JsonDataHandler._pair_data_filename(Path('freqtrade/hello/world'), pair, '5m') assert isinstance(fn, Path) - assert fn == Path('freqtrade/hello/world/ETH_BTC-5m.json') - fn = JsonGzDataHandler._pair_data_filename(Path('freqtrade/hello/world'), 'ETH/BTC', '5m') + assert fn == Path(expected_result) + fn = JsonGzDataHandler._pair_data_filename(Path('freqtrade/hello/world'), pair, '5m') assert isinstance(fn, Path) - assert fn == Path('freqtrade/hello/world/ETH_BTC-5m.json.gz') + assert fn == Path(expected_result + '.gz') -def test_json_pair_trades_filename(): - fn = JsonDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), 'ETH/BTC') +@pytest.mark.parametrize("pair,expected_result", [ + ("ETH/BTC", 'freqtrade/hello/world/ETH_BTC-trades.json'), + ("Fabric Token/ETH", 'freqtrade/hello/world/Fabric_Token_ETH-trades.json'), + ("ETHH20", 'freqtrade/hello/world/ETHH20-trades.json'), + (".XBTBON2H", 'freqtrade/hello/world/_XBTBON2H-trades.json'), + ("ETHUSD.d", 'freqtrade/hello/world/ETHUSD_d-trades.json'), + ("ACC_OLD_BTC", 'freqtrade/hello/world/ACC_OLD_BTC-trades.json'), +]) +def test_json_pair_trades_filename(pair, expected_result): + fn = JsonDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair) assert isinstance(fn, Path) - assert fn == Path('freqtrade/hello/world/ETH_BTC-trades.json') + assert fn == Path(expected_result) - fn = JsonGzDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), 'ETH/BTC') + fn = JsonGzDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair) assert isinstance(fn, Path) - assert fn == Path('freqtrade/hello/world/ETH_BTC-trades.json.gz') + assert fn == Path(expected_result + '.gz') def test_load_cached_data_for_updating(mocker, testdatadir) -> None: diff --git a/tests/test_misc.py b/tests/test_misc.py index c5bf06311..83e008466 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -4,9 +4,12 @@ import datetime from pathlib import Path from unittest.mock import MagicMock +import pytest + from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, - file_load_json, format_ms_time, plural, shorten_date) + file_load_json, format_ms_time, pair_to_filename, + plural, shorten_date) def test_shorten_date() -> None: @@ -57,6 +60,26 @@ def test_file_load_json(mocker, testdatadir) -> None: assert ret +@pytest.mark.parametrize("pair,expected_result", [ + ("ETH/BTC", 'ETH_BTC'), + ("Fabric Token/ETH", 'Fabric_Token_ETH'), + ("ETHH20", 'ETHH20'), + (".XBTBON2H", '_XBTBON2H'), + ("ETHUSD.d", 'ETHUSD_d'), + ("ADA-0327", 'ADA_0327'), + ("BTC-USD-200110", 'BTC_USD_200110'), + ("F-AKRO/USDT", 'F_AKRO_USDT'), + ("LC+/ETH", 'LC__ETH'), + ("CMT@18/ETH", 'CMT_18_ETH'), + ("LBTC:1022/SAI", 'LBTC_1022_SAI'), + ("$PAC/BTC", '_PAC_BTC'), + ("ACC_OLD/BTC", 'ACC_OLD_BTC'), +]) +def test_pair_to_filename(pair, expected_result): + pair_s = pair_to_filename(pair) + assert pair_s == expected_result + + def test_format_ms_time() -> None: # Date 2018-04-10 18:02:01 date_in_epoch_ms = 1523383321000 From 7daa5bc33881c1e9919eae61510284739078ced5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 12:50:44 +0100 Subject: [PATCH 0226/1106] Don't return None from unlimited_stake - 0 handles this just as well --- freqtrade/freqtradebot.py | 15 ++++++++------- tests/test_freqtradebot.py | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aa47adfd4..ed9cb983a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -250,12 +250,13 @@ class FreqtradeBot: return used_rate - def get_trade_stake_amount(self, pair) -> Optional[float]: + def get_trade_stake_amount(self, pair) -> float: """ Calculate stake amount for the trade :return: float: Stake amount + :raise: DependencyException if the available stake amount is too low """ - stake_amount: Optional[float] + stake_amount: float if self.edge: stake_amount = self.edge.stake_amount( pair, @@ -286,20 +287,20 @@ class FreqtradeBot: self.config['tradable_balance_ratio']) - val_tied_up return available_amount - def _calculate_unlimited_stake_amount(self) -> Optional[float]: + def _calculate_unlimited_stake_amount(self) -> float: """ Calculate stake amount for "unlimited" stake amount - :return: None if max number of trades reached + :return: 0 if max number of trades reached, else stake_amount to use. """ free_open_trades = self.get_free_open_trades() if not free_open_trades: - return None + return 0 available_amount = self._get_available_stake_amount() return available_amount / free_open_trades - def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: + def _check_available_stake_amount(self, stake_amount: float) -> float: """ Check if stake amount can be fulfilled with the available balance for the stake currency @@ -307,7 +308,7 @@ class FreqtradeBot: """ available_amount = self._get_available_stake_amount() - if stake_amount is not None and available_amount < stake_amount: + if available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " f"lower than stake amount ({stake_amount} {self.config['stake_currency']})" diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index c8b627ca4..dc74e507c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -189,13 +189,13 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r freqtrade.execute_buy('LTC/BTC', result) result = freqtrade.get_trade_stake_amount('XRP/BTC') - assert result is None + assert result == 0 # set max_open_trades = None, so do not trade conf['max_open_trades'] = 0 freqtrade = FreqtradeBot(conf) result = freqtrade.get_trade_stake_amount('NEO/BTC') - assert result is None + assert result == 0 def test_edge_called_in_process(mocker, edge_conf) -> None: @@ -576,7 +576,7 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade) assert not freqtrade.create_trade('ETH/BTC') - assert freqtrade.get_trade_stake_amount('ETH/BTC') is None + assert freqtrade.get_trade_stake_amount('ETH/BTC') == 0 def test_enter_positions_no_pairs_left(default_conf, ticker, limit_buy_order, fee, From b37f34ff5bc5d2a3399af6c29814031f3bb5f6cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 13:25:11 +0100 Subject: [PATCH 0227/1106] Implement amend_last_stake_amount --- config_full.json.example | 1 + docs/configuration.md | 17 +++++++++++++++++ freqtrade/constants.py | 2 ++ freqtrade/freqtradebot.py | 3 +++ 4 files changed, 23 insertions(+) diff --git a/config_full.json.example b/config_full.json.example index 981fc5209..f39abb00c 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -5,6 +5,7 @@ "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, + "amend_last_stake_amount": false, "dry_run": false, "ticker_interval": "5m", "trailing_stop": false, diff --git a/docs/configuration.md b/docs/configuration.md index 3b8760366..9a05eea2d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -44,6 +44,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -146,6 +147,22 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr !!! Warning `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). +#### Amend last stake amount + +Assuming we have a `balance=1000` (USDT), `stake_amount=400`, and `max_open_trades=3`. +The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. + +To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. + +In the example above this would mean: + +- Trade1: 400 USDT +- Trade2: 400 USDT +- Trade3: 200 USDT + +!!! Note + This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. + #### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index ca4f3cf36..a1bd70183 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -79,6 +79,7 @@ CONF_SCHEMA = { 'maximum': 1, 'default': 0.99 }, + 'amend_last_stake_amount': {'type': 'boolean', 'default': False}, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, @@ -282,6 +283,7 @@ SCHEMA_TRADE_REQUIRED = [ 'max_open_trades', 'stake_currency', 'stake_amount', + 'tradable_balance_ratio', 'dry_run', 'dry_run_wallet', 'bid_strategy', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6c02844f1..5aacdc587 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -308,6 +308,9 @@ class FreqtradeBot: """ available_amount = self._get_available_stake_amount() + if self.config['amend_last_stake_amount']: + stake_amount = min(stake_amount, available_amount) + if available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " From ca054799d065af3bf745867bcb20c06fde06aa5a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 13:25:21 +0100 Subject: [PATCH 0228/1106] Add tests for amend_last_stake_amount --- tests/test_freqtradebot.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index dc74e507c..6d794fc05 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -140,11 +140,45 @@ def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: assert result == default_conf['stake_amount'] +@pytest.mark.parametrize("amend_last,wallet,max_open,expected", [ + (False, 0.002, 2, [0.001, None]), + (True, 0.002, 2, [0.001, 0.00098]), + (False, 0.003, 3, [0.001, 0.001, None]), + (True, 0.003, 3, [0.001, 0.001, 0.00097]), + ]) +def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_buy_order, + amend_last, wallet, max_open, expected) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + fetch_ticker=ticker, + get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2), + buy=MagicMock(return_value={'id': limit_buy_order['id']}), + get_fee=fee + ) + default_conf['dry_run_wallet'] = wallet + + default_conf['amend_last_stake_amount'] = amend_last + freqtrade = FreqtradeBot(default_conf) + + for i in range(0, max_open): + + if expected[i] is not None: + result = freqtrade.get_trade_stake_amount('ETH/BTC') + assert pytest.approx(result) == expected[i] + freqtrade.execute_buy('ETH/BTC', result) + else: + with pytest.raises(DependencyException): + freqtrade.get_trade_stake_amount('ETH/BTC') + + def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) patch_wallet(mocker, free=default_conf['stake_amount'] * 0.5) freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) with pytest.raises(DependencyException, match=r'.*stake amount.*'): freqtrade.get_trade_stake_amount('ETH/BTC') From 41945138ac569947ed5ae788aeb7d5486bfc2c2b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 13:35:36 +0100 Subject: [PATCH 0229/1106] Converting pairs from filename to pair corrected --- freqtrade/data/history/jsondatahandler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 7da1477af..17b9fd7d7 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -30,7 +30,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] # Check if regex found something and only return these results - return [misc.pair_to_filename(match[0]) for match in _tmp if match] + return [match[0].replace('_', '/') for match in _tmp if match] def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: """ @@ -109,7 +109,7 @@ class JsonDataHandler(IDataHandler): _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] # Check if regex found something and only return these results to avoid exceptions. - return [misc.pair_to_filename(match[0]) for match in _tmp if match] + return [match[0].replace('_', '/') for match in _tmp if match] def trades_store(self, pair: str, data: List[Dict]) -> None: """ From d0ccfa1925006bf8be1365b69cb5a5efb0ff79f1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 19:50:21 +0100 Subject: [PATCH 0230/1106] Explicitly given indicators should override plot_config --- freqtrade/plot/plotting.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 1660371a1..dc4766a84 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -176,6 +176,12 @@ def create_plotconfig(indicators1: List[str], indicators2: List[str], :return: plot_config - eventually with indicators 1 and 2 """ + if plot_config: + if indicators1: + plot_config['main_plot'] = {ind: {} for ind in indicators1} + if indicators2: + plot_config['subplots'] = {'Other': {ind: {} for ind in indicators2}} + if not plot_config: # If no indicators and no plot-config given, use defaults. if not indicators1: From 888ea58df246186c68330de93b66d7c442e2bcee Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 19:50:38 +0100 Subject: [PATCH 0231/1106] Add tests for new behaviour --- tests/test_plotting.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index e5162bb17..78c01eb97 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -387,16 +387,37 @@ def test_plot_profit(default_conf, mocker, testdatadir, caplog): @pytest.mark.parametrize("ind1,ind2,plot_conf,exp", [ + # No indicators, use plot_conf ([], [], {}, {'main_plot': {'sma': {}, 'ema3': {}, 'ema5': {}}, 'subplots': {'Other': {'macd': {}, 'macdsignal': {}}}}), + # use indicators (['sma', 'ema3'], ['macd'], {}, - {'main_plot': {'sma': {}, 'ema3': {}}, 'subplots': {'Other': {'macd': {}}}} - ), + {'main_plot': {'sma': {}, 'ema3': {}}, 'subplots': {'Other': {'macd': {}}}}), + # only main_plot - adds empty subplots ([], [], {'main_plot': {'sma': {}}}, {'main_plot': {'sma': {}}, 'subplots': {}}), + # Main and subplots + ([], [], {'main_plot': {'sma': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, + {'main_plot': {'sma': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}), + # no main_plot, adds empty main_plot ([], [], {'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, {'main_plot': {}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}), + # indicator 1 / 2 should have prevelance + (['sma', 'ema3'], ['macd'], + {'main_plot': {'sma': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, + {'main_plot': {'sma': {}, 'ema3': {}}, 'subplots': {'Other': {'macd': {}}}} + ), + # indicator 1 - overrides plot_config main_plot + (['sma', 'ema3'], [], + {'main_plot': {'sma': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, + {'main_plot': {'sma': {}, 'ema3': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}} + ), + # indicator 2 - overrides plot_config subplots + ([], ['macd', 'macd_signal'], + {'main_plot': {'sma': {}}, 'subplots': {'RSI': {'rsi': {'color': 'red'}}}}, + {'main_plot': {'sma': {}}, 'subplots': {'Other': {'macd': {}, 'macd_signal': {}}}} + ), ]) def test_create_plotconfig(ind1, ind2, plot_conf, exp): From b614964ba96fdee8b713d4e8ea7c1f6441d23cf8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 07:41:39 +0000 Subject: [PATCH 0232/1106] Bump pytest-mock from 1.13.0 to 2.0.0 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.13.0 to 2.0.0. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v1.13.0...v2.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1357bba00..64402bb60 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ mypy==0.761 pytest==5.3.2 pytest-asyncio==0.10.0 pytest-cov==2.8.1 -pytest-mock==1.13.0 +pytest-mock==2.0.0 pytest-random-order==1.0.4 # Convert jupyter notebooks to markdown documents From aabeece4c096296bd6cfaf1efefdaced24620743 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 07:42:19 +0000 Subject: [PATCH 0233/1106] Bump flake8-tidy-imports from 3.1.0 to 4.0.0 Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 3.1.0 to 4.0.0. - [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases) - [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst) - [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/3.1.0...4.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1357bba00..13bb62e48 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ coveralls==1.9.2 flake8==3.7.9 flake8-type-annotations==0.1.0 -flake8-tidy-imports==3.1.0 +flake8-tidy-imports==4.0.0 mypy==0.761 pytest==5.3.2 pytest-asyncio==0.10.0 From d846114d3cdbfa845069aa42f995905a74d86f03 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 07:42:44 +0000 Subject: [PATCH 0234/1106] Bump scikit-learn from 0.22 to 0.22.1 Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22 to 0.22.1. - [Release notes](https://github.com/scikit-learn/scikit-learn/releases) - [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22...0.22.1) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 9b408dbed..43cad1a0e 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -3,7 +3,7 @@ # Required for hyperopt scipy==1.4.1 -scikit-learn==0.22 +scikit-learn==0.22.1 scikit-optimize==0.5.2 filelock==3.0.12 joblib==0.14.1 From 3c0d184097af10bad14b130af968a327daa92666 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 07:43:06 +0000 Subject: [PATCH 0235/1106] Bump ccxt from 1.21.23 to 1.21.32 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.23 to 1.21.32. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.23...1.21.32) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index add1ea0fd..97161df8c 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.23 +ccxt==1.21.32 SQLAlchemy==1.3.12 python-telegram-bot==12.2.0 arrow==0.15.4 From 6da97fafa8db18e8a58c01db894b67cf9a6e94cc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 11:45:12 +0000 Subject: [PATCH 0236/1106] Bump coveralls from 1.9.2 to 1.10.0 Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.9.2 to 1.10.0. - [Release notes](https://github.com/coveralls-clients/coveralls-python/releases) - [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.9.2...1.10.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 13bb62e48..5cc2e39f2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,7 +3,7 @@ -r requirements-plot.txt -r requirements-hyperopt.txt -coveralls==1.9.2 +coveralls==1.10.0 flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 From 6ac7dcf5e9f52735e20f9ae2b9c82b23523efbdf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2020 11:45:22 +0000 Subject: [PATCH 0237/1106] Bump arrow from 0.15.4 to 0.15.5 Bumps [arrow](https://github.com/crsmithdev/arrow) from 0.15.4 to 0.15.5. - [Release notes](https://github.com/crsmithdev/arrow/releases) - [Changelog](https://github.com/crsmithdev/arrow/blob/master/CHANGELOG.rst) - [Commits](https://github.com/crsmithdev/arrow/compare/0.15.4...0.15.5) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 97161df8c..c10536603 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -3,7 +3,7 @@ ccxt==1.21.32 SQLAlchemy==1.3.12 python-telegram-bot==12.2.0 -arrow==0.15.4 +arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 urllib3==1.25.7 From 2b3f2e5fa817088c04267c5a488aa371812be1c4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 Jan 2020 12:55:12 +0100 Subject: [PATCH 0238/1106] Add first version of documentation --- docs/plotting.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/docs/plotting.md b/docs/plotting.md index ba737562f..5b5199821 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -120,6 +120,62 @@ To plot trades from a backtesting result, use `--export-filename ` freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/backtest_results/backtest-result.json -p BTC/ETH ``` +### Plot dataframe basics + +![plot-dataframe](assets/plot-dataframe.png) + +plot-dataframe will require backtesting data, a strategy as well as either a backtesting-results file or a Database file, containing trades corresponding to the strategy. + +The resulting plot will have the following elements: + +* Green triangles: Buy signals from the strategy. (Note: not every Buy-signal also generates a trade) +* Red triangles: Sell signals from the strategy. +* Cyan Circles: Trade entry +* Red Square: Trade exit for loss or 0% profit +* Green Square: Trade exit for profit +* Indicators corresponding to the candle scale (e.g. SMA/EMA), as specified with `--indicators1`. +* Indicators with different scales (e.g. MACD, RSI) below the volume bars, as specified via `--indicators2`. +* Volume (bar chart at the bottom of the main chart) + +#### Advanced Plot configuration + +An advanced plot-configuration can be specified in the strategy. + +This configuration allows to specify fixed colors (otherwise consecutive plots may produce different colorschemes each time, making comparisons diffiult.). +It also allows multiple subplots to display both MACD and RSI at the same time. + +Additional features when using plot_config: + +* Specify colors per indicator +* Specify additional subplots + +Sample configuration with inline comments explaining the process: + +``` python + plot_config = { + 'main_plot': { + # Configuration for main plot indicators. + # Specifies `ema10` to be red, and `ema50` to be a shade of gray + 'ema10': {'color': 'red'}, + 'ema50': {'color': '#CCCCCC'}, + }, + 'subplots': { + # Create subplot MACD + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + # Additional subplot RSI + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } +``` + +!!! Note + The above configuration assumes that `ema10`, `ema50`, `macd`, `macdsignal` and `rsi` are columns in the DataFrame created by the strategy. + ## Plot profit ![plot-profit](assets/plot-profit.png) From 3883d18b8acd80fd541ffb2a69b9a1136d7341ec Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 Jan 2020 12:59:17 +0100 Subject: [PATCH 0239/1106] Add bollinger note --- docs/plotting.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/plotting.md b/docs/plotting.md index 5b5199821..dade97968 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -137,6 +137,9 @@ The resulting plot will have the following elements: * Indicators with different scales (e.g. MACD, RSI) below the volume bars, as specified via `--indicators2`. * Volume (bar chart at the bottom of the main chart) +!!! Note "Bollinger Bands" + Bollinger bands are automatically added to the plot if the columns `bb_lowerband` and `bb_upperband` exist, and are painted as a light blue Area spanning from the lower band to the upper band. + #### Advanced Plot configuration An advanced plot-configuration can be specified in the strategy. From c3fd894a6c25c709f284b8d529408408256fb505 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 7 Jan 2020 07:16:31 +0100 Subject: [PATCH 0240/1106] Regenerate plots with new settings --- docs/assets/plot-dataframe.png | Bin 177349 -> 216176 bytes docs/assets/plot-dataframe2.png | Bin 0 -> 195009 bytes docs/plotting.md | 2 +- freqtrade/plot/plotting.py | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 docs/assets/plot-dataframe2.png diff --git a/docs/assets/plot-dataframe.png b/docs/assets/plot-dataframe.png index eb90a173469bafbd11afd28c31c8e3eccd9b9e5b..6310b23b4b8198734173b011bce7c7d079ac3fec 100644 GIT binary patch literal 216176 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 z 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

jj9>k~K~SvRZ|By!WYsQG;i z$O~^bTI6VI;n?Zlv0qQJzT+2Np+CKbplQIku?mGDBBguA@Vd>+JaJ)Ebued1LoFOR zhvbS4vU!dX8uA`v6)RYD-l5XS2TkV0u(b7##$r;zF-KCN;oY_ak-SP3 z+bPhEl;Z=5DUD-bEWx3$;Y+~XC3>42H*R4`!}iR$FUdR1&w+F!{a5Rj*%Y2iZTc@} zKNa#&L89`(eNz~rR+RPE=r!=jGECWbPMFlZl(IK%O5d6iiB|$Rq=zgDbu)*|SjhA4 zVsqMk_1^I{N9}5QgQS%^KwZO+8?Q9*TjZJL-d?PZia+zqgL^B8{h&VBPkVhfhL{`? zJ%^zxK;0RbGvxN0>MRV&&|xT2*4GSDtqWBa+miRe=MmBLQ9^@v0fbC=aJLMJC zCyIafC=wCD<9UYzfN7JD5sG!>N4|89ydc}JY$1b{yVjvux+RViIy6V7zns{xg+`9h zbBWsRE=?AqcZrtmM7Rt&ywQFHO~^c5lNSTO*sKRd+R!Iy8>qAIvsizI4xJ=T`&bFI zes>1>PWaZ{CbDW~sJHyhm0kO5Ot5_G)4-lpkBq0QeFG=>&hE7K%d=6D@Jn(vryXO* zNC%?E>=yigx-4{0jE(NsoASC(>3xw}s@QAfHc6g7tiRULc8(_70g024C3hx`*2ZYs z!76A(_PC*+3tU9F4S4Lk@cBn<7fMY(i@EB^8+CtF&fEHowL z|3L!&!v(>~!Ob;+FQ3t0>oUM_e7=!6yj$-9Uh}ssONo~|rf}b#$Z?%sRfrK!Th*o>lN&bX-kJ9Y8UB@sFDz-WkE zjL?1?`-m@t9oFj*wcF9(cIC{Le?gX(*kh$~?6sBLlBFenm|;XR%11z>>n=fApZAF> z!;T6A^ z23|5VZ@Z}7I7)CMtAcXI6YGwM-=Qoou?tDX4| z%}a;*{@&r5ZagAKj7%7j_)xz8dlJpaG)P=EdyuUwA06qvuf|JWu4c?h@&1}Hb5c_3 zQaJ9pwZ0B4p$ZiD<_m=$g=WC7-7{DH9f=v1Gi_(?;?V(m^bwK5H>PLK2wSuTGp?ZJhj4m=k4s$Gt1kwCL0@)~=(}FOkQKsKx-i|(qpapy$izI-;;y>P9Fsz#p^EIP_FRJCrj zE)w#^B%i${b|Mw6O2+?#a>hzAY$j})l>+OlU;02(_}iueU4t?+f%l^OdWODLB=R+` zf7er)B7v<7fS$G@ULTcIv1-AWg&^VIN(7E_lj$H}gi89@U}(*}cRjanUesw#tZwB| z&n1+_&>-F{*GZ$M>bkI#(oTp&69;u$st~9g0j|tB^`EiDaIcQB=*H$!b`MmU?h*EA zEOu?Ykk(w?P)JTqR5CffB^j5gr`^!ttkbkPuT&se#b)Mp`(m+LSl_)&)2b+pq7D)oRGI8umKt~^7ki<^NiS673?5@9z}iohmFS?x1VS}Ep&5TB zr9u4v5iXEpU`&BKL#j|*-v%hXC+2b1u*ey|h|J>vv-)!HNTcn{mNeKE%;*59NPavz za)npK&Zneuj);?_J4@4VXfA||wO3}NmYSg?j5a2I>!t_`oXM{XUT?d^MmT`pA(R&GAM zg)BOfY$xd?SDs*w;$qZxp#GZ-rBt>YG7F38m7tu#u0VxBZ;HG)3A?gNlchua;$H+J z^D^DuY?2mdVVH^E&F|)EBv~qszxzA2%rB=)lcEP>E&Z!}`B{YA)_gm1^m6gLNFq|z z5hHX9@iU}9?q}Dy@6rOKN8$T72icE$>2aC*>u@nkU9J#?*x2e#wn!hRP+Hc8LD`V7yZTNZt_v% z3C5Zz0!1WB%}XgPB(K#d#Qj(73w8|_ny{mwBn<-ZAKPO zC4QrMF>g0B3sg+le#=Bq)zE)-V2rYp;TQNzmb&TckA#U^ZXc=vE@S4ThDRgo18XMN zyvCY-ot!6PN^qeuJmL8?u*um*#;A&PmGs^@U5lrdDzkt@PB0nuUpHVZ_I)IgxiH;h z7!`(=N8U>jy}^fsxVhn}`L#dwnvpc0GO~UtT#nkVV2&BR-Bk_K1Qu1N&rBNY=L7i| zGU%BUZMKCM4Cwg#TfpNk(8Pj2{|zT~Jpit>Dx(p8%ROThGQDQJ$*EZUUZ$4{4Z=Uv z3mosl%9kNz5qcJ`Ul+ItXX`F#+hsp^+fB~Y<#;QZ!T2H`A_T%4A^KP&Wr1S0^=>j0 z23-*Hk-Ix3uHCvAICI;plAaYh_(E&vuF01oXQFeU(hCV$Ep!p7oX{6__>a^m;j}5% zfW*|;b1$4||D5+S`-UYdS>vSgBI~GZBGW@?$0o~mLDBBFC6qhbsU2vhiV0Z^y)Bmb zU$IXp-s{{c&!>#W%B<#>`U!*OW*3XLZv2WXak9@99`5&*BY^zKXtudUw}aUkIZ#Tg z&x_$cRiRx{*@WdU)ndMcRE6UQ$?a0nkh+W{CGA@JK~r7p^mU5|S!(8_l!j2b5&n|R zD28Eu9qAjie7T@^)jz18bW)>%p;nd6fA^T3Tv1#8Q~eBG4Ot%w-yXww~If1kdUqYzAsNugT2x3br-kcjQ{%gR1git zfYEfl%e6p|z-K|yOJD(IXWlmTv^R`%4XsFp&t3l-pV}1?>~()L>ZuZtacuh+0y^G(%r$PC(a!wWkx zPaDJiOp>q<1Ed)_5c`kET-+z9;O*` zaMGN#DwWioruN)Uh7ke#Ob#D9EnS~B$QB@vYrmwlKkdCOR-Ejcq?X2(-tnQ(^XD60GvTM7WgDSv zmmNX^4Wth*p{Jq!*)oSRC5q*+VwbZ5_-u1?f%>xCU#j4g>idYdic0RBlK7l>Zy)P^ z)>IKCv<;?}uamD_NI%FS2F7PDrwW(u90NsDclLE&CbYgOA3w|gLKg14b^W}m9?b?@ zK*Ey3w}YD(AP4o|l=r77;`ORi8RyPdp14Yu z*+^XsHWuf&dFd+p&Z*NUBH~}0#b8FT5!S1%w%+QB4CH6#hukU>xp>MeI#0Nd-TIIc zeE&kQeZ3`%l9c8CON~L>{qVwzpJ4r^YTj^wnl_Q7!lodQFjnP9KhVqB%h;RdQ8!1| zcM_)c(U^(rbwDpgEQOhjaBVG$Gs8J;9Wo>p;c4DYmCaw9NT$o&pBZJDKZb}eqI`9 zdH1dD2Oa3$zMR$4FQUo}o-&hUgEw~&n#6|kTp#wz18U%srqIQ!2XqK^;i$H*mQUV( zsKof5uHV%G z=hwPq@v6FvxMA3Xi5z~v6LqIUqM4Bn_ts^k$RP^<65E&wd0i6WZ0wDg^8;!;-m#-B zFhyetC(2>&oV6gJ7^tuX(vQLIvdhkKK;q1ajck&0(};G`^u6UrPw6kWGgY{%Psvj) zH4Fb9Oi2Ray4p=4Iwkw$e(g#N`;@F(d{|U@`q$+Ts|vmh36CStp%BVXiNcQRvUK(J zM$y3SrvhKlFdy`HICI)SX4xFas@d}C9Df3*{~>6J|B=-2ez}JOOxM7{pD1)oy!2Gz z|CPx+4k?iJo%fm1;iREk zW>nKwDS(Ygh~0#{Q>H<#?j-6gdhh==;a3Q}>)y5BtaQC6@B9>ED!l8;%9yD0Srb^B zre~&4trr$n5;Iby9A+8vZ;FbYEO=q8zB%bG{lCC#(9yDktr>s3H94=IRWKHgA%xgbHKGXH=+bGrHx+= zD@p&ae2v;=bHS4qSC|#yASYu2>=^`{+uE_%^z|vG(H9l%y^kIFBC+)t~~0pm5&z+V6~hB&v|5uzb(_#9J-Rh;}_} z95;CRhQiHi{P->@8-5wL&xR$yqrj{;IRa?51AP7RMw{1AGH!uD@a9I~ z4wMHf50A=?6<6U(Ar`N(*K?UHsA41qPQANg^6(kCk;D!1@O!UW{zY^}^N_J`65dC9 zPd^i+HJn2CC|P&R4?edZ>DY0=?9L2f&vj|1-j6FI_9K(|qgmWu%l0p=<6n9X!9-Lmlbf_foXczo&Ocgp*tvNsDTp;!e;<<>|}kYD^3ALN-mHX63iUFVk!! z*inikv6oW*RT+TdEt4h2$Vgv;flt;4mq}!A7wbRh$}rukrMQbXDW} zP6oIV?ZuoUR0xgXmmVo?x=Qar1@sU+?|u^(Ty`{d8(q zPb6R}unyh}(RNfE%u~ad2B@IRnx_tSLcYj4?ny>WRfo8YtoL%DY8QOS2M z`L8NNnZ=BB^@*6AK~%;`bLN@8ZEnY&ngGYMg<_wN^lA-jA7o4#+Qj;`g`TPZyiTZV zFeUifJQ3buD)sg#b9TR&ITiNOd5?-qw0)@WueZ8bC}{52K-06LZX^QbyLqQSA5i0~ z_`^a)xqW8R6=ylmj6_7%ZJAiO#!TOaKi`yvWJ)X5X0)eYxU^mT9`sT&_G3 zcw@tHGsc*)qXsjVI!U6{`+wN_3aB`frt3fmE`vJ^?oM!r1lI(2C%C)26C478;O_43 z?iSn$8r=WcCHwEU$$QRo=D;M=(_MAD`c`#SaVORIF!OQ2zKW#KrQ0X5V38nFfcCp! zjlcB4{U|K2zlSNGc5l9FON7Bj`xHS_VVQo6!^N$?i_xW*)$@twL1(nl8cn_F+c#PbIjcMZ4V0SY! zLg-a|hv`OU0MD*=TyVi%03H9tbI=mljvngiG7z|W%I0y$2bN^!xGX-1i{fFE;WU&! zbH!0>)Ed|w10IuKQVqqBk5N(gHOKYTwFL&)P^qG}`ULb34!Gk)Fu<^qO2Cxr{Wf`u&XK@JPU=UbZrVR-oYi8ely%z zOGH+ZRC9Z;l3XVdw2U(wE`PA)k6;tmucz`mP632qwwX6xUS1D33m=|N;^v*Ldr`q4 zHk>E>zUu+oz0M!=V|LEfZ?|j#2C2f|QN!)4D{usP?WM840Pr|Q`3#fy8%`Ct_DJvh zG|>r{3^3^ik5;~nEf%8~ir!^MUch(&Hh_R8sJ4z|N5ASPQBH=4NG^q%+Vd0`h1hW& z?nHwa%Kg+~vf1qZFNVc}LJ8f+Em>~#?$nHXc)n1qIWV!Cecv+6`%EsFUKti%krn+! zdZoJR$eF}OW40bi6-OUtU|Qa@!d>(5X7cXbzWJM)dS@O=Se}0z-yuP5ClR$r5)()L zA%H&x8RXcK{(0mRA*(PtEndl{!xTtvumuXF)?Xt=iw1hHF;5sqWuxJ~H^?T9l(*~f zLf{Xl;%PG2Hb}3|wjIW%p@~&oR%FS0c9nAVF;3xVvC=`Sme(pFkJ!;3*A({bhLrh9 zlv2|h?ddJwbm-fw^3^RqhB|;Wk{*>0CTFl-h%CoVbSHy2gfkYAQxFAAQXP$?D6Y9x8zm%{wkNg+BcBc@ zY$9b`-E!>QBWPzjgK2W6cbO-*K~)RX5_;NdOetkLT!-)j-39{d1Oj$Os@JLUoEF@E zV=mX&UIsK>VuZB@a){hrTc)g6k^PV?-4p$OSbyGAgDS%a!JxalPSW(=5usW;B||ry zf994uW;9IctuRSiAywDU=wwqG5f!9P>YO+-*d9*tQXp>}jtzk(-36hLqDNA)oyAO}!ma?LX;!x0q_edosi8BrSLz5OaBV+!kjBU!(j_klrl)gw!p3llb(VmxGEed&bbaOSg8nsgIo zpnA4U`qj`nB4&uE!L=aFGUfk}Ib$lc0FXe&3DpcHRsc_vd=KvCUEw^JcUxl}q@H9>A6I`8PZlWbW(cBmzO+_2=HVje#P z&3TJPyoX>CHM1hjFr60@f~L>EW>sq*Z36lCaMgQaA1l)`-u|*mo-JR^j>-$B`pb74 zfe^!Qy{y6%QgezKu`y!rqg6puU|@Ab_7(^a((OiGV;z{KVlmH>TvjH)OoXX439iK# zWOS%r!7kPk)!DQHyxgY5gB1ZJ;k2CZ;@fqm^W=+K2y*2nNeKzC< zSaNk_4yf8MU=WTOJiL`mk{Kf|^)-d45YY2v(~57Y{;1&o3D5aJ z*AX53jIk+0WpoX~oNV)g=J{xXo}M0+Q@Gq1-~Fp#-OW+BpB&v?=icx@Ze-l@lwaqyQ()K zo7uUr35cYJh4JQ%M)?E#ooUY9^}64tY`h)(;u#t}i5T?6mc!jKz=5NoD>g7a*bZRieHpRsAmgj;^lIAE*?ESWGbm zH6t)yYjZVi>q%-JPepq;2zx2QD4J=#nv!N;t#R$$ssKejN{=0b^oR3#xO@q%ovZx? zczBLUl#s!|nH-Y=;&;{%?LDT!?jDZ;3FBzX8`Td>vW=760w}yxDM^utxDAx$9-lIF zF$VDoV1)P!4yyGt+J=98#7->J2{|Zd(7k6ya${Bj{vPV;4s4fot2M82V748Yw>;-P zh-p5w&((Dk`!JNPkgVo<)*wmf{4-+k3uJ7M>%Wx*o|E+x=Y!-8wB%|RU$1%37Ll5+ zxba5G;Ea|X&e2&X8pm2auHuo@mYQ;lcZGZsDM3@}^ z9wlX)`aZ1>ux^#|HRUz<$t)0JG~{$D6#AMeYw`>V33i`?>Z9ewNOJkHN^13s$TX9r z=pqyX@rgNxWmo%ER&TsA$Fcj*u32-3#qL zjMMcJ5S-PAK|(>`lhh!!Re%+iGM?a^9jMt&dV8sQ%#3ZjVyn!^F2hF+F`3|Ophe4j zhr2owM!EhB=?`-CjD6fC}Xz$>&`Lq3a29E_9 zEV-K_kxvrh_0N=57r5?A=@N>sP9-x&iRFiMb6P?&-HM_(;_EFBn8xzTP6Z$@lqBfK z7j2gZr2rwBL?c;3*)prrrPCkj>1-f(`>VF=1ol|VldiDc5~CP#pupiR$NHlfIRG~i zhHS`)ay~E`Uai}VLb`rT2CRo2Z1R2Ir}`wr33Be@*3Dq;5_E8zhc$hp|LzW-bRp+KJx}!{^c;nl$JoX9(=*WyEJG??38X zPtH%K#pa++>neK)$9ihJ%y1KW(oKtzp?J7qLg*pcJHvs8NPBk+RwADoSK}1a7}9h) zH6xG&2G+I0W??pZ3%mj+SsLy?0lwm{5CU08YH8g&3Um*U;aD_+Iu^Qzq9f0zH zNc4b(8eE%0n}Za4LO1vgRB+oImuL9ANx z-~L^*0v};MmvlF3YRB$d$BcM7GI89Bh0_natPRY$NgIK>>Uqe%c?_z|PhpNl*yv0oA%fem=Iaf2lM9G<<4=gIXP14-xR6RgtM|-FF_`jM744#i_hy|UpQP4cDIz0_!J*rCXPONj<`?dwC#ILaf)MTnyo1Q6gxB=`oJQ7SO?Qw?)uMh4|a8`y+T zm1j*WWReYdZ&F04y8n{6A2P_0xyNcCObKaI=mp+oam?FiXt8r+qr*Q4=LBB;&MX0V zJ^?*bD}2YDX}sL$2~tRXoYLfcwL$Be|s_6MMe z@u&a+h+u==NO|h4_w9ikU+kIK{%bE^K{F0iMdiH)>b-v@F2^Js5rPs9l2p*w6G{B4 zduCujXP!VN2&4WY?SsarRj@%C_IHf>=*y!nMA7f`f7cgCW>^BRI?)NB0jJUeV#HS- z7UhfXWX*w4`u;zFfFw}9cWISvo{+m&uKDZYp4SYol?DIXmFTbCDR2nUea&E1fhz1y z5-i{>-faq#LQg0dSN;(Y4C}+^qY`6ILSj{ct|AqD6bU5wV-h|Y0B->vG}k@uVHp2J zkyLt7*L6lO#`0zr0OR5(j1|4VzF$h_A-rz`xgGC!iN6A`AOf~}x%3$=C%u92B>@3= zU~;_so4xrX7M^-FxQ_tDVzGUE{JBiGZj%ob4&mJI7Ul01-GSVJUcXo1KG1R~XIP-3 z8i*p~yg`lwUvN-$;79OB3{-c53a)OXPk~&QI*$m551)~Gq38aT#=nUro)DpN9j4v; z%#@;MO|nTY9LVKd*sseFC8b^6_n1>HX=g!0|JJn#$o7{f=qL(^5`%%rLY~50|FFhD zG>IErj`G>t$0_-<)68UVlwR1%A)2~KFx2lZ0%&EOq@V@@Qr3HH;4oV>^X)>465}#x zB%cWq;K7MdO_)Dmx?Cfl?RSNfsLUmQ#*9GxeFmTj0rWwW(1*vHB4hO77xQLi#W>SETL8H_3DEzpT#!Yse{GffTo$+|<2ST~&-0`ZUW*2FGMN}FO*`otBd=cn|u~vd9vW^*oAfXDqSrf({-^xbQdzeRhLv-i+ zTfXfp=-_}?ttbo$ptfl!aj(R?Izyxsyr zpmqtVpX(3={XnC(ivin{U3^qlJVeaH-g12AqpfxGb^a5d|0wmPi2=X@Ttgd@NmVMJ z3}BFjfV=tEQ2%|x}*q1G5~B6z4;>>2MYs2LGqmu0p{h{UHKIbC_;b zpw{z9B&b19#bGr~*~5@9-JOipa1bK9#zP;saoSyz9etBS--=%;Bp-L{!{!6rkUl&brFRhcJHgZb)(xfqqt#=V zUJ|{$*ru!6z8$Ib@=qh1nDpB2BXrNqShpUb4-UfvlbUw7F2-p*V{Y4|P-S;xUtsjZ zG!oOC&sqw*BFwbv@2l7eDi`pOid~nRFil@@D76hh&+q_iCf*Pn+IuuZef81=PM6n19vsIJ` zkON(8#Q`@F7bpCrT(+YL9pklap9+pI+c=B|b_lO(Y8@OevG_HfAH~m&MSLlGe*v4+ zhukhw&+_>op{SZjA3Wa1H9+^ z^_dplQ9)oO#A*1u1d8|Pz|ZqYNtw@cH6oK`?SrJ|x`B;NqV~CMUr5=c{ToJ@Ze7F< zjcLh)83zC`YuLEN0``P)uhJ?6kuy5vpx3}~VR0aE#a3! z{9XT$tY?j7J~YKP00WhV<@rZWWh5KjfCk>hPJKO=Ce; z$<(yzsg_x@nQJnSVY7a4-$Te#c#j|U4txY?UgORg4tt=*28_b<3IV;LXdzTga4FNsS>A;M?#xVa-jY|*O3h~R6F}|U~HQ?g5gvSSL3K87%lN-KW4$?|R()m2r`3a_b z?&Fcie(r6Lc~-TDy!*{&`}2)<&n#ulvfP{UexZen=VM${U-5$97HX$9`Qv@Ia6DvZ z)krfd2EkpY9$<2S8XTWWcYgJQIn7mW)>`Bv&5znJYCMQPVn!enLxdWfC*ZylUw?=10EtTwWr=_05ayx*^xNdHei{(LfR(XEiCbZR1t1 zrBF9QxA@ASU8!{I6FOxW|G$c+<6y`@4O3zz$f8yqjzG0m&l@R(QPlk|8)?sZ(z9~7 zUiiu_^?@k<0fH;Hr$1;wjbT9cNCER`f}0|7pg+wwCa_@R#OrC~uaft0?Ug-i4vHwk z$MGXCyvS=zv%eCRef%lp_T%Cu4y8)JVC#HfNN{lAOd59foTtV>4F1#H00m*ntAo^i z0||1<*9Gy&%CTm@zQW5o*vSBg+XLB@Fey`qg#Ec&B?+^)f>Yzxj1eJ;5B>Q{TXEXw=k}%*_-|d@DOPXIv;L#Q~*p zJ~L&y<@5|nwwFrjx-QwX(#J%Z4TsD0q7_E=2n_Vtf2NmGj>1TY)5{>0bg59G(|xO8 zsbWMZdTpd*|0kOVzz6^lk+Ht~I*Qr_z_ZV57n021Xsa6=Egq$L-{7#6A#-!&j&?dM zyl#-e!t+%b4(lVu*ricL=ZWME+2H-1&VcwCh@MAcNx(z=y&S+ha9FklqtJ~TVO%v? zdQ|4zjsxWfP()aFXBcs|6O@R{n+dF_AM6g7XBiI;a`YO<{evoltgQjr?K?lX7j5VP z%ZCKIA(7FOChc0r4P`NVL~4JV+#_U9fbFp5L!7Nv>*R1Q@yX#Umo8 zE<(=cJ0|?}@7V>Q``7SSYz1NeiW3<;7c~)7G%_J4qX?(}!=5m9jF_MxfHvGh=6xiR zqv*kFZ-?KRg+Sb2%SKW8)mH&P4mRbRBP6>!H^yAz0bbEDN;=9&1PNi64f%*oW2PVfWbobsNf6*L-55nj zrCu#O_u)keTGlO$JS`rV%VS-su*<(VIFJY2fJu-{I70`Dbo>Apmw%!D>i){At@W8r zcddE`DS%x#^WvbKOd>lN^$&yrnV=z1f(hN8zT&&lD6M+=nNfk7rFuPAjf7M%i@c!a z^BM%XaYP2Xf$5|(k{-3KXA~Ei+pzz2m$KHfT5}Fp-T_=wYbrJ}_k40HyoF-WpDyDo z@MvOy81QLpsH9HwI;Fu7RWnwa5?@hs39X=k3Gvrff&emdR{572k>xbiMN8gY$~&4} zK2_W&^EKQA*|-rVQj3b&S|pOZV$t|t)ga^05Q`^yB~{!sBr_g7MKeZqn}oR;MDNXB z+=L7ile$xqy|@eFqYwT|*LdbKg>Ol*nJ=)#bF&+p8(TKLnpB|3YeO~2nYSyxqE!6}RCsN0ALih`cr?pp)#KKy=a%Q0t+Sr4L`bC< zR|qHpKHFNX`=$(`h|K)mtt{P0(1G0n2aNHDMOull4?Bl57YVzp&C{ir+u+35Xd2|i z;;8z+e@%NZ1%T4;=F8CN{Sbe8v4shdL|N;7PvYwFe5L-g9nvz#Mh4i6eQ+j%5c4wrPq&wG0|tZ}Q1g+^3hpwGotbM8!Smw1pUt+( z630*Dcl#L}1o`U4m{b5ilPb&ZFXcrdGY7{%u-PNVX6PK6%zk59prs1Uwk(RK?z>1* zRPrR@&QptxNjR|QB8yq4{nlwnj4?*I^GD1qS`heIKneoXD=Hu|+6TPoW#a*uz$%Gm zsSK4o#03}P6QA0Qotl-G7Z~ZCHb%);VE5;^%|x-6_Pdqh<~Ti$V$Stxe;Fd^z*mL9VpOF&02TsK@NTg+=7 zX41M6!FU5t-`9W+R{!@mAhjr__X9qI8^HX&|{OUYb3QoS_n zaK2KcXS4>#FeFYHy6{oj%d5WEjEmA|^{6gmh1#H;j^D7w8V-VntA$S4yHQijQgMq{Gl^%zy#27p z9L+!HOGEVgoO>kO;|%t%A10vq?vl$MR)U`O&U+-Avd z3TPi2&GG*q6Ceh+f!O$A`5e2nYICIgd?16@edK6AcD*rM74w(OK##51x3MVb4fZG=K7#Nh zTWrB*#s2%OV0_Dn!C_~pyU38-JG^5Wzl?QeCacI{Y}!~&@xMR!uiU&LekKaw`P}TT zJ_YF+6D5TEJ!o<$zyBMDUp<#ngV+$O7E}C!@GTMJRfVj6rkDf%3fvp! zssX*=KwGAJws+*2W-8Ce*EQx=v;{L-4M~(V`gbI%AN#8+i4leVyCXsRFYgDnp9e-B z>F7&tW@MG5u$QVDxNX?JtRw-$M^2xG4GjhzC%`y@sMul@=!>j7diUPyV=v=QL#4F3 z)D>OLkD4o!NibuhgWT8nso~U4SOITO zgj%ZHmpSo%2Z}+MfRN8kLkm>8+r9u0tJ(Ja?z;5{5E?FO$zb{E%gnrSJb1-~Kbp(! zB_Z+obWf>bqBguN=SR2{LDmI-rnb_VVk>l--$f5Zg6>8tzwIgWyr=MbY(pa8oN>&( zUV&p+6;aj_HD3q z8GR|`SG3@gT;F>5r~Na+wwVW|ZakNwjLVd^yLaE&DhAbi0Fh2%Hw}jX!SJf9jV*oJ zVb!ey_0cy6jMZxkLY$_65C3B?d`=Z`_qj25dM@EEn{{n9>zk1ax*r|jPx%MHIvLQc z_gPljHQPELA>p)h>d!1$+E3Rr^(?tn&jOlGsoh<#8PXrl@DAe|x=`vY8j|F+XQ1kfDBnVIDm?`qb# zkn3ml4x6@i?mGR!T126swD%XhjCvMgCQ#;r&C1PBoi7J6G1KR-yqqwXuSXV&9?RG9 zsMFC(VUVA_dKWZ*<{2&Q6iAjLnqfkJ`Y|~C=?n6G)?_pI9rp?tCz|3g=4xy?HrmL} zd~vXX-IF^>J<5NX3K)u*k3c8CpVvj0u|ydDqS!?K-KI95vJx@j=DXXAz7sKBNH(%x z7IPTdALk3y$)oYiG2p3+A&}0?5akjTpRoR}3hPq+*mw*}O4n}x0-HzZ_DS7}pz#7o zO@W6BIkQ$f#Id0~N9c087O(xK1}i&nDF;65PIRJBl_HPYy%rX4A?zo;IKEO1&-wJe zd=MB#acJ7N#!LaLMy}w_uTLC-=xVl|0$Z6j-=~Io0fq1p_0y!oXX&F77bAMSzi(w) zMxPsS8)?Obv_zzygutk_$7S4#D70YAn@k(mzgDke1TigSY~5wlu&-~t+-be2Rkyfg z!Ryq&=+<6%M}ubbUH4o{|0jE|@5##<&nGzTw8&F7zmGxJ z`8~YEo|W9Gm*`?hdioE~Y8VM(_dtHaGFyOB{j zs}SCCehZf+ysI7jwme0&LL#@N2|4j-mwM$Q?0IKS#9E~~)`UU8W@84s8E*!1*5<94 zkf=WExoVEPc{;QD7dBN-yiN*GE^POw{H}VDrNPQS>PZC0HaG6 zUA|Yz4@VwZmG*}PB!su*z&sN+l%<>j0xTcXo{F!|Z?f$t1B2~u$R4VAIjn63biRMY zvYkz#Xnasi@!Y8q0y@rr7FV2`y1zG-yvDmB!%*C$Y;rid|poL zP5Td<^QztW!i!qu?5{3Z3?%=%F@4ODzX_z$#oz_K*o-G=_~u8gEGxOUAg9pFS)ry> z@j)h$i>WxDyvnJsRP2*bRj^=6jz_hdZ3eT>)DEG2#8+tCl4Zp?&l=0!2Mgd53tbS8 zLvnr>j@4dyITpPrHRt*C8}GMJ-znChqmSTXM$Q0E?u!)E!u{ z8CLO_7j_TPp_Ac;iQJ-3#}@2Ya0P@le!f{OHR}I7Aj1S69_Z$mIqg3&J;1oqtQ4f5 zf)73LW^6w@6$bC>m+5(d6=>_GLD=(tZsM7+o_oPym~T6k;vL_7m_mZsh_039D&Ga~ z2d}WSuaH7NOADE_r@}e{onbIJpp8or`)=CT!CZgX#|FLgk+DJSHFfBL(;fA2rHnbT%)<@h>q#ZdUKqX939F1+23526} z66+Ue{UE!2vy=NDA_07ckpqrCn{}hVxMHLvIv=}}auDgv-xYfOcsuY#hP#f5*#Hjy z7Iv_)=)!RVLQlB0@fvEH3`>ZI|A4U-Ge>Fns+YzZpwWWig6QBGhEb?GW_y~dMOmMk z_#bQ}5Q5}3bn?Zn?=QKPZ$UdNS$3x385Vk_Xw_V6b~xJam(DKnJtqewXh57b7j)Iv z=hSB6M<{Oqr>p66c!J=5_IP8TIY;ucV;E?s#{Fk-F&#l@IiMEc@Ynmm6bNubIxLws z1e+3QE$m~_M3zhL%Q6yx3=3}B6BYBP{V3{W`?0##^8&=(rIpL#Ja%A0`HyM>aC71R z()Z7F;J0_*%xkauei6I`Ft8jIqhz~;kR6sLb!Bm{SJ^nILa@0Klrj=!nu7ot2W3rs z=7q~m7>FFG3glDEi3jA^DeYV4Iax{-e0Rm^T7ATJV&2FZ~M+Z{M{m z=k;`*v?k44At*D#78J zUbJp<%+sC4bNM)diRLVgL577c%@*wtfwfBMta_7qX2sV{AKR5*N+~z&PD>Znimw6t zpCdS1z#H5KwtW6Yi9miB0Zi`ujdm5G z-_=E=+fqj(`mrct%S$RyM9{wfiR$MqQ6CJU$3f~$0^2Q$C!k)94S*@4N`slv6$#!X z@P6OcWHIC@UNw)~@$5sZlw5iSVivBEjZ7-%(!mxepk0Z?o$Kzylm*wmrtIl!&Ris>&Vhsb z&8KW9CK2#)j@D$Pf7t;*daxoUSoK${xeOXr&ywReGG0GReZ8I?^FPr|uM<1%)(gAJ zeVd)znLr*DF{jcLvB$|%`ZDbtiwXdh~=FC739&+m+g&FrfO4clxHujv6Xb2I8SvW+WC?gQ|=_6STR z$o5|I#Kz0}#50EFztKwp2?!I+L=<|q7pBwy0i4M!faS7IC#1%&EF_*LZt!Qq2mW4B zlkNyJUa~r^R=W9h^juNcx*3kasd@2n3U1YiC)T@B;Y2C>C6OUNs#EMX*J%=&dl6ZI zR%>e$+Peg(G)U?#vB%gd0ZlL8-a(qPV@zK}v6ae&VCnbvx z!GanwGqex4xRQo9jG+pxg7B>ysbZqQzyPNA994QjY-rzukSrghgs-RQN}@VqoE3Mi zMvLpWrItr-HzkTo?5?~=-oOtyJaaZUiMe)M$?qKGAMxM>&v2k1Uz zQoyrS1WD(q?>H|WZ48Nb-eSZq`;4X?J|Z$Vd>IU0bK^e4mBr(IxjdhN`Z%>!-V!F0UqGt=u^2+<=_xuUp8eO7EJC{~R<;$?gA*;$DC;}(x@ zrz`SKc1|;I&vuiPxaBD$L^QG}cFj4n1O>bEJk;-o=o?+e?UaTo1h6JZxbblXtyFq`6nKORo5%btf06PUh7pcVQ3IKe>nd4mz0 z?s3-6&3A#BV%2ayI>u{lX>HF|KV|I7chRT4QholR&g-EJ36Brm3{bb}^{{KTa$eBZ zbhsnyzTa^&LU1rQ)>66N%kO>>B-#8d6YWTPl=Whn<^G>AQ zDD`JeKumDHE~TrA`;S6R5JBz?)viA<;|N?y9EkMg+dnmX3&D&{n&+`8;d5s!^06Q; zkatpIVR2`1jd2<@q zUT4@VVx8)}3}K)*O=726Nb*C~G0;M%;}EImI^KKrb+;b$MSX5CX7Ae=s(qnJHW9nH zQR{>HWhN@$;D6!;|3pAB;Cuqmf}32So;HS79}bsKyw)+FmlQW1ipuzy{nS_spY~VX zJ(diAXx(kMwR+7(q~C6|)${%=dlbPhqSi>i?Z!W8-nXdQcWZtMYP}wED9Wpx&+2F& z-_!I03BIoF==o{y>E!vOO|8vn=1}Vw`cy<9@TP3_9h8SmKJ<4RALOCwa=ZrKsst_x z#&E^CM*>GhE`{@{^kj$-^45vrBI?gKEQ1Y?!!gBSi?kn=*XeVRBDhDjMR@U%kHU;( zobu9oE7&6R`>elz@USTE<=`f`yp=Q9X{3-Nr^9X; z3u9O*mTayno0Sh@ZvlCmDx$sj|C_{@AI{(F5WU%$y*f_VDX3rmBB5*}Ph^^V(p-~; zJ6Terb6}O0uoIsz=*P)D+V0eRd1w|CDGZmU_1rr#JE=#JN>kc;8TEWq_SA6w{oUe4 zv*s%qk-xbqh?3T-KIe_p!u7kCeshm|H~*kOGu*|T&<^K3nsWs;6`zoYfFO^>FppV% zJH23A)iG6-dH#vD?c&CX+D$vjPF(Hg6c=4NFZ-t~$95S8)jL2L>d#CWv{~77=*;p0 z(LkagGbIs;A!|mRPn~Yt-&nKy(>LULQ^pQw3mV3DEAv+AlEz#(m208bh+b)kGzJ)i zQS|+5D1F??b=2B>Ts(Xf9g~^GXhwy&!-2VFPzV5SyrPbZS)I|yDJXfxOTwr9d#~H% zsHE_Ui+4ZWpWFLm+dzNR+T7&^=Ap8`(s#s8C@)k>B&^zIundR;;T0O zh3$a}BY;Y+c6s!K31W+^^v?qKlX?Y(9Hjua%pT?C+Z+B*Tl`MT_p^!`)=X;i3#e^)>f(FAaR$d`kM@CD;dTemi>;=5g1lr!E=^YMWDo5P2$^wyg63-~8un zQ}v>o+SG?AmVnw0^trIns?HPiOPYYAOek;QBC-2?3C?J7b1PGah7G0;N>PuE{J~LZ ziS;-)A5Q~8N`ub3it3Og`C4ppIaK?%!z*#cw}j8A#$Sa*o>$#k+*(ZtPc$}pnboQs zb|@R3cy2FQzCLS`JNhWAEe>*xzL&aMTTHQS@sI26b2SSyUal553^u&CqeU0v{PY7c zEaMwjaLRjfpFHr>sJ!o)(<+#k;aTbc4r z_21f?&jT&KT%P7VpGG=)Zk=nTuUb}J!QYOYWSgsL*C%~&TJ zFwtR7u3A6^Q)G05BfAK|g<66tWZ2Tiz4V8qP0rCD8bqOh!p6olGw)0djq`&yqPj&C zX2ZvltY77|2wD<#E057+XvwfJyXK~E`*eCagrEs()#Q|ze+UmJ}&Mr{xY?Y--r{oqu z9Ik8itx2(Ju796d0q6S`YR(ONtdi;|f8Qi{LV%3*8*G@cXt~sM$k#%t3L-i0;_}=C ztIAu=kvdLPYC~+B!=O*$dKpAYVNSUd%sPkM-B&zS0=2zAKDiIGrS0@K#^&YO_P2XD zn}7HFvLDOJKK*t701h$_4?#BdSOfuQc){il*tYaM8&-zrd5`ZEI#&c0#rxCCk%WZ+ z2dMisb4x;`pN%?F^l$U~ncy4)03>ZRh8sK^Zu=1AvMOlyY*oW8_Y*(dkI z_PSsh5Er*&Lvq4L4=_%&5I^V$x(e6#-DI7Y6UzwxA6J{P3<5&|=(&4UhtIWm_t5GG zz5F=m_1vSVPG3-Jt$Y1^I}P{Q-o|?2ZYF*^2Xwg&YV~=VC(FmrcHDaQMLJ)0nh7ri z!Z$;VH53!^6glFgWfv*^u7m$+W3?@OZbx#?{erjdVI+OX_}z)~?xiem%gIN#M1H`- zEK*v%-UqnOpxt<03X;E%vVJz7eV2nu-m7V6wHU4-U3l?fTh@0wUBuj}Mi39V_rw*> zSN-FzK$uGz_+pbsmznX5MZeW*{);FwB>v#J!`_0~=6ah5<6Zh@OBVP!YN8~`W(C@> z*f^3u0)NzP0;AIzXw&AX`22C(N;?;cwln!k6Qp2 zK2OaVZ}dtx3O2WnlJ1k&0QEDJUM$7?9O8anxaKAXwba~5%!1+9B-#Sz0|mYKNc|J` zK$V(cf@42kX_NN<9!QcQe;v*=rZgw_DNWC3Klq!kuJ}3GIqssgnISENT-FiJ@Kxsc;jZI)_ z4r=x+4w*A|)Mn1B2H(|bJKSm#E?*Y79k;C`J(;_Ax~*!jw#1dvT>pJ-ITYJ|$m7tk z_U%)*<0n^E#RF~kj14%aZAB@jErJn?*Tnd&-$Zikm}i}5+KU2&a_frN>%&}^hAk*g zC8o(D?$iT@A@0l7P=CO^#SmW~Mou3hdh{}mD z!W+}HC>glPvQe!dqUWQ5SY}zMHZrZS`-q{0Z^}_dPKOY)ysUvhgF1iyZlp`K6@|hYc z&arTqSTuV`RFn+=T>No&rQ5wM|LOi4dSADH!;wL~u`?x5QNNp3Hht3V>Ycm4F4N?K zblIF2C_>)#K3TaP?~4574KD1wh5(){6$VyC7ZxG4qods&nRcOLZ3iW<;8lK4#(B(l zxon)byMuLWyk3>N(yK#a&O0M8yxfK<#i--vWPw$5JEp2k8QfL>_hyn-3lvYpJgM0n ze2I8(0Fpqr0fMV>-$H0jRlqiaH;YN03)jeP1}T6DQU2Ln#Q}g?!uuSvLw{|iHq&B% zu>*DtY`RGS67@Ih19CbUS80IS`J{+G*?69ZS6auYS^3kWT4<>%b{9w_#KKv88gdvI9tV^4NK{F%Tmr zhJO^~P>ua|9-P(8U~Fo$IW<0hj}T&&)ufviPV&_OCVr#^ED6OKm-c*%o#X$x zJMrNJX)g^G8TZ!}IXU?G=R8F514Q1E!{_+*qlqCOqoNH}T5sUY*Nf26Pe@5+CyDEg zt5I?IDW4k_A@maNqboGNVJRU1HB6M(P`&S3$MjUApZPSaLmcCl31w{I0 z|1Pc{7o^4W9R+Km7vsMG{I*>%)GId78|j;?Yp#G@O#3YeUj4 zAJ=lDHME&4u3`>%cdI9E{eM)wgL~dv^F7?8v2ELF*w|)c+qUgAPNT++t;V)(+q`4r zz0YaS^ZmVlK&~r$-}9MSGi$Bc-FxRcd6d)oO-ERke;Z$N}Iw;b}0`@?8=pvFX%B&tX?a<&!l69$?R=1+(30F4_BO(i@KJH z+E!q!Y~iV?-~SzuD8PdZI9??%aH9D$Ozthb0zzVB+UVd7O&n zeY>^0LTj6S5JUN`Q_H1)%@@+z>YEWG1~?`h@s8`fN;7a{9MOjs%Gd1;C75!Q2$*)L zetJi@hKy&XmM)}al`U)F1hKU;)szi~AwG=}BE#iC2>jL|eA?brV%|^)7t~`Lq0t+3 zFoob_;`Jx8)dJxP@Au^woU=gV@|_jVphMGaoh2M~{lV8NOjq(z8`oglY)$|r3!>K` z3ruFy(*LhOM@D}F-|2VlZ_@p9u4bq);jES=lzZ3`eJ<^%%I`ltCrB7Gn8&?8L9d-W z>kaG>#w^HC!f0usnTcJsD(%|9$;0%Kv%up`%+I^Ko%PVxdE)ozb8jSeMwi?AIo`zE zbyYXDo}65iS~bj7b~=sXyJvT>zYX%0tqF_;HK~G`J@GDOPT zv;Xu0VlPSC--S|U;a%KwtKWh22TQu@y%+&!n~{J`F(PjM*_)FBx6fW3d^i(SZf&Q} zWeSJ8a=3WJg7r;?rNx_Mz_uEq24hw8j?t{y@Ltm*@8jHX%9ozIcFL+SBQXWE!7oH| ztOo+EIiy|w$Ynel88jc28)zpZ0-*#(OYP?ODhwWCp7EOf>^pIl%da0V++-2i-k`Np#7w!2uTlku$mdTKEv zi$P+hnsNXSDrSLf+Wb51&JW~qY>e>-Qb{nT0m2J*j?vsQuI%Bj0q%lA8Z2O0lk3Rw zyjY5ZJszda*|3U46NgoZi+^;H|9%N9|5P2x;OxJ;zfT~0C8H%oDhGsCSb)Z`Q56FY zf(9X?26S@Na0881ZYE>4RI3d1o9_?0y{Rq{b}0szL0dveOswCT*E>sk8?qVc7 zaithnf*f5DN922-qdunO&IW3}3d>Z4*t!!q{Eao(+^e6)Z1D(}9x2ll0B3jZgW$SQ zOqHjbUx6WjV{;NejAk!e;G(zwZb6nQJ-5i=j$qY0dS#5)&81MacgJVpPgkv>)(7wM z7&Ps&;oq%Ghr^ICqq(2n+2cilLNjM@23xhnj08e2PQa7sZE&1fk3MVyDRgiSueP<% zO6g2;LBAHB3{3oTo~Zkkm`*7sLl_3lgKdUH`6a#B2+21W>h%9FFW6;B45Uf=9SfTN zXu$)}p!T@rGg*$JD+3^A(R(;StC+H&O79)uhT2S0vXj zTNk9??>_N_7r;BLF;5w&yJ*xoZV3Ph0tehNjS^9$NqeRZ&Gi{&MK#OJW0CS;(1cJp zDn*EKDd=Y;Jx;cjSP^hgJ3qIUqfjCTg9L7j+a0Z|DO>FV79=( z2FiLtjVP0rxzR4GrjT+`*{{wbouhWO6DZArXYR~CUa597M}o{TEs>IEJnvsj5})Wf z1I^i~fNz}SX!R$w5YAxt_EUC#254SH?DoCRo1Omo z`PF;C=$gHS3dy$EOEL3t^pue=s_lQCiFyd4O^*ygg%zw-+`hX=w5qAUrD&IF zo|T3_wv<)+j+~<8QVu(cKhLWODZ}Iceu6{=$Duq%02nR3BTzM9`$*e}x|1LO>{o&c zT!_$P;>Ygx?YE;b$7#t985IeAdNV~t7===n%XsL! zw3DS+BeZ&-O0rvvJvzQPv6^l2t~HyKil+S0nGB_|tj_@Pz1WZ{5wqlQW(gnVC@D20 zK7|+F_3Zy?7jC49Qv3ua0dgF;e`)YOs6Ey|chASmxhNmzUmWsaJ6K@jd)qU2jqo^C zLIwQ{lU;6)zyfAug9HtG1KH-vI?^aukJhZ$#kFw_wa6Y5B$h7L#&JDGUic~gHoyZIJkn3(tO4Texz zDvtmJTd}aP&J5V@t#5B+N`<1>kA8$f_7FIiFLa?4^Uj-@sJ$ayKCwq1GuG&+=H7G4 zs(GFA$(j)93j@hG_HJCfnVr}V->-ISw&P_lwgx6yo%wBGbS|NXXZApkkK^8|hGtWB z&;ho>jH*!MYJME{XV)g{01{MHBV+~OW;Y+OE6CL@0W%|jE?Dd?E?eHL`*uY2FrW4c z3i~pv9qQXAyw8nU5qeN~ZEt+u-|k2N0ctBHnmxMHV-`3*K?0N_g)N^YCcS83nTwi3&)?sTuN>vJrPF)bs0Ni|}s$XBEGw_g^ioSUK z{E{NTPSZD61eZBDCm~^eff`L-?=)6cx?`>8HO*!vmL;s(*z2X}CFLze#D0Vx-pfWS z26$h?la_j84Q6QzZLgZRSW#$nay3!443*N<9}n=~9P4GY%-Ej~F@cZ=FqmLjNe_R+ z;^LS)0W$D9MuRQ`_+}$ zuB?7AU2Mu67L*Je(y+VDoe!bLJf=I5jYVcrss)YywXy`jg6SKDz(FRQe1V0Q0CpWu zynnGw8kplAGsx$i;$91T`QrN?_`)6Y5-XKo^0)ZlB3dQt;E zp(RGc5=C?i_O>Cnc5s(07^=fcapnV*T~*2?;C;I3DHJsv7gi8b)l|L<&zt#rvF{RB zP(;paUyAl(N6i6Q(o*8w-hxwNq?DM9p-h~t6O8yKYaY6Y$J0Yr`$34+dU^Dag3np; z^`R2;Wgmu7j|#^%iCNSdgvCqVLoJ|$R(SjPdA$9q;wAM|OZAN-*3|dTG#6RF!&{eT zO|lAcNHs`o5%WD=9Ots!z#YMod;j`Y1Sr6exZ9epH%)(Q+|LX9cjlbt^s)azH<7Xa zXgT>;!pX2;J6oaB6?Sa|me%j9tDXMS^x}vSgW2fS#FY))>zNvpUdbB}byyn&;=Q*Q zdaZ`__tTik=1Af^W*j%i8)?$2Srr-;1k>#?(a6~MKvm!Pa&N5@rmhqFXcvt*e`FiX)2Q_(r3uw^`TffqWb z&O{I5djTfFJjNA2V{84}(4<}UbM$lCC6{Xq&?5tS8<75ga0mhDk{~c5R|O271+HvRSr2Voa1APMHa8V!8@%=Dow6A)VQjI zB0fNkW&|+~KxkPm2H|d?((@rPKe!DglrcyjNoE!U&Yrb`nA>inBg$rxUZ#MJJHfhv zA-C6FNU4K3T48A=Kf>F_)W%y5L>8G z`!m!6t$dl{s-K=*k%YdVQlDY`Zt_=mU0e2iB6*;#7hR_?71hv;gUO+x^RD z{nljf=Xv)hUGR&Hf59OUB^aKDPjNF54)u-nv6I+$Wo5{(+6)w=;RZ}hH@8CG3v=6V zG{0v}a-!}e>8pyrRW0b|cuseyQ4jU3MLLB`NE`#=It__C^(eTh9NjP??5iwOs}u9T zP6Vs@LSEAZVx3|`Qx8S{hzv9^C=Mgq7pV$}JA#dH?erX@-M9{C=p34sQe0mjlqJxz zx6XGz-%ge*%za+0!^`Q!1E!+q5lG% zJHh}bhcbS0z%_Q;p&Fo=6=*f&n|`Hq_R8zwGe>b*YZ*j$-C9-jEQ z(NL0>?}?`84Bq5ra`)}kS9TY)FqeqkqEURaCEv?97hZG9wP86_NduSIlEoKDF1f~@ z(I;VO|7UL+jqqn)X}-978ApDK96TW1TxvWA%w95SsrDsLngV@g-j!@_|02H8c>nc8 za6)zeps6z$j~}Q}Vw8Dol>JTr8YzZX4=>KxO+bUP(eABfbDqc&l_!boV;={+C?Rl? z+xvq<+aD5N>B|gNo;L;PuiZMi8U-?rga)m{%ODUbENhAG;$UmFSY0@xjn}I4IL=WI z1DAE=Ec4z9H2BgkHRq$39fP}E9?%mF#$La}ftoe>{hu9!jtInRvpcO_FOUmPn%1~f zU?wnnu(Q_xbbHQ26sSP#F?r6)M7EKzyq!(z>PSB(7ibc9qPnh?n~B>GYXUs4|oWW@~7p6iRy;iE%;{tj(6q ze-A#Dd3uhQS|e4KsM%;lUS@WDchn=~liFRGBiEd_6vp9l{u%>^EoSV=S|KAtkgVLz z$F7Qb*rl?SI6SzvQ#?I?R4%$x&JlfGV##cxf#zF3j0tYhG?I%Z*Sh@8SWzSZ3o)`L zoC`sG-Tm#e72{P5K-8Dt%PEy#H%J}dmaH!JerxwWls4K3{-`B7(>4hLS&r`=S%|P0LXFUt9;ANCeD5 znhuR z{}VG}pJ)*0+Bwm?_WHEB<_w~cVr0akD8}!r--bU>KpC0-8FNu!ucY279$F0ktcr9d z>$g82nQr9|y9kj7H1OBrLY6iYY1e}Ke#+WP6^fkP|A{5rwgWT+o<@-xN+hO~w>jKyMiUC6{0deT)s%}C z6nzf35ovd^aYAy^xjP*HViBO~Pi%f1psUXQk!=0~biNQ2wwU4mJxoZ1v zDyh4P6hC~sP`>;$-;&9qS&8?M=_tAFKCz?=bSSvX0{GfKHeuEwGwwN~e%f?^+@{%= zOLPo9@xU(QR4qkSC+M0enH~L5Jjt{~)`OMn*t(IbS;77$ZmA~6X3M=zpje8dJTB#a z4|QpEA69^AN95QY|4_EdUs2ySV1P=%q&>sjYE;Tr5#30tz{YbBTGhf>bsYy6obQ`< z;#$}UxR!Rok{3^o!3*28bsMjD@)mTFU%-xgI<u;*(pC^pv~u8U53ta=L$r2k!U zKNu3<**E22L@SMQH&$J09FxfRYuSX@v;x#|fdT0#V7pH4D%gzwr{hTli-;EDYtOa~ z$TDXe3h(*0o7OydbRVHvb8#dI6v^v$O6`edsQMf` zOQKUAmyjr7FCtWgaameu2OKEzFEBgE=kg(&Gv7hXm-xA-+Q3cs#RZKge7q_YT68n9 z*y^0H4`9cJOGQ$Bjl`V5!@3-ydNoX^Ev6wn^F|(Y@MAV^aNX8%O1*UH9p>tF_`T}G zQ=V+rt47vZwqyPm=2X`~E7Qh5r0(U3`VrdvteK7fkt`YT*f&GbwSG+8mHy~SRRjO; z)pwCl_*14Cu%+KaM94T9n?^=!+uz1reH{$u*3S2|W0A1gbN2;YuC{9h|p0K7;ztGCE~_n zz0OiqtF0$fUm1Ac@r!#OJ6z`0qj-0Ib)ncc$u3sfcd%7qWiXv)TophiNQ{|=otpg$)_*0feEqD+hI9FDTumY6bDTJ?@7 z^p5ecakct{cp)pI#j0gC_NBL@*Px~~r~^m5KN$!6VSVN~0f>F=r+|vefl=hbEV-b~ zFuM(_2^+Q8j=G)O$yjdH6wOI)OJhDkQ&PB4V{@BQ6Mg5)AB%v+ix51mn{6N~Q-}Oa zXZ7{`$uVSf7l&tt(KVmzjHl7BN^(U8aegx~XWV(sfkmc^aCBi&c@aj@S7G4zsGC@iN?WsLU9>Hf1DD8+GVByQEo{ckn;aCNCJU-O^3H zP5Iec_AuZExA8KW6FUFtNRdsxj~a}-w_8|?rUSG-`S$bh zVK7U3Kq2yKFxm`dTZsGO#}$fnkvC8c7r`=e5-X*@7Ak2=Bg~j{mMrkGR#V%wWBYN#T zA+|bS=4@j(cH7T=>w_W&?IQ7Jh|w*1aKtfQ&FcRe#DP)7NxXG?uZElZD7_aP{^1sm zA)?LY$wN8oG}SLGFsRoaX~v>W{Wm%Gk;gTR2Fv+#WjQA&T)N8DlS7l-@& zf&RXZ>HXs1UF>QW`(?MwaI}Ksx10p>gR|hdGeY;gRXew8ZH>Y`DSu}_j$Cr!xyzdi~Z|U4w#iyH)A#You z@`JgCsAF+*Y|IJ2v~0|&GAB4sgNO{@3ceC)SIBo+0i}o?8qHQcip+Uc2QO!Is2=b6 zduHBtU3j0FxcRJ_-_MKYnB^~K$Jzw8JzC@wP-y?!6Nmx|q<$HSJj3oz4~XE-DUztc z6G+YZ-;D+XGroyqPP6R4ed@(O!2%I@OAvCA`K=Sz)!Yz|LKJTkcVF#6KqI8ZauRrK zmG~2z*nJY%t#7kj?l|UEtVDe+j}*dT(uv(7K}5xcfu-U~)P#Y97rdr7AYLwdMl1cIx#7vPDb3sErRb^>Umxj_&nlVn34@c{ zCy0s4wcYZSD9xt^I!kO;v-umL?kb0U>;n(LDMK zLH@BF_#DOOb1k)VDIp6(^^MTsRZ4Q?1HagrXmkSGCu4$lqv1>L!Xj?#|3}k)5a2)k z_2~9)x4GRy5RX}w|yTMu(aj0ltb%dwy}+hY`QANAl9x=`)U zpF^?{Z8EOPV1r@cG%BP%KKuX-weO`)FO$RH4j#b|P(-uj^aPiWLsxejhs4gIRXiu> zAt*^DuS=pr&_$Ax(?wG?#yV7|VphFD0|wIdULxqJD#EfEI&zt=p4Xv_^*#gE6TYYK zoxuGTS-3xkPlt^!LRNDE+A!~B5OL)4uBn}ZO1y8*YBkE^<)gBeGsEKNkixAT9T90G zFFF25u|7f5frB=@2Q3ZU7#5PNS=&i02AIK%Gia!>IS;Wp(qUqlNeAp+F9~OKUL+3= zH2>)n0!+j|0be6Z?NPI%9zWxk%)|K-sc+3(GERL-w7~6!bG|^W*v*^D5`Y!7yY17| zx-vKc<1~AQzVbR_NP?Itj}INPyqrFy32$BE<=Zgmc>C)y1u}@QtiLi*xg_t+A^&7x z$o(c2lZgoq(owu>85eqy9j|E-gcJUC~N4=97l z5{4QJdv#HZa_&|#yeE67t%PQ4jDnt?yJJLJyUI7lA#Rb+^sZ5}95b|%9ZgP4Uasw{ z;B?qC1KfAik1TS&(Y=qP8IaWQuBns-$59<{FTlI?<5R6B0pHV(&h(}MQF+X3nopFs z+R^;`+2{`=KhD?@zLDC|+KK}(mA)&Y*wl1dJ4v4!xx6tF+P%kB4?#|-CliCbTQ@aeoHVDXQqJsdiBl^XWN8lW9tPlt54SJxc^+kfLc124(mvb)HzO+ z^eesc+0T_#H`TkuA{$=LQuh9erB=Kv=q7GY-ynH!`D3~LAZNhz8xntqf58HabEWV} zkI5ZofBquJ2vGie^?b9XkTG7;3^wp#?RHs7?F-a@qCblTo7pc3rA}%!=Bx`kr-XDJX$(^b$q`xP(=@!Qpj-QR6odZ7YddL=~b7k*Ds z;SEsBUIxdl*k9NVFGl>5g%`?}A~klL@ae|^^G1nWrfm;3OVoi#UCb?eUP-0Icy_u1 z#YP&uKZkmHjpK~ptUAf%25YQrf1jXtTRUW)3k!2HW7ytcb4d~6#-dIFWg;NfJ{mpxYqfsBcjs!fcKQw|GpyBraI=neeLwpn8{^^V_v?CqdZ+1T89_(%##Fqko! z>3%T~q!)sO$BKq$?*0I)=3{eq&3|s|`|+-l&4Ilh2$68b@lrRx{Y&wV*!yv~*lL2_ zxB$eLNFUFMBgf8N)l||5Nn0D^KTs5qfzq^q*8k`=w{usYLhPMiQ^zpuYjQq(BzfInH!+tl|HGv)stycqMH}1nMTuM69Im$VLZL z;qK{zmX?|k-&s{FYe)AI9;$zaqYAc34;4>lot!!&u-T1AFxSEik8qWVhlRH6NmND# zg&W-YFR9NRPH2;8bDIQ};YVRs_BqQv>{(vdM~Org@lH?p7oV)U_0sws<8XuI+yE;+ zzgg*G^WL_h1$?{r`#r1JU=E&NLM7_@D{D~RZH5K(p&5C`f5Xyh)B}G z1i+m=K-o%6IM?!$C|@NS(eYt;KI?pn69F%|p5HMpmmWxGwW9{b5_rD?J92ot9o)#fhSoFoDbT-oM@GDy>v=yRtfMlc6V&fv-m4S+y&RwJ0@tWAcc%90= z0T`2OsIp7JL6qAN$p0Y34)QlhxpKD0_%@J9dLPT*-N`F=?)_HWDvLTk@SvF5>x@rj z&TlF|jH$9Tqkz-mHmoX~#eXv*SsVq(63nCphyTM`$MVt zju=)O=W@31GJnEwn9}^5&|Np7vBG=}!AJ7hF;^E>MK5FBD)pINUjkmsvJLd>8VVmz zD9DLcZb)9{!o+UbYIffsP$`~4&sfMO|C`_&%~eFbfHQpzaDtX_r!nOOj=Z_j{s9|t zavEagizT~_n0{Qg@IEBScR@EWNm50G^0xdML|^0^)%**A(DrFBqxh5eW<#gA5tfOw z+IX3y8}M}TM%_*fj_q1{)U3t9~h|8hnkL*f9}N-ip(w5pEN)&+mP3(e??zWgu%)%TH%?!$(9koY;0&muLwH%KtSnv|oMDAv{phd2(5j!zAWa1l;I$TmTVu~>9S)0Z= z`T!_8wDf!Syuoz_hik_)t<+leEYiQ2jIa~Ffb9o(GxB^8DLTv+>y0Ki=c-VCpADL!@6_j*~ zZW!f5cjNxpr;7yC)lZb|y*K5-D%;<~Z`U?%tZB6o{<{*afNXrP`$Ie4$m2yd*7vtn zK%XELO;o0rL$#L69h9^bt?*XQ)H7l-T1wGeWONDyh!_%M^y!e!pAq8`xqtXfMBhM4 zQnL2bJc(8&#llhnc5iuZ7UIyka=;W*`$ z>1-&kq@3Bs@9Ie&je4&pv0Gq%A*56U)!2oiT0AuYh2bU~6So)R`10nGH!(-8u0yJ3 zewv{X=~}UopY2Q?$UQ@^HTEZi+v-sR;FG!k%yzV+mx<;w2&TbHDG)>0dFHS{dF%ZcZO|m4SX=SQIDxQKhd&9+P$L z&)S1l#lhnjdi?iRctB&q&>8(+rD+Otu==C!{IyuG7Y)P5+tkmP;2)A|L7A2%CvgCV zXbGFCDSvCbCLve@21hp%57+~q>MMEY0Z^;ulPU7KH5BS}Kxfk>_$-wEepX67Ws zpg>c<;a@+5;RhJGZyqGefmcK?1Dn6&S5J8oV=cScCmXXW&BbYZTw`wf4i{g_>@;}O zCXSJ>Rx7yZPi(#d6#(SxdTa}ckJjr^2YTrKl6VgzpnwWoRb_enG@#pc5 zdTW;>bZgDi&6ZDJ6+)%=V(}N%`84HTa<7@x{|^n7BSAs5(dso5a>iYy6F9z_n#dsh z_Woya3g2QH_n$pFO#+{;+UmitNpnMq;lHYjCde`!KKk{m3!LV|*U)8UwhGBAc0ezV zv>6;H^#p$E0VCo#fwPdYOFnL&Z~>C9HW6?e6}OcLw+9A~U+}VTmRDI@-W!5&`4hJ9 z(j3A*6V{wsMylJOTAg3}hz68@_i7%*r&Y*STd0#DFVe8!ufot880b@q9n|qCO_G2K z>x|cj2>=c{d;kh9x?kF!$a|MA#4`Jkg+39@nMFrWt9G7$9oa(7~(o<$!YjRU6 zURFxl<=%QSg>&%Qo{9byoy|gXh}@n`=|7D=aPwx`&R_Be!e@Kj4V$g#k&~lL$rD`| zRX(@Y{`RjEFVoyMz=M*>v6^1VepkIPY z1?q11&Z8qchU12$$6>DhU7nJUr9qj#(Wj)Wubai`)>ladGWW) zwB+8flCWeai8M64SAw<*F-eZ9GV{;A1kL&$$okN_sgkjF?q!Md8|+u%ieuGanYR~?-Mw%?eK4w{juG7Ai4 zhX@Fok?BDpQhlURRf*PFv1jhj3$Z^nihG~T_;{S|nm7$uBIG_2G1<|0^+cviFn8r` zmvYR#f*CS64s$cm{8FoEl_$YP^)7pGdMLR0ehO`*j!IoVE#Dwh$&$NpqJ-;^&eRxp z+HdiG)24B?LB{q%vT8jpUe#D^T|7S4T)zs=8l<;_amn3{ox6t2rOhCD)eFsoN~q#+ z?le72vC~~;sl>X#V_mYJF4&7mOwR<#(Ln5_!ed(TptA8IQ4T|WEz?S#|9DDv4$2W| zlVIeV+h!-sH?VoS&TgoK?}4XDDAs`cU}RK0(`JYE_XqYt9G1?ai)}C3%Z0JB?`eZV zpd~0nSG{#53}NSgw@v9wqCz1A*L2PZWlH^Gzz}7pzOir!Y~eD_oBsL5M_L)62HRPn z8asaLG~o;yu8n>GO99Q&hK3Sdd8cWja;=BI(BO{?VRd%m+1fNlj4!tZn?os1GSoM> zEkb3wNXkS?5eQe2iNi3RD^=iEmla57vr^Va0luc4IMOYQb^m03Kz!$*>ejTMP;7JL zyTHcvkX!}#kau-aEJO8`SSDMgAeH0n^|Df2FNWofM^#0g0qk^}0*uc23+D`Qk4+>5BLw;7hBjrdy8{HCmXkrX*X4=mP)$&BLvtz|t1gCQX%9=j_r5TOwA8o@(2 zi-M&y;E^rthc@N=^^OdjfxqSyi@eAm16V4^`=rjFlqx2OvPCnw@V)R@WG|2c5ca6>jgApv^5;xNWRygHFMLdH2+wtO|2@Mz{JO`bR!hC zZ6U)qt1@`ELeh*W-afuze|w0X#KA{}=r=)=dsqfiu_cuwbF;@wZ%P%5N9zyyD?0Ko z-AKM@`5*lYEd9)OpA8WB`HlMV6-Z0locsx!AF-`cU*iL_2P{6UH4faHeWC?Y^aP;f zl#x_{n-Yfysx(N1$|(bGp;=`&dc|PEZo___S=e%8TWV4w%5@aDuVcpyTtvoq?YwGP zGW|G6`x~X7{DKMb5!jcdVe=kDS^+9*CNX`-Ka9*d2bl?Ne8v2ypvmXpB-PzG?F@^1 zmXS0ngbqc&{7ezT3~kBx%J;S_9_~YqtaFIU+AKtK$RD-GXn+Qp{~ne{^iP2$$?1B}vX%UPUI zDxZfNDMr$I>cwi<#-R*@HqC6)xzD%~>_*kqv0-6R-|2BhlSG|nCyaUSGfDijlivhA z+~~jDcro22fTgWFivnKdO+m>55~0b|!s@p#n?AAbxZI0wfh1kOF9(2OBnq_4Q^+ml zjhI!}A?bfKIR6gXVz;joNgIIQydhT;#(0;|_(qe#gAYufvpEBNf1o>A905q#qTdeN zv~zURIO|#&M#eXryM5Gt^yvg%3qG%7ssz91QyI48jkMY&>Cwyr?EJ#7bhooJ&cf!i z=?;RP#A#JL&Gq&zqk-pL_GEZp(gOJmYM{Z!NN7}NEz_kg%;_rnyJ9E_XF~@AUK$Yd zxm94^T+xF?B*17JtQ*;WX}LzzA<5#=(<8E1@N&6JI(=^*aJn5??DRC;Z=FQfG32@p z1>$s|&EQ*tgMadTmRj|vaXmvT7g(Vphla;(NX>CegCpE+prpY;acPN%y`rHHalGsb z&J{t;fEcKtb>O6y2fus- z(O!xMlETA6A5s1i$6pYeWi{+WX2hVRdP7?J0frIb@6lFEwc}6*!Sgf+72w`^8!jPF zw9pea&0A-iH}V06aT39B)CP1oqVZGyNhIpNU^2oRDe@`pKA8a90!+!%U}r9L(cOTn zx^GLFztc^r(-%J7%t7lGvw>S8=YnZqqzNon>hN|x*YhjtBZDY$$YpUURe7r-le;2m z{Vq&?Zq&6||M;!SX}?K|Z99YkKNlMMMdB{>LCuUqwe2Fj5Spzrq}s~wd3Yh+4xIrc z+Fkf?a)BD$=&c*|VwALE@O+XFJfP|9@@7Ho!QU`F^MxB_xhcK7l-rziJ>l@3z;OiWpPaK?CStYIyq>| zRdj^KjsyE74GM=m(YzKiQx&vj-z!SIfGX6_&={kP!+vEL$n%nt@~AOE;BXd5aa`s) z{kJM!vJ3mx6<&?Ecws%ynRIv+N3U+^!imfK7`jjHiR$N1`*QUm`s1Ii8>Nc2Q{5JP zY3evQSLC-~WsxFXY@XiTy^~eh98oq8DK;ZJ2gux?6|g>wjqKrLi6HH+d)-vz93+z# zEXv@ym*=|I&CTknGFAd*gwW#qUGym;19HmcOy8@IsBD)n+Cb0QdZXzoX)uMm-LNK5 zhS!a(c!h22o4-Z14#XTbM?1nzw+;7Ag+T7Ud>M0SMzSlb_b=yZN0WKp*ox3M-t)YcVQ6+yQ_;xSqacS=gGtqYDy<{|p_#~6DLoJ@A0rb`=yMG@HHHLTh#G{J) zPSH~AI56GqAbq*V6R0TJ#?Pj)tx2WxH51JcD<=Wcu2e{;yM3zveX-=AL)yMf}CM;W1WHF?m$@^4#IQW z5}hsiizIz=QC2IP$FKp|xIT~hY^Jhsr)7E;oli&|z8+Anb3V)gHk!F_G6CKn&er72 zY;YTLNCAp3efeh48$yDwmMf9*yzG8gL1!XFP<~CoP7Jif4q_; zna2f%!#$)#gAHyq$Un)5Y$$#4ZKx$l;1Iu0TF$VZ?Q8h(v^93eGg8&0$;5V43fQ)T zGQr3cK@hg+%arVAI2)~r=YN|!gcGTe?xf!6DTw%F+c1Z+pr$XQP$F5uUe%Ah1qFt5 z)VQ)Bo6(D_vOmBjdNCleg=t+w)CK*I-R6;l6BG|5=9BmqilD&0lNC?pmT{r=?MsH- z;SXByhUhmhalgonU}gM@{a7^~i`fGX*8Qout3+w2pBW2+xb-PPho6SarcI7@(VR~TM>Qc9*4UI;Imf1j*yT;iRzFy- z=33!IB<;@yB8_%Zu?M~Df54|=KR;1qn3+N0K-+?LE}o-w9oO)!l(2i|#7fzOU+d;*B4|yAG5`N3RN+ z*7jA3p%wj+MOIZU0A(NO9^ikt?g+;5&*{5NqWmX}5HsIysRES1)`E)$e|+xmLhGx{ zpa_ReT>6-R-r1`><4H{Bw$K)-FiPChIjgYWDPQ1}BEN7#HCL)GF6b49r7T%#)T#MV z$}lVaP}vS|ydMpC<4xn7_IC4(E>LM*Z2P`dFM-1MO=Y;MX-MSB{b?Yu!)+{2JOLe9 z9%)+(W?xMxxgG(!X6BR5L9dt560Fr>iw1daXq-8NF|BE2!x)GEn(JcWJJGaSm}cJ zSL1Yh_pcz~u!hoo&bDi3Owz?vS07a58iW3+wR;|;Foh0fC}8|KX~JhR{tD5(84xY9 zkagOjR%29(M_V#j$TZi83_7_`OE`ba-b;I9!`D+d5D~etrNovO?nKzOZ`BF*5E7HY z`XQ<))o|gJjJ)*>X-2KW)Mel=ju2vUZg5>+;2SdW=@pTi%8~n? zHx36VpmG{~OWTe+Eeq4%9pEt>0y$C`CJhN-)sPqu$_57~{yixNXe25KRXBLId?I+V zg@!j57R&?ccBeGxc0|l=riNAr9Y^Q;@pj6@dGD&j;M{o6-e(~<5Ap)ZUwi~@FN6oE zq2FH!z8ohl#0xS@^cwa_KEc$eQ&T+|I^#uQ>?F$D*)w!1s_F7os9~FVo@DxXy#cL4 zM`qp*N}`j^uzd%J>BZLkv{hxr4YOWV1>5(!H}zjTUPM2q&g~DY2PB$(db01|;x67$ zb+Q_X*5*Su;L@&;MT%lTz&V)(pr($MO>dzHQ!=bi?QZ&E&VVESrv>;Zo2|D&eL@|S zhR}0A#%#3xsO4xMo20%h3jcset>781r-UN#qGF@l+W3qh*2p}}i+jVuzXEG+SiKa- zNh+fquXrLO=od6O{z$d$FDUVAnVJzFg)BR~Cxz}En^658C*$gepqhWyAS*Hq3ge^C z4ZoS-7>i4-foKq9`RGRGm{tcFa`m&ZZ8L~ckR;~&e%V>do{Da0|ld~F`TR5NZ<(5HC@UWRN-h7a(v6@r=G3Or9~_9@Q`7P zdYV&V?jg--U6}@meEEGIj)tn_S;zjkeuTeY=1hbQ{i(q`p}XeHXx_G#q|2%C*6KaI z3e#ju@g?%RM_+p3bVVG0unRsJ%4o>rch$l=Dt^{2?x7AVip2XerqVU!l=of2*d0Nf z2nD1(7NME?d!z2p4dSR~W6O>ag6}AklGp*t9m_>)*i}P+zlwiSzpwyao->{NkF=}Ve!vr0=f+{$Vmpw-Oer80JV1430U2hA+VcB3`25Otvq7s zJ3|=DtNE3B*~4@+ z+x{AIalhwY9fUzV*t;Wq6aEyYBs1&1rX(C9f6?ePW83tDy_)B2KGPLbJS0=; zB?d=io}se>dlV?~^bFmg|K*?OY4T}<9oHxI1m5SG*b6aaSYru6`Z(uu>);- z$LZfXRVUtM1mi2^-U31RV*OOQE;km6Qp`)hu9#PSA3?vCPix`r5wZkDR~_g+sU_ZV z1>ncU$yE32pYeNtnM}k;?+NwnCcrqR*Jnz$a74L0-RiXQKtx|NT+s#f`oqEZ@UCR<=aBn~0|0C)g z7z0tVZ5`WA$F^-d9ox2(j&0kvosMnWwrwXb=f0UUzoDu&*827?Pob-#>4~Xu8nvh! zawo-LN|pR{7}m>AF~d09*G7Zq1L7o!V`l^Xw^}Q?{KV6P-S9iNSa`7@a2t%;IO_#c zGZy{NV_w2UzS)lJ4z0yQtlq?~~0+Z2gRvp}K2qKn!%1fZQX^#)5V6#5qh zXJBG%EV>>rw-7o^4ZgMbM8 zF3$;$h#oF=ikpO-bJ?e8UYp*Vk@{o}5W%gN`g9=1NcuNa@#@Y&e; zIxmN(rCs3tpUUBY`c?Fv3mWp9mzOMZ zMFEq9%PM^@(PP?qFn;2aed8{qc(pURBJH7w`lh=?aS zyU)IyK`fn71~kS4b#vR}YCWg*-Lbci!{J8bc@^{Llcb~S1xyrwHOdiN?oXcDexac@ zA{M+&CXP-O!(O=8jqtfHt(}^x^C9nvpCIG;mWtkSjz=VUBG0WTQ^xU+h1QbUrz5) z@9^0$S$u8pgICL4A1*$(-QT<0FIm0+h8j0feu^m&k3fHn;aY+(#pM~rLZkG758zE< zv#L{d#0~Bk4t1s5AIjvwV6F=m+dgRKI9;DO>Vsx(GXv#9B8tfvaw!>dfHJi$w;q#U$}mNt$DlMjoLU} zwi|II{?}Wx&)ur*cJZ>rmpv1F?hWn#^;JJzWxW9ZZo{|!&`Ij?AnxlMj zzBS7n%u(pig}xZIP;56`%?|o+aE#rNSO15Qbqb|3SA_BprIsg}6Q)=yuamFORmh+f7|Z6io>9jhB+dIXRL8Jp@=^B@e2 zXMgDZA%b8)^~ez?dKsu4%44y=Q}%l zm2`wXjJ|`9?hT{)O%QjU)l6;=s)7i5Y-=~VNt`S`b{}G~)SmxwM7!I`ixA!X?jCv658| z$Jqt2;UsOkrlDuv2BY-_f$X7+wxoWEJY)76JqZYRI6O4=whf@Ux=#*XXHMwu<(5-> zyWCEjpelJ9cL-k{lw|Ak?_we%od`))f9oC``q-STRV|Z)pWED0J|f*RH-FpLUIAC$ z0O{nG7AR8!O;1>N=`>i56w&bd^r!GKay61VLRJjIN#0qWY7RnEBTw(99j?o=ZfUK3 ziQT{Q9ZWhMH}Y(6Jb5msdx(`+$E;~{roFHiMs7uzZmn+KO+_C?aiv&Go5HM?S|%hI z4=pG+o~eseOHwqKFRq9yvbyEfzW)~U{&S!_0_qo|NuqSVCx375g?Z1HPqq;3?UnbN z;XOgUs0p%AiDoBhA!kiKW#t+ntD!r1_F?ePW=k_r)8QWK8*(QxpG^?63=|N>wCv}X zM8UC$7E6_f72-5kNHCmp%i)w z!I#79tag_LutWt;@ zENV(>j(E(6jK3VGyv%9yyHBCH-aNc`U&OL8kTF~qUFCes#47@5`!r)KnOkWR#{-dA z!?8NQKZ1V0~D!sGJc<;{}URBAQdNb^`HeB7nF$FWO$0k*Wy8ak$8pZ{Tio)fq z!YaT=O0iK`-di+ba6YR|eXT9LifUd~IsZnSC?*hNynG|gXfpg19d3(wvo9J3>qAK< zI)0>Doz@F;8Sn5rc>+1m#B0bBDKV{Zfm^vzi+Xh(;2Fa0CXWO@Ph*v@z#)IH9a~Z> z#iYXXu5sE6Y}(J-?eG~M zfDg}8?89pp}$!yG(F++M3Lxi=n}<(wrGQxv;4t;O@=qM^-F+CUcPj$%|a8@XLjoDB|$a8_Q z%X04pPooWC!pUBTcM{K2N-47`Su?Wyph$vwehYa8-2re*UejJDktv2%EpT>bx_}IM zI4ldQHV-guie^!MeObeCd$U$E8aO0XFzemb?)*DkcE>L3F9|~n_oI_h$EwRspU<)w zr)SvB&)4DD(_7a~8+fRXVZ$8VEhS`)6gcQ!-SJI zco~m7im7hV*?({u8y@<%>ne4YkVCKFiC1#y4nidwWa}>bn3t5Hy0DKgS;&4#n_j9f z-eG4@SE8=9dvw@vdbwB=RT7h4d(0>=gE+sG8^#E!Mtq!Qs~!zZPB5g}1tf(#$8O4R z%J0D})xIBJtre$fIv-uT8(egOTd)1b54{anBso+(td<{Xt`lI-8;62E3ys!04KNH@ zPjV=^SG4aDf$XBMW-6;rp<>?7cGu<+8Z`*fn+aX&gB*J~HaT-vcnAH=^eVp~irFZ5CW9Oa$pVP#g&pPhdun z1i6SPv&j`*oVl5s2g*OC;_r_1L8l8pL{}*sS2;>f$GZF#HBU|o;%P*hMyR$nCauZeB1gx2gU-c_%i@JQC z=o&N676RlcEsyR3!)b9-St3%_Y}|93b=&mLqURWc&?t8EU~}%i^wFu0NJb%bE&{uM zlwdBV)%`KpR)D{-E`C}B1^hd;ay16$9h!W$s`l#9lG(M;r6aj>W|{ku*+Ay%#4f?{ z4bHl5?^--3PX(Ioh9lO9I*i@NnZ*8mBg9v`$Xw4+IQ)vkcAP@_6a#plGAA!l85a!c znE2}b`rF?bY-c*b(Q4-yqw1`M;{s=YCG7Tow9@rD#BfB2ZC+m+VcJz$WSX*0dLzb`htgLuk%7 z9WH4ntW=%juuAq|u(<;Ve-oId{)`)6_qp{f{CSxOA|ZO_1_3O#9(N{ZAi`=@#0b7S ztS$AKRaHZF;{-P{mcKj3!t4!?z!-zWQ~R7L zPrk-7bq}X9hPX&3GT&feInAXq-H~2}b(Yj2w@009yMG!{m)>~BAHQ(i1j@2K9f>P6 z+ZX}sci2Hux(<{80K|cJMP6$FsaQtSBKCi;?0@%&Zct1McS*53K!Wa>%-xot9-a5( zoV~~7cwFM1FKNJmwyMHpVKIb+Qj(fN8rX5}4GSPjzB@_18{4=`O)r#)p+6pKYU$jt)JTp zVp#~N=w4ag{`$pmiEkK`K!ZsZdi!_#?rB?(WLxpiyr*>1v;8Z<&&^<%*>eBn?C8_; zIlApxW;|G4R^tBN^a<~vm8bgIlFS>dYP72-V>aG9L6x$M=W*y^Z*i;me-_n0hx}7& zRHOQ7KeDCNbW}GXPRe+@XH7_S$nqdw*t0;3;pDZ`vfi(=ao(ffmr_scwUQ?EyqL1)Ip zyJ1Q7h%7YyBQ&fx?r1n(UJ?<$E7Jo-9|MFPfDY^v5}<7mJ@zxb_e1OFOhYFwb|GL? z>WEFPL!?T|^8hJa6GFgts_t8Lm&vNAfR z`Tpo$k=%Di2epWM#eY;9j(TNV!n%Y8eCbk#2oXW-&HUY{w!laro2s}7H8o4Ifej9C z{<0&saC8r~X12N31!5^sk!d^kQUrg1L8bjNNC^t2bBz6Mh`XMiAd4!~Jbid%&0d+8ok#gGwM_cyO z)9^d3K`w#*g7Jg7LJ5Whi=bPu+)`tBk=YfF5cYqmj!QZBcxPzbbYn9ya$dCo$*93{ ziWhF|jZ^bnFv6P-Q3$ll_^pDG&WxnxZw1dj`P7SuS0eZnQKox^m7Njbs3U)dCs`}A ztf?tiWbt-Wr~vcFOTw{~Lno_U`rrk$?Qckkcv|%;9ne;u!17nK2}qHS(>R;9Z1|-7 z?@qk9KfAKi1YY~%_B~I#vC{yGEmo-|hGNh+*Ns{p=DMJ~?V!TG$OF(2yw~af39#%y zD1fz0cD%+$8*TMRYyME{(!7{nn{woEO}ZZp>eoekE%#^j_!dm-4x#u*9)jr0o74)u z#`rd2+j{z#!)HlVlEKOvEx23 zKzI6O%n}>kOs@5kj%oG%y;Qgdq1!D-SdUqB3lCS2KgJ^xy8D8vN%C{z!ds>OE{iE0 zSTgF@V|NZ;_~U)$Z$o4;h@>c*!fqfDrA|5GrC z@*W$8yK}88i(QZHo%AKjkc^QWq-&%sYRx0^Kzv_K6?$99gX$$!-WV zqe$EAKx7K_y@F4eO8)!)S7LH%hTLO}OXgjfN*8_LB@;8CS8Q zjkv_{8^|~_$UEQ2^5C>v7yBam6@sEya^t2Y>mFz_Tq=dgwDgZUTSrd&l(5V$?g$?{ zCL51sVLixpHPc^pzp3fUf{NNTQT}R-Tb+n=${yYXnqQBHO8PF&><%g06mU2^v3a=b z@kCnt(4kmC)ik02q8Rj!(|r&L z1fVs`QX!WjHNbk}Zere;Rq>!IR&SI}R9r@!JJ0lf8nJDT>5AId?qd9~8xugF|9zDU z3o_xotybI95^byXNtcDH`BddY9Eo*#&zdW3f6-zVQ@&7=Av1kqGG(FR{g{DQ;@SFM zN#sgW374P}YvW2&Cm(07yZQ&RLY$7?#zIv8DMQP>ik;*dpBZRfbBGGV5tK85ZC={5&Mac*{Z4z)ip|)3cEO-f8#ZKDv*R}BO+?i8K%?`}`%xhn;VT>Ur zo&GhnjvluY@V9?VF#OJ(V6J2SHy6FU`6JF@;=Q|sJNAwWZm4X;fAgtlw5~2CxjiSJ?F`7+rKe!1O{kjA!d877bJhu zn2eI9m)GXFQo3fNrus|~^%%c5nNP~j6bx=lata?n%HSp#q8DX2p53aJev=A^S3_Kb zCdy#iym!}eSvuP$9#%tSRd!G-vIfF2OhLKrLuyK^?k|`^B{7o@VqEuER2-98Dh3eTp7Pu@wNU-W12=OEt7L$5dAq9p^$K7WCn-y&=c=B>9F z;ia7!tQrFUH4GGsqJr)cyQeL|t}rvljK!%3Zyz%NtH4Zp*1}TatDCIwhZH#jFepsW zua-WdbG)tkYe$G6B^j9K^=;E=q4iNST4Zk?83i(ET`z%9GU2)aA%?FT0s$_VdB;nP zMTq9`HS>H3CXFE$P&qdybcOjnP?jThHF?gEfv}d-BO+jG+0&c2hIFjJDd@`Xw5oL> zu3-4l&Ol1+JPB$hTMO=IsVJK@sN+O0pT)P+`hlI+Lk9VC6r!sA;MY8E*z#Lm z3tpkL&64iV!p}=&i#jS%8(p~BVq?SsG957 zB3$tD3}@Z_mjx)Jru5db=KLsa1?z6`q-AsqaYxZ)c0q(L&0)u(Stz?3Uvy`u+)1+N zJ(H-#o$--T@d~P$V0N~#LB58*Yj&D~PVV|R{fOU<&%VpvPr9c1%3b;Euz$sRh7P#x zyIEzsm`1sh{agwRVdDQgS{MJp>J=cVv>#E>9W{(Z?DwP|EG5`eB@SgC6Q zKj!1IxGy#y3(Zd?y|oHeJxKBFl_cr+n9ziU!f~YiDz5Y@TaHFWKM*o?$6wT*D4QfH z(~$Ewa4VDXn2p46vP%gFcJ)_-$3@8vOS7oyqif_6J{k#8*EIwk*Bg$r8YtOeulv=D zMl6X6Rb}cxSq5p8XSe%;xgqbaE4F^FIHArSi7!eo`x1+|46%Mk47{Z-W5&=LRe>Q0@i5GI(feNg$w<%c`4E z7HeiZQeqzD$NyY`GATlR`Yna=hn&qp9rkElU}%g#8i?qe-gP_b-7vsf!yQmoM* zb0^t>U$4PsCW*V6nkjGEn&YZcA^jLKfX-FF@fYA?B&@M^}%RcG6T8&+XYoJ z7o!Ls@^I92jE)BTpu;ZEI0v?BG#~5>FS`=!4B<5YM$2%ccC}nJFg&Ry?1Dm)VK-lG za^EmaG73PU!ihi+11ZGs z@tKwo2uu0jK`tTcWmpGnO2f!`SCul}WYBM4^smpp#VnvI8F`UQIP0k#YIM{Qll4SM z@%ySH1;`}HC8M44kvZX{z&ayU#IH$m>pCGrM{W4;S z=vAE5`$2Nk&)e{YWF=k80>B47hVN8A3g^;ky!z)zL-YbyS+%~@UBN1p>g_qNMn_7I z1(X$?tZ{Lqw|lA${x^#!N&{FULC}=A^8_X}{IKs2wq*yJnRu{IRQ{y$fwcxoG=`Pz zb&<`|9Ml@IQ*V%7iy#qF0506}>8m_rMG%0TxTQ1$Z9J4xGETM=8r3k~Q;7%ze?(Bb z#!d{j2kUC|%Y@c%BzBI=fW&_OXHh0B%yABWB!_o1$Z=>82#Dlw=dliMF@8=UdWn!u zO`&1vQiuH4s{*R)=I~ec0k%9?}2Ps zbA$lI!M;EjuD3s=?_a<1RSPvZ^*lNIn%!4dVfB|v`K2J`cmS0sC|%y{fE*cxE%D0j z*o2!l?QxW9<)*8zWWexZctOzv8|&Oqxw0Q{#7D48SE=JHxzSjfO|2g0#<32tkp z`o!DVOZUvBjqCSqxZfv5yL4qEvtbDz7}z#I!cb_eJG;s5@(!aPfI)VdO~p8?-DH2> z8ND8~Ao7OU&lhIkKk0bg&Cc;wS@V-dZ>d(7|Dz6h(kJOQ%(P5kviGx%hi>S7m##LHP96cjNj0G)?kvi`Q0@-v`c?o-~hT{S5%$+)EDXUou(^QTNh7rP*HW4aj zv%;{r7+SHID(hQ_W6x4pdHw#_(z%{M*=1fNB?sx-J7Sf2fr6_1VK58^6BY30RIY1Z z>88urnE+8?@NH`-2mbUH4v`=WP%encbX5+dx8a| zuiy{3`j0BmqJ;qAnC3f6W^#2LS{7=ewq7gOZN9GsfV)Wr$DVRPA#PJg8Ea?p(>BV1 zef#4K^)9W!{up=aPm*dbxKMgfzd3=*sAc650c>rerN(-={%RiXW7=WP$Bq zQB9>ZK+EV@p#y})#XL27xSdUn^Q@d}35EdEtD0PDZlZ(35+@516~SZ?k4L9l`0NJe zcE@_-4fxPvAY$*6b-`zAtxBke#u>4a26AR$*!n=0NE*s z0=7_kgw{Xu_^ID6Jao04&Jx70vxSXPU1?64hlLG2Epmr+vt%)rR+k-zUUuB;3 z`}Obl{UB3R-IvSKyx1^TY&!hcY%2)Ect$c=K|RQfvf1oF6!^KEf0X`&b215&{&2L6 z2|IAq`TV>SW70};A=@ugeB{3LdHQ(OBeXXg!Ce@ywY4$aSbX5n8ZYbN(_E#y_*~p4 z72)^I_}&2@)MEUEK$-Z-5GZs*|GvRWB7`HxUg3e0B(V3sY_HF;${74nxLP4Ts|g9# zo(MW#5PlpL3$*7Z-4`4Nr`ew|WY5`e`|aRcAO+yEzU(v&im|Kyionn4x;II+ zSudb!JFZR0X-U*ShVau|H}xn`YAbO!ZMqyb28+AtO{Fra>Vl{EHOKdxGb z^|WAsDQM${o=`GR5PFTu`kwIPiFHO%O`)Q$qXWf}?=W^T-iafY3${P{>k~qz;iWMl z@1_1Q^5A?fy85-=5f) z?ClR4@aK+JJzKUI%Dol@U0zgGao)`&47ZVxaT$6Zt0Um00J$*9Fv;l6;DR?y8Q+5U zpkI0c=KN+JJ$dIb1gqQS<+)x(wh2w304~5(CmX_Uci_-%^R@Cnq&Pl0;?HC2L3q~$ zRm6;=60T8YHEShZ2Ghn>HB7ZEINTpa0SY}+$%k19Gbx{}bzZ0+AUs@X8~UwTIia#& z21{XTscZ@2>T8hVastr_I_OF;OmI>n25DfLycy%2Dh#0DqcW0^(=|fEm8R ztA7xT*Q^y?%ctP*| z*H9Ev!f!-JKrFvns+jkDaVan}n8s>`&CTk7{^^V99#;6TqHHEztY!$PwcuWc`4|eW zrcw9mIAC)H$47N@?o6GHqC)4$@Nn*j2?2Lh5Xaye6<@Y!0vxO7b4_ zqz%&2f=l@r#(H0=g4r8>%TOEWhiJi5Qm1rnzZ{M~+>mum&L!B~j@LO}*{N61*jXp@ z$Bs=MxdY680O3SQ+P2e430NH-bfeO^t|8^HpJASM{j zjIXy3q6DJ8=*B62RGYZcKbR*eP}}lXNLE1fN~1wEV4P;L%lN5SY}IJpOH?I2uU0Sn zANizn(LFce6T#i4HBG}-c<|vsSv(IrlEZQ(P6rSgCuQrPKkTp2l4?Y-d{5G~>fS#J zD=v^0R~(O(+xWi?sQ52G`V`0#p_3ePAn19aU!6hnotOz%ghZ(LG+M>`ce{~#t>jn~ z%7`b!4RJG8N$Hgn$aVp{xzZvQ%tk@kJ2WlY*1rZA8j^hJlgYv$YDWUqU_z5}eFi8R zsNYz>e{7`>%AuG`U{!B|#DhUw6OagSbhN)g#+To_@N}6-vc5P&>lNp3YNQQDQ7ixl zKZ|n+S6E(zCqS9PH;(X3T`y2lb+I3QS?nho#hs*zV^(gHu`JBI7DfjbM&w}3gD=r} z*G*)DHdp+pb(47qiS}`Z0E(^kha8R5fLpA*_grey&E6^S9XPAvADL9aW#6K)OW?mF z&&3~4yF1 z7YGPDjJbEO{8{MlX?kIUf$3-MphR6

3Mw#Z*c8)g^BQ;Bau8lf+*Q2n115-$Kcd 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 H*Ynn2bl`;q literal 177349 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

y z>(8^tpo}<+f=NQ}=L)*pYoZ7j(-B8|OZMDCO7Q>Fklg|c3-nLKeL|my_W^pIXU~ld zdYgO2!ss2Kg!!@;IVjPOaGbx9lOg`>s>lSO{Hs5-^#CQ4vey2b9{XPWHf}tjK3$8t z=9lNHU8vU1%w|XvR$k&LYgohfh4uW~Ra@}e1VTe_k!O;xG9Bk^B|p!bJQ(MXcsUcb z;g;G2%Tm5eSiC*ruwO{!YK19$PzHfHXfBpmmZ6xj)krmR(0?M`zEJ13BPLOOF^D-P zz5EU&$ztdCj$Wbt;JPr*GEKDeKk_3tFJDdsKww%ste|#)t@tlO0w>_dWzK9^OxczA z3E1YAkpD`+wao7D%POyz4W6ct8(6LtBBV3KpW0d~^tooJQaY>-2MS4FVYe?Y09c}* z!f&9S9J5t91u>exZIIjms=zqh$>k*8m7`N;FOOT$=@W%BlQABw2pZOYGHGyU+(qZ_ zi=^Bp_X$gt*wm=?r9(lv`Rn_M0O8oUF=+%W%SpFzW;>3WjISm+<5(JCFkPI_w-)Lx zH39NC|MGjx!oiTo*wL$5E@&6S8R&nu>aT_Pt451Xi9qTS-{TDXFJgg#M33p{@$Cj+ zB*wky6V?=0UCHZdU;NXJjfMGHs`6nU3^Ixu?Uj_Y_bzz)+j<|XF>mvc&QAWK)*hqt zsWUhcOZXyChF!D9IzmFZLITYJ)rXN{<*I z&`ze$p{*u;7*W1S#PRkDL@6PJsICZLh!G;DS~|`?gNu6VE8A*0eaELH6!FI&A8Fp# ztqf7Qftx*inxJuehzSneO(4IUMjSrCIXQy-anr#jO1?Tfm3)epLDO*=#(B~JpSvZJ-d^_Mu9$p$W~@r)DaKoAePOz9|+-k>uo5qu<4ypfAj1@MUU z1%nbC2oravyxS+^<+cXc!65Sod1(qG`OPi`&^_7UA#+95Ac?XHO&1aEDqXV!5|NA| z;%dQ)K;{0ijdVW(lnIEUyoa#LB!`S*Z+r)7hD@M)r36ffccJiUIQ@A;TPEI*OhejRvLqFLZryF0y)yjCuZXvo)IO-8m6brSEmViLqZ$YC?e0 zU+J*Xcl5rEQhtRYMFW3ET%a$jlwOw7p*hovW>U1vj zera7LH(rNg*dqQ)ZfK;@6ow+$pD75b;%Ti4tuICnV>L-jW;X%2&@0N^PMsA^f*TF9 zqJ`M+u2uL@4^hB$ZARG&1Jd{!FdT|)!Y4z&`>&oIhg?_szVe`1U-As@XEg$jCJk~o zpAAnhytso8Fye@C)8Q0Bl?I|Wcs|G3(`6=pjHj?1ghAT)G3`}NSgqALJVb;sEJpP( zCq)0AKu99`>u~gdGHtvs&-N&5XnQTbcV&CGx1Wh0yx|{tt0%{p{g)R2e&Fr0AtAw{ z8k>a;CQ8@!KGUbt^`^C%|Be77fE^`t5*-Z_Mw*Aj8M532@(}=y5Huf%XNfk>9U>^_ zG@m|7kchLi0w!t@$-bED*;4UpfVakZ!G9$ui^G^M6kr9mxbWe8U5--cK-L96-0q|AdlM|_v27PK}Xa3 zvuksu<=~bOW7B;B<8`_y230yI>UPq;Y<-b z_P1areN9d_dN5^0jxL=C8W2hYVg9PJh*+jxW;lpVE@ZC31<^JRK0M&)} zF3xvS*LBwt69H)-fZ01(1uPK%G9@x$fgg-@?Z3C@`|)*vPt9&A}kZss6CD?Jt% zr7uj$I-`iD>mCqx_z%RT1szdxJjplg@saWZ@*?mw9|$Xim?vj$!3X1VpRAOK$^_-0 z=-BbAvuQ#k;h38%YCm;I(QYV<{%ktDs_5x$Bw|NbYVjS9KoVvCkr~Bspa=*^INfkJ z*zRK#Y1><^?rJ~u&hYrU4>-ILJN>(&LxKW7rgEGuR;)}zyLpa>vV6Tu zp#ET}^Ppk=Ayy3)I43ZGR4I3{MgIb{f_8U9t#uj9i(E-nm$j8P%qfqoOofVx)gK!3 zz8FSJ#X>H`f7i_9H%iY`Zaana-d8`0VQcK3-8o3vrblJGX!^wZQ=#|O+P+v?4r47^Mr5^3@P=|gY*KwYkF%pPCxT_lqh2zvBWRgn*vb${{$ zwRYqqq^f_MOnwB=pHm{fA3%zGnm$rlYJ$^hNgACy(z3~4#*IdD^y)OPS$85!t)UGE+j zjal%GpS>XWmt_@k8hb*kA2TPaF_=*LYT@>Vk%1%%jq;Q*1juj69!X&-GbpgQT2>@G zSPd3$Z#}#Q!1oy}lRJNo|JW%_;8Y;YJK`DyVrX6>^LT-oP}$NF+9Ov5^3Qo9PgUf; zH?(}u6o+ll`)soBZ$(+P7QZ)d(?`xd{NG0vJe zLg>hMU3ZP1rybp3}NfTP@a&5v4@kHg|R_k z`+GDyBev{6a9E6SQ3r>}-v*2ybTBFuj2dmCu!Yhh-hS1A@T{4Lgol|{eXUKIQ)Rs} zFCmU>Y!d2U2S>Xtgeyj;1;pZqdJ7Lj7qZA?u;t%31$C@yXOjdzQQ@=G73@8$T}EGL@^4E~POnOB(%m97Vg z3NZ4C;)u}N*GIjz`4YD1ZB{LIqZ2mHXFMvN&Ku~*v;>-_?DN2nJk&eWX81?Uk?sap zc$`v)sXaX}c3G}xX#?3yL297=^Z0RXz!;?m{x8U$CG-VDw+I@Eq}13ey>Fcg^Bq4_ zU-atw+bs=jCM!)DcdbbBaW#I0z!y*)k@qhe`lzqaV+ugqab}W!%ZaG=nheG5_YjA$ zCZn~&Q~{B-D*CZsvDSr4Sc#=bndtcAh_%o%(FuV{b{|58`ll#0 ztKXp;4m&HWN+wym*x<6U`Yp#oAQKY#-PG2(MZg%iVWU_ahVk7dX+8 z6-;ZKtkLVj;^vqB~=+`$Jt- zkXK9;SrnU?C|y|OQ<;Mub}oU;)mJ?L_m`A5av{$+Tax0GS+QJ2USV!v;C#509TnIy zg*#M^$aV|sH&39q$2S_)caK*pJT;i4=!ggAVl44Pv_u(N`Dph?yUEi;VzkfNyNUTs zjruI*mzu)Iv97ydiSjw8n49GhM$WF9vLfr@%ul57K%hH)d4Rs_?EQR7C0XIPbbB9r zH}~Ae2ftqJ+ec}2rOgs>Ce@XXYM6c5>~xq6{lV1seyu8R4V^5#46?MggmE|F}ge{1O@t)>Vs zh^$~?w_uBFA}U+alJBD0sA3YCYFY)u^jGVyryR0Ko9rKt-BzQ)68#_i^&y13f5KqMp< zuBoTwWGQ(_gk5-S;?%g5y4Ed8>yOLnx+{v>w~Fls-k68zdYQu@9ld?|pVABQNQ>pA z)(~N>auyURz4hYt1wn+C#)c;E4BW7GZ`C4DOvi+SR3XU94+L_XnlktxZrr#sm2u2G zb~{Ak7{eMdfi=?1bmk_2A*1AD#%zT|I2dZWH^#_y|zdCPu@`i~xdz{hY@@f(oH?!J}R+O?f~DVMqNz-+(sC z$)t02Kk4U8&WYCT6YM5*tYGdqpO*m(hU+x5KEMBl_7@5{qMG_lxRu^z1tUmZU-Suh zTi0_rg^U%{Zc0{bu~3zz+5qG{GBIVV=GJPauPN;Y?;cyZA_Vb-W3inv9T;t^Y&MBj z#jW$jV;EYRHLq^A;^ynt9vU$$sy6Y$D+)vxO&W|rl?gvgB9Nv$eaf_hFAD7$i!XFu zo;0KBpB)b;wNE`U2sd5#=k4I{MRhy|P#ngX1{5|Li+BKTFhpJlnI?^VAYqUAc#LAtD`S;Zc!A!_0Z|g8Y*^h^T0pv{;&RHwXwrO{vBf(%e*ugYH=?tCZuRdo)ui15f^;%8CSFnLkP;FEKmviGqNhMWO-A~k}R``V#88WLbCL%%uc^y{a*)S^i@>p!13ijzUK1F9^ci@)X467%Xpa5^&-{uo+Ygo(oFXYX zwx6tWHO=h?zhaTsaO|1E?P9KI$;m(pM5UwypmbbL-y}h$#K=nVq@AS=zGSVrZ+28; z-+eaQY$^rqtlQ;NW|Zo9p3LR?`mU9J*X2o(>b73raLo?IfxJXeK_jT*&BWlhl1n@$L~w$k>4bv|`V#%7{d&lvbEx9>`e=IyZYMgF!J`$1 zgok28r7g$D*NRau)P)wfGZ^uTl-Dj_sV=y=vhU6H2vM{D7+rQpo*nuZNOHd|nZ7o& z4CxkpuM3K~On9fCOS=D2$aT30n=oocp5Jsi7S)^O1G{{hIJwwYzAnP(*F^XzzgmEz z6d$RxR>JwTTrxaGuPL-?c}^Hb9M#g%z8KuZ5WeD{{OPvnRHL;4blE3s@p8OQYL$Do zKlrS=yt~`>ttvnVop(Xfn)A3ju1rnWcp&@QP-VD0rlH&on1NrJyWnWBokfAKz4>!C zW<3r$0~~1I0BF-+QT(H*y->}jMDzhxtg{$-({pR)mKHO5Ogy{U^m1V35bAVrjxg1> zV~LLR6-Z9E0I4Otz$X(^Q&a2xJgQ20dr}AsEfF_Oi0^Z@r+^zp)Nesi5yojez5uEO z?6IrS$+;0M%_WNN+?h=8Vs%JYhn-b(lhkxR8;* z19N_zYe~|>nFi|Vk{Ta2%Wpn;_2_2ISY^h_k9!>L`TuH_YL=^nC7nN&3}Tk7_?fEl z7Q$8+w{s09-qmJXYgp0BUG;K?rNQ1F1T$aFB1~px!D{ET8?Ja*Tu-4yM5@Fbr>Bh4 zFM8|mCM%<^6JG1b#*S3ZJZe#x3B<%Ipp?ubVoCh6-9tkD~Zlp9(;-mv!%iQ>tR*T?tOi6m_mcjIS5$oFw$ zRw;gV>op%;x8xK7e41{`%;HMYG2;~2@2mGQ+K!$U9~W+6tRiBunY?y$nx~ZOdWK-G zA=xVF3=_U$T*Sf|+-|`ic8GX_+-Py|-=4rq6EWC+?Sy-OpZB!#4~nj^P8j_aLjF2P z4$6)K-WIM4VvG>>ECiThOhNnL&|rL`;5VP>Qz|} zm)rQU`(vk>v81&6&|2U|uxoJSO$#@_W8|%R!yZSVdp^9TzJ^4+>Kos8eAj2}3ew`! znmpQkFqgnzW<5B|NCv{2kU{Z_N$RZ^|BAu3uY3thpg07m>h4V=hAa*%7h$s|#yY$h zGxqL#ppYu`l0)}2M6D;zH7o|8!e|svW{y+75iPsttAKQ2g8J~x4On}!{ zUg*W|42ej_FBXJtkOGVdDL=y3>jLUgBM{qB>Uaac;+t80&z~aZ21;41Zpm{q12bYx z_`qdBwKV-{)?gKHP05`xG7>}6aNZd*cx!ZAxrDA`Xm2jNVbDD7!?q|rRT1ui40yoFXo5zWtnavt$s}A>iTIME)z4b&1`A&3Aw?hRTM&T z!5s{Q-#}i0tI(m^oI_shK5T-94uh32<0h8`tifjPiEc;N7H9> z1WtUX*|G|~)M_si)i>x6=JYtFVyF?kVBSyC5E~T>k>}cboN}(ZeT<*UhA_xyOmnwgj!>|~k)tmR_We5?*)4D=u78^&b zj3->2wW;k^L%4V`862z}+z`abK$*=a7Vr=rC4<>wixh9$Zto zKAUX@03AGlImOgIFtTu?759h<-6?=XKlxx{c zQKuD!8*x^|^c_&agnEcDnl%!4tasd6<>R2$S#Wz{X(_T~K!k2J(@VsaEs>@FA6wrX zUDxxyo!q32Z6{4*JB`)Yw$s?Q&BjJ!+YQ>-ZEV{%-dlgZzxA$l{z}$8XJ*fy{cJpY zW?*nTRe6w$f>q6fLq=1XkKE9MLPy;xpb~ZOL`R?@w0g|A(syQS0v*Q@n4&VRAko+t zH4r22#)1*(7I;N`NhT!z`W$)ID*M#Wy)4X9S2xgEnL_zv)!S5HQIV9DWzK-XHM3zf zSDoZb-P>C(f34*@vNcOeG9s9&oG{;4Tl@@-$&jMb(rKZuJ!?CMHx%CZQ*%UwkcNeB zR3Y5K9)jamLZS^)f0Z8%o3|UO3TKWNs;KFX<+5D?QuxyMM10*`4h5sND=nbZ z5!uGXiFUO0j2I6wb*8R}-&^<)=v@H7_eqs4`+&3zq4$Klo&ui5HbU|Y&F74zM9iz2t-(J zod}Jrppy5qrdg(2KQQEhY)hmx7$R9#%8S1F(hrR=h;UT!MzOofW~+iOFfph_N`npK zFh~dvu^u|gb0+bAHOjRV^}y*4Z{AFb@Y_Ct0@I^cMPF_3tmfKtR~b=fSv(fQ3$#nQ z3(drIIc;BtgKA-aO^xX5>xPQ4TJMSJ1Vy8bkR`HP28?>rJjsvR%-xs#botLA7UNszB&W=?+O31;hks}iMzD<(NJ;va>; z|ET?`q$ahSfEa4kKWtd* z3g7;+TyH0oydTGgf1=n9B+)vQhyGIz5M&Slonh^ehZ*z~4b);X+Xgcv)jdt`=Jw>%evS*W)kfE`s5Oc+@^O48p{=4@*e=)mcq)gSNliFRdJzI{ zFBA_J**c6Wb{||s?&x0*<{?}euOvb9j?1&2{1{sSnRC3?@6*%gB|+r9A>=oN>l*HU zMZD4`GIDSvhJs>juGe{M5nQPsMUcG&G0i_fnbVQtQNI)T*$KX@?2gX>qYCUW`jeRK0ME{> z$%8=GVE){?fJ@Gf^3wF1k6wDhEhRe`>`t-^bm1~3MMg{|3+wKP1BjLB&&4#w1S^bi%*#nN98J0*(&aK? zo?y;9&lqo1lHa<_*@%dIYWh&o`gE*fk3gcL5?Ng7O+=F~N#wox?R$4nP%v%VWeSGQ z&9qvl?Z4EUCo(XVDI@eVOAF-R0hR3(4FHYQS`-MLBg-_dXK<~3L!HD2?AvuL;zU; zBH|69G?w&M@s*J2O~0rhab(H1-t@}-F@Ioz1MUa`z4c3b}JWx4+n=p30@UgWJ%~k;bIYVI(GXGcy?Lves7H?tM zTABMsAmI4>;_=s!InNneo4bxrmai*$9+=GO#2R4ipYPRAUGJ9Pr|+Prwm%;~^hTuZ zK7;K|cU26n2S(&}(H)aw2{ew-RejU73VH%Wve!48ZFPZ9$rsI@^*SW_U=L@(Yx#o;~RQixV)y;O{bV8f`Tv29w>O(-pA zGO`Kp6@)5VD5Q6ZMv9qwM$M3*>4J83z7>(i1)o;yLF&1`(Uk>Kv=j7*SWE@AC-N87 zY}TjhP=~g}XtAiBezH|-&p( z#ukqh9F57c(-63V2^;aV{Tc;Xu-dqu(%*^ng8TeRglmbcG=@J z9wKKav$mk-DO)PlaX!z|9NdtUm7<|eYDCQ#4(!=$oRBBe^tNBLVJ!_6u>hLT5zw0L zlk3CY_+%)&F(J+25CAS#{XP=8n{Ca4;x?i8g*nIDN$phkbqW{5oWclPL{*6OkjK)i zhK=)wzR7C-?<*Po*WF(}jfvhK9@PBd0{kI10zEh&zf(2SmeG7rq(?vUWp z8wQstmjKTeSt=YWex~udza#03E|@Ah;gtu$GYSsC#fv+C{G66PUo045E+e1Nfiy1= zW@_0;250=Hfc}et={Snl36K%b5_G+Fbw1T2?+ba%EPC^72p9Uw7G>So9hndBD`F%t zclYmz90!R`6fbF~1NL9S{}p>=(*bxh@1OXLGV7H?m`|V2E?O*^@nY*<_gRjtz!~q5 zjKY2-Z!LcvNHP!YKWD-{w5Q3f)N2<_jOcJM{2*0u;&f7u1`RC6H9ykcXfa2yqFnV2 z%o`Yb@|ZHz@8kh{F0)Zd4XKHvuk&m+%4%?rCm=9}frnEd`xy}BX{FY8r6yp?UkV(* za!!n%3Uc!=?%AMqvB69XM&8zY<0zBParuKQ#`XpTp|Kcl{&KfErhXuDQ9vce#~%_X zV8R%a*MAFBHoO2OH!0ti*?pDVjxTPw<*+Ith9V_0wj@{#8>>DjRoi64heqT$Q5KE$ z1ACfnlVd=)d#mh18tQ_OUqmET1DJu`x!RISbd{Iunw%wr3!0Gc=$*4lt^GtBT{1wl zA60K$1oG@9h-HL}mn;NC7cwI@rzz^R+&PIEIf_sgsuibkz8Z1O3$c#VH6IVyhrk7X zn4egwLmC4l?ROxo850fmwR>Q>oXyJdT(1xGvK4lGzGTlQ4~YR_ME;F9nxpjLlW^V{HJJgJ^|)+#1@ffF=Vg|A^iaW)24~ zBIV|!Qm{0ITSaK{_R(3xg+*LW++_}N9{gm3wnjiTpS2mqgp%KjjZR6DF@{^Czws~f zLT4*fCmp#)WX8YpVSXdDj&?RNEq+?d`Wp(k(ntWPGrEO zZ<}j5#a2Z4aFE+qQimlaK_e3Z713e@6o~VY?d@wD17F@;>=E!n2F4JU>rZfXGrFce zrGRS)*ztQYh?gTBVY|+ycU3tI6bXdr;!Jb66G0JbRW8|Jk-$EOKRVxO{zFGt6hgs( zg}vW9lLJK;Q(5x@MHJBeoH3>~`!Gq*TJDRpulb_(+?1ybCPvkd&T9Wkp`3)@C*TT{ zSJRS6EHFkyhrmTouy5L5z=z18P;IJ-Hrj%vj*JNDw%Rq)UjfTCqS2@b6SZJg%otFR z$50i1j!=Dm7BOeD*!;R()}{^wC^peVDQb# zRD-oD2`-Psqq_!!CyHZAUPjq4F0~7i)UixK1_yU_%aPR0&Nryv%X6lDPd2?7xLh@fZ8ose*EsLVVOprdAa03310H|K}ajw~Zb zuR4;lwxTem;s$ZmR`J{xxRz?J^E#Q4 zfPA%`qm_@Fpv4`^P40&!rB6|cv=szgqlhZzbFm#ML2^GcJGTl@OTgfyD1G(XOfse( zR3K1mKCyj}(v$kDg&KrD#B0Q(zM`+&O<6OvOL9@R;VmA71u2aB3@jb?=#)l`b~ z$d@M$m6m8{Fz=Ocp4_<%6&TiYben)f5M*-QwK>m(34H=~eQE8}IW4E~)uvJ|h)v_0 zj#SUi+(Z3INZ-zvfJuDb9M~ z+}T)q$lf{04Jzr2YC9S<7m;bXU4uA&)E~?2Ba`vEE#Bed#24zQqH2YVf0E2xn!vX$ z!xltH`64RF(CDMJ%T*`u+md{t3CxCRS@#-F<8#FAvi=#!${XP3upVKHLjP;tPZ$+4+ zjIrrc7dHR@c~hMRkeELSAF4~hc(A4Lz;PnDveX)@bovo^IQJ3SnKBt!Ur+wdqnWrg zPoqzwd&`Nv_7p*(v>6BM7{*n!Qj1RMUFg@K&a(vi%HCXW{iX=o};||Ge zwZdPO>jZZb%<$E!7p(Dag2}ZJ6 zN5DWJ_C5ZmTkS%8fa{@Mzm&+NP&FfQkNcDj9)q)!9w5vik*U-}T ze-#}oDsGH~Y({aww!?k<^tep9rpXrYGw*PY3egN4F&<6D&hcZEwz1Yda z&n#j`?%vDgK_35j%A%j~NhlU;Ww4Z|POR zSLLi`~rT|cx7bkqhcw2>yUKkIAA(KNNOYCL zT6>Vt@Y1|4jw;Q}@OjfY>r1fFOTdn9w-}0(7F!6nb!dY>?!-ptYtViRSUU}MC-y2l=1r9~ zZtz8`!)*?{ ze4JN6EsMo)XTb|9-Mo5*q3AwqJ>LRLIUncuna=&#E>lI}eX1n<8L28Z$iTFv6hD*@ znjq9704pW6x{(GZe7m`^i37*Zn|w-n=_3c5@LWz0RRDA_yT9;1l?EPBa$YSX#RiPP zfB76h0xAsP>*p>m#{`Y0bsXvbiniOX)O%YqI3WV>WJH3q=`gVm@>pITG|D?%MCjPkL`VLS0{vZ!pk51g2)v(_jRt=3J$uIwC`S z_G{rdqVuAs67_q46C%hRX1q>)`!Wg4&DBbfK$Kk^qpQxi=DzuU(zfbDa$K#o2LfsBbb#5d@)SqZ*3Av@fAS3vrtKx?! zz(~KDOj-|E>*P3q053O7e#U>g(UQu2F=vI(e#goW$P@+HGLT7U`58|B8gi2?AWAE< z^hOb_p`CTPs;czh1(O9&AX@ECwPcsJ&2$D`bzL9O>vld#T9OkG$qp}B5Ik!5_(qo9 z=`0Uc{bsz4liV{-u!ZWoGLR9J$n*-D@o=nw&Msuj7sqs{W88w(EENx{kk`h$isZ*) zb!I?PqlUo0CHQuC@EpR`dN0{s-*!(*PSIUY>qZhl#vKIIH+&|gUGo3vU<_XtI53Hb zzFkj-911LT+d?@VS5#qWH=>qH#5HHZ0}JS&5ZkYkywmbyaV*gWwJS4s4#Gjssuo zF@ctzb%$?$7K$5-2u_O2-@Luo-41H#BQQ1rCYI=}X8-3LOCVp8uV5oiC#FS!Rqwql zG}ECvHmYG(t`C?KGbm_uCE|cXFKKQ5l-Yu0qZ#Z~)NzTmJ7w`WYh!dW-F_?F^sfXP z1!!iA`ty{Vl?{Xp?n?#vL3a^yzVhA6VFr{3isSvuj!7)5r5hPEL}`mHY}ls zd%3k#ziHw=uwY>34TNs=hz0rD$MepT9vhqw!}$z) zU=bG^MOKDP%oO-VoX=Z_j8ErKX)9l^lJ`I~Q&-JCd}1|)qX(6RRc%Z;OcXxao=T6O zhB)Z>u^V?@L=q3x7X;GBM+VVEf3|Pg+q~~k%dlL@-12+FEQ=Gz^2hoOwvLCn+Ofx> z5tw`2@jh`(o;Ah@a8MNhB*BIo2q@y;M;6x?qM<`kpSqAxJu%0=tu>R?@jK{93I|#| z?k00L>}N~n|rJxi_4r&4BP2izmD zr07h-Y#ZR%s6701@gaSHbNlu1je(Opl`T|h^N2twZqMSZZ3O8b&%T~EHButdpBI0N zcf*BYg2(Rb9LDDCd@Z`ztcJ*z#qRa4tLU{AxSQY4mt2bZcoCP)$Iv;OTABinOS~~= zVZCI1L*sd_+;_G-`UwyG(FeF{Ui6_hpnsMO1iY6PRGb67j;KU@%-b@T1FdhxSPFtO zE~*g5R3*d%krMCWDB*g7j#s?|`o0+9{wBNJQDv@yRNK>EV$YD^5{%UU#{vmJ$(nAM zS3KCR06oEH`4zk%8}wHngF)Z~KMR4Z8PNF#s{UIF5Z{l4tIXYwLVYe=9$d?@+NUZ} z(}THr8<*xir(#78T*$Sq6;YjFE9ncnXNfwciVqv@rNyBm`ig4!NnXO)5HOk!3%8_W zCr~U$nYWfUUknPv2&>1dKf*YL0kkyEAao;8LQ9&)Ub4rG8sy069erP3M8!H5>ihgj#6<*U z=rz6j2J1=qirZPYW80O;13grorXAeOICa3T=GHe3y9ybaQfs4fW8&xdYfj00Zg`!W z;MVr^dX0$+u~O06*J@NKR2`ALkBwvmy1imcjY_DO?BY<7H;c{(?GaA^I!wu+q9Afk z>&5^Lc-5PZ({Tgd);(GhRY;t_2IbKosIJcp(Wiia>beM}ia}Sn)aEG3BLg2!+#wOM zb(yRu`Z3EXuE;XY!(mY-6>lIyQ2hiq5mnimuSa` zTF2lN@6Qx;-$H)Vx`y|rb63}^sNtB8`)c5?#P6@)!to%#|Kjg_lGFEqu`CpAS%0_} zmC|skX|QzX*dP{>8oC)3*~-H5mLE6X(BWDOK-YdN6k1I#fPthJ8q)@8y%&Zw!#MRt zC+YDyY(akm8Fg3J(()<_PXien8JW_J^kyRG_^!S?~U0`UCFI=m2(T_#DuP?8pwc}P;=spHfM% z7#9y0De3WE;R<4pw)eiS+VvN_BA-LsQ$)x=`!C*ytgFx4^O%>n<2kJUrS=V#b!3G7 z+T!8LbdAT{p$TgzB^y`E~iJ1w;?QesO%7ZdYJAi{DwxFE+`)2a=AB%}Wmwq;Ee!~6S zNmDcSY6ai@a?YD>B(2;AoF3uNt^(>P-vBr`gh8n>XPHGjgKbast3)sqYWTZR&oC4w zxy6sCF&t7o48{%-j^7!N8l*h5%8B1ep?ph~KgCUBSgr#>i%j5Zs~VvK-`siw@n+tx z%Mxrai09Wv5hu*napokhDS*h7^<${gJ48G+yuCfn(z$u@db#~PWKH66LEF(YKFL94 zd~V66&Fy6JRpCGO-**ks#9G%9&cYpxY3=kduh(^itk-*@TVYi-F=a@TlAx%oI|PgmRbQ6vs%6_A; zFFs@)$2{c-i?Rr3MlM*Q9uph|_a)~@R(6{5+(mZdqVmGD8=Mb z(>r~vFF3)h<6ktW2=LjFET4^A;10H)^$xOf{7c~OzzCu;3F#SsOs4(f*?4;_^*qiz z(IM^mxNqSam)!MwjZ?Tc1=P&ej$cG(gyShM*(-z3+y=o0wdLPlNa52;Yo1ly{;+ml z=W35!z;!X=jcqy7k?yJGAQ~U5b!xqkN;Nm`JloJxdz1faKTuah>2|;xK#V!XUhXxs z@P#t`tp24RcX_@&_)U*WWY#<$=W%4T14>ad({%*gznv5>-f0?AZEV!4He--0&+VgS zko034LWGNZKZPG?s%5e<9o%_)6fw8Jl$Q#5qVpM!M&i{M;* zgwlnD+&*zUr;;I(5%7u1>Rqf~!P8kA))g9@8tZ1Y`dt`ILorclYSpO%b-N)QqQAYRoRbkRGdL^Np%lV_b0)$h`OK2b@+d1vtARI)|yrlr$Ef>LLv?Hj=`=Go|OB)JPdE zI*(lhX%byQe?$;MR5P`I^+(FOh~RZ4ox7_c{IGl~l}IMkYb6~YhDGx7Hg?qn&g~co zXS)dM7LRWn-b$Uuvz0O;@?4`z^n?EK27&wL)Dn;hOYow9mC(3&A=ERF+RVflI(Yol zqvKVtV;UH(RY)aECw-Sg9=IXiG3~MB2xLDvbwlDKbTpdGgw>NGFq+-jhnJkaH$F<4OT@7PGeg9D|3hGLI6GsR z;t%BaOw3b?wQnwj&n}f4&Y2n>!A9-U#X6KXSu(}quu{b^U;UmQkGQTz&$DF$1UiY- zjhU%BLEr{=ZLwkB?zDytb2VC;YD-2q5|%a%=_bP&OnUmfJ3jER;J+A49_S+oq#)vO z8^KwZDPa)A=ND6o_pIv5hy~#yVq$|L1V;yd2oMk^p>_%?s3AFM4mxS_FYJk6@nc0t zG7OZ2AO2+`Pq6@wmfQLYYQhd-W2&%%!6KceMlx1LCC=xc;`CfdoucTU-;5=_!_SP= z%4LFWqUHu53;Y#p3*_72zNJQ+ayA?G*ztfa;Ysg?pL`+mrgn(!|9s85Oot@=& zClb8NqKB?4gsa(#PGQPnwkO)PQyk3;sD@Jto-1gg4^d<%O^Vq=^icl{PmnO*p>B!u zDJrMad>&)pJuZ=HN>QlnaplPk-DgviOnuZp((s8!TFpZsi&%xFpQgWd+DlFdGk5iX zQGR8FCC^Qp2p;x@!&oSf?X4gwBy6G&#Mi!=GS%e7biS}X-Ku@GS)F{8!pE;_&7tM< zy#z0GGcNHdE*U-=bZG1f|Hh*`2^k`}sI3&`p`)i|FB18bu(nHrcB0X|)CMm@V7OcI5+G+pc3Aca9I+bWu1wN9@F|w$Jir zpbT=s$`^T}@M+41Q&XNRaiS0C&}x^$Fh_rk9VEcQy!LaV!wsgp@+e_%?g2TH$-6I! zp8fUd@r+R{a{A|tL}n%Z4$C)cP(*FI)Q*OZf-WrI;jzhB>Anq1; z$UL=hYT=Z!Zr z1*2lH>6;WXPG_E$RHGqdJ`Vc?|DezZ(w6|JFk$R--H_Zr>ToH_mv0v&a^5?SFY`%` z2pm_+V#}CXiQ|J%kV-g|tK=h~(3=`YPphtsTVe2R4BLH35#lyI*uUKb+_Le4KcYL% z6Yn70hXG53)@GIX4()gFaU|0{L-iWGc#}y=f>DUbWASCi#ltIK$Wow6G0o)S73g38 zevL;I5V7{8QshH}KQwbQiEx{fUfkcvrv;Nj=eoUJt*a($q@Ut+t@i(8Hy8+A90qYG ztRL%mtDZ>2`P!}5)T60wrIU1`qjHh{XK;MkX+Oa4#pON|G}f|y{`odZ<-!>ccFNTI zIc})3b=}V%!s@wX^?OH$nu>MiJIisw4h@`g1mMj{aF1QYm4{SZb~Po(bT?1yu`oLh z5)Tb|hcB6T&fmX>(QBQSvuW4wkAJpDgR2T;jIux0jd~8w?YWF<8&Hd4ELL$utASj+ zNGLgXSvb7lj3tAW#s1@Jbtb>zL;G|Ngz1YXMpQ5|zM(YPCY$~)hzdwhr018cm61< z`_?2gX@C8yn*02)17}!D=W)k+i>$=^d7(qDIvi_)wB?#t$@1~af9&ZlGi@v_(l&;#C(d{_NUNZ(+y4Ri;O5d)>IQ7>NdGH~HFaJ6Lvb3Nd8PIJM%fDKE z1oW-#2@K}z%TfdS1~V8`w~+u*@eUI$WZZ9{|KR{%=NP05sfVVPhW7$NCgnS2F$aCP zk1|{?3zGvBZ6EC%*m>tZKir8NN5Rf~Z?`y0zhOJFfgw-`J}j%tcdZre$78E(*`04S zi-40u(gUvO_bCjyF(03k=8JueEZR)or#>pWk#Jt&g%EMIRD z7jRN#BY@WSx6kkUo%EYaa_Mb=WoZJSj|fWtJiqP{4A7U$P4x}oe_V@P@lK|-jgGcc zC;RXOXc6$&B|6VDy}VrK=Ma_LlW96iECsA-p63B)b`Tu1w_7t-84^P>GMO=N*?QlL z1O>iUkZ^C!UGc53gANxjlo9J#4{|?ep}@VvFsDd>R-3I$8r8oTOYlMeJ91x?m=#y8hlN_Z%|hkY5fe)Xl>8EMqy43% zrGx67PD{*M?gg{in&>gtZ%Xg5t(Q`wfQNJO`CkxR;%NFj)Yds>m>8yWr z24_CCe^y-Ls>PB{E1u)wvD<>68t=pP&zZMDAXGj~rS@Fp<(HBbL}}c2>1d>?Q*1Bf zs+*@p&imKw{jx5aEA8yG82|A(P#3<4GAWCUYdI?}^m02{vGfaMcmeG~X7534Q;Tux+g6bLn)0 z`7Xs+tsN(xL=t)1tE>g`j*AxPl^PNJ_gOrqNn@g2oJv*G=t0+`k=X9XbFPUyc{fkV zA)V|QLpW_*cEh}^${{OlJ7qMnem(n$qzBMEmbSb~{agc*rLmW62*xLG(f7TRYkcR3H8rK!B{uBN?KOg@DaNz1i;I`E>Cl7<(C?~CE{Z?z&2u8&kHHMgx=z44y%F^_VICsTs6CaSJ@I* z!od4h*&3(pAul~8-RP|3)=1(ZT}a+I!O%unnl^ux5jj2TtkEpzwc}_c#qFPrsLnQ4 zULBnY%omh)vGP#Us^ZN)4W6LpIq%F1rITkY zEh;Ds$u{pqoOde0-@YF^JkX=8 z?3KoD-~c=`?dMXl2E$mr$Xn3q> z+WeWgPexKy+9sEkh(u3@KXg%4DVicFMZM_Swgb2kB*i5hY6qplMKXg5pu+VtdF?Fr z2V%lyEY~6-y6Z~2PsPSD@GXA(R6qQlZyrb3^H&E}Di~;~)7(~LvBzfW@m&5+Y(&$a z^N-Z#fR07}JzC;aBfC7Q!;OdTg9I?wFf~V216vHH!aeOK?z=IjdLc()Gi=^t3$xXE zrrHJK{Wq!v0?lUu-RIjwar=>C(i;JLZMoMu%Rpx<4TY}t`9{svd{Yato67oD@J4}+ zP7(Bx1Y`8+;ebFjRRbnG+Is$eBw=VY>4EEcJ!nv2yuSX??;SAIZ#?GUyZZ|4t6OPq zPN{pNLjZ;s73I|GFR#pzJ`Re-Cs3i@uDgNJ8kLY$Q@@bqz2UF+E^h15C|Y6al*WD^ zKbgha*v4;mxgWh_5YNlMHmw6g=B7y=68x9d_GOUpNhHZ$t-+*D82B_>jcbBm%lvwa zU5TwghGK<#OyMvY&^JKUt=8d8N?nk*!5_+R{Kshie8X-ipYge^qHL2giBc)b9s%nL z*=ow+2Jh2#p})XctH#StyNFKPYAR>3SI-h}t5YvC1zbwQ44a4WM}11AbWDP$egd!S zoxBONbF3P%;X5n9;bPG%+0sH2&`?W z&BYNk-x&Kd+Erx;c8$!but&ZckKKZMuPKNW2XqHc4Ez)PpZ_jD;i@g*DtIX{IlI#nt*$B;pa({ezZ>ojD-zViv6GLP|T?}$+XE#Hckz~lUxL; zf4;qQmV|FBv)Cl{bHta~{BK!1e*VQvT}nr~d#@?>OG8mn(19t2SJLV=(mB7K=EO*M z;6-<9r{xI-lR)dxWN<$HAt&q)c=+SWUB{%QiFg$S( zy#+PxUk1Q8{}no;FDtP#M^-UsCxfD3xX~M?zyL0}q`YqkL@NxBFy&KQ8`6tQv6m{6 zME_XdE&I%OU~@_X z1n!YOItL&mtI6KbI*LO4(QI)a9_#c$;}Ma(`j2Xvp_#-HLny_%f%>*p)Xu;=LP>Tc zYHZy7k9D?_VMb?D^+X34^V;nT!UFZReDwa#fRG;WyCSSC1aVzv5fCi`!l~E~-s?tK zTTyT8Zp0s2oo*99nb1LOrJWp)Gh;Tf?Oi~@AsRWpv2alCDq;HZCP#~T-^O-uEM3tl zW;~{};SBEm*X{$M7GDRGaeC-~&iEo!h~!h_;hsmumcz`TOZ5)a*+q(vZoc<&(^h!& zwe$j2Ypu2Z0PpqtJlrI7!GaO9My&G40&=soiRP7*EiTGX^blS0KLTVaVC8IJvR|GJ5+FhetPadYi9=yanDQTwaZZ?_c|9awlomo(`wFMK)xxvzcnj#Jn8n^7%y+h60 z1*s~_7y@1HxPiimn54ed_&mp8Sw(P8ZwpH)qpGK;d0OBeEG+I{}4$89w17&VV|nt1Hw*SrW%&@N6eJ`?u0Y9 z^!O)tXYaeELXmOty)ue%LzRUEmLrGHboN=t_1;FBZrb_H^ZQki2;nfw5ZC0Ok^l7J zXUdtF52%GuHOgqosQ6^w5_>_k;K6k=18b2}pM$^l)fmp0^{+f<6uL{q(IK&4K@PJh z{wU3Zd$!S7JTa9gX<9b(i?emH;sQVmDU+4VKW+5QaNqUXZ0eTXK%!y|sRoTO=efwd zdi%f)YR+O#Z76NMWh6sf6JQ%2-^!>RJ@MU;f%j=MONK06k|$+xDd*wV@ZzlO6E!JS z)L?k|s5U=Zj615I@c&q95MLxhpVMmal&^i4Bi*y}qGGhfAWJN8&D-V`ImsEfU<}Mk zn4nX#pg%oz`WA5f#b-vWQ{dISA~UdoCOeV!bry935pwNV4Z_o^omeoKX=37R1vDQj zVya|eBjnwDH|*zvb{&#*yvhk3Ja4~mTd(6tmb(rGh_)@hbM8H4D{08!v{|Jofu^X$ z!uhANKQe2;1tj#~lJpTII8F_ET!OK5>d3|3@p1h9xz(h-*yN3EaN{NS(@Ca?iIgGM4dNgumu5oD2 zz^z5++u)w>5wA<{)g{MTOw`=B=XwT#W>lvQQkU(2girp1jRKtv9%L&eSWpwRoeLzo zFfiKNnD&RAf(!cqIbYBv2py`Y%j=sdylJ+MS$MX{Ka5r{t#6Qi#kv8d%`lQ*KZU>` z$){e3QXF^FXJuoZ`AS2e!Tz6Q*-uINf+7QX5I)($pK$Vtf@KUPR`h7{7uROyR)tt8 zs4AeAN@L zy8f9KU;$EB5|Qs#Rc%7j2<{I;%}vME#kq17>I=jLRxu|E40sThLL+%P7vmbO1+o0t z+}WalN(`$q<{5{y26EH;Pn%eZJHD2d`NB$fwogyasuzj({9*Y7O{-t1imV7!TKEUq z;lq#=lwsXyz!B5|a{tFb5Pp*aS_l$t*!UpalrOCDRU>4{i4$e@sVoE=!+rgV+N?=4 zA^hJZb>l_dMf%4P`^40>f)RxLVv&teSbx--I(4BGRZAo!x0Z4lKPl`cn}H9}l-0l2 z@~GmbGOp71%(MRD}GSRQR241_2F- z<_7tW^F}d8e;9Y3WX?|z`b}eco(ZFQdA@!~S#3rp>V_|mMtf4*#>KlEFA_F}@N8jBj5aq|x(0c$%2IU=XRn!^8>_;dv(c`R4t&5pe zTFrp@fmf4L*QF{-awR&>h1^sNb;koP1`RyBbvvaF$Q2=&ReH%EFIH&?wK*Y0jW`qv4zLc?@*!|TNJc+PeVh2s)Weg-27 znK{CqcosRoRo!xyH}50MS;}&osg9`?WP?L$u&~jje2kDBuw$-vz)E*dZ3cC;IFf z!gqXO!QXbNPi{u1+Ja9cxc{3e|5eBUa`OVBAw<+#uM~h)(x+ujF7_P!{UdCJ56Km> zbUpEwSMep(TNJIm@x>*K314?77ts_F%d;hop;2lxW?mVwEzp$h5guhc`E?f+>#x6h zQ+`6`+)Mn^u=t2TvJ<~i3+^KRMA)qY3F%a@Yt-HxtMn>djSc2Da$1EH-szVf{Vu9> zsuKI0o~?dJXPdsC_Iqz9`Hor2X@a|8@dGkN)3BX|4HpV7nVEr*)aH#qR}^|;`y8uM z$Ozdx%5b?GxT6Rn6-@7sMWF(St~MA5ZvLI3h}rAKb)F}*fXbrs-??lT2b%yDRKB7W zq$-a2@W?H%ooPh8Pgx&|XKl^VB&=H%tk6$e4-wz#WB!kA^zpg*VW&NN2PeK6NH&Ww z0cn7S=tmCYVvh9EmPTgn+mWx*&p>jsXkUE{@9S<<7XN1wsF+0=lbAS=sRPf}8o0Pmjr zJz89x3O!VKIxs3>X?>>vdL%i?%wU@0Lul7=`Au&X{5G{DWQV}^$ohFN121#{EGc_9 z6T!+m1=ihst4ok6T6_!M`1V`8{$w&qRk{94!ys6AYyq8kCW8m$YfJE_ae9w;JTzZS z4Jd3h>-}>U-1P=L)K$v9QRMqi0nG>4r2!-rDUM75 z%iFZtJe@?l+ic*#a%fyJHMg6~SgSP+-N{}1s^vzUfYLr%-1uIm6R-|q<5A$T89&rx zixGkC0(|9rQtRaL9j-Z2hQ5MadL8=J}^VRV(g*{a2Xf%Sh< zOeQd{tgHpSpcj&K-($AgoL{~kS z48LM>0nSfkOhha6vwaW3_5(lto#m0<1-?R`4`8o`-2BA`od)U zVy^dNNP>}5871vlK759{uE-#PtYmH$(p_(l?jgsUyuwL3SIiFUD0~zA;8hjjrBThL zGcaT;uy#Qqi!RlvQ@_yaQHx$gwRzShP?YIj{z}FqD zAlrXss#EX*qkE0JTQ3ecbZr?wF)+T??TfO#)VGPlF1(elrYg6H#dc2}9XX95)Pgd4 z#`A)M={I~VVJ^p7j{0kYUawzm<K)cUhKp{Qfb7pNDTN#lKuPYXQj$DLy9BH)M4uR zPZoOL#r^}0y#x2j`K|#+kjrC<@U_>(mbYnjPwUk0x~zeMW^J+dCRHrdbh|o}XYWj* z{rmF+$Mx^f$Y%v}=QURyC(5)ZPeG=Uz0k*=;_xJ$R%mK;EgSfGGzS1~`B(bac;AS7 z0Fh!9NHy2v2Tucfp;^>a9iq^9p!S{dD${n(U1ap-cghaK?))0Pu4erZCrB796_8>$ zc&&;;RIEcSF5g|r_2EmX-M^+cf`oCdcW`*q(M7-Vs9q6PWv`cGbWo?wqO$k(?D=G8 zhGASl!GF;cJ6hcBCl(Repr>VICdGb9%`SmMv53ts`I6@gE7Jur5!A4n9x*~qr^v=l zPjs?bSpuBxTieNQ;kgFtHSX%-bah+yh+NulSu2CTHHA|8$zR{w@Ukh?$dDm!*ja{+ahcVwbc*R7h;5dZlHj8+<&x8Kyw_aA^!o zAydQ^%Et%JKmop|!=<;D%NK?&RoKtb+n3whzvkwGd2n~;5L0M9&%^h8R|Kjv?YRc< zmcK92DW@B^LQq(?NZLp0&BH+axfsT2f^cn|v>F*`1!OFRRNh|Q;T z?~Pe~j_I;S;+9j8btlmkm!{@YPy{Z~gNtFf+?nMDTY%ZJB24D|;yfY{^aH!$@tW^R zd@Bb&{^lbQB#M7oNU1n@HP8w{k04yvmi|2=E`5>Bf2VmfBlXOPs{dS zNYiL1u;9o^_GPXYmunrzd$LZ_OMRniyjH*`xy>d9yEUPX zb$O}ATmk=avC;iBYMvwZinC7N5&})*U-b`RNiN40W(RkZ_rc?ZWWbwDJHali zjr!f;D$qbpatpfvOOP!-fOU}};g?=%uWu~uBkzy18C23;E7gL~a$4gKt?uRZd}bXE zc1jMf9M{m>h-}wQ$ZT)YL3MAo?ePVorb=Lvi)`@gG}Qqon7!>Q_wqUH|Mq*5WB^*x zM6R$!8qz1~MT(8>(oZGBh&G`2(h$j&4(Ju})vj&28H37}#&ef?SbYZBQWza!v$h#f zxf-UTLwyN1M8Ju2eB!G4#XhP82bMnBH~nbKb3H)gH|bKy1Oh2<8ei(?a?4>#h#H@$ z$neU4gXuv&qo9Y+*XCol2d>51dt;4NL;G^%%S#o&`y6ozCoTJIiCW*AdbCP}%zC6M z4i4bB%d_s>WKS(_V%#3CfBew-+6?64pZov!e@1Cgp2a6S7g5$;asaMc<|4(HLMy^c zeYZd`@(e-Gi_Pg*^Xr*Ia{xT}tnxE?wqWvofQXlH*2`PYg({6n2A@%jm#FB_Rngg( z%-&I0qguge5(K&(m7w;WHKrdzAeIz=p&iU&>)?P=jpEEZt!Q0qg>TR9GP||qt=44j zA94Rl3G|XprePI>Jkap+@#cf5D2od5Tg|RwE_&zgvhcmZqs-i?+5PC1M{BY6uKCfv zNb7Y;!*L4{+!nW%H-snsHpxY(2tCL`%J_fMK4@rsNEV_YRUAuws;Eygg}y!X=9u%R!MO6M!!Te!rqo z9Kc-LcC1vEwHe>u66nY&KGichWlC)_y0*t%LA#5sGT_)lO!2}QVS5iw%dyJlLlpOy zlJvh7+JJwr+|6%8$k+o;sbqcl<}CjhpGZxpZM|UsHcs$BvA#xW>SPEqabnVg`9@(* zX_{mCEBA_VcsTqUO z;+8+K)Y8bL_^MtNDZQvI04KsztByY&hWJU(6ydD*^T*%V2+F2>!M;8NgM3#UQsR1k zK53eEMvW^ROLAJiODY>MPTB7aI6RRUmxfPg6Jy@#4hK=U|N9K+9o42Q1+}V z{;+aTnGF%ofZR(Fq57*QGJ*)yB=!9aYA2VHk}1U;Q(2tThc-x66|44C7{xq7zT!gi z-eV&*s(&s)Ur8|b13~^mP7L`isQbr9wN;yjR7ti=9*!9*q5(bRZ#U?F2~5D?Z<`nDuN{0PS#_$OKpUV#t-+tnvor!(xiP>-sMgdx4V0#?#fDj) zM_DF3M0S}AT~8W)$t%ZGo1Sf?jHsKl7SpMYYd`0jt0D+S{ADpa{HislXB91tmXoo~Th&N~=ClNw~(zL1dK$ zK+Buy>%4hG3+F#SCUUIyx?OgVmEhUdK zt+l;{H8bmMHUiM^qLa8YmXXjXn1JXQHUBO+ zPj6ZJ&aUvWrzAK2B2@tUzdnZScPEZUolxXzsGSGh#C0N_Q32;NtSN;NM_TOt-a$c6DXHz$ z%xN`vo7IZ1OlbZ71Bcv%ZsO^7H~HCSkcmI3qK5Yv!RjSS?h;OEK*IGX*#io@P?|$@ zSfQ~%x>oalq^`fi0i!Bt@eq@B_BgACE9j|{#K2Xv4J)7cFE8aV5yjP~vLK^~E||9!jm!}Sz_%Z8W@PjWDjWl}x-I_5`(NL^Z+bZ+xqCf+ zw2nz7Z)!~7Ix^c^bKF>V2n~u+*YUZio9OKExrl#1_63@dQ5fXA{DnLP&K5*O2qSyr z)_Liy=EB@AUf7hgzgU{diurl}Z?F1)zIvnNH-G!y#|>XouNCh$h+Zrb5f;5r{2$Yo zrtUM47h=Gl@AGFw)a_s4j?QVVFDt`zw8>&si~X~whWX}FLME=5pNH_fk9CRsJ)R%* z*4mS@Hq<$7&B%xsahx!1j6Nvquar-$Q zk<@(g?Wh>zLi_A%(eTMJ{;3F131`@szC3VhMQN~``0hc(QhG0t; zr-rtcr4Ct_7{*g0CL|hc_%q?#+kL{yTMGB*!x*zsl(sHUt5nsS`=amzA`JaBHnzcK zAd!C*iXtEd7zwLsJzDCpK^tA=mDsy2(GN#?67=qOx?tMHQ@O1HIpaEn!!nBd?k@Os zzEk~cCnKFx|5kA#Qd1h|tJ_pg<+!@))oq6e_BW8v)Ge#-Hh2~Z}PkkWD*ZXNeMdY-}g(x!!aU-KCW0C!yo3vr*qLg?Pe9;+`wDMB%_Op z+l|RS9qiKZl3*(j@CLTdi6_q5xYnbDOFKtz`MqFYp%iMoo71{IKgz1qdwfV;(@|zX zsSzwUqJaH(l#D_LeXK;}^Tu_jUh~EDl41ZO|9 zl1hJR+4#Vx(;c(MT~cf6q}woBa?9}2XtAv{VzUDslBHsbcKzurz`BFJU6t#@jx$dl z1bB$J!E*R#_ehRW<8{vZc!d3VhW~UkWTQ2e`9bu4yRC>Hb!)2VOjZWj9Q!ZITH{OM zu`;YNcgf!W*ro08O^bCT%|#z9utNK4c@H)v^Nk4oe<<*`+V{N)6z6%HADpp`K*n~J z$<1!~D|veuDaNr3yG0WmyuIiNP~~PMJ_+P76o(A>M5#^5CiDxm$> zl=XiSYaA3PNgla=Z)gNYB1{=q^NBx!Ly(V0%h5{b2)PY!ZiB?Bn8s+5uL3^#Nc{1Z zT-`bM32X$Lhh0UwBjl0UBy`mh4YU$HQ2UsSfm}`N-;PX(rkO$97SYDPtWRStnyxp_ z>8&TTUR$8(%i^i{1E`U+01pL^W^C5U74NcrFz8L6RL*ddH&mMIWg zK1U?L3Ks{_spKlXk(+8;qX=aigRy3h%kzdyck=I``1hX;;dh(cdJLiCPcewMUafa1 z^`}|Zs$txEi3jP7r}b&q3vs0rv1g~c4-0%K%z9((N;Z|B$~%pyKCi3|so5D(b6mu$ zeA&l>3x@s{7;p(~(PXRap28Ey;jPBLdYb1`hh}7`?4grFbd${jpfxGS9X>cwaYA(( z9r`XbX%GG3EGowr1qoO71poBfZO$&9Ip)KSODGIVA`PR@`nJQrHq7sSC}L36ZLd1W zNadl8Oc%gudXNJ{;Jv2Sm57PUP^?c;tV=h8;W+T3tQ#3}W???E?o6sXa#$B1e(bJt z8jHY{Ff~L6AWJ^#pJM?-BS0#Kc9dZ~ttkiQCvnVOd%#5dDg5@0`}eD!{n`)6D$>Uq z1hLcf_auD1f05Jw0Zh;oG7^FU-Ce-2WtgpA!@v!A1L3>L4^-7`(4U>(INC->WxS`6 zkdYhi^G(6P`1HSLMKJ9^h2R$VQcop#xkAt;H*!AOcYYO>Y*XI(t#(EqK{c$um8dU) z^g}});aM%^;aQyY43$6%J=KmkXg*V0+p&vYoqz~UuYM>jRxc}b^4$cdrcX^VNzgN4 z=Z*x^!Zq9NJ6Lw%1AMn7Pm&(iGIvzeh{9~~JnB=%J#zvwG)w9D9{GcTBr8LiI3NcC z6wQsXYm$Wzb#CQL2nr7=LoWq%c%+yvjNbE$$N1*oy`aA5YFPt0=Q^OMzSbA#1mp^I`BaJ+#mlzfI2?5i=>V zl53SJZVzV`|Msy+EfC_gC}TCQY;7*5MkXV_3l!CL5mZs7Ol7p17`br6v-;89;fooh z@_~YI)x{~TY>^6$v-n3GjpBf#BAnh8WDFAD|Cs;p(pDb0s;LBgSI1&JZ#U?<97yhu zFFtXro+!g0(#BMjqM3UX=Bk(nck@mJL?q>n0F`6 zK0U;H_aN@xlN$7S|6rU)-_tOGKfLfGsHp8R?cLY{tDT}Rr|^(5jV$m~R?;A}mPR62 zT@SKVB^k*Y8jT)m?_}AfzfXqzT9Op90*MN0{ARC6G z4!AjLJsPvBqTrjf2!)pEhxUh3&IgLm(3IS}wEK+MU?iffc0s0wYR}~AO^=-Ub+Vl z*`nX;GZzLO&Sga(15!^ye}cb5CE)l~;yw(H$c`T+haOIo@FNHb-7|qvyLGcP=(+v` zbz71O_yO?wVs>CF)Uz)`9J;$Tjx@CCmbGZKqAMz6ELlc~j41$$du;iBt(fjPpo~1T zfOAiT@<*ODs6Z-ZRM*5iSzS}MoZH`k0z5EzLSr>H0CZjAE^R)h#j~iDKD6aR5j;J? zJvIBos_R_L75n=dRCMKE_AzCj>Zczxt$p)KmhWs)4GY}@K6il($;6JSh?z0nKO&%;K_LV+q5$`7pbc$X& zgRKt^&iNJ;iJ?<>;|AbFMqXg;50xsk$#Rij#VREdpBpAEO)JHVrT+uWoMq;k5y6MYzE4payFL7TmJ{10Ax5{5rfKy2P@2r;^Zi5ecMeRda@|wBW^aW4M(oNHJ` zdq1M1de`*T`?FL1(_CeOl3|fmZHL_1+`UZ$w<Ku3JqpF@H{f$aY_RUp&{Pu!ay)&0-(X7JuH11a>Uq3eQ<#DbF< zsIWUVwe(j8bDlYXws?RuY&3MVXJb2HMQTXy??xZO>RvF-zinKnUNVZQyr!? zopxPjU%rq> zs)qN((M@@kn44^w8bY}+f&X!e-hqe66Y{v_A7yBWV0?-969NsOD{WxXxd#h*nEQFB z%Fs3{%_}&qK8ae(0ie&6qCBoV0#5O58y!|jMYK2+r%WQ2hxG{+tR?Ogajhe?qPVpK zzow%{*>^#8jgERc?ijhIfUIzKQq7Vd2cCkZ6n`iT3k45V{w9Xz$L#g=q5%hXg#eY#Bi25G;z2A{g3NizIIMZ=>$N8-Cl=hZ8&Uya+GB zDj&3McyTE2LSiEm%zx4|3^s9l2TP=EUxj3^#XWp)tm=n0-7I%j8-kQ;OaZn2?N5?O z+mZw2y3;#N_t9nngw^OlgW*YbHfiG@#bEI#A&CC5vp`3Kc%$__dYK{t6$~epucq;` z?P2~0d65d1C4DEycF~{a{luTxo6EMN8-8EvVF%~+L=IM#-!EJIHH{~kAz920bX^cB zGjE9ul88$1H)tCT7~$dGj3rNj7fs4umO*I^enIaYQh<=*@yS>B)o$?n^P^84rdAQH zR-dP>gQtvr!b~4%eU@5g8Osl8hX-O0aaPKXypVgBZIXGXIW z$K2LYmrMi-!BLwv*-E88sdf$4c)Ab#OR%s ziUT#dPeNWUwYW({y(HDYB{c#vK~E*T$?VPT{e@rF^Ddr~Ekn}F?XV!Q$|eR0+3+hO z)(NxDjKqicXW5;N*Suf@LW92h;?J)z-<$QI6%lmr`>N`S-&c8YEb9#C+(&U;U@4Rs zO%z;ntDYYx=lJAvvJ|xzz2<|USVc@Yl&P@GcsNQwHFf%q!;Y+bh?r#b^?qIEG}1gW z-genJQ)Pm>lUXt^H5;LHc?MHtqPa;+-%Tx?CBF=8NGv~C5POz#*VDJ4s=Z&wYS-jU1{PoQ15$Y#cuzh;yzPbeGJK2U-zT~cl0a8ZKfmry@?pvtLu zo6jD)c*k-lrOAw3^Usgl+#M@aR{<_=JJ3LVkM&|Psg^bMEn{p-sdP62mL-X?B7IRS z^p#S}#TgyGI-TYLwF={iHraX6u=qqV-A@J4C=E3pt5@+@!Rh}BTZD`TzqKt)H15xW z4B(&Pgb#P&PF%fPE~6`ol6cNB$Su<`yUw39Jv-ne>ggDxhCem&V3hZYMpa9^{2 z9AEnu-<-Qo&1Y;5?Ht9QkPy#a5zaUNiXhkHb)Mtp{$)a-sqT3Bpltn+#J}s#pt<*A z==ovZ#JmJ|W%0&nN6EbBgKslty@b>?Vbln50kadLPRNqU%0$0U`+0;K9W-M$@+TzX zkXk@U;sX)O4Ui2(S@)lHtN$#QabSRZ?_dcqy36mpMPS|e%9EuI-)oDY%m2P#9sens zMokFG{~@%5J}viYO5g9M+nmR)V=sJS{n1*|LDBw$F%5_pZxqzzbn}*{Ut}%NbZ&@ ze35{I`Wb=ZzY~?ypWNB2RlXRca1LsP-%bsKYVZKB7XAVb8M^XZ?tNC%$k)DIp3XLa z)D~nkm|Ixnn&tiqQ6@FkoxS$W83gP&`n&*U!7Yc;JqkJiom^jNzLT2xB|1=Ff5dyQ zYajq=4H8U3Y5#TA$D0J_yT!6+CQE-(GIDjasqmJVo{Z)I6P&XyL9gQbA$R&Xs-I6k0w@9sTINsE8V*$Lrskb=JPs(^B1e(?J>X_JfR9 z839a7#Qt#=#=g@@6;lnO=sv`u+8CT>W&+j)ySc(f#{Szk5GIy0LohX!&q3jFMn7v7JxSD-3$B zfXzoo%aNOlDaB~eDR&rUKm``>j^|t_L!jeGNeQ(?R=#Ds*cycX%X$&3nm1bJ1vFd_ zh$CqI+dc1kS{CLM=AY~4BWT-YTP2y^Oc}$u9!^!&AN-mMCC8DrUO`p-EPnbBP6i&&;tQHlnlY_}0DuVnlQWhy!ydh=S-r z90PlDmv*funfE4CXzcL)I^XRb8=!<)JA=N(lMYai`I#rUK_ZlKq$%W!rEsk=1^OIr zLw#VL&lCw;dCBwYhsD^bqJBdsKRclcZv*x9vtLQ^c z+7D}b-9nB+I8BV-)cw!k3i^Lf0CpAvYGuqoPxWwgE>GTSsX{73sI*^sg!3PgOCd40N|jW$5W$sZUPO%phPyj2BN#T z>#0{a}eR?qf` zS`osABst%dN@d7AXW<8@uQJGsvhJ+zw+GB8vI^p}vnqQ+-`3sr8^7!o#X(NuWSoiM zxW*8PSV}T7YVNVH!>YU{D|Yr;veh(rTbL88EY|bVJEC)-Q+sbY!q3O zE0@G5Nijgt(&$>s?mdf7CZp4{IpNZ=lD*#&X>)e`d^06(^GQ!nB26l zRKZqURqIu5&0y+w)R#PQk3~o&y{(wAOc#7AR9W>`%dYf=OOXxwh z6BlwJi`$0PnY(z>Vt3o-HZ&EqH;lB&MA>0YQCYHNL+{8mUE^{IgliPm& zti!$UZeY*Km9ot>P6aiyX|Xu`bf$%ZTwJhCpySz{%<kIAAK5>MXoUT?^&ExO4as`!!Js}S9~EzxBX?17j@nWJI4^@|gMdR>`$ zfJkkw7yF%^e^Uw(L7Y#C3d{*|DRne!kSe2SlcDbwknP8O)qy%~hcJAuMwiy(36dLr zB1g##9tLb&MAz%2~bZsv6b?zFtMFZMT zk4Pl^JxdwCUCokI%Z&IvyeTM8k5I_6v#AWb-l@mF^YvIR+^0?5YFpj`?omaaQ#VX3I1)0M<)`QE*D$SctAHu3HIwr~xxNSPrWd&vmVPmZ6b)raKLc!$s2 z$G37LH&zn3E$d}Us*s>an5xgX7wqp-?>ZmIHO-Rax7+3H%(B}vcxJPLZXBk=Xnt59 zRd3H6$pv286o@M1!VM9DFui8ye$I>W{YsT`amL`QG8%i^ zOOd}_q2%?+q$WSg`tb)nuD z*U8%3u>;gVG7>7NBUVLRL~TUy9zE|2r+PYTJIBJpI|r|CaU8%akP0g?M7(|KwC&qv z?U%au6g6?>)tT>ex$_{8Y~SRv8!R8eQLcr}&2K+FMX7!kPuC#9(jUXQ#9!_zU8)4b zL@hGcRnahSZ5|WN-^^uY@AlHKKBw;mKm>F5GcrU>Zu#==JrrTU-#W@OC(9iZ(Ae zQMk^Zr>n2|zn;B0y4C(Fi0G~bhV3_WU&lHc^v1gdzxGB!R2Nk=g#eF%pn(4SRNSRIHjt0=vZVleP=VWXFvDi z;$6p**G?-LU8Ty5!CO8|Sz!H0=Go{WyJnyti4_F0jISt?zkY$o@qR6H_Fy=0f zUSY1vbt8V(6$o&|*EzaHlfvSDuAr&X($x1}o~xGWfe+2^m9ugU62EGKMtQA$1`}|- zQe3#R_nBP03h6oP)8@Sy&!oWcwovAuwH-E_{W@W4?fZo5IQZ_yQQD&22$Q&TBm|s{ zRBuYW{^e`@^O}`X8~>$rw$5tJ;>9{cZU<}I`EqpdvUzM8vwI(FEPu_nJ;~;Xzi0lh zHQ31fYx=ozxsFILP8lEe2wn=xO;oK$v?u7!DyB_)O=Zv{+(So*O`oe%-&R^e?-xo3 z&pJAtTS{a;^%(WFjVdL5gVGjOPEGw-{%y4HVtk6Al6{a0tG%5NDZMzX=|s55CUaZX zL?v7&sgiz)P%PSwG~Re%*>q5-yB+uaEl7Z2ST)#RtrbS!a&D!v54w4G#w^&HkUo#ikSr^NY3( zvHU;1zSs=T$DfD!mi$OCLp<{!vgnNE5S`D!xmQYTLvN=B-9lKlqIxKa8>!Ea=@pW| zI7{!&J5v0XZsguCCGd|U^yU5B%yk4>Y@~!I#O6vmGZxip;5K+wmWy6N!{S5c!4}3; zzaJ|B_@{%7do&KN4=Cmwkxlm`6`?cV_{~eM$E_~fEAS8R$60$rX%2dm;{_U0?N!1> z=&%t-gRP75e;n3d9bagg#I)Bavh77bWy`fN3;4e+ppucxc9m^Dp5adXET1~CV#`oX zlq$SK_!26>__iXj=K9uwqkk?g%g;5iGLu*f+lf+w=`Fy$m#YfqFeThe)N&gDWLGGo zQC!p}@T`bb4#}+~m4)4bwDfulF%$(y5_|{t-yh7pfO}uBE=eGqLk8=aa=^7?Ds8uR z8g}+^25)FO!j>>{DEN!Vo>)eUr3})Y@Hf>%NTX4uo60K7QYKUS=1W$kqyt zMlHPTQ9iue!}v)aci{Y&Tmk2krVG~+^59ZeGWP8dk`g?lV#yGaa@$mv+pj|A3^cB%3g}y_?8IV3!m5X?BFEVe$Hy&vs!Cka?q$+tp=`E z&+Il8MP*NPP7hL(jH_*x#BtvKvSLL4GxoU_)B$Ztalry4uWlT|K>71oXRXCiE<0MeajX%=G*RBjVx|?VS*J+Cg5qSf%pZn&KE> z$KjoCG*`)U04?6=L2Q^j+_W2$V@r*m_6Dc${LQD{8&_I|nWp0CThXSM{kmHTfN6|s zGL5!Xc1}$7)=WmJ3z=0RYC7;s5%{>k%***#=s$-?7!Y6&6UTr1!<7iA2c=PYc$uI# z1N((~fY$pN{J^2{@!YG$C=_TEn&kGC&o3b#o??9``X>9Lji!o;qxykY8}4>0ZBjrM z-|?xC$`?-~>*Mr1`6-a0asANAUDC<_6n#&Ly-Ko=w)MFK+*T;(ND|B3)Uhxs32C>A z>fTbotz5NE9Z(}vwMMf@YpdyT(FQSTe4ZYjWMCW?@aFJp} zv4CREsjNg{by6^o*0GkrrKzj=m7dEeHrifFx+e5ti|ILJe`uhL%AG_0?V+>X-#p4H z!|6CGb#2rw-Sx!RnV>?`4%oP4I|%XXK083eRSsbACjT9JKEIz-{Un9PO{T$w4WB&zm;hWgP@o#z!Jh$ zWol5U<9RLpIb+531X7DKcT_6xO>!DeD&JcCrn$J?*$X-A(`;P>^y$dJJr>6~$aSNUdBTEEkfi2ZX!NgPyi9 zHmv*gnznEVvE7Qx@eOtxezM`$$MVXe7gi2b7hX7-ofx?*bj&&be0s!zK2zrgofa8D z%d(?Mi;Ii8qhvcDyGro8OV=qpo0~3%Y3**S;ZA01kvC zK^t;n)g!IJ@Q`vUM$-gq_)FB;sV0RR?FZkd zt%N2~+e|D09FNZ&0aQ8kkH3h+66u0R2cigNz>O+xync7X=4nf z_PVV|Xt5OY-7@JcHdcY;U0vFtu0?nc-GMRJEt*MZX*)Jj`nvj)D4 zBn5ql6!lMcBZaX+H~8m$?U~ZMOCOw^i&SgH$nYcge9BxShA;+AIpvAe4|thqeTn}E zWdHidXaSlk$mpCvWQXd2g%i$S%47#7WM{f9WwOavpK*DFuwB0r$H=&y30{W?Dnid3 ziYMEs0rsR^Ax*TWYt{!o#r8zz?hIi|MBirSPE%G&FuOk|Gw<7sAgl}TO(GS=13m?#)#R9Ht)YYX6WBZrc3Ww?=_PWYOam_=p zYX#79j~FzMX9Ij}zCCet?njk=E8g#nW?13#4(GhgS6~uv@6h69uk@STB21M{H)b&# zh9Ce^yA6Aum0rHlA*Nd@q?6U4v?w&8BnPSFbt=-Y(W)O?_#))6YuegJV3x$CF4G!JM|JGNJDD2erHowCQRLyjA^ zf+W4L=lqG4hfi=+SK5F_w@Ji5I|AsXv7B4z4pbk`Kel+q0xb$!EecRMq@>b~5ecMW zD!e(}btZRDf9|#xkUXB}2MiQvYq&|jl#_Has7D&kdi8rGFhAs~i)z3|;{UicB7_V6 zCn^mHK!gTm)G4Dh77CfEEqcg0tk8uhDdP2=b|5{2tM6%TCk70LS=OW>s^gdFg(({0 zo1XoPkbN!ZpxL>t;F|Y-VPUMMJ{eOwWw?u!ss1Iv6*Bcx<;V~8%4Re*>23!LTvcEU z-QdXkYTs247wmYCGWD%(xE-TvJkU+2$|4*iwz)iRFgmr?ZF%VbAaS6*A4H}2^2F26 zbHO11n4M2#B{2U-!u{%V zNA>66VFHb6Y}w~63NYkZ+2vOEvE%7vOS?XTRE;9+;<>Fn&#dM<_Uy@f4hr=+^F z8LlgeI0N+K?1qrka-y`Hvv4`K5?>B&eS>||v|W!@eNGZi zRm%=d*)>kG2Y*i7&q2y?mLeh+v}hutX2UeTKacb8&%*;{8F$o8Zvix<2~rn4(p9g^ zV+2P7sDthCa;kDNbucQ2kW~6;%}{nXB{XH=5-%v#lwCf} z4Q@#(+k}7sF_l>sXDzXZKGub$@&Hy$b^AXOJ}7eTlL|gIql9C?_9^vjL8s~AGM`^zP`b!db6r1Wm^};}Eu+x|z(gmq!m^B9VOb9cL2>E}2{`bFUp@8cPgQ^6} zwf7hJV^HtyY#ih2J%v+R+co4Ko82R6rpzrdD0?U3M>^HQd7XNN9zwgC@FSm5$P6>` z5r|smcm}tv!}nx=0~uZt#rqna%jl6gFZtksJkmE&Y3_ddai@zhi|cq=;4)USw_(Ty_auI@ZjdYV&N`_`l}(voI*g#nRVF5=1t| zew5G%q(S1D#OG16qD>I{)MC^IG^yLh`(z)BMKK`=Hwcq)2a(x zop)=kNmE-;G~LJbULkG7f$YO(f&MdNgC_IrH_)!)C?MKEd~Y~BlBQ2-xkufvU3l05 z93TO1F_2!USpt?ei*<>XU5s()b3Ka%WP>q-gavVJbs8i9og%=s0%aRp6$H6&I3+_D zi6=ykq%lET>;?&c26NCB%|RmcJ%*kIyRmfRm9?)SdO~saEVCTvYWz|N<|<*Fi%MBa z#jN>*Bp;=>{wqIL9tovwA@j41<^3YNb%D-RkWMnq{4-_x9nOHXK)h37hxbW1h0LV! zV(f7pEarV+xU8dX4p7!4+I^ILv_^z_i+mZSSTaPkb|BCnkx}GdqgH?gjk?|;_o>MQ zBu@FBx=B2GtodBDOz8gnz6YVVdNY}G`P^pC0NR1aTnqXYEh?%WAgLgy-18d94w7on z><0=~5Dnsg- zLzW%wIHy}o5w!Xi1r@YP()s2}M9yxB`#(P}Fz*wgFRtq74-;g}(g5zFgUC$+fWpJ( z(hym{J{Nwi`@Qqc<_+i=p_ofEVYxjl#Mgbmi@f!tAk4(R&dzzDVqe-z*^8|HkSo7U z)M68=Qv=@Rkn*bKB}a0mz*<}Be);4UAe~6XlvE9t zTRd9~mT~F~U&Ai;zXKc;oG9qb3tn5$Si;^msfU4RQ)|0uQt7C4zj^%H&B`VY@$&5a z7Yx`rM6kBiMhf%!J07vd$qOLktQA74Dt5*i_kC@hXu)KT|8f!AdT5eOvRuEDQe!Kn zb_6b!e7)ipMH5-PE%~By6}}!1c`+G%K9#RdwxOg<^vTo0<)>t68a6$M8Trie-Jp(JY(Iabwhtqca zjgzjB_MC>A4AZvgoJKfSbr?@5#y^KCcm^SwFRprewEpU~F2MEy0Fo>6s*X3tXtwYM zb49nvesd=bZ+c%|P8PUMB>?r!uLc6mIo}k39=(}>Y(h-VK*wD8MbG{u2Hm6S7U&L8 zmBNr9rwjBNEKPvBQ~i$Y|9Jrf+lyYTQEi(|$`Vi1lsFE}r#_h{hAX$;8_*>A*<59j zkxeA{#TltBZ&OGQK)EF%9P=+pV8!q0p=se+tbH^Bo)~S1Q0$=#9+IE4`t}0Gtixk^f_~NV4z83+48@+8`3aoKIpw zI>u}1q&QUCuQ3jDT&8WWSU(a8RSx6km@e*Mh4Fa**~;h$&;?W_&Cef-1J0BHXUJT;lh9JJ6w6(( zwyatJ%dglCt3cv{l~DhT+g~6Frz3P7n(>Er-g<{fYFhzfws$k|UP=T6a^s_Gi{@&! z7vc&F$IvGFwq-##flvQ`IeQf1#+DF`*tq!Z5JeRB`W<|AG2r>@8zS z#dIjeB&V!nkgt2!=ZEBgd{(~uqS-Y)jbt_S)sJn5s{mjz>hjQ!C-*a|(YKo&=Rt^f zP1+?J7+okorzq#~;&AXJEM?|CN^EgDCHd~_P-)@Xj*a@hFPoHdpV0eM4DYC)di`(x ze&aVe^a)JY%LQjg^=bO*@RWtD@(Uyfl!SCEK2$vs=vsBY7Rl*XJsOp#oy|Ks>dR-= zUSf2e8lDmS{6F^IGOnua3mX*#K~QN>x?4~hN$C)fZctLXbCXJUBOsm9-6;l#ow0ST64`g<`~Zy;~8VkRX?!TAGT5fU#y&qNJGQOBJ|F;`+N^A zO>4K|)#_6PB2LWX^^4=(uN`MNsvQJ9kc)*KxblzqG~oEFh*M))Bd%E$dbLYTP`4=s zeGLk`%n2mdo5Qh1a#dfZS0&>C2xMdtzTw?I?b%t77W&T*^EjXW(8G9)bVYF<-dum|l8qKl|4@VnjU0mSe?G<%Ba|P0nEB zBOdwE740iY6k&A3Yu*l9$F_-kt+gn8G(~gcrcH0vLxhP8hdNbkpT~qvj181*4m0IN z%Cn?C{~ogjCokb*lg28FpNfAb*o{nDyw;F;Km4sAZexXdXeQ+}LVnL=;lSi%W81up zhp|fWYn!DMGFN;oP4{)ht?U)DCX6>G5hjT=;H%EepojhvOVkw3QJAa}vc3Q>ImoAC z8~972aVW7+;7tco43%gh;Xmi#7@Jf!q)93s=PZZ3H>>EI>!-mP!JKc}6E=K?hty8E zw9}RxJ@vl+hFnH&Uq@OL9O9Zxy!$9ABI~|Cp2UVBcI=g%K-M~BXfE#bjCT4eGRs9v z&Ds8C%S!P|k*|>f)>3abqk3eLo8G6==UZHck8$hl#afGdf&)p9r#Dc#`*3xoTEpV~ zdX9xPD0wI=Nms{voF3-Zi*U{}sD6@a+hWgze03>6cebVE$qto@S+SPiBwKem&0IVD zwnP*2E`6u%or!%$kjaT;MSoNYGbcS)KWhl?XQ6PW!4BQJ~-?xPXTHYWl zoT~Xq=T!)I+H-VI7GFnxO0%#SEsQOHf%B1VL)6LogI(uNwCnf6FF~jNC;iU0#j>+( zZhdj-(5bW`X)GhY9W%76ro5Or1zSAsbL{`Y##f&nToy6Dep-Xq(0qT{DX&N);WdiPf^1 zJ5++i8=PD;-kOy-)&*PNA@GlUpO8mkQ!%5lJfTwXoO)#^yx!Z6CxIQw-|3y$9W;}jF=)WGE;W<`R?mcWOXvxtp7>JGgfGrL>0$u$ zTFE{67smqR3`)&R_V05)%MOJtZpQc_-^E;*!zCu}yP$bpvbcBr)T~2jufQ=YasvMH zyfD;9ltPp9jC(IC+wFL6-axH_Qi4e9Z7wH6<(kUgr)Iw@>&9oMSc*?R`1hXW#7smRA^6pmQ#!vELiNTnpQc z@`DpYTcZauw6gmYbEw67((Bwon{m=_Yr|eTHAa3V7?9%mEQ9xyd68}nPD3-t%(>d-)vIL0=j>NGYio2CwPsH8!>-z< zwN7*ERrK!sOCg|P#h?t0%BB4#-s{2Srg{c)(#6sIWO^F^&*B_r<2g3zC~PNH88OO9<8()mgN>ql?O@y_~VAlDV3b3DERt-2;DtUoF`47`ABp(o#m) zllpm;N}E$s_QQnBizl%HUi^lh<_Cz0d2;XXz$U_{9m-~B_1edDs*kT3_t5ENsmaxf zg*cc?iYLQK$6IxW8a}Na9b;Na69zL=9ye}@tIAjP#~p}>cNHBIIXVtgrF}1oMA5Xl z$}iDwFgl-ajA&z~E5~@Xk`oX{Zo~+oAZdfQZ5bqGM99F>#-wfv7S& zUMJQZsDU-UR&*CLqK%EGQw%6@z0y_H)r?9DjTX>}-qjN)db+L~9rjM#Y>fsh0UxK< zy{P815L0y5GFN7nT#c|2Em!7E7YP`i>&Qzrjjd{-!B$j;8_ug@3 ze)j{zIE>YXsG3^6_Ti}Epcnu2ktDA?K!WZw%Oi@tmj&`)A<HV{tpJawP(y+{huRiqOVXIO<4$i$UR?uGKIQzba zImPRjpSSiBC*7-qhNQ$=>=XGhjxX+(YvSj!#&^`PA<-GBhGK#YaoSiBvP@S2Q>13W z6vEsJugSd+(iplh6deMfS8}*C;)^g|W&^|!9e&lPPkcD`+ey969+P@!QZJS-Gi=EI z7Vs=sz{--K+1EA9eOt5e#3(v}6C(l*yl@m@%Gb^_HnrSwDMPLtWlOG>0WwDhL*LVl zxgnW}1fcfFtuA9upsY^Z9~b>JPL;}3*t-$Q%gZZ-AbE0Jss9`(t!f*TUaep3um=+j zMR8^bQjt{de}4!a)ws;&xu|s8omCdx6v371dM0RmTkZh4~jdy%2Tn zii?m<83@{#k9eB6WTc+S#!R;?r>!44uY&($THyya5XLdD3Yo99%$#{j@xfBl0_arh zboOie_6nDf^9b?SiDWm)rKmgs=B)sZk~**?QTk(a0t?Yb4q1D>lDZ_JP9K-hUsYs* z5%ze@kX4@|#Hf_b-IZL_YIR=ds@;PFL;;|d@+*anNRQh33>(*QD647$SL{h?#+Q+8 zBiq@kaH)sqp9l&!r!I-omH5CxonZ}18t4cZ4)e88R&KR}BD8aND~8l$e!2ESVZ;ZyRH?Ibq*rpCB)57n=Pk{1@3%Feg6TFg ze6RqS1=p5@6=6w@fO&3M{?Y99=7`3sV{@Wo)+dhQi5X|>l1&O}>%qt5QaR+(X?~9x zL?7U2Z<+I6qDf7@FX@WXH+$FWsG$+#=BZy1>Qii5JR zpg5>huyifxIO3U^pNaG0bU?>OX;wVoUQUZ2%ch<%<4o#}TOpCw(9ES}ob+9&$v^j+ zZ2i*Cre`Rq7)-W2%j?rC2)i5)ai(2`!5MmWyb?RoPopD9c8 z4xAx&hCLRpPsc|Qf_%55@1yO1Wd2+d_XGVSCsYLO!$BX(-`Ja*i89`hCd;FHO%t?A z+;hC|5}wPt(Cs&EAqV?>B&5X7dT2)p(Xhjx#|6C`vKJ4cuzzj;xWSAsUx}{0LsC&^ zC+Db*;9-gnt6e#VF#F=x=+?z+0RbtS0kr8zgu&-hSFea!hT@ngtssWTqSb#qe-I%3 zo>zHs!PCddzi=2QA(*LouP$MFUwn~$kIQy6h8J5E{7t7S=v%V1f-#!9JFauSl=K;l zY6NqTk@=ICdRy&713nLvr-B4u+28;yI9Ht=ra={UzxqOq=NjBEamrt8V{;EIEn{e> zB_i>&HCUjzW)G+$RMR~OuVC*>V012{AP*QQBqH&fY2ZMaDt=o~cQ1|TS6}kin2gB9 z7ZW`TcX12LQ%i@Y$ZNw8Mx;<#?GxXjq2+$IFh*m>q1bl)qHf-P5_rw3ttp?Dq>=AM zP^xSgh@wN>)3n0Qg1;77aWE3t56Zb1xgY%-8TuEAV;KuDa9NO6CUvCPHaq-K(lV&^?bTDC&Ovx12O0TL&W7~Cb%Cc!#P{@b5P>i^aDC)*?ygHE;gC38)3X-*bp3xCIqCm`xzos^UR=i zpxX!)}Hp`zlzN+a3~6b-hfcpq5Zy%11n`|}Bnl>Fxt<4RtR zmvYT47M_lsMJic6ld3>$ZpG`PE&U@If1_g^vlE$?E%$jaYK0KK97c)5VAE?(ujc){(HggMn-Toz}^x!!F;@40KPIx zB7463NLO86l-*E@=#$5LM+G}4e~xG5elQ^mWSRjOBFrgwY(FR#tG=j1;aG zZW1YPY)qml)`d?wb2XMRAgkkXYVoj#I<6`T9;?ZUYAVt4=Jf>XM}uYXRE+}Xhc0s> z!DSa(otK&rfxM&TpxRbg|HG0-oAYW`>Cqvd?ZA+v-)(U>g@1b91#1t-vXh!e?{UcW z!-l6g#9VlXH05JW>jy}VFocOXyOOlKc{O9#~ZV zP~2LWVDFf&e}I&ej#r(DQZgLPjg{)X@GV;zCPrj~K|E;a$vzS<_13pZa^4k;V|YET zG`@NaGu~|QD!1t{w||%^G&%oiuY4RXm-fCldXE>)Q6nnC^INv6krvQjWo4gg7vNp% z+Vcuj;iV8^kNH>UE4j0gguA1!5qKCR4Pvs=g!V@dOE{S&>k%~l@BA(WKwFZrb{)?h zXS2*gxi1V<_4~@jb&0B7#RXh!5dyEgg&lY8#C>?kXMKz%BbWqA>*ZBwr zm5?IWznSap$GF(7K&Wy(e(wlfp4&`R?x8a&Y+NpZ&mOouBnoXjZzBMUhOW&7pu?S$ zTXrTFUf6$e2#^rx`pCv$p`oX_gwl$9U9|}|n>XK*=WF;}@7(EoV(vJkD(`|if1HJ7 zcZ-1GP%UFU42L_3il&)3ZALh4vPFIH%Pp6SGrI<{OTmuphjVR;!o1?|-p!7yawz!L?0 zOCKs;KMN2ME$gkZ&f{tiLzJSgJ$y_I4Q2xtass9bdLOC9SvqPL`{_7H(d$T@6U+28 z&Mjq0d6SFZuEs%+S41&|`~#XUR!l6S43q{XAZxK?LTE7vwy zLqdUgD3bEb9eNI_ps}`=5Vl@De~PziyNnmTo%XpOW3S5%xMDAsE zV(*iEYxwx#raw9%zL)F)N#QQpmj}UFE5~JMSZ$5E%KoR2e9JFB1Y$~;-*fkLMN|r& zGB%tIMeuQ-w`?E?Nz|6tpU)?|o?WK9V`kINU&Ja~TpVa?gZ8CS)V|sABL|7$+06$i z+9wp$sfvh*Nkl@D-JBa7b>CNA_%wJQAnK8=;NvGsnT|2*IVSq6~deA3z&QkMr1{yaht+oF>P`)#R+U#L=D=Fta7|Hm6rN_#D)6>+^G!M%&Q)C$QiJ_bu( z)mZES5fUYxob)qOeVVu?CI0lLk?-;%+LHVFu+`fZ2~(HUpAKJd!G@~0?z z;3eUaIKov=e=sbFqjBIm0b1ECTM9fn$f(E zSsBCheD`g<#{gwr_(081%)XfH%2uXTs~S7-j$m1Yrq#cUCeKqY~rpY#Zz?GnM~-E#XVID zC&0GYd+9<)8~7oj$|Y7^ewvtR1ciIA_N$N#KD%6$cKMqzU+CD56Jjr zKX7thF7>ngkTa~=YN+J|J!^t?PIkqIvRxmS+E_HML}VEpv<_UR?^=G=A`j^dy__a< zwLz0q^sRQr|u$hNw>$&Q~A|9Er2$Ki#U_!G)K^Sm$sEBMZ@{(ms96r>3THk92v20@Q4SB`U{t0>uP@u|q<^C|v zQ~Q3eI1kM*M>kgKOPr6ZR)Gk2Dz#&px%(!I%(;J$j1UPu2OlQi8_Uz=3qDvy~gE6fSr)D z#XXg>)q^>O^xK?@N7D^0bb>|h2Iq{vw!a#ji03Cd4c}WLTKSba9BCY%GpDe?T%6E2 zFeGy1^5wWwAI&W)B~8z-wA>~#!cY7LPN`Rwc4a@1)ghqB;;F{uxYJR(xVGJ0v?~lZUFb^5`S1_GYULM z{TCFR;4m}}tv5#@D99#~8v0~u=s1RnL=FQ?uG`XvZ}-z`0Nai};q}D7^)U?qhcE-8 zGbUX~hlQ_b2hr_ow$MZ@rhB6Q^3KVR898dDTrbk`@F9}H1p+zM8&#u~C#JA=%2!&W z6R1^-BG31_vGRca%ofUKm)~PIL}|}+$s(kFe`XVz8w$mX)|K=bB5b5j5O(@D?bQ%x zB|rvYd2uqEpu*~i-L_)B8@6K=S?m-MAItBN|DC(Hi2n`@JHV&flTm8kLYE*CF9gD- z;_)7}7yEUs0(O0IiH=5mt5gV4bIgq2nLh`m=+-{K2e!epET;FiIPZ?<95RG@cKo7y z2zIJb|F&1Kk?Z`%VV~aw@C;Ncs0!x=Uw$K z&f@Heefez(I0t3(w(j=5+oXN-H%|t*3D+5TBw@sAS$=sfQUKa?eQkg5E&gF;9u7C< zjLtaO_saa5vb1w8T36Rr?(&GSd*FgIytgx*B4 zlBSk%yiH}_N6Z<*Ucy_X+dOc?q)om@D7zu5x)3)RS&w^C(4aw(4b_aNZRC?tis3ok>2l;67e{+=T@86e+*>Th(n zDjA@Ut2ge+1?E1{EsMI@+1((3<@|ph;M3nmaY+5TMn^Gpyk?@JIa+l!jvi>HjHqpV z^`~1QM#Tpn`$0D`PQMrl5Z8OVjl1yR;k0kEie=R}_(BbW) z4B*>Nx9J!^G5-xDeidMP_#YQEH^2gm(2{W$Y{r94)ppwse*5?~<0h^KY!>0x$MQ0r2Csl6?ZBjj8gdzJpE9o7H-9|8o7 z7Uc$PejvT({V_z;7Od>T_7E5*5oz#y#?SW@;gfKgFlDxjP0yyo2nlz z#?)Z+%*`=g= zO-0@4uo0}wfSm&d%F2F#8uKP$FFXJ1zQj77oS1|z>sA{SxX?Qepxt~{=4JC$LPS~^ z^V1ZyZQ^8lhdSuo9k&=>hNnf9lUq1XKT`DU%NV?Rg^M1mtwR6pUj$lUboJhbu%VW< zjkuFy+VioBXLZ&m^Ns_(Lc~1)8vgYQ|L3VYHTvn-obaq_HK38JzLPr zH&TaBz3?uWg!Kc5+bU)!<2KiL=T;1!r( zUIXVb4#Awp@9!E_!baKSzl0b>YP+A5ogEldTX!xR%j!pFtFHft|9gR4Tvk@*&lr0; z`5o)x5k6reo5Ck&`bt8X#|ie|GD;Gf`p_EJjc6{8iL3Zn@uIs_x8b64JUh9qfiYH>BGW*sjQ_AjBvOuLeC)|p?w4E zGHY7czgxXwC>IQUm4hUS8UY2~(LPeMGSWA-ZCl1kbn2gZq654FO2z%}Gc6_%cIs=d zUOWM(X{*{zFY2Rw9?hj=;N@zL2?LH|`k$q#^2cQQLAK5t%$lw!MT%-6K{2QA7=2rS z3idx2sqrhlw@839Bm$imrn&!=0r3L-qSi&Z;CZ!^Ks=Zl8Tb;=&s%tqERU^1xp^Ii z1|Ajda`M66Mq=FP0jvVhuI|A=Km1=8+ye?*j&Iz`e|c%{=M4Vu06&!U{~tp9m+$aI z8@er9x&cE(5t!h4soHh}(0)7XPSI6bYKc+r*VLl?S~3 znQ0^^;hoya5^4TNcYpciv4eOzzYXq$9`}z=pKxCcN=P&1S%x3<9!2rENY-N zzzHyVtst2;5z(2FeW!U6%0D`M|HhJLBKS*sR}EFolQD#3KI@YTjE=1KcA=yfX78o5 zv9|xKq%y9nynQ{4GkdtqUUy{`?)Phh>`yoa!v02&4?i$TH17ZLznlQ$4<}IMz)i7p(sWkis4*9H zKV1geH4?0DA8=SgqA+jCqD@ab@{0>7A0VLW^mbN_`~D9|!-_Y5)7g1OkSKzMfkVrc z)ZK#o&w4zY(RRxY_a?$yYs+P1BqwXlLJuN1j;bpQWurKnTy4)PQ1YFxyxDm*oX^hs zBhtFF7`ReV|8>6>QX7G`40+UMo4Z~F?=}U|&r=(S{op4i*R=z8w#q`c>@!;hx6YR+ zBEDdBX7ZGsy9TzOUnSj5b}w=5?@~?k1?qA$;gMBt2ln#v2l9*!4*MfPLb~~7hE_`Z zJ)!f*bDarFP#d%4jG1q5Y3>T&L|~`#v&Bvk=96+TGP0=RRG+(^=iSDU1TOnq$|1c)&Q! z_DX$6j7I^|bvFBZPS8*H@IOHR%P8QoJ@Tmo91O14Y%E-l%=)*+wcSRgP&kJ>lU*8* zMytjfkH$gu7#=2=0O~VwwEi#S@T5XLnaVzI@YOiT1zgO^eItA=G)LsVpr3}Zb(7!Q z%Z1vnHMG)=xm_P=vR_Zts7`QZmaMlPphP>`I@{hx4E%67gM2VMnW1zh8$njGTj`kD zD&^%9=Q!*I|0u_Azqn}^8V>i?%2Ty1=BM45ETB|ey03CYvqe{bG5&u`;R<7SF8!de zX(Nqq?gWyW#)P(pw{x{~z*uEATe;faX}+#KQ~qC040SihS`e8N5M*YFWmhCgO`m(gL>1f7r??0vg*zaZ~4wu*aij4IKfI*JM=nk+FimjF3*4pr6 z?z^8nP97DB;l*Sq<+)jHxe`!DMm9{@45u6ZEB5%GjBox1eE8Xs(bc8rY9KDYmu^SJ zI4CfJqQ?FEx7+*BfLofmVCN)>cBX6=g0pwJ@e?)@{huQN)z(3U@y{l>nu&DA(X13& zvUxl#__Md>=Fe1a1_;GZQkZ{(oA1QL0K1L;dX%N3VK+RFz2}+kvc*6&aF9q(tlKX$ z{d*BiV@D&s)*6pM=bJ=CVn&1KI}a^^6UdE{1(}36(tikOci` z)?vzE*M(z>`+Gw?C(Vktj(D?$gmCq-yl#gzRT@?kkmLBNd(jdh{sC*E=hZ_am%SS& zogug@8@rZPXHQS~P8JfClbN0#cq$gn175#mz1r8v=2seL*B$2Ul!p46kIdlbdK)Qj zkO%nK-K5(Fsq5t`l~%IreukSP_u04jz=7nlvxM2g%75a3zzDn|E!!0e_Sh(83S3=H zEc@l{roE)>ou;FzY^mhIP&6ap&4PcK;%SseR=!fQHu>bVTt|SCE@7fhAkx8S;`{gh zmgA)+KdTCcUkFmuPRu;_$wt!!Zu4CIhk3}v1<-y`Vev869q58UG!*~4L&8dNqV%c5 zZ~q2pZM@&Bese5r)5fOv%YV+yKhUZA6sAV zxRsMo(71I(SrKgD2^>8XJ!oH)b4{m#ykk2%a^OqgvkJd6iT53kuy0mbOcvq}or{i%J;?bvw;aP;iMG(}BU z@bN6)HkakvP+gJKU%^Znoz;ewnPxh*mD|PIzDaxQp_U`KH8VDOKD*?kES-E-H4ZIvJ2;M$@3_fkNuO^y zn`>#jTDpl^Ht`5Yj9L1-Tk7X}XGsPp^36=SrrYl81ha{~AmI3ya{eot7}UD4->K8>MEo^yDNef<2dC;qfR#A?B2 z@H$wgtZALI-)2R6r$)d*IobU%bc-?Z$Ek#`oxn{=wlRKvUrnHUVh) zqcfGknw4|`8E~<8%5L=>DL6OB_%XU4E+@6FIhA!92-;-`mLCmS=%l&q~e_b8)+o6H~TM_Xf2qtug*PN(ZbhEPlFf{ZLK7EY7)6#AR zMH9D0%Q`cNi0<~Ts2gOhr@VnAAecEBGMukHy{wURb87rJSGjXCTe5!^U+dH3X74j@ z(8GWGP6D%N_<{4IReTLLlUT7D&&Hoj))@BUGh44oTDZMBua1=zW(`Hkd4;Vge^5fA zH;HZZn#DNuk;E<07QZ{Zo;a^PcRmM=(zbtQwsBgU2PIgjjTc@bb<;SA-3T!kJauxxTPw4s6}kMdR@HZW;tphEo1bN=krP5 zXMcW1`1+Hz`lYs0NRfRxiplVpW?FHqr`$uJL_;0Wt)~Mu}!<7lLOyo2qwh_vR8Db{j(30h+2)rm@_hzbg_a ziQRClSKPRQeSh2>E1mh4nRvdz3Dftd8il`*Ld8Eg5jmfr;bd?Gz+?@sRy)Vno_-d@y+go1t(WCLF(828OOdm5|&rV~Z>;JY(ALvpzHLxqJsz$yo zK4`@@%1K}r_xH!2$$3lw!-xpPYmiSt(%G7p=dbqq=jy>B(F0Ap9lpTvOU1npJc08B z-x*8Qy87ywOgFh=MVmf}{-zVO-}lb{M@ZLv1sgzacdE!D`{jR`<}MG6YIr#xpfFB)v67y}YePq_Y|=!5)ExsRGn0ZF zR`%w`rlPYQ zc*8{JJtv!Q!*Z}gVVwU<1^=1Ek6$p<3&Dq0$8~w-Y8DShoLmjGZCe4}-OhGuus@di zW%Dp>sjkNuV*z7b2L45dV)reL8-V(`C^qA%YO=3{pb*liAARAP-@Z)!Jjq0(yF@Uq zy*)Kle;e(i+~-e64cBG^w)5=~JSMd7tE8BE6VJv*O*ue*o6^Gy@GonZ<>cf7?NycM z{#?AySE*5Lr}MLW)y&twcJW^Gfp%b?j$0+&Ki+CgtkXUTL_}Hl6eCAOeG}0}Eb`nh z;+21lzBpk*)N)C~rtV}?8Mvaelh<&-(bU9YfFsCZjIbv{IsHu+w!V0Vkc198v)Fr> zJ22=%9d~!FAue?%dDj<;^Ns7X{jPPJNe&(-8)F6Mn|X)h+U}42M4<~!mkni86ggYG za4GK~S}FnDd$iE|jdrDXQcE4-U}0fAfn$k?iBVAz5#j#$@1vK^Zx_LNCy>)o8F$Cc zEW6hX*9E@3o|Z1dWyl`qL&=SfquV{(jYqYOVrvf9S5(?ATVLC|p4j2kJ1sR#^PSZV z5O6GoxuNMH{WLxOox1kTq z8M6B&J9L}~%E+$epr5dZJ&OGQJ~WIk@gUNCXP<}8<>E;4^{6s*w~CKWoE}$|G;R(b zX*VG4`=B+cusiSBOpE(<6%{m@?_##6Dt4)76X8Q2v3S%vCR_|953byWfEGpM5P8R! zIgg>&s@&OEF2oxrqL=Xl-?Ma7$5!wI&aSi&<|kR|12OzFvUiQ)X5<13L%C?1R$8ih_cavEv!1dJfPx#b4tBI>iwm+v~d!uh|P|;{vZKw@7dr z-9b`=2R4d|q}W!xC+%a`L$%>tm&UMMz04VNBXYvsjnllbK{DfY9XNa%-lUK57o*VK zcI^v@D6lck8wsxmo61QUMYaQ z_eRDjf&im~D+LUq^4ROt@SRUCZw&w|{N+0$;nkCrE zXNH4wp1P@t~fsf-UNr&L=cDr{K%Yk}2znu|0i3?X6kF5P=7kop=?xl|67 zT4o?qY@k$_WkfA_5R#8obL_Ipy|*{gd-hEO5UV6br-+@E(M9|kLRy0HP>HZzd5aE+E(0d zxN>zr8QtMKyKFhxYPz&&JWM>%c5R>f4)fl)xM_z7y14`0w}8ee#}HkP@I360!5rs+ zo9VLMEr^seZuj>h&#Vkx8H+hDu{z?Y%V-WCPK}jdr+6p67@t^^aKa%h*)utaym6x+ zzZmiskkP;GaIeQ-$wob-D8#3ObJ@z09AW%>Ewe!$t!y;n`*u)T6^ zYddW%vF6=6Cs{V)_kKKbl4Wu29_t53zwzZRC#}*1$>{{yIBNNSAjVUKIK}P*F%}YH z1To={Nx$ZSm3x8V3h{_yoFp?CN1fM~Vt}KRjZ@b)!cALk3a;{BltX3A7iqv2=At9Lz6fGB#dht9&ivmZWir zpG5v9zbhue{f!e7N#Zx;gAm^!Q6i;3cSE2DuS#&W-_Gn1u^I#Fnj2j47o#sa{Hd}{ zsP=rQY2L7&k3@;J5gQ!a9PHmmavq&sy!f=_6Xv`8)!|(3l1t{`8&hnswEOuZG>KG_ z-2j1FBACiP2X{L4@h=*4WyKGsQMA(04{-#p$Iyt4(SLxjvFueE2SV^-u%3hhDc@eGsfakZj!R1L9yhEm+zqd?{hqYRtUhk%+A4ha zMi!mKVFPuMbZ?&$BlRrd3)T=T5D%)sE$w|iJ<(pUA;$@&cUiiUXyWK$$;X@dY@T*Bu4scLYl!Is6-BSC-xFxmXj6595~6Ypp(V&C`Q-!(5Mz( z!7@>r1Y{`WsRoUF`oYi}=gry(`WkslRND!`X8uuF!JL4%x<&B}y;!agMQB`L{o6qH z9jUFE6uat4@2%~1$}S9>Mw>`{SU2ynycC5Xhe}I7^(ZX@q}j1;30F<=2V3TwZ-$aa z(O%2E-`1EqfIs^d#HDC`OsZe@aV-x_YOV0$&Vn7)w@gO8P!27HyGdjR66^VfB%gW3 zR$8xJs29F=Af~~?ZrzA=diHMZ`FHY1J@_*A^^qLH_Z!X`aNE_RW-6XnxxF4Y2gA`M zhPduHIT?Fu;aoPxY1j0;b}_wd5VIqO-5+s*gyYNvPOMKxqMWVr?O)Ht!yvF_j*^3@ z3|y%gcGWUB87)}h(|A4k)zNl|craWyh^b&`g%60_lAm3gnI!vl7oZi}HEnCXf(uD% zXXT7m+^rr~AEPxnF9^i8fQQxmaK|erRgh|F{hQUDEs4-anN{HT8r(l@yBP__h=$-| zyDX`OqFVv+bcL{5)i1Pw7-I(xb_Ee}uY{A$%o)sMLvvj;3nrKDt`jI~Og}z}onw*1 zDo3OX`pBFqvma1RQHaDNYQTWGWEaaas(fQ_OY^D zbruiR6A{X7w(fnbge3h9^mdA!SCh0AthE@syp{QCgyDD0&Jjwv|80Q5`!OYo-)r(r z$(Ro{j<(;^*{ko7YEEek(E~V?f(`fHSK23utGB6Fqtfkr$W??*g|2mgVI`@M9q&?) z==%zOvPL6D*!52qE~TbjEtg+AZLV~XO$3V;lxSRbt3gifC#3ns?2lRpeCp&H8G{(6 z2HDdje!=Cxwh|GBgqKaA{n^uGQLi*>mb(;;w%!k{(ES^{`IYt(eP1CBryefpyw#^3 zQzy<*qswHv9$sFs>-H!E>(>p(O{6n+%P*sj+Mu{RBWvq?gg?Kn!Ek(qQ;%aPQQnjE zd0=)EeGzPLOObZrJ?A)Z($A^IN!nBw1$=d$u_y9?+iE?FXT4{v>I1)QHVG{JKyRsY znS6bc0JrH!Me<`@SUFlem(2_=#YPMXv*|F+@uC`Th9%_w2C3}|UaT#we+7yk09*(p zDWQd(B8%)~(lpYRah%8S~fkO>5EUt~eo zRHX;L@QhP{bqNHMh%*Whmkv^6Lr?ofB+ICNI;|Iaew39sMCHZ4`X2*1-6)_Gu=v=hTXds?}fT zM|2pSA?tI++qXH-1wSkaFihHgD2Hxu*Xv4@b z;hnMlqkWW%yQ8~7JfXpNZqku=6tI(@xGS3JY#FnAX-|lF5I|PfYz^kb6`-<{8KI@F zai_&EiQ|~|W{^AZ&&ovn4*LZFc<0LFd-eJ4_Heh-JqSCRVkaj3-g}Z1MKrS$51Nn# z2~Im3v50;6oh5EQhEfw{tAU|GPT8+CsW^{7R1!Gj@X72APEvv#`g+U?$kjX}krm_#}`E#b>g1~w$ zIbi3Ihr_9~p0Y2-xPG2Zz@MXh>6U=D){c<~ZG%qm}n~8@|;7%c8vWtj)L_md79y+7NhMrY~AAbT|lx*J2DgwSDlApb!pOjO&6h?`5p9lL@}0C?bWPGE>{|h9MrdmEUlxUd8ww) zL}sB)_$#dj?I44N-YD8M%Denk1;tM2KT`TR@NbRGqE&ikTiW_tVR9-GO=KW~H;? z;r0&cegicx!+mj(n|vU*`vi1MoHsv0*+RR~-jI3eqtug{M^6>3YYby`=iQSc2h3qp zzEKl;^5>xqnr`;1q8>Owrwyx#Iv}+znM#7Ie&@6o%4E|vLddux8B1~M0apv~T7(SR z7@!U~?Yw&`5*ZgwXBmdiU;0bXb6@p1;01)jWFfp?i4H|JzyIiP7Fp8sgkc}=UHgvI z&fNQ+A)ljE>Ks}){JPprb^pXJuDZ4lPl_K9IvAwLJj-*=7wV=(d}lA5%ADTX13g{` zIt2EX4zpO19W+gBirN$&67Z0P##$JcnOw*#n~o`d`+Q%s+>{MjhhG7Wqs|)vA#?B~ zJ(lF`$9 z`;NaMvg$BfWy7ALVQH#hc7|*2Bti5*%@}yu}#Tj$M$4liBE1qNf_Y$gR z8a_Tg-2iV#4@KhzNb%VgaU}-wx_R`RT7Hgf{KPpv{OL=tWIkd`FeOrZGAQhp%9 z3!6HdRx1i)_3)X}-La;&wUZ_g!{H@~mYwl@Wp9D<{r0S}6Jdbcof=v@B0c^PTaT0N zM2BrL8H@d>kB)0JvHOcEsf^$!@r%Te&q#F1Yckz2rIJu2}8Bg$R}h% zcBT9JDT&+T+>-Zc62W)j`jw-vr4Q>j8aTl67rpgvIPw~3`{0n|DOObKwoX=$vB_k_ zI9>vej*A)HJ=>qTvlJkx_iVy({>Omz(yP z@5$A%jfg)Vv!CxOH65{QjYfUV^|Er^nlXDf-MsOeHlKqRYgu-z1ZxuF+4PCUz~|Xb zDL%&{R3c@5a`6^HDl(a-7L3%mBvtk$zb6Xq-@+A1`JAGeH7EF)w?ZCnbFrdbY!5hM ze4A$PbJ>WYRUAiAe{$OdgxQR@HD^^W0@c2V1A$F^Dac@u`0H0r(@gcIGuEC z+qP{xnR;gCJLa9^oB3V!Dj{9PGCVGIeq|CUqU0EZ%cDW7q_C02y8wbVWq~nU@|JU}H%n1&B zEi~Zz!t?;AG5@S>VajW8_|i)D^U({ChTIaD$gj?Gt!h{M~IheXw@q&-_*{urM2R2N>^5f^AQw`Ll_&ydf8RJ+{PNRM{k z3>NAlHptv%l?2-3)pM`G-67t@D6zyBfX}1LBTK_}J8nE*0nG~8@;>7$WkA%P;jxQS zcia$CU%raWU&e#hZT-c2kH1XJ-wBzZR(0CUi0;7)2^=L{v&vqlbb-R?gTF??FmTI( zrIfd<umKOmtH9@e1x|EipMcM77sJq1cP-7$0tHf z>E@txWb(I~cDa&vumcb30{r^|V1cNGw864vy=HE;uHu07vQ~GH$p}(s)?59z+(OCi zA9eZ5OG1vzO2MooEY$312tcR+VFj@SxD2v8eG7tiv)>oI~yk3RrmcbE+ zc|-ou)7i4|yfWT#czTJK`piL2?tN+4XE<1$yq@yx>GZemC|y_mRD~AJ`y+r)UBkqn z<3963=wF2hZU)Zp$};}n~Z$zDo z>Z(Irm&5g=lE?D|eR61)opj(h&{xzqE0p%mdhhPVWoJcOAq^Fg^2y-nZppujTG4-G zWWtSNCSMl-DyQ~!H@I>*=zO2% zV^b%|@q(U{vBqqRpMW(p2S%jYMtn?ay5gspS4KHaE#qEgkLAd?!xFIzgPoIdbQWx= z{#Pi07ALtXtMrA$Ro+fypbq|!rOuh~{{XzaRFu%){uat_gkG3FZcN>>vU=~0Gk95g z&U-8CehZf3emMWW{r(EC<-f!0{$SAq39BkUC9VAA%NvFrkE1qhuUu0-JbexH_lil2 zB;fz_H23~9ph9gx4OObuwr@3XxfrDJz3l+?x?x1ANh`2Z#+LRQ(=@opDc=3T|Fg`D zNaA*6LG*dSz<)VKsh2o|hQrVS3R%U3q8?n7P=cC;?AyAv!`x1qzcK$}Mt`Q*l=E&t zm{C~hU--Zli>J?+e@9g+++*H?`ntoi zz0lJ<^Pi#TzWS8-l;~!)Cvc0qt)aX7#V(Xj`^$Xu6w;*7Ivtl48$TXiZ20GlX}@X} zy^k~iW;24%_syo~XhiL4sGkP!(m$n^rM@4Sw#}k5jVXyoeFXjxt;@E5{>sj2*a<3A z>k<+1vBAt3Xh@InKc~4;!ti<8nBLCRyIz)2K9g8sYd=vwh27QQ;N^+XrkPGLH{03= zUU*QYM2>!AFS06bD_6ZS(yrScOb)=JV;#r{$=ThLzR7(6S$s3(9}+xzSy(G-QZ5z84-{ywLccv&J)Ta=5(DtuJlfl zgwX9EHVIeKWbfb!??Ix;g9l9MF`<#hoL&~CUu-!i`Jf(#&8-A&$c}#53uwm%wUqil zr3sKvGqG())2Z0Jfai68Q+mMt{%XOeq-(GwZ@sQ>!~D_m%j;fD>M)$V!Ng@&Yy-{n z^s)!<@HK0r-SyQs4NDtm5z>nE05k!ZPSH(6+os+Xa+?g81c7$Yig=Cund|=*YaI|d zIgK+i>eA|uQZ#CM7ld*8{f4IHU2aN&oBg?P+1lu;gJhv;+aAJ2Lv&H^yMGug>Q#1Q zyGdSbP0#tT6j?X6&j4D@wB_i^ucF7s!_4I1wqw7@c@4;8=g|A5@Jb1I?FGSwZw>6C zEkxEdBGUHetvm5dOfbp$ceTk zHb4UoMkH%atPodpT=)A*L*85KdUG6$y>|Cg#{1V3-S%R19Dh>7Um^nPhK1dpz0Kt# ziJolrDxyaw%B#a--f~tIp^XXQb|^h41lH>kobA(krs@)#pK5=Cf6ZDK2aWDr1<$%s z5RT#!gluS2d>jb7@-ZGk_DcD{$0gl{`%@~`;Mee7tpe%n^NtyQAg z`{-bdG#=|x0r%SPjbfiJpN>%|pV7~CKIieX@z;ebhH=b2lg5axgQ|#wnf0>HeKUrD zhp^s-8hP=s+7EV1w(zkspQFS!e=Pegok?Bl7A&;f*TmG4Wc7*IfvZ=F>jNL{GOa`> z>&fZMh=vJK22C7iZ2>_HZogPAkTJ*c<*NV)YQf+87&UM6lW@@m=Pv&Z+G4a2Mq0m= zixC~wYdt*_b_H>ws3{e8FUdU}+*vQvGQi5~&{WXxTD9Y#eBHPo4>nN#IYB^>`L)qG z5qU07vcPsGDU-i8>^`4W=7o5)qN}T zIl*0J!x>1~bMMq^uVcwx7J`U>2qnwT*WlZU3WF245b{q1WN)@!L#&3o9V2wMKP8`} zpvIo4Z`om|2P01#gV3Fm5YV79C`x;@jG+~~Kq$*B+JqGR3k0mLDvi9|!o^U4y>tGf`NY*#9$Vqvp${VDSKxA#5gR=^CHPtNhXg#% z^{RC9SwQ(iXniot^+HEmu8-1`w{2~kM6ztT&4q#g(2?wIAh_FGf%n~C3vuU_MO(7W zVzM8Pd&#{?yWX_zM$FdtI_>2w$4zL{mJu!S;%;aXf z?c(M`nlt+5i{TA3)dNgx0rSzmBsar%gWBBn$%z!*Nv{?byLRnH$x(|qHsp5)eLc%+ zW!tj_tJBFAm8J3=M`qUl&QvAxaJn^HTeu>b=rszpCnupR{*EHN##{!bxSVw|s)}tU#85MWgz+!cj2$k6vIcH?k+Ws-5;M>m^G#HdefWZ-K; zFd(|jXD-nGX2jl4U)ka;&cZc__$8-ZtQ!=W6oq8s{@x`2edGJGb2|eU{xfHEQzzAq zC4R!Vs#iRRr^fNC#u}Ky^qf}onmZh)!Y(yiLSPp?m~|lU^&RE12#Q<1q+;|~n zzInpIU+@%fVG`4PL&}LS8;|4;D{-@l;PagMzT%#4{RkXSDz%HCZR5{l!al`WTK_$B zA6igpKKK`PKp*be_lH0b{8;GSKAU|?%Ki?4{rVqaPW-=U$U(^zb?GXvTF85V{)sm+ zd<9y36m;=lGn-29N5L#1U;PrrQeW;<61kqySdBoXG;zX=R#&N^cjQo{WZ0HXSMwv@ zATZxE=XFu4dO%o`@?q?6y)lZ*-{#*(Xk9D)(<3eEGy(_V;KO>p6gJ=0a*J0(XU%8t zc&c5(29cJqWj0^UYTXsl)80l~O+f%!9I|FXH)<4K-QnA^7&Pvty0FwG!(_syj9Y&}{`W z36?eu^g*^~p4F3U_ui+eDVseCk+7 zyuRh6^{RZZ+bwHwYDv2woRkg+&=H0)xP3EJi+7({{H$-%Wm$K(tK-PW&fCnhxMPzYe)*l6Qjk+6g!Uan4-6iuDXA2hkP!xaX{6+)!9<45%1`<+~Z<1?TyuW zR8J9>mhqX|#47QrXSS1>Zx#js!t{M5eMfV)+87%kH2W|Z zpitv!!jbURB|j7{H_|zxnkmihwPt9uD=_5sM8g#V=JNsd@kqQ}G+{@)_z{bKj?)Z* zEE>nkXTWo22H>!W4BO}MZZXjsmP9*x-8nh-hpA%A8i9SFLzeE4Jl zSSo0#MKQL3gt8)!y!DpIy3juamEvtGjT5*E9PXnnT;u@?_@J_b0+={Tll#-+oLp* z$M=)OOsxhbxNE1h*T!EgXCCdLh?JVN9IaE>0J;%raKWp}sR!@szIT&(>NT6(KnT%W z_hzPIz9#IelQm?Ej`{~G{D@tx z~m7px;XAf+z(52s|x)OBZx*l9foKVHBMzxj9QE|y=GHp zjlZ4rr4l>*?8*03-AiO8G`;$hsneG5=W7P422On^h5XF!R5WFP1zoT52^Z-^e_MRt z-ZrODg%ZIDfEj1mxr_njpy9D3rOnpg2&VQwmt$Xlm@sB0#{{}d=`iHfIYH>0jOD2* zH6DJE5CZDjNf_wvqXPn5&5E5WB%7p`ua(r;)MXo-m?;_3DBPW9#%Xb5&DE>?Tj|tY-e#F|txlWGME%-dvwmfTM3$LfdN@U-&&e{O{A$$f6tOvYw^RY9@yJXX`Y3 zVWYneYksa)Ew~;!&|^LwC5>+I`H0o<+0k^Ed1%k4^gH(CA~N%MO5l3{!=|98&BCXp zIrK4>kkpkHoAPda4Eefc?W9~(ldbd6`NTM#;kP}dv`{O@^rl8@pV38}Di6UsB_oA@ z@GQfa3QhK7Q7XS?Lg22#ywK(%wbQNa`wk(q##A*0P|`-15Midep3>zYHlLCkVDJQ9 zuvLgjX*ifd(LJHDiQ#BU5`v)S)*4-T6=ftWfEyEX;M25{^6|w%7@L1q67u|4v&90V z+S&iX*NHD)d2m#Coy8QB39}62xFLN1Q_Ju(rJ;T$B}|n=wN;>q^s~wZ1C0Z%4%tLi zor`X@0uDjj#8_n zqRJzam%Jbyi+aCuw;kA`Ysv8Cy|*X|6L-c3Y&2*Y5lHPi8tv3rN^96DOq1l8snami zO*#TZ^RV-31e|a2waj4kwG2hA+JwxFh*4Er2CP1G11c|pe9v71O&A0xKb@vc^or2C zPkIVQq?TdPm)wjFI|Lm+^a?^my^^4YJZ4;96R)l26ONnNpY#S}utCuAH>@urHLO1w z)@~m5U7%|x7~W>oJx&^TB2E#P6+4&WKc^zoeCfPPGO>);N!PHM@+PD7 zMvv?vm=11DG+3J?*HfyNX+256no&H=LsVfSau} zXZg%l+dfYR%eX7FE4qBdqU}P39@iePhvGD=1dkw@8f9Ici4`T;v3lzHd>VPD3+EC1 zKBN*xh0eq{r8b8mZQRM3H&R(MITLfUwsM!?oEv?(3Cnub^YwQk>-rT5{}7`Wq}gYB z@mEvRLQ0A%2d-g<5{1q=%zOBL;6bGHvJ5zGGCjm6urC$#JfH72P6LGO129oTc9{F}FNTV>BgS5#d4_9i8lo zOtdHxo%4Gk^d4(>?~R0jn1<5l$l#Aye7S_Xp5Hqjk5tJQ2UX95MLq+@2oF9tG8ARh z_h$PfQhB0yP^yN2C4^KwfdP%p1=B%r@cQ(C$6Td<;qv_m3m+kc2bs*OkYqdlJSsrvhF`0h_R$i zNL2j3C?RzJzJ<&Y4T7t&o@Sr%#n!;r5J`!ui!e~6kptJ-p(3-c5rYbyu1UjP#E94M z5C)x;I91CN6nLm4mKC=H>II3ySAl1}nKoRZ;@V!tUGH*}(>S^s!2=5FQUZEECCY#Y z0fbF-O`)g()633x$NlT&+3)ZPF9R^vPBp#xJww#_^zuDpLA0z=^CI#80EYi>67qk5 zkqA8yS=^c!#Mo!ypi-f!!yoo z@bEs*nu*?vx?jR|6;_>Jmu6l2$$1I$G-%2ng@~dlK?5Iyg=epg$seFWjsHDMNk#)u zL5+K&6J~g!BWAaFeHnhyO0;8x@rMRr-|#PP@^5K9S`1(F$A&dz+8<2T1?$uSJa(D| zo`Gr)fnlO!FPQn%y5%V1>2_hZ33+3t?H z;B7&d#mne1Vqv-Y5LL}q!@c0=tDw)7`}f`%U2~iPJ@3LY7zvP0`5%k=|ACGFU!VRC z=+D-~cH6pDJ#Mzq#nXa8Y_MLZEG9m_O*-c2ikr`Tdje!?C9>kHt4b~6Hq5T6GZ>Bzm;!Job_{OIuX z6f(+psi|nmLH?osS7GoushCa^hkestY3FNel^CD;yl#84WhBHB?ekv18wCrr6wGh- z&};sX=g?_4ZLi^LGXI=! zWW4df>5~47`@DDJ)6KE#yJMW=fPOAZ^wN0{!Xa+FvDxu3m;|a18*g?f#ZpCuPNLmt zQP8RNNN>y2{h@9`fym-QOOy+uUj{frdgJiTF@c+m zRaZ4h62KN^e`8?}8CfVt2Hqy@(_uS)a_Wr5mQgi*ERGk~>HZX(RWro2J|wa2d3|xo zb!8qoJZ+~dD3VJzR3^)6MkXZoi;5JvlU#DR^Hk2yi(U`USF1p*dl@q4Wy}${_pe$Q z(ZH931N?eK4d}VAU~+GEZWJl#3PhYbQF$&MiIR?tR|k%=#edIm-^;g@*;hNZ&!%1E z-NDDQSw2*(D;aLEF<*@tVD)~99n2-$tEDvLwYP)skM(N_bn8ygl)%BEHRiP~;ct(w|W=e0E)MS6_4|j)35m6$=H;^h(FCJji`f$zrgXE;Kndy zi5}8no{c|6S~e=!;ZM}U$t?y-uS>s2Qw20~hP9{=|5_-1D<}N=V@kiAvQrf3_n?eG z9MMORAjrnnI1?Vu+4uGL_H$zSM03~k!AIX*HP?mc+w`XEzM%hgWRf|foWiv4DPG)$ z|Frz2i1vaG6=)X>lFZE%99%t5AbQ^a+365?B}x31h*U#M{N49Tl(=`Q!%WyHx zcwv6L^)jw6%Dd4)*LlH%_cK1QEd%&#gtE+Fa1)*gukqK947qHX+DFvkK+n4g1{4_# zo+h|Hwgw#;N^!vJSwcx<-0(l;NwK-K5SUiMJ|FCS>OO{$m~D$oHd|ZI8?dewceicm z;~r*cJYRix%a z!GR*`aD6|GZ-2gjzxs-t84!6MX$pSsZofYo+<0vG-{<+i3w{o!b$v_=Zm_oG*EjO?n@MA6erq3 zj?+_Ao5@ha!9L05bWeus?d3$`I$mfX-{`y?lN<4Y_35}E5s8O5G)}sNK4V;-nz#+` zwujfOp`N+s)0KkD?vxV#Z*gX*?|5XCJERO%m7E;Q#2uK?ifj^0=H%dgfE%asO7m6E zWo#Gq;MU-;(2$e4@OF*ksj7GQ`Pmfg*A@jfA02g4B0{;pChl0Yg-?RVU>Y;L`fF3a zB;Dgzc$o_e!%eBlys5mU-m$9@vCOJg6rpmTdj(1>X6G_8NRWr+e^}h--77J#7a`sVFU_vhh|HtneynKMY%yPZdGZbxqT>DokepgTX;tRgH zB<#_Hw`{SjEIrh5!?Tw>JIvhCvt_`!xGi7=xQ318Hdecqb1qaG>l(j_!>dzjtzZjA*I&~K*?!Ai#qK6c9i!+`yXz8c0bd0y1B zez~8;CjU>Y@V^|*TrI|ITeuvC%H%0=Zjk`ZFl5h3G7#b)5gI99>B`U{F#1Lc){qHO zSkUa?Ac;r-lTt6Y1}?J`Y$$6cPGtG}+kt^BR2;_?R znM@rzg6d&itnksUg*{VsBsqE1D=-ZLPXAOvyWFR*P4>D+cGui(*?jObud*y++z2%- z$$taF3yq{W85NifZ>+A`s`ORye6H1Y7eiMlOw-$5VvJz)Ql(<(uu99qGuB*-AXRkg zK%rvM5Gt-9a?%MMUoG;wt;XZgQeeT`kbwO0RhPhJ6J|LV5b@cvrfy*%J8$#tEbZp7;b-7U|4fu3K7*S-vt8$w8uH-W z`l`-br!vtNWi79V=)>yCYkC~_@%+m0CN3v=#{GD%HQw{Ej}9tvw%jsyB&sbdEqS?t z^LeG@5LlL$1+N8@{1=e(YNQ7?NQh>bg~*M(03idz3OP#HHJ{TMoxki&^sBW6F+X)( z4};s|GavQZP?2Y;|0Bbdp}8kK#fvf-#vGAB&ps8g%h=2JM{-v0rn0wcL8lCpK0QMU zL9-g4$^#e7-nX~jvAIv##)@?KHm`9YCx?+BNr+*yog4h41#7_ck8tf>ER8RnwSP9I z^ET*wA;6go?S!KC>%|xraYWguG)EajfbvHOjlNp0sJ&yS3$?ktWJ*4Fz06ii3g%}s z7@7wP+)c=v4YLl)l3n*Kq#Ba?aX$PR-^T?q1|aGDg^UZJl?WlX z@!V`55Nez|k8!i{d0khzMCL}~U8>nKHThE#fHTmD+?jQi(}4InMyp76R63LeN@j3M zffpZbR{&JZj0Z*wM{c_}wOU!71@r_4JK z@7LA$+iUH^SudCPS5I$sPyBAiOV-A&(kBnwP`Hpu2OZbsOy89!m&rvGF&Oe!k%5M$ z`6WzHi}?N|q!#WfhK)*B{sH1Ythu@gRPIc!ksKHSXWludB~x1#J58V+S5CVz>xb*K z{y~gXZ^zBVY<#VY4NMF3aFbt{Hq6Eog{iI2W*&MgnB}kB9PC*EL#c7SaTZYI2+Q7$ zH3f_wFWR?~!`WZzAKB;7v#>cir~l?Qvk0oCPQ<1J7H10f(15$QM*x)I@6alh=D~$9 z_z7RYikXFX(LX9LWQl0Xa0M0#=AQukQsA6ws&I^9CjYZdUZg$bpgI!G&R4jXgP^;O z3I#m+v&$Pz&!QPzac4v^nA{Spw-Rh$nvkxBcp z^zdxaVu3=_@>YCfal)U;Kq?O8a1p)tJO^incF`m4{1a`P*P&KnA z62jPT0{iK{f<-}KmqUn}VR&Ip@7}2N9>KMhmm8hp?9K+qDUEXSerps@m8mLGBcI@c zXL?7SQe?+?3^))HQG<5{2QDii@7EAtD&}6S;G-<_7t*nIX(^ z3T<7p^1p|?o&QoUk*vaEP7~8|T;%en)JYE&deHT^roeO1Q72D3RoOnt1yaq=MB;M= z{}&6;2~SL!ZCNmsp*8la1Z)#T88=mljqN)#YkmdEu{Kfv*x30d%~{A6`oRq1-p$Xlz{{DZ#vADRpE5IWfm+5Z5+SsPi>?rcCOQl4aNiU zPT;>rAx+X9@~%2MULkfXb#N&?xEKOUJ5Dig<3$;7DzMSmz-o!XAJ9VdL3PT8vG2vU z?FZpOH7MkJD?$V;oW4{CO!4%huZ80~g)R3{CD&@~o&`6IU-DHzseI$%A-S7&Gj8)0 zzm=XK6!!EN?dLV)x$bPX8%aLux^yGKiqLCCS$*P7rG=L5Q~cTOuW9*_0EpiMjbRyS z?sfCT7i`29TSu=CxTlaWT?1|5Vk@jB^(K$O7dq5x=xcfbZJ4Nd zgk5Q)(X~HkS&Gf$neVO5NHWL*VuePqB_!1^OoH@d1=&irPg^fUKZ`PqdsKuaZ+LI0 zFH}9+bFDRXl_p4p7~TvBf&vr4&lh3>f7LKn(^Jy3E;7qbpt~gPio^|rD;yeWk5Mk4{dRU>R z--izrcd$;j8L+0FeyFWcD$s?;AH-Ebbwf*3`};6(IceU{ACM#R;U{$j2ml&>% z4Qzvggp=hTU0BbT_eMff{#kMkH*Gvfn@47DJo{?|>1u2YmsQvDCA?^4Nk%@kexPVT z@;yZO3Kvg#{qyyx`kS7S-B{!>v#f*n zg~lWk-%OgDF!`LPnC%0eo6Yhqa~ALg$FS@jh(~(;e`+ zn$t`casjbgHK~*vStT5r&4kh*ISqTka1#nqO z(HGo+?}8T3^a2-@mBHp&%w^4|UDTid^s!0*y zJ@C?+l5PlsJpNFN2%<#plocfZz2J$?+ZdoI*46dLUb=dbM*8bqbz@)zStWI?0WReu zl*#estPZsm*n~LolZ3DyQ}iS!&+104lCTz*16&c^i%t#4gkagS-+YJ@eo~@csHazI^SCK~{8I zCfrYXuL#!~+Ox$N4=1?af)0_yA!nCb-xz?uMZNpV?9r~dStC!e!I?NDgz43UD{%Qz z!d>HSWSQ)jb>w86xRN!AcaLHqw}rcqQLoR;Fz-e$p3!Li!z;ugNG`6OJJTo=#HTsJ z#t3)75)~7#ge9ju{OLic)<#4zXd0H6HPXlxlHQ}eVEd>2l)X)1FB%wJM-mzsDPm-8i>hYAxZmssMz>{ zqK!?w+Dy{$c%IRC7lzfV93?_KdRqd0T+f;SD^5ftauhILXh*&Wv{3>={Nla}0>Rl^ z>NO|8=Kajk(DVUw5brY=?R|p(;kX zG9}GSdguOwR6;0qockOt4+2#=$sS%qShPzPG%}o#B+dpPP%riO&1^IqPj|*rD%8Ni z0x|8`N7#CC9SJTrJ0CSOO{+S`{%9*IUG*!$d3O+>=81`9@G#l3?T!-%vHCjpjDRPxYmcxEulSP=Ha)GKdhi&iZpc!Sd28i)|5yF^OjDea3wX<>+*PdXSz4ls)UP{EVJVODjZu9k_4a>gYct&3-^D`7Z07;Dggq+Tio z`)|oLiD&ql2$827pQ3o_lgva*5~Rjj01P5jvk8!(X?)fpi=si;y2&aV3f97{>cV@Q zR?zY0Vd|lg1*%RDBUYPDzw{8j6oaz?)RE8xF2v24-qmN8y~3NOd1_t7J80n7gWXH# z#}yQ4PzqakRq8LNvG{c4sY+EJ`NeFjgly9o(Vj<)0Umt75kE3gwfO*HFEBl1`OKjh z@sUOszKnYSXru+-U)S~z91C->kSP}&nwPBXU!Wzc!)(YUW1^G0PB3X!($X z3+pt3E-4>Gx7RhYM3P|-URVlPFRPUP0FtQ(f{Mj18wob?4A8(-k{4A9yDBvCd%jb9S`c>ZCFMdQmX=r(!Q+5L=Z^BC3?$7x0H%EfA|vB={rl^p8BnYHt*tkR zz*sOzNT!`W}8BXtbmL}+^cLe8PcL7-rr;7(^DD6!-E`uW19I$pR~aJ!OPO1oDk zh0o=h;V@_;B}kzFO9E%Yz<$ni;o8ORL{~oTU)l?kwgYvJH5Ixh$_i8+D(~84kv|B& zc>+1h=8^fP`GRn~YJ}Q2&L=iGkfCp0$D^F&0~DQj=-nW(H7AcyAPT}GZebid07D5O zImMSkkc1CQZ}tWeEcPR(Fs19Hz}`6~;{2xp$yhRJ`IW-Uja8OnLTEBDbpmTk2n=yj z^3Gj`Df{D;JW`~MaV<5g7h0Af#5{UXq=8lOP80e7^pxC#4kt>X3ahZZ`+>x9DZD9D zg0dIO&6_Dt9n{0&iX`SlSe@g4g`UarT4I8}nVKeGvKn+lXVH2Ir!L*Fxm}mZBAZbd zbBIYM8WDiNMkS$A3_n&kaO2wf^IY*jf|KsP31Q8<_HWct4Zyt zoFZZv!Ymc;P+qYOIWJ^oH#c7>`ZonpiG8BrMj#_SaxUTl1!r34ea@&L?4B@fa_OwW zl@vG*pX{P7)J2l9g|O3~Kfu?}7k2Jvk9UvW5MC=&SM|r{!Gr1x-}R(uq|W!H$Q7ya zC^3PN+KHh!S+%{LE$K8Oq8s6(ZD-C$?3Ac?Y5^IFWV0+X6Y`1ae|^(Q-oxpfsHAw^ zbY~Jq=Ag2Y1tNXJ+0_9PlYZr$rf3Vi6+(c{jrfPeTFR2amFY`Z{dUpoOIL5L>8OZoXfOHx*+BC{aRtabJil7%lNukR~ zMFRH`c+3&2)_k|OCipaSZQd?swJhUU#1#9z4~eG=7jm}BWoCkRnn}BXtKb6&_V|nR zNn^JUm(bLGxX}HuZPJ8?M<>d#nzLFN$g-Pj6mzIwP&9s-jh!a*Fh=LR@HNES5L~yM zydwOHnv55=ersPgK5y8GiH;1|rO#@lESwxn^j_kEjEPJAQj{8O{bj_}yzN&MgIR;C z#YYv7hg{@?8_t84$wUd98H>gzd#RF1SHQ>tY?aF@H%$_o9E58^l$3+2pI}<{84ypul8KbFi3BltRoLsl2=^a0~;*>rpZ18RQ)Ps@fk0YZcQ2*!6 zfD9DbcEstE3{lQ{++C={CR#+J;7R8g^-C~0H9S3?Mt?75=ucrWrsq6H3<{V}tGjuB z*o-=dCcIZuIK4IPW%SnZ+^r9a_CS=NnCeWh<+isI-MEp{?&Z?`>3l=h0o<}|kWH}N z^&Ci?kU_&ZxyND7@`wbG^OAEPr72=!1>Rr>AYs*xOl_o-uwbUBCTgU6+>%xEG!nv2 znLry$A9HaN5#9R~HW32fo3JC~ykXo~Nn&H}yWm-~09>{hlIaJvqHsS9lvL9v-kjWx@78N??R1qREGc31y;-zpFcxp zInyk#LT$@6$y91pA#{kc>)54SFfj(&sDkeqSD`Ek)_}&pC?D&}UvwkR5K9i7MPaXd zu7(4)v;spqqS_tvMbh&Kfd!u+|11jH&RrjcT{R=w;#5|~TRQd1TI=#L@VwL(S~s$o zjgy4NYBOS@L(gnLG&@mC|0<`a?=r?TkLHC*wiDb1XARj4UEUYT`QjmgkD;sM1pz(| zU}>N;X;4il5>TDi(4DRKjuI>uPn$+E8RtKw-3&1&QXY@@s(}SeB@9pzA6*RH%L%z` z7G-2^^EF3Pf+l9pxJx1#l@}Q_)~+1eKV5e2O?!B38jWv3-k;HlXSZJaGYD{uLp;NL z^o-f7qH`*CzomRQTRWKF2T)F}{At3#&-pc#I0=oTw;$36hlxqndL95bLFfbhb)>-k zbAkxYOjd`si#`ldbnvxeU!TCjg))vRhGc*F#;IUnRTfBLj>0yCd2+U*T_+G$Ks{yB z;~>=rX#U7@5YT7KWpB^GLrA&6E>VsakuDt&lYqfgj~}YcIjJq~BIhgC3D91r!zDp3 zOkizktVbp2lb**nQJD;0)M)>rlS8<>`VDd|xcoKl=eJlu)!46UvChGU7ZgBwEMEY# z`cDrI4$1-oRN1@AoSgXoLP(MK&@n>&QcFuku zXn*d%D$M9xROFRZZ{SQ;)w%S)f)g5gRHwO=&X)LQ#y9<;EEt4SH86_ex9>e`cqHj8rG8W3$3*WeOK5-Y=b1rc?~jFM9^afamld zWFX?&h|av>@sbE_GesQ8K4E{f81sylw4;n5=Iav8;ciJzj2;=wV1+}WMPqTR zqP0-}J$|5Tlm%=WV`jdWflCekLG!^Xxre8+5vfp|POve5xFEiwhy$0icg7jwFl0&4 zZ}*J@cxGFk4%^Coxl4$X!;QpA|LUOZV8L&$3CXux;AqmZmvEs6b7P3ZzYRMFWn>U_ z@6nvxi+sr{fEn$;DBtak!0Ts#NKM5e^PYFy4LBa+{fphT;XG>%Zl_t+G-rbVc>vf| zD1{D%Q^1IjMr+GZWptbO1P5(1K zKDGlvOHJ78$J>!%?dqB54iuKrYtq&NvmsTMHp)4o2SU9+v`^;qIhKzgD%jtN~7?iXhTO7_2=Xrp5Of`MrYiM}uhQ48X2YRLKDxX8>Om zDk>YdvexJ4Cwa3>)wB?0Xz;T&-WTE3t0VX9Jy)zneXi8|n$DZOIILuV0ozPt6C{ob z3v)DA^;9+vfRz|GYR6*-8NnYl%`%LWJL?36={emdwfgrduKPN!%mh&QHkr~4V7Au@ z%aUXnChoNa#^nBEYF5}rVBrT;?oVOcUJ#dQ{$Az!F!_G7XA3lm<13y~BM~43P`O>m zdyT3YKZ&_mAqPP|hoSsA5OVY|Gx`ape3x*dc~g+_i}BKhs!%YSwj;=9=CD=d3!&yk zm1-@zT^3Lmb_nj=AFrXKXv$Nymb^K$T5J7eCpyE!m$0p0+X8A`{2kR5ycKw?jV54bP$a8l z!?V&lGbDW|w660D1LR-x84Jm<%RzB0Z1H|@>FY-5U})i{VtcN`EXs_E@*_49L{4;T z<5O~pJSW~C+N)+@^t&>S!}Udsw?EcwA>0yrh*Ufj?Ps>MPGp(o{-WuXqH|53Y#3<) zmdRmL%T3zn+#?CXc~kj>wGe=wPL2rqjju_G^8sVfdSYmnz#_6r)Nb(nMTUHgyJgFg zoHg;xd7ql=haEzKLRBd52q(GUub&|<{ADH6*|ZhNRvScAdK$BVqE!4hRx+{jj}UGm zumtfZg(8Y^KuHB%ei=eI7}`Kmwy>aoN_dW_l*{dk_Vqqv$OTP8n9t6 zV~3R|&)BPkYJ@|C4IW-eu(!L{?Y1WZK%s}bk0D(qbPE-lichimXWrnlm=g!zkgrCu zWAQ}l;BezCK;>CNdM(5!ylzrwUu`Wk{;9?}@hD15SM@_ZiTC#}j)yXDn3%MXVoEO8 z-zwjqz;~!j2+s%i4Zn{IrK>Z2>Ui&9xHnAZdr1~_%7)>_d@|d`2WyU58u(Xg4UB(v zc{52PHY2MVE2FE!bu>pH`&UP6fHPT^dZ@bPKdd7B`*8ALK>t>oPn&L;Ys~Qi(x#8` zXdd)FEHiUUsClqe1?ZxBw&W0)1Ery!GThd$x?WRBRL;08$pa9m7-}}{58$x)dYsJS zfBCMB>b;Lvt#Q~9$##_k;M*)3E(nyR6iwmfImzty5^M`n@3D3;?2^p(cD z9`n{8-~y2zmu)iV>UM-~eE{*|K`?S^)Ufe=yybBxmdvsRI8a9a2;LPszxms)PrY7q z3^OK%6xZh`Nt2s$n1zKV|Jw$WGmUSeSKCmqBP(lf0`E}Gaql;r~15)?=hw^AhC8hbGlG8a4&-+yxHcADB5Tf6(Wa<>?1;f z@$cvehUv~X7II>#zn)L)x0MR#U*2OFw460ZquB(yBkHt;)L#C$788;xkTyB5Lmeoe z2oZAgVfh?5S*@IrFf*6iRQXevK#ilEp1MEbKRB?*hMpW|-hX_@iZ`<=DuCLbU|{$7`~A^L-@90M1(rv!HUjrgH%Ta` z2NM-eED?kfgtz;MFuEHD;d8R~)0*QnydUUTo*YdCaSdxiMeF&(P*?~~YE;bN8A5Io6x6W&+(%{lb8)?%IW^3N1zabOPBm(?Bzw)@^kmbiCoZ*fO$QZyXy{6{bLQqxRo<2(f}Cg|E;zjHyvv*D?Y zPz@WH+DxGuE!vLHA=JZkn7A*k-hw-!yY=Vrl{+2>n4OjsEJ92`ta<24o36LGg#|6V8jVpx>{#wAZ{)sc!HSSPTC+Hl`(tt*f^x6`l0$?18UqJS>GiCG22Qip zTiZ`9{M&*JCO^4`0oL>cTFc@iMg3)KmRMgVrNm$IVe5yvo>_)wq|= z#C5q0>Bqekq}AZ+18cS*gWB56EL5XmIr>DO6lcw`wC_ZQQrx_rab97u^6N1aDXm9< zrhuWV%+?blYHSn&LVVmPBwJdJ+Qllbn8a0cW0UH*XW)TyJNuAl!||)$$$iCwFKlT8 zs;P_{^U_D8NufE~Ra0KC=cNOHp?(3NSyj7M10NY-`OmSH1WE_YKGc=Ab5WrWSKUz^ zqqp4ydDfmQh<+|o$Dd$K&7@#>%M~{Ui$;zuV6{66;oc;M8M>~x09#eDh>k|!y$p}~ zP65zN{g%c*xj)8=aYFeHTD0j5Q^qG(vt|t>$1)qHu7eB+dW8^qJUjh&v-v~e#1KC5 zcv~HTyQDYj^3Va5RtZi#^_`hB9CaHh=X~fi8inR4mSSi#aN3(rvF18?cUDVCN$h1t ztzMF{T+|e%dwO;M4n6LT&NILN-fTdbo3_>tgA+jH1PiCxV%i=Sm@iEhdscf#mqqPn zcU1IA$~DP4P8uP(Sa>43&T|t|dc=i=2DcL9F{M5I;T{gRU&uU@H@?X(EoGIiFpys( zkDgEt^vy9fNoB;R@3QnLOIvecCu~Px;BS4|rvJQADHfh9G?xw5HCo8x@nO_m6d&iA z6N74>m9?~`H#el-q2H~{0-}&}HadH%8%TaXn(ep)vwrP&1CSR(-54~KBJ{@c5FEoJ z5T{4)wOLInohY$%uX^>%zp{wch9frarNEht$)8YjIP@(AeId_vRgDMYF=9zJoUH9T z!Bt`<#~N;UgsG}h$7QCwoDM%)Iu6zP3HG03cVOgpwf@pX2_1rfmVxLHvIH4=1k^W* zSS7JNV3Xh>$nXp888b0vHKvYxmK*gWb1)GfoZ15QE(b}F4OtmF060r0OW&JqOrgzH zuU|kUl^mQ&8*NgUF1kPF7wk0fEW$g`=^dYRrbLV+dS;B5P1*YL&XUHlwSzORxG^9x z@$o|8c)N~LHv3v+s~-WiB_o+YT9nD<%XHSY$l1xS$XQ3O-#{y{zWq;iG_Z&Ie1fhMD1$pqZO%G>`rUmP`kDenHZ}k{eZ&UQ>x+*O#w%bHM}X@rj8} zAAHK^$$A!ImloE~qL6{9Ef@07=}Y4&WPG6C8rmKfn093Dtiz%S9r%iRgzf`0 zdpM6k-xC2&-_3o)jhhTqO!2C+hFg;c(kY5+I0C&WK6a>#W`%Vt9m2VbRT>jy6oW*=Z9cJuY0d0>?<4pZ zC)l>IYc-Eu(#qkVw_Qo6=7x00hx$`7Ck)r-m>o^8n6v-@AOJ~3K~xaLXgtHHRQuR&%DZ3`}0Fbr31QBiANQAlO-kf^B<2P#N-kru<&kXNjB_{-4@q>wgAMh~!Q|lPivAm&t z4X=nn+I{BJU^Sug3A0Fz7khoxjZMMKCI1HcX$aGSs(4^Fmy7DydKn5Ns>8?EhZDm! zxIbRiGO4kEP-)bI_+4**!1ed_^^%KWeKhQP9CzqzF-#%D5xAdT*q_D9tnW?widF#Y zxOw!}ru$<$#TZtn0ZJX?L z8*O2c^{uvbVUK#1OLuAIHABx8;`$v?RVqeD@lqJ zpJ#fP34 zNJ*WEG>P=~2Zs9lye`OXv37w)(FoA%aol0EA!hd(>d!$uPP-V`W;!t>;f2)*zOvIz z78Z)ANE4$^9pE8Qbn#cG4(6&tdFn)U+&r6LIy4*Y>1t<;X68f=ZD41Tjmf^|(Ewc< zfy1{ro|Iz9k5sL3-2B{}b^WZ0BYl)Mm5x*@U$g9}ZZmYtwhZ9+$7fMC&CmknmvujjmJ7&324-x+>~`A0)kSUYpaFrpVpT4{qY!@n8nYQZ1f zz0Kv>Myz?T^CD#_JdS@Y+&g6D)PQFXuBnotIpoye9Ba$%n7_*|9f}tQ9r%=ljIojl zS4r+uG`iP6bnUSayNFkaWJove_yl|xI;HP*FVYt`FTHl{*RXVtc&@`M3|(Ks-AjFh6i%G*x)D1t^g+c)(4w<*o4$d=J*y0!#(xgQ4q!)BCvq+1_S5&&U8%!E#)?V*|bYVv5Y6^@VF z*kw(sxUeUxH&JdL1@hKGL3ShckJGmyv|(h!n6 za3!WoOHZTlWN;oHHr5uSbxj41;$OXc2ld#72l<$r-QnfDY=}5z*sto#yMCM-TLSf( zA-p6CFX8XFL@%shkIlYaSnd4*R z#}|hU7{X(Hh#=sQRle z-Iv6*l3ZfIfCC?FbUPk#Gu`2Uf-Asb%rN zbNF$8=#-4|u|A+)e=>xB?Wnb?iBxM)w(LHMD$>jS$r&AK6C3sg*<|1dpuXd;Dw4Kg zv8yJU-Hxa~BuT3}8jxABWc0JD`(tXOp$@)bj6PEHiX4(LHZWA`ku;1=ctC8K2+JRyoXlL%s!*g%;b1*jo+?yXCA-X&1G< zC_V<(j`LqZJC?>R9XK#-641-zo-1fmp$$eeq`)d+-@;4|&-HKe+=sV_dTbpcyj_Em z>ZQdxRS1{~SI6EG)4`I2Q|gA3 zRJW=_#j3a=0~vUdOkvn_9a0R9M(q^Ut$8r6Xnli#VDL$UNbU}5IN4gF(^u3USJ{6_ zOAgmFSm!Y^TXu{jNKqXuaCvmr+HlsKNFgITocn(%G&v-y@LZf_$~3OXVaAVQN3(gj zDxHN?TCOCT*Bjo}Ms~Gdac3Ibi~!;lsH|p}n3hmJ?1qO8dc|EEYpNiiW(H4_>v?jp zzR<^1m0R5J)wZ4IS4-tIhRijW+3XL^B*>&Dd9J`OwCtG0@>MG~p3FTAWnoBr z;dcV8BZce^B?d>5`w&SIAX^V49ygd!!tD!AB{t=EbplJvlwo`e5*-p5_G{s?cr1Eg zQNXC6`O~*%7I(9&Pt7L5g7po{9hhU7 zg*vy%q;9X*?lEgo=`tf!TIXBrzXH|40#_dr$BbITbd6RZ?ksVT#`zpxFCkIICv>2q zb%~Ui49n3Z>b2)A{BqhUu+BWBi$pY#`Nez6Hz9D8Tx__?t}vC4ofoc+@wor<=~KFNIzJLq$$<;qr_4B`DoMTmr!vzJk^y z_o~US11UcgGu8YRiPWK?3@HQDHsQPlQezyeFiuG0GUa7a6O~NTPFotAhXgU|+ZP=6 z-pG9sqV2|3)Qr+BxEj6Uq^8F$*p+6G+Bs#C@gkxg0X8ydlkD~;< zPYkZT6;11(-f-CrbM-3li#SiXs;ianCBTk@W=7#DPIK z_B-$@6ZfTQhoZZR!Q?J{Qk4|76!)d*x2k0)9Yf(G*T^kr}r9)5~ejTn>;(UI5!V@3&r{dbslhsFbi!I-`RRh$oU=Jovdn0s6K|#I^Sad6|ido zL^x8`tg*t?E$Kc6QZpQ(!AEYDKfxt#U_*)NXIc!yRfN}2PaH<)Tssd=rPE!J2D*X6 ziosgCcrQ{otBqH1ZHyE>q$IDz9dNwpwgS(fXAjAm+oFz2G*tC39otASKLjQiv7|VR-^nKl0Y!ru@`b+SCP>zhNFrwTi7V~8xP)KM4m}G+ zV+dzSgA8ogsOR>}u8^1C{_rlhN0bbq9I)NZo1?=1i3!f331)3-53 zg|gFKMLf9`e^w<$r40gx4*0M&Ybp1vrD>>5jcoL|UJ0>uA5dTd+-5u$!<(ujbzmI% z?Z~ZcE(K;0da;1ercd^lyuF;O!KkQ;!%-tfBZ@`^ZAs)PLxU=f?cRx-r)fSdJ8CPa zW{kStER*c9Fvm&hSPcTU5{yrr6x22oxFCn2VRUK$ISa$l-STgezDRGP*Ojeqk@z^1 z$v*fyf1XIPgHzidlF?jnlmfC@%nGm<;8!rEVc<+sCkyRSwWU0I0cUs$Sb>vF+dD;1 zKuPn?h{>ai-@;N7+CANI4WMs+lTuckg=u}^kvkWhkZY@#dW6ef&5RJ$wq`UMTf-UK zZn&2S5tuV~2F1qYX2O$2TYgwZYtC{AmxnEEexE&8 z&?^ z;)aH94vgtEPc7L#$8BlM4L<2#|LtI%u2IZsvHM0diuh;LmYgrerTLpZ_n}X5|3N_` z$T0g2~vACO;)s}(1y$JJLd#IAIu`(s0W zQr?ww?c!y{AZ_d@}B@P%FK;r*)cw(l|P(io)gUc)#}SPljQ1iHZaBP z{?)$kU~&qtHdn&3231*%mL?t3tcN$iDaFl`iXO6TJZ2{s^`~aB$1P&?(N*`VD)}}D zWLYS_f_`G+713rGJ=kogvsq~av+=c;uFM-)vM8!~2w2?FqEhhi_?H6cVZOt%3Sy=H zsde6LAQQ_DML%HY{-$}vi;|mxK#Ro3KA-oU6KB0L^KaPpr+9p2$ABhnY0Yb(p}h?F zmFe5kV1`z-kC|&E!w35Zm_@MKbcc!gj4*o0iEE+`bYWrUMgRm8ua;k4f@)8TPg#b* zIw;ZXc6!yj2kSP{r8<{4kpM*>9atUdf=u{3KYAYaLJG!BvR!K&YIv*W>cDLi|LQpB z>@_sp&L@yAVX=am5*_w1%;0hqAI4v<*C(%?+8djPo35*iwQrZIjy2R+!VF7OD;tsm zxM4QyM75bP<`FrH9WKUYQa=m(v)IB&nqXa^`fWbKBoq{O62DmN7xv4nIVU%OMF}*E zAv=Z`;{RvwO~C9r>O0ZfeV5)Bb*t5KOV(!DmN&35jsXKV4ntz5RZ5e&<$K zSJkOg=iH@RQs3`>((O8Rs{U1{PSt3Av!d>CY^gl>1|7hCZI&i*jiK%s1UOsgb?K7GK!4=ld19zawxHQ0Qp+Am4G zYQ0m3lbsWP&Gej;Ix_G}aJNJulSa@1b4RlPtXDrW#tV;+5MfX^gWJp(TifP)OZno? z{x@8kdmr3316zVfxFJA8@h0+&Rr?+d2e{&Eq%pnwbh9AiA%Kk;Rn?RlRKVc1PS3;R60~R2p=y? zYe)?}80yOZs0hv~{Y3EKsFTj`%C<5%6EY|2y?mqFCOZY^T%r3OT89Fh#)ENFGzZ&qr0G;IsBFpZZVOWokbbR%~vHQxvv ze3;N2N-jRH3uU}2EFJLp=5|bja)_`{ae#& z(ugS6K$KD-b^F!a2$xcdtfp)e6&{qG2t>YZ?P|Y;&H?<{JSS8q!Bz6 zGzUynR%5(&WN(4<9UYBt8v6jQ7JHiAx(v?VHOoK7$S{O|TD{C_K4ZjMm2PWN?E<{Q zxn7YTV`f~W_1m1EsCSLE+*PFCu zytd38r`^cy1yjdG=m~!uFa0F?1W2u$v$0W(2XNNTfFPe`{#cXzs&Yr+tKGzIMB#|}3(dLF+ zs_mh#o#{M4FD%huL!Ls?PNQtJYzNa$?3&fnqs)vA9=P|kU|(raPuks9{mnlEjZ+_Y zw734sZ{Pis|KVdF`NW_9&S(Boem7)}z}8<_4#=@VI#Z=1n8{enIUNL4mrogDx!D|$ zqinnwW_UuZwBiuOpX236H)IuEh@Dzz727=|1PHp-XhK0&h@bhRic!akudM##EdX~YS$bZlTUSxdrYNV*%T#t3 z=7nEyYu9C3n{c{hI5x^n2TT;I=NeROND)a#>F^!(tu`1&=wc%>tp(Pm=J%EG z8iLi4TuS|3u2A0{C{?3AltD}*UsU~AY8~r`c0RfWN3~z8^3Y3q^}O2PhG3qg7?Ip( z9L^Idn&mA#KzS&nZe;65a|W#YgIbLV^g54-jEI6wTIr>{pERt{?0TzYbIw5H)W^@B zJbUx=uEs1Jd-n9*cIv3fU?`PM1dq509grP1UW^W!wdtN= z{J3`Fo%nZp_1KoK&GFFXr6_TNPC8bRz^7TW4&ErkJWo|2}pUB6+5mY$yS!jRD2x1LV?l459>6DThr zPa+i2xFEVTmm=RLVQ#B5}`qZYG-KUQy))+4h!wWQP`Oa+jusd}ala=kO@@yW{92ODXa z)~`t*p*3Yfuk+2BY9dODq>VyOGGA4$1QvR-EA9uk39nMsMSV&Xc~A`_KjfJ!oV@d4PahTa(AMzq{G;pxE?OcNX~O!+egzqE0M*lw&V;;Obo{%xRIf zv_whdc=TiYrRu){x-h;(Jgn7GEM$b7MF0wObY=<0OD;t+X7c4~%n_!NBz4~=olzyR zTY)JfuqiB8tRF1hYFu!ls4~kPPWnu$Vcw!eYnc@qU$RkbK;uVxq4(&p(aNF0r>B@- z2D3UibtBR_Fk=dLgA0B5Tl8CJpmAWtfAl*awoXO~DGE$FoH0>iz(&!g^(&9| zD0(EL9IFAO$ClL?i)=B0paZvrNi*n#QW&J_u{@vg-cY#-|($x_k4L5(*7LV`_+-{ zPeS07vvGO$_Qogq?R+dpl`B%mn7N7R7_zjzh_H9i2?wr)cA-9Y#PNmiOYfR<4e%@4 zPh{Gj&CUjZmG%38S%l&qq98N^*&R)pV^AMw%|W>dP(uyq!e8?(8svrU*nwZHiE8Sm zu(nt6B17$nr>0svtXPDtP5tP4z6^iVFs09A`N)-HZ$e?zY6mubPgX#Y*6#!2$??O3 zOzWkh5q5bWM`ic55-i=0eEhYoEuFBD&gsOKx2q6?>#tMSSpjoxtizTT`3lpNK2igG>@Aq&7srM5>{lqOfwN!_=PJFq&*+zN0aOUXqYc+_s=$eZUmZ?V-> z39Bt5k})oSS04C-aAMp5&2peIF}#QfD7$ILuY__L#jzJc=Hj~}A$7;Bg+59IuUmG9YIFxe>XT^o*coV?_x6sL6ciHc(rbE67#qfQDS^5x^XU zz`eSzpSIJ%>oz2!kF}0aQqGs~Ol3%N6eW~VRUjj4O^4OQTED@CO%ozWhu3Kyn151c&7vwzs$KX@+g7&2=!Na; z+2R-KL`J%1qZERKZ?N_rDp`Km*9IC;& z%(3iI0d`GT8QpLh>QfdL${z7jsGv^{&&qTwM7@i85OSVsd5ApFEVOd9{ct=ck-C?xhtxUd|z0h zg3swPbw@R|RUS11vF{pK*|VklPVapPEwr7<Px@A}Yh{@=gx`<$%b{KQ}U_NN8v)<%6K0`i5T>#+mTKn zdrHN6^^@c16qguorbcqHN1628efvduRXB16$xKYobUYVe2V)Z$zw&%3U+Np(ck}QE zpP&2i4Y>~?T|?t_9AK4@#}A~!_lkm3$B{7HTRs{x%EJSXLdSg|cPGl5272&s+vvJf zY3if2dQ~(Azk=JZ#A!{DKyTZ91w1~e29Rx>%eb%UhMK$Zui2jh?W)Y(q)ubQe$#nV zRlZbQ&UK|>xm_GyNLR(+25{b`qR69Y>TLz_c~QBzI#+Klh53$5*JJdKGk3E46n;2T zrN=_!sSkoXElVU0vRa`Yzxim)Nv5_-eQ+zwLJ(i=(qs8OsgnM!Qb9@eaV+q$=(M1B zLWE_Q%vDW+Ua5+|g`($#SYr#jLa*~sXA~qcQ$Ij0AehFc0zr;a2yzrw$4Qzu)J2#G zTcC=`Zs@HJE}C=@)EFlwc4qj+GowK7_t!1Kf$S})+&#Gy{}#oORpSrOcNM>)uJFfE z@HHv)q@EKYRg<3Z$3BjJo?ZJ_v&N3##KE3}S3YU90l|)B0zIp))1S7~HR+sd0uZ?y zloBPeFSN>@n_NvpRj)(#V4?}n zW0KJXD(j3#u-P1t9o|VJrTal}cH4IG@0?h`JF+jtzgr3PVqYclh??icSV_Et)jQZ~ zaxa7RaH2@9hbhcR-;;)E5ZqIwc@_|T7-}!~UDaRZtIhdgYclD1^^ISkEpSPg$XVd& zsXGRu$mOkXnz>2n=K3FAlWQBVom@V%0Pljf(H51=)GGI=2Tc4|>&GR7#a zkmgmv=ZIW(_(8wy`aM}qnBK%T8lmX4w(Bu{E*tO=c{m4>dlu3+eR-N^2n)*7r&xbsitq}HYwlc+L!E>KDk!B=%oF$+ zJ(yq`P-j3>fTwV(^wlIJ_|~P9Aa+{mG)nk*W|2ZG5}h9#7jbXvr_1&wTB%1f8;MkJ z*GA!P*<@GT_1#y6?X%AAqHY3s)il^^chT=e@_y4d3A6#MRhko689`~tW06}4pjryL zS=5INcO6C-F-NZKv3}84CVUM#tt)UX!36LuJWUkj10|9S_fpN>$33Mfu7Npyc=&AE)j;hj$ zmkN*p>BFVw^vg~bn^&5ViL1NgT8XodN4(S~V&rG%gbq>rSarv!Lw!0Nd!=KeerGNI zrYEU{En~onhEN&R4<1DO@f_rLZ&WyK)QySC+nyD#+x$KYrZ!*`K;%+~ zP#iDLoUuAVYkt;JV-iIJl{oWzg>+GG%}5jtQRUzEqB-Y8X@ChbYnCf68!6+O-Ekx|?S_SisHrcSGZEn>!XCTT(i<)2< zumbUeo-sr}<5Om4RI|0Ml8a*os(pL?XJHvI$4%?JQAWllTNG`we^WKA3FZ=-2sF5< z!tt~Lx~;4PA8-{4(l>;&ro#un4K^UObsz@UrVqN{SOkys$5|i~& zqZg|j4h{0E(92*wAR>*f3It&*w`Zo_u9A#uZl_X%tRb*az&rX|Wvc1dniIJ{E4-fF zs-&?`}!zh{Woz!y2QAAvv33Q+9KjF*Lv&sNcc@e#&fRfN# zcmB<;vBC0S!m zkfi1Vhd%7UP+q{f7{8^*nc5x2p_Y|8f}zXTZGOM*ErQnvuBM=;bK4>O+cw_~-+$BA zt^)5sb5{!7cDbFJQ^)rLE2;sS5w&-fNVQx;O9b*SH2bJfjk1g(K6EU#F8iD5Bl#dY-SCzmG?vN0r8i5 zzrPN-h3|5mG*c!bQ>~tb_OLX~th`!{o-}qnsQN4)wYcU(>fTFZd-tgznGLOSqNrBw zUM-@ou7D)gF=_zr);h9KiyXp!3xhYV()cZ_QMxfXjS#t_p03AM`r##wB(AuG@E|aX zQ87I@k?Ul7v{KdhLZbh%Uy}`MJUtg#k689x`I?QE!#r6OLfQ7Fo9P)NB@`5z!J`-1 z%v|EbX`K4_mK(46{5}67r+a30{^Ni6zhC@9p}O7J&!+OawN8aq@3uCR<&*eLe#?5h zSr~?~Y+?swtG5oMR>ncoIIJcd+e)BkK4q;$3hin+wUg=m3(OvQx=4`;UM&Qo1#@$( z^tsHk&`oF(2p=LJx7pwZmT+c>i&Aeg7W-lo zrr)t_8M_%JUieJOLhR~r-$u%*`eDO?qoRyGd$0(p8>;H#r7yq?d9>wo$FKMvD9L~C zJeEDa9m8GtGdHLQfo3xT_;@)pVfE+?#!`m1?qr}emmhj$(>q%hq6H986a076$b?>^ zjtpGFw)|A_?&GD;pFZ~mP6)Cv5d#7A;1R$EBYm#bfz;%;)bUx7A8OJ?qDG<&pHYoq zZ^R4UIX8p~(&J36OmV1payJU=WFLj828$UlktrU~^%$YYM2qSh+Y4%uJWbn_7;wF? zV?J2$pPg$HIg1D_We%J$5rB-);PTCywJp&Qy`vh3A%vQJQ%w+ci&@V1g;4_jz{hNd z%1sUZW_R{A2)e=xWkuvP3Ggg2z0PNB{G@ua<6Y*lUMDaOPs&-XqR`QAih^%uJ*wn1 z-7d2=EM`XZwi5mws{aBA$c@z?yMx)s%L28`o z;gb=mwsDJT79vP)Tc-AT^MdXK55vXgqZa20BF_T8dQp36(iyPUXZ(jYE!g3ik=Qe; zRcl$>+tCQNFEnVH9<3z#6q>=5>RsfitkCB^jT6y@$bPbZl%Ab=^U_U}4>7D`6%&xe z748&xSYQ-Y_ZQxRa}l23dS^H| zID8tFc@_Ci5EY6{Fx7BSjUVP#k4a~saq8p$^wU4`H-CTMkN(WBgTxR0((k_EM?ZZ0 zxpNtI>bJQVK zI4l_lttK3k=?-e5KylD;;a-wLyE+6)S=~)uNf%?sP7q1S5Wp*ZfA-FO*|&jlgiq7* z$~aokP89I0C{a<;Vtc7m1uYDU-jubP88^)p31MAu24>Id0pV`y;<(y+S{zIZ6<iY`x3Na>;M$%ox1$S?}`9tsLmhX{Z~|Sg|5c|HhrBwQlnvY z-K|rn)@G%~P+oP|eaVaWkM5%$w$K!llq%oUfoAa{XnI>KB}ofAo)V9B;XtJ8F=PYm z(%hzc=MUg<9}RL>u6495+&|Ce?xXMOc=k#B8Kp@N4VfL~Iyo~Y9loke#Gnd6#!fTB zJ!!Li#Lyl410S;sZVMWSHjV=XU5QC9-+&Bo$R}^ug0Z~ zRYQ=rD21RK_?RnMOR!NZ4Hx5l0sGEObZ!lDJzi(+aa-Rq92rEbG*dfZa%Qg+0X;nr z=j9O-<=7atv=Wt@@id+|4~cp~Wp2oP-{rk{1O&;glZ~^YCKDYJCxjwf6!Dt*R=qvy zmMY6REycdjRL|CCR)t#C8D!QV1rQNNYS8qi`C98t6BFkvyrG0IQD{_ z!@^Ka`%z%x1j^`Y7HnSqK2|XS-NBuL;P_hCh=e;_{504?l%oQMGu|)INaltQLzVnQ z=`$)T?L5(0|O5dWP&m4Z zdhYqxGIF3Y77tiwEFP-k-M9N()eyvZ3yzlSa_<*vwJDLj`;o3sY5r3hN}5kc^{Ydh z1hLG(Z`EpMVhIktu-D_s^fe3o3e5u|wyBGt0+A~gb_snJ*mq)9KzGcPCguQz#CuRM zD{9twJUg1ip;WEL=LO6Y6hPXy^H>gF^f>%O!;dz73StH<@CS46gkl9IlPg-^xd4VL zleyu^ckC&@j?e_A)02#$hONS?M_9~Hpjos789>6@L7r6QZQLlmLGe4Kl+N--ulgV!)J5k^5aiD@9(j(z~Ke*NtA}d-f^l@imABO>bje% z$(r5dMx8=8?M=JbS<@-@J^jtc&J+9g8SQ_6&xU*J7)mDu}{K75YN}` zNhkdbl48C=TithGfec($CG zC-?z~Y2df!%ut?gG|$cL*<%PgZ1nl4Y*zSMO}hJk+WwS_;9q7A2# z&psw^w}vCovZ9*y-Nq`-?#n%qwv%-wZE z?n7-&!oMC|2X=VO54g(e*~O&8(TsLUZ`bNeUuIcu_0g`fmrMM1GHg}`+a2X|iO<_b zKm5k2k1>_o`+9!*$KUe1zwyD}`^e9I;3wXOKR3ht;&^MBY5^trd66$=6MlFAYo|Nu z`RAo?^bm#2;c(!Z6obh{NRUB(;E539jtw2J6h0^l9y&@ zaaXah2p?+b&G8#LbSZPH_!ZD6LYD^u=&Mfm&vb+3T~=)u&I{>HiE5BK;D1VoYv{*c z@Go!2BZCTHE3I7{i7PJXkK*Y9LFfF`^VfkdC!|5>J zfG-5oV8;=Q<3b|JWo7F#jb&{3a7}FP>NQ;X3A(O_>OTSFGgQI~xB4LC#ld!+R0W@I zqSU)^-0;=5hVrl`D8~<&NCi6fym&*c0!a15umyr05$1&@J~$6aduK{m&5)A_BsXb~ ztj|518y!s)ljS4UrdWrDI%|b`6k1PwZUxnN)N<3~ZV$2<$;YU^>PNwel82+#AYG^Z z(MY(qHO=Ng5H+O|Y_$hd0}F;HkqcKfGhm*W!O`$Cw7Hy{f#MkFGPp1Bga@;C!J9!k z!Qj+Joy(eE4plNZYW!||oH5q}4oCA$sb)^(y_M6mK}4si&WN^4LlFjlIRE!VBN<-s@iRE`ERZzkFQY^2tB`!b{%# zGe30u`+oI*{AsbI3rMUcS(dhio+z8J4-FeqhuPRuobe8qPo_D7OA)>p6wa!?Zx!T; zWgcBMAGj5YYov5PIvU8XrC?Gq#RQ#|EQpOi5o0G z0rbpVFWfolNlhDxMm%@0-YH?fArd7k2gZL}5oC+XEsKnVHhe2Zb~Oh2`qEu9w71DzVD-`ji@$c8tJ)$80U`_MJpx|b%J0c&N+ znQK?82lUW*S_w#!f)g_-uaLbCa6?w(KIWfK-fSNwAQ&7D-c1?!6?PhcS+DiAdLF+U z<9e)V8+dNYm*7a6LiDn=QxrpjAydw=W zoFpQ9t8%?(U@g~By?cVb_&@*m&m4R9wARt#d+)AE*I)Y6j|}bHj;5NML!J1S{^>h^ z`FHpJ$;W@8v!nf|KK$E%_~&1K-;cf7>}ySZJl{K0{y|4JWwegja!pFeG+4b?WTc_v zkcgrI>I^WK7(31WYBjWmvj_g65Fi(thM)h?zl9h~ColZK3F;q)8P&T_xhlUwX##Er zS`xPhA_Uio(qUj+?99B>r;AIf4!x_SpoJ+-6yD`CS5${tvwT#X1q3=uVYL^ol*HuP z(|kL*Oo}=_y)>Xs^_~|=iR5ZG1G``^nJ69xlea4);3hAH4`oQ`v!EiOZWJE4J_AR{ zZO4%ugCu4G^hSKZ*#N=>cy++CS`3q(q>8=qOs z?8zL+z8xC9Y?FwgsS;a|;w#aOv>~%FH?o3kZ@2{I5hk|p2c6J~Kqd#)rzV-h^3jt^ zFyUHv{(p)itUps8vrCfx?NnbATN(B-sF0RKfO7n&DU;>d9i`}D6L3buDuNQHr~OLk zYT@w#4KlRz@g2m~fd472Bbt6wx*n_Af7P!C>up!|HQ*3XVPHXE?8v9jJOr!3y0w0Y zRx#as4p*0Q(;b;@4X{aDDbWhaQ1y@ON4evL^=XQAz_#(pCbDg)zKUjF*b1=uOqPyr z&s7B}-hN!D>gKLmhgg#6;KS=bUVIcA7sN;(7F0D7U}L0zt2w|#C7fP$^-8YTjlaQ1 z1MXVoW_b(vBIu0LiNvOY2~QJtwf?Ucuw5gH1*5}8y4W-!FGK4c%~Lf?WhDdGpy1g z+W_?+=EoYL=~9!`?A-g&>Bt@WpYbFb~U$zSozyJ$e3BTuZq+!_!I1P z3=zZncW;%|P-Wh$=prrlQM3M5$%fAWw+M|z1XT>7U^vBw6S+k|<7c38-pBv#xBmFD z9ew}%4}RsFU;MdO7Q(eHcSdB+$3{#(|* zRF8n-obZLYP(D$ShCcMu7(s zL{45(cZ`*3syV=LQ?Gqh?pGOcg z#5_#zpTfU8&K!dNnz|e5-9vdecCM@yxc6#VbXXJAuC%Qb=Gy>bj!vP*>N(s2{esYs zykfboq0LrOH(_DL2qZ{zM|?-&+d2ltEp$)r_8LN15V>ORYF*W9x*mft)k_zDV&%if z9RHen8R){O9i}s;HYh5Kv$-y;XGb;1RHVD)$RWW4Xl3FoT823X|C&z9DLR!g2iDi$ z(V*i%>Em*KI?LYh9XfmKR$PE6k3{7H?^@>rRf4S zr&o{S-_(o^bA>UnJrb_~03ZNKL_t*eJ+@!70=X;=CXyOtpz~KAYjfAJmYcr&_E-GF z2VeCM|8e)p8_irJX3MoI0ZI}cG=}M;@#pzv9aOF8k?k;~rtS2a12Pp8V?upggO3%s z7H1`919~)n9wP-QTACJYkKDt}XjfDAL3ecu^XEXU(?URxDiuRq?P@S0Jzi^qUttA3 zmyaf?Nua`s=?YD_z)RCU8rNhfcGsA^d7i5-FzdeBsyjAY*pSdhsf*O2hfVT)O02jF zTzIP8!l$XNI@TF*#3NDx#c&Giy<3GB_Y5>neSGxUQy+TIJFdBMZ(ncMww|?bt>*V9 z|HH>#f7gHd`Cs|H=gx>&5`5t4eCS|^>w4(QJt$vV7SUMh2OMp9By117Fy zrBG`qC9Jq0k1@+h>C{9)^L8+oH_X2Gnn&J%OOHSAE2BM6@rX6!>&<(sEHM$L$Z+_; zEc9oECln3BRg!Tr-EIc%F(F&J#S=9%6(-EGt7t);SX~l86Z*37#z~!fi|VMZVXBcZ9hxJN+5!F=VV*S>Ms=maF20u8!us{!sZ!sWaVM#bd zcaI6z@tQ1Ygyh4^6;TL|hie_L!&EQ4GMh!#kZP<%9Z!k4Lya&;4l#APsstmOA9o~E z5oV5y>jYaOlQhBs*{qYO#46dsFB^>zIoHuz6wARal<3Kh+pU+dz@i+rumGlSS{ZrW z63&97FMr_Zp>K@$pG0APK0kEkM!d+LXOp#GYhl!`GF%pEEq!=tRKvq!PFnot=4S1y zCWXs`!U1+Y{BZ#5R3r6q^Q>SmHA#wVzDkq>&*971GVI~ByPOK*c+`*8#8uZYf2+be zRKGThOlzq>rZ`~2L8NZns`X}T0{bhWNkDR98a>!-rD>lplu0lxc@6MhN7qri7A~3K zgeIw42{!==%@JF_wiUG8MKx^Pnn?R*M7FSx#{2i{BJET3DISKVX?DaIFjH4{0f$6y^~o1i@#bB zyhU!M)rSw(8ma4_j7hNyGZpXS%hM6y@NhwcI4lRh-IrTw8M*xUb9?TGHfN@AGF?YW z?;;B&hYUwQY*p}7GL<#v5ST52OkvV~FXH-|gP7d<>B>~Yfk*LSW*2yxYZ~P3-$aGn z#73%*CF5Qb&kJ+B?h>wc)l);(PvJc4?yFW;kw|m!p4M8W(-aQBUoX&`_4wXzdO{wX zV?oF*vlRicU0w~{ULx|OmY;xnpIJVH1dy zM4kOhci>;spBK`Xd}Zd^&m+rrZY94iTYd9h+?X2v82TN$ew$sRS$I7U?|K|R2F@IW z;s#Kj_$_in0Xt&r6U;!Amd!mqp#b0G3%-HaAeck24gq1|ZrOd6j((qKM?y1`%t->B$))fMtV=R z(-b+xqyw_42s6hh*9k%437le9OIo6;+VNzm%^`BGqbW5|K&{3+BIzK2xQwkpbFvG_ z7svX)bnKdY$6mPz%Oc8|s*ze<2f;}%S$7qJmBZQA9WwM%F-+SAeKk(=i&)jn3q4u`c*@`#u?A$ympalO8 z^@loTaf|S#%CzhY)aYk2U6VUA2hR+3isS~H zg{S$zwEt+Pf3}c0WV`$CMT8_UB?s=_BpOlA5JdDb766<7BhJ1;^z*FELnqFJ)m&PD(0v>0Ja zUo$7+)WTDl>CBFnt9SSI)_CZEA3vMfS#Fh2By3;2f0?d9ZSm|KD8Bo9<9AQD3(G`y zdU3w>0sN5Riqk9SuIYOH?zS6iOr*8BVATy?-g;_s42h{O>)Jikrfd|}TWVX_3FO+$ zP@yd&a$u;Rw&C%;LWpWVKIAB{FuGxM2Kwj0%6BYp?kv*zuVevi)HJ2!W-G$7m_ zffv;B?LakuL#Foy`QA*`Pd|d3M8zqGoT!i3%7IwavJ`ByLQM+b?QqN0Z^b))Z>D8B zxEgrqw&Wvf;u;LZk7v3j);7;=r8~bh_Gw6c+0GM#E!Oi}@6hu1*F;(SpBWava;JxSUlxoi;pZs~IAHCr5Kz4G^W6Apl<(;|IM`zBy6VDS-`h~;wO=1O zyjVWp+BMu4=(Qt10W3jRZ@%mDd>pyaA!3Fm#5BtRG;@3w6^w7bMAHEV&2AHLP$`s~> zJNaUHs@(omEmlbOFM@4lSm=ZG>}=hS{&8WUjiFHmKj=V%V3`o zpSI&;gEPh9_@(93WiTQAy9z3Qb!7B3CS+glmEAdG&HJ?JS%=SJRo&s+@=I_0*UA6y zZ24=425tyf+L@raeq-}FDAsD{T&`2us6Bg*uNL@psawHx@mzUq32QRFXeoQeTLuAb zc}+muv3kqt^IroemgfCZ2O~F=^>Q()oSl3c&vb9sbtxEl8y9iasS)vd=CUK;&a`9t z`25+-Os2neXsD-_>&He$F!%^g9RFmW_x_P4R}vg10epk7P?z|Bm-Vr>2 zQ**Ytxl|T$ln3|kI`Z^$ue$9f{C?`#bC(b8psM=J*cw8`z{!?;rg^M$8JG-RnS6ew z_2k^)j-^}cKl8pl^qqkYBRgJLUL0HJDsnD}(Q7H~R)^!;Xi%@UE8CYTEFCY8?GH9} zVbRS2&a#o8KEn|gp3xC<419R=b6Sr+4Q%z zw9Gb-onAKmRXbL%8_%40X68Z9sc67zM;0JFP%*tTnc?Rat^TS$laHB)A1i@45hpux z{n;m*K93uBH{U)n*)o9;?Np!qi<<}jsRib-@vddM$96XzgwS$y;!!wnMm5=YU!ip@ zEBuaMwp^aEyGT4!{4Q?qF20~9?+)LWvFYVp%b~%h891}_6<>ir`>`{xl*h*Oof%y> zXRbzS(~iuZk!{7nOs@Rw>bYR63_du{x>r{9-LG;r=Krqef?Z-;xJ$^|!eg%V4g9&g z<#tSta6VlYk?)g-Rv_(fhED?)yw@5KL;N;mV|Fjk?JcD&_&oAYH0g){h9v}OGeB!V&hNBgzC)KUnjJ!{_q z`g`}GyV0fN=_alJF|l<|Ua>MCFaz>4UKE~~E3-S#%<9iQqbzK5q@Ak=7c&nWpFFyl zg}Ny6(|dv@)fZ&)3O@O@VI4$ znVs_4v6DXN!0KpwM+7@M*``mdtaGgNIcSgt?(ovBXO_ey_it~30%hOm8=vg^od5YA zImOC_mT7&{z~M4pJPxpt+`=J~m-cD1-gSCA^X+4~$#X076@DH94)}|wCm(Y!Eg!;$ zW`vsK%<_WV?jT$<lEy>{QRJvDf*u>075II2XpmZm-<3SFE(v=N=sSD)4Gi-a0CF zS8&ebW5O+6e#}Sd+izSwN?SP7M-)zDd{u;E6jldfU!u6?Go9_ZZX9i=i<7(7jy7^) zPmVq6?*eajq;4kK)pQK}Ku-%8o3SS??00|D&8IV8n>sVrli8(lN9RhXMDLa3%%n3# ziG!JGZw^?65eusjF7KwbaOeO! zeaq`^`<>ta%h$i+md=j0Kl<#K-};7^YLq~8p+G%mVc_ka+&Pzl+wCU$m_WcJj&Q)8 z%^|pR3W`^@2_-vY_T}x6DtjIbwK)^Ftw^m9IO*Arr%|nG9(+I@F;5u1gc{Cjx~E3KZa1GzN|;#msx&g0S?Shw}_B!?dK9ve2CdjK%OSq9S+_<5`Wl zeG%}oxNF@V)||zx0WJU4xp&X^Otw$;9vpkq%=U2xkmBmG(r2Oa1D2Wf>3fpoQ%we@ z5jPDYR=s;PsY0YPBuPvi(jsdggyNpg6cDZ4fT_^?w*8H`W1yyDK_ZX2@I@WT63)_A z*Hwla0aDDh4G7)&UGvYB{u&A#B#%x6d2IH9$pqWi{ZPL52lF^^9-S!L1D$HBImbtxhq3 z71n^!u?8kHM-gXps`OQ)mrOd7M6NJVkFm*M_d{&8wLu=Z8YLRo6mKLN53($dls~sU z8@_Rf&>xz78!E^U@{X=6@Mm@f{z8qD(9GjcN#i4?+VSdHr={kFJnOAc_~;Aq6SR>- zA!s6cxrrg*HQLu6J)^MEYzk9E8)E-U@mS0%4*(M>Kpt>*bR5Y7Zpck@)Kzo8B3IlI zWEXUQIKx)91Y0PSdVuoi$R@*uBNq{6Nd;I6U#WSEqD*`}|t|~-JNgnsr?A$tm5eZkoi6K#NU+(%^4Mets zH;5csQU=}uH;3JcrZQ-t8ht%64YfjGj2*>kPaQo(I4?E;BJLTrYc!(M=$b{ zw!$T|RE=!w({F4Y9wiVNuwtQ4Af4c=p&$|fr&q={aM4zT3YhUv3epDB+B=E89vMCcJZc5ISCnmbO8|2$t&5nOKf!{~0jEZj+=GQ3$6 zg5yL4Qq^*KGI*F5C;-GIu2YjX7Fh6R74Sv{h|9oad2RZ zz`u}cT2D34SL8kGT~Id@D%W}ydW6Yam$4TC%QZFRvDq?Q2C&0JBMcB^)5NOZkVITTeGj^)aMA$Yy|a?8_#W%_yKs z(0P&p$YUHg@RQ;@hz&e;5BI14;;R`LRK$@=T@vMI>oBQ4V>N39Sy&MobtGJBALcTF z160CK+q2?yL~b|rJ|fs6HDA>EZiQ&ahJZ$*-Wt5oREoj$g5UX~h`*JUaab?5O}8#| zmnSEiYmTI(j7{2@Whw<#zfiw4J_#R7Slv3$YEww|h2tQFjl7-DeW;{8FCr;Ba)>!Z zecI`lSJ#lEt)td>0D$VY+*{~4ngaxL)Z($W6IBSl9Xk~?;65sK&M-;R8iY?qI+dk^ z$ziHSbaWv5cJ<|=!ZbgTA2{$r@oR9L)YmXnp{Q+4@gS-VVLd z;BTwKx`rxI4pviq(;33SiCIb23TgN;XJ#_UZ_(*tK=SE@b+GW@zy#ki{CQ^k1Lf6@ zo+iLRh|eZbqJ_*x&$`px93ZDlvzdW0h5-X;)IHg{Yf1SUN}HBsma3O+&A}!r;hbRq zAtiKv0(XQEM(Y`osPPN8a+E=|@rJhxcMdON%IoMxs?FNJ`LSQnN~UM$%)%6N4VCd1 z{@1Vn>p%X%cfRy{zyDkR@#-tqTn0Yy6L0(W-+uD@_k8-7e(uL|SzVh*^)Wq7xNB@1 z+YJJ$$w`uee)lardbRCU`sBLrjlCM4?ju6h9r(wV?gxb@Aly=*Z83EO5Vx34eQNoM z*p{^l@O1(p2DMJ^dzl|uaMf@E%0TiIsJKyyP^`w-YLcJ0X=}h$=&;}~*?(_=-kl!+Hw<37sWZ@c%po0Hkil=sExXQBpXeM!bkqBIX#q}qNc84 zQxQ8ZK&fDtfH;ILf*VLdv2$2&hkn^wj>4I1SCCx_FY@T>{m|?{!@FN`&WgIrvm73> zXc_z;b~fB1lW1FS*V0Rxb)W@tM02t%Qr99DE$Xg1m76gW6$@@m zhgO>zQ$RCrBj)}KlT_4}E%;Tp**bC7Fy)kg?#h>DjVS%QVLDR?G2h zwN=v@h?MGU+Kauh`Guvn){Vp@r+258iWjt|&RlOFXB|o@HdG&8L@g~GKxkycNk9IQ zqQ{>3xJ7Yod)R**eXzdU@$;+c0WXkSJy<86hcg!%}>uc3U4{QDo2o9@iB(epkR?E8Y@A2v z7+X-6w@_w_;+Ile ziL4O@AayYlL}54WNJlnxDA+NgZs(HYGM07bt`hMpa4azIg4T@QvgW0zlB9TUB!+~k zZPM8gC5hBqe34Ckmed^su-<&Rq{0-Pg3(2%u-HWnFm*X}f*=F8*D!7-H8JiRO>HCd zF;ZdSzSnV;J13(RWi_a1@tf8H$GtVV#B+gKY_&l=cSL)j1iDDRn~!z<(WAwWA1i(q zD*?>j>C!&~;9{yxkUBH_IBBj4Nod3buc*0Sp;cu`X9ysP)oLJY2RsiA{3#G%372vMLzTVmhjg2&Q9m`hZ zHJXVmwA1>{GV|+lDJfEtlzZ_*)lirdr2;9Ey@*1t zz`a)1L?9t#3OEjTuS>y4-YPfzHupt(y5M3`u{Bv9!F2BSr>hH@a+jKAZNzCSu! zy00&HLzF=!(Wp~YW&iba06kQ6`C6^Oy{*O!!?Q#yrvE)@Bjzq7$XVFnCLRVV`McG{EBS zb*{$(St8RN>scSdA6M{6X>_r^`zXXgFgSJN*!JU4f`G6+(=QVPubf0AHQOm(IpAY9 z;JjYR%(?LmtX@byQ(E&noIS{ICKNvUQmsV(_O?)o2KUDNI{yI7Jf1$dCP&zf16xVZ z)3jr8bz~tk43r!HsQ}~-UJz`&*q_yKH>jbxU{7KkurK{+FMs z>+l?no507coXr5+7fF!?!5jXu##4hfia`EiL)1X9eM68CiFaSSG=0;GTX&2`Xrb+z zL_Qqh66^nwY!ju;s2g!s;hY8;_+pr}B>Tt%nv)Jw82}kDs-q1r=e`VI@3B{``{F@j zKxnQ203ZNKL_t(A;$F;l09QBDa}K}r^ZC?kGIah8@-NXpsD4ay>=KHac|LSpmF{?~ zNvJ-`R8jX)@c|Gmy@sImjCj zcY#(Z>n{%q!G_zZwGn7GQSM+pfv#Ia$YYZRszj+C3 z66vr2e~huTjIKd5F)Af#V0*|zD{-uJG1$ylndU>>@Deu!jg>r~$4zC5>AXho<3zd@ zoRx$NP?M*5x*mgmYnX_dp-YaDg`GtK2o`9>3fmU0z;CTGT>{(ZdJ{Q&T4&NxNWZ7? z?!arN$pZ4IImSAgYRsi5buBclnXd~F3F3Pudh}+50mtH_c8OYnY=JtI`Eq0~lPCoT zEahlHb3kTPILZmR;4|SqL(tlBj7X}tz=Qepjyl{w)mTQ1f|wN!-7#(q$v}>#Ob;Md z@ur+F39y$cKk9KdSrUGQj8d<%*?Qm3*-$~u;C(EU7NqXo!~kT(M#Ef3t=py?&fe@D z+b0j<&!wK_t8(vpe(u8ub9e2^z8cC(#A98XdtdWlKduf=-9*>dvq7Xtm7j{%Y#ojb z-y@L>vqqn&fjc;{*q*I&G43KTk;C68w&kb_oGW=o5PyS@#*Ot9)!;^zQ^e5ZWjdl+ z@hkEb$6E)7??09(#A^Q*>QPe_khS)$(Sh}#VRN==m5EXuwVQKvTU1p!1C3B0f9f}X z4&S%D{x<&LzyI^s{{4r4=B~?vL$SdhZk;OdF$o~!GB|oI{!AJT+Q=cqCOJt&%*1Ug zKsx5wJ#TEvG=qjj+Dz$=8s&1!u2r^x`WmaGr_yPS>ZMRkL%Qdn8d*)k9=7Lg*g`bG)Q#aD|7EmM_BA#5?>NEsSIT#uXdv;VX75IR)xWg z@E5T?`d6T~+Py2fTf>e)4?g+Er3h@tnW!l-w_FU|(;jt|7!=`J+O8was&`Rss_v6f zZK6C%nJ6Pq9k>Bnvr=~~-(rMF(|!}>AgQ)Mg9n3zQ0@Q=<^bE~L~JZ-0`(;~D`H?Z zW`nOl+k7vTT#iYo{?c^eI2v(VL^g>Y*=mOfbC5oj!6`;7Q6eVCj4b_j-K{&8uLGGh zK&+yKXHE61UA9oyfU_FXiKeXD#uSzkl`5;VYAo1yZO6sdq5@6eN_=4EcGPL=XtR2V z!wnf%yPNidO+t(aO^EaDpwR+2?8KwYi__? z6SUevMqMwN;uX3JEdh${KZ*t`guMg5LRzfVMD9_I$Chi}?ul3+v+<~hV)e-|ZeZrY9Zg+im$XBTqpKBk>P0qJm*8+3p+4rc{>Cr7XJ&T(iK8bTKXM#DHgK-F z)tbP^m3SHN)he-!c_{=H9V0~n1V=^x8R&0w|I(nJZ~unVxVT<_PI9- z9xhb*1wdm}et^AzNPkGGn%0KL$IFSX78Yv=z!vJv2rz{f%Az8izCtFnO1Hiq{|19}S` z5F#+&A*$gPXu)a{G3tJ5;oBOQL|bhH_!an5u8;} zocY+G4GLOTGXr%ivfF2G zPX|vrYb+#Z4E9lIF47%vK4h~_adj>VqJeuas#!g${ky1DO%nz=mYq|jyqWDY=2Ox#! z$nj30UpG*`_LRfXRZu~wJH|?j)g7Z9)xizZNF34{W;ozUSHFO>S}l0CW7XHBi>Hx< zS)Em@1p7`p>R4zpw@@JAT;cah1Z~EPBqc+wPpz41%%gMw^>hsZJs4Jq!$M|qjT+1(b`KDrE-Kdzm>UHGTh08ZyVojSN$|aNZQ?HGlBE$&ZA7N>hUV8Qn8?bw ziYz|T3g|-#IRq=Bi_h&*52eC*=oX8pHlvP3)W_;o`Lw7OF3NIgb!jpM7~L&@%n2sRg^ln9gpH=v2PWu06kEwrg)V+ zYsLfG0LUOljb#JNtyTez9yr_LSre{~2N*QS>7p7{-Xe@mOPe9bXVNH#t8vy=t%2E8 z6a&}WbR{G)I9ycka!czsUjM#t7fc2BWbSEDwSnHpv?!3R*XF1Fgis&T^A{TAJ@;Sh z?{8>Mbg$ig_#1|MGQDUDIwK!mE9!KXQ$Zi|D4V?rJ}Ym;giqcg zjulvTOV6I>YQ$qA*g_O;6=i(n+~jb$a$swO-!V9r zgSmI6aObCT5Eh-NnT#cd6=V_-CY_5~_MWXZteRC{lOmo*CD`P*H(_jzBa8!MQH?iP zR9u-=Iv}%0zSo?t+6K1DM-Y{NjBAn^i4!d_Q}K=4nW~{q>zpsRJH2h9A=I{V^`H<@ z_!YSYp@ijDX=WK!N6~gV3lRWTKvS?{HMfgKZ6_pAYi{McDcw{rhbAI#qbggiZkurD z+^G54>bDW<R2~>@xXV+UDV5-{c0B3CL6#ylD?p_)gd$JL z%6|rGQqy7Wli-}} zIbNA4L6J>`)q(`Y{7|K3I%reT4Ew0*{p3%TyCz9pfcm&OCSCaE(GgVi@8Z4gzgO5h zvHv4SMJ9lJLm^@M$rHMV&-(b+gy!%>35#u?Hv6cA6I4T(kDko}#S4~E{N8*2bvW9% z8YONOGQXLB~W}^^$toRjTQ<@X+4iV}Zw-nWQ%c;UAN`3Rx&7rYdOp5C zdDrb<`SXts^!MUY<7WywSrhmeWK_78Cb}O+@xhHGSoN@Azm%_fvzFX14IqqyF%FeP z7;TcbrW%w7l9gKN%0yo(pIjeN8aGN-o8cjvBaJm>YZ@zZ41H4~tx8gl169JWlXHPK zz|??Nd;u{zrdA?RB&j*!ERpMQ?3E%~7N&CgbCIoC=$S>e4Rk$5?@Y*0wy%xwPA^u&%%#HvyjFSn0FS8e^ft7i|C1?cGy5G1d89 z`yl~BFovcWIbm+deF)lQ1om!ky7@rv&f1b{ZA~h?a8)wOs;gsYxa!pJhOzxr>7P+r zC*3hx));!zRZ6GH_P2&#k;q*O#tFQ1*xNZvXudIaCfhhJhO#Ihc5Q6bUa?RjCq#{3 zp1kJXh+F*Ch}=n}ogjtlF}f>v3XKDlGJI=Hjbzj)NW5u+qI(+bqtmM*wVlrgx;AV| z{95P4+6W9+Q8sCr^lUTe2uM7q1>WLPcT62CwlI9~&W4E-%O|aa)e5cBAnFjgqBl;f z&ej}QCDfKiVKI~EF(17o5}NT7&wChuUh~Ksd#6GL7CAs`qGr|Y-3NTboFY?AsnwBb zd(C@|xfQAttQ-m4oansJavmTh7fw%DSWlMjiS6250S7S=Mf_t6+zmG1DxZs*JrA8S zo+e#(O;e1by@9V!14iW2g_8!};+n6MM`D5FucLhg;qEFWT7izUc**|Xloa-%)`=vkb0QG1)ed)Rzlq5X7Dexj;L0JoL(|}vdt~v<62Gc zMbJ(o)W_fW&ci?buD7V)&z`Nh}FW(jXVuL@}6HVY_&>($1lDcj+lKu_H zogp97y|9NEZ9dvedDur;p*ew}2B&>BQ7B@R#*I9XKO$r!AEG1Rmt>qT3x^jefskY9 zF788NQV(2J!f#Br5Uvo_ao%m+RcGFs2oV)zB&h~jo9L;@#6ft|;lqo65osk7*$1D} z>LUK#*l2z7cBVC+@#gdU!+7&jZ|?XHAA<&Y+llQxKUjk-NHiP%mBC=SSL}4#$=ROq z=9T8`$Q4-ODO``yoiy3TddjN~cU+v5>$C^T8S9=GDUUpN_`YuyfV9Z(&M&qO z{Z*U%nyZC=o!Bs`gfc6rB~{9_?#2^crBMNR{n&vqZ=voOO^9T=c-foiQtD|VuPD*h znE;7gflWJBy%-DL>L7+9x_e@=8Xv#ni>EJtIJbf)TOhSi1~E=w^Y&6@emMkBZ(sjM zfCkCs#;(awyR@xL*W;w|G&};R-zRzdb9dsQpx-J%kY%)@|EM>-rZsyWg9g&&q%l3; z`N}ldBio9z$Jv&$PweE&l}`_SY~bk}kYy;I?6H1f=_}jBp2Mf04Uj6!@vQc(Q(OPOv0S|>|l<@>w3v?uqNu)#IKO943O#Y6@q{*!3laHU%~Fwz*Cg~ z*&0?XlAyqiHxYSe<#6D(gn?FsXtM>Bun~s|oC^a2!qbbwGe(@1K`!?yqeHC3Y^p-* z^lrEUYEwTT_F`Ov`l#Ef2A|G(it5v2{G<_m6~pn~s7{mF6l zpz%HRJK$YJtiMLrDmZLX1>>X5l!twkr!aev#&9wdWGrF{i;C)H_PkAqQWT2-1)AxE zB{f!@x9-WEIJ%(BN)$N5?kJz9NG}sR|7Ha(&d#jhC~>ILs7&`!kwmqx9*5{?`X=Gb zi)2KdhlK`tY~VQlZE!rJMyeFBRq>d}6*AtOx3q6N@W{*l9=|(|7m#r%YREMyw?h4} zWh_N{9FJ~4ijo6oUvpjV{ScmsLCJ77LR-{?lGKe*fT56&Mu4V`fAN-y97n5%@y4kq z0=e6#ig$xqL^XsGLmS>0H8;AmGHtN~4*}Xn*A8@l_+zsEb61PkfuGuDXN@KPBCEhn z41|tz3yb%YU7aFhHH<0dzsg%w?;OX$ny44k z8JrF`^gm^M8(j^|W{GPtH#Cn+rkgqIOJg&@h>!#YZoJspR0FfwY;8->9m1NSxrWRl zErP0m9M#>zcHvsoG138BCJ^lrG0EtVqs7lg-Et9>n;!SH)M659ZmGQprt1~6IU47R)dh_4lPh=dbvQzi%Bw%T`?nI2p13*_qXeDCJNeAAvWG*;up24-hf@&zDiZ@7PwnIBY|a-M zIJ3N+kwYmGLgH1T#+HJjLrbozyraMqKnz=GTi%Y}6!7pG!n-FhO^L7O>CpukV32qP(|JGIu&`S zJ{H_N6V}CAlyM4U_d_GxCFF3%O2R_s(5m|n9GfZxOVl^n<|uzO**NIuIRc+bm~}B^ zu)h6Y7a$!pqJt+?n^haE#?}>^p_E)Gxem;ss^OKyOXc|4@_hlpf=NsC2}7+FlyKY* zJ|Eyt_>tPp4Wmm3>ye1~npc*qRMV%Y%SmIp+45ziVW{ zerybo+82*nDi%x{G;3M7vjy(G%R7X^#5B#K5GM;=5Ds7QSNJo#;4%}U0uLSh7%9cW z%9}*`m#k!Fv30`&2NvSt;>V5@??y%z@b)-sq{F-UB53VH(R_OQ{V3cvdEij)-2t!F za%JwF)PBGL#h;!FsHT*a)VFLaD)9n(f(;S zaj5}=w02=VswFJFzw4H@@j4YY27JIxyy_q7sm+v1a2W<-?Sg#OWbY|l1xw+tvf&2D zGhVh#Js<2#0@qI!04A zZb}ijgfv7_xw+UeNeI!6S{Uq?<{7z|af%aOW1*t-k>p{8Pw$;wXq!Tbw)ks11j2q1 z0!(e0euA)bz~i`m=he8R!fueE#PqIHeAJe*B&~(%zbnCa`?Gffe|cB-RoH4e=7rvB zu6+cmWGara5)NkXs<+~p_4stK$l{cNFSvW*%dyo30H zLY!Ir;qT(1XOQ@GO!r+OB+pPUI~zP?Z3o zKwiHkwepP74Df5+iL5ALh)mRcZeV$$7$81z1_YZlYxota!wuEPC^22N$XA@d?C99` z<7hKCr$_&=BQCkQ-bo%hD1>geR1o&sSo@+$DoU)`CUK~t*^z-KQDNrXqhRTQ|HDlK z+y%IOVC&(Mv`0z-+1dqcGqB!G_nyYpq0yVyoMSRAa6`t{3I~)b@rA7YZg`>9<9;(J zpf-GFwg`|j&<^L`R9-VYI{} zl1@*@9Ccj40RWt$#KSd*Tzv^y9}SRRHVY#>G{}%xRE}RtkCIWR2X#Z@=JB3FeEUW(aK6psZ!Nl3+$mz@Xevl)UJL%}IvSn(lerXg3z(LubN=@o$; zixbb7L#{~)6w_F-Sb-!=wh1ncQ3AWOuc6GZz1j?CBhy(EN~&zc6kza*ZEt!Z^vG9C zzZs3M3<|3izEB(^zh8s>&}B|4O*HZ!wFa%|>ydg!@cOE8f?i0T8YO@7wrZL)Ae9=r ze$cFn2=@-b2}l4ItxBvAE;Ml~YY7tReUrjdlKrZ?frNc9saAcRC_P&FE)E~B05&v8 zcl_?lzD>M|*}L!qEklrF6hF2^3iOQZAMIP+sP$)pQmyp3&4~&&&U=S1MPGknf1em_mZnNaP*Od|q8Z?2FQ%&9 z@t7{?ODcYarhmYmO!FbJ?9^eB)gK;u9D6w3S@iQ)sXd;19Dl*a78(V6gyh1PH0jh) zyUo1gvcB~R%tx`q3$!O2xu<0cNkF)YsXgTzS$yk6>qGp4c+_j|7QI*q` zn`s}^c9?pF3CGoP>G(rYiYbpY0!Tch>#oQ1@>_8bD>riMSD#4IxV$is)0Uz^;-#cu zGzo}d;_wE(PD_ux=t~RjlZ}@s%q2t*6ut|%8e)oFZTH&}9{SrlP;Gg9#3zZR*d#r~`rC%92GIIWO5oC~)EXWaCSD~VtbG`*g6?9`T;zCWxSiw)ZLY+xq{5+q97 zPYO>-cE`7gzfCo+q~Go9q*SA3ycsG0NO%0=x4`#ox?D!_Lr%jj;Xn>pwnU6;VL<4J zsdkj@FRf09!c4y`xzK+|18rB6kZi4p!|E8h#c8^G1`$&$SCa{0!U001BW zNklW5Wh~th5|!EAD7{wCz0@TseKNe&MqG}yXG{`tqM`qZ`6Z&;H**B0fEHh44X`^*J-o7Qc`*)ker;^$0zM`Qh2W8N83lrqIS9 zIWq@*aIRNmCG8*C_gv{7fAP|sfv6JduNQag^G4Q6jS{E`{6b4*MbwSzqA}$T0fthI zLkrdz3ek%dV#Tv}b>;Au*cci<+=cyXnm8HH-e4WN=NK=DYLIMauPj>a(;EE_*az!K z9q0kr*xlHmZD#}Zaqz5Z?p19+*6tjI@@4UPYbZBT;*FY?iUYC**%@R25*MQb3p73V z7*xZkY;K7-5s>ck$YpiQP}eXXvqj?w3tezBel3AxtYS`qM8@Q+IF(`~$tFTzW zZh^hgy#uIYG}(-L1A0^*s9oVeDN;h>x*rG8@Mu3nO}UR%vk$m?R52XfH5+hM)tj@s zMAs8lm1ftPQ(pT6}Bey_)e;Zp3buP9h#g0XTB7GwlMS z(Dc1cM{`?7sE-Nh<WNrrQxafdPE?-u_ zu83^}{*u^-(GlMQntK_@Vr?q6P;Lk^uE=_e^sJ9^nwEEI(BxWc&>R8R0)=f)35}A8 zsE)IMC&Ku^aa3rZ>OQ@653=PTXAVwPSl3XPR9Ualu&MqeLq%;Pm9`E{Sg9>iRS(Qn z1xKwKMzcX908JL2g|^{XP3DL-hRGAN3f(AB=C$bssaUS!;11%DpyQT0GCb(cDFOey zqyN=4LG>lWAN71eL;pDen{f1sujBP$dd6+{<+-Fex8waM1U=bXq8f=U=i-cVT!4}S zsunKt*rsHK((2NM2z(6s@$~V<3~NlCC(^e%MVi&Bt_kA&AC0W(>3ZyF8SgJ0ZX7Y7 z+U=ZG)v+}6p9mao>hy_%XF+$6BC$}x)ms@AH$8G6b64}ZYCT><@AV4$qE9;wu49D& zj-sLBWMDVb;x6prv`02i3MGjeu!7wWZzULsb=%Z)BC=;}=mdAamO>x?%*{4CBoV>^ zp&G2h2>Qg2tZ-RQ_R-{Miut|GSFsiMc8WSQHY^Pv$8W1QAx)JsCWhucYf^U{UPP!r zRr+eOF>K=6JQG!1vU>aYZ{o?=BF#Pn4OJi8NoaT}M4BjpjlvZbUUc0em_Wm6v~)O^ z5jo{H+?BvIe$s7Zto(?DXq-mph0~KfgrWc(DG1GXjMFk{Z7QnJ8tI10p;(m>5qv%$ z6@V#LZ;A=w>?hg=N@nVIW~>KBk| zjRZahJ*ts_jXY->46er@hVK`7BZg_4p16X0CFnwX ze9V}vxqE;NDIw59ftjqL8gG2LRe<5z;HAcs#2%@GlhU$=IOb1PC>vCufglMuQtMca z6SHNZ2e}aAo&9HN^V9^t0b@2@8hxmexf!gL849qtGTeSV2k;{7iaWp9ihN&)M}c(> zw-C8P#<*1JV9v$nxmMjfupEvfg${Nb@CHLCuSey%tJWb`P^|{-1Ejb^tv@w4BwU|% zpAot|9H~;Tx=Esstgd_v{W-YuSB(X2@c%kiy#LdnqGG0>Wv`3xk#nGzmg!#qGt+LQ+yIe0%6MO!y{$ zA&x$3%ge&|*-YmP-8Y4C8Ja`S>nODVP&?2LAjo5dFG{SA<0k1m)Tw^x^;NN&Fe(v! zUAPBIohIs1ZuU}CAG@EoRNo-05(6Ak8J-|2I}D-gNL3;Sqrek9yN;@6 z1*Au1M9NT_3eve+Vr(^Q>eab-!*2)^4p{;YR@mHW7p0BV?7acpq1kD=l8Tq8oy&x? z#?E{Du7BW72cP)i?vVk$Bh>v-*=p@nLr`HItO}g>z>K4bX!EGdI2>>ozfd(}O|4^vCE=5$+j63=w<@QY0WceQx%^*~C_^c`CYop0nXcX+c$nc*8QMBfwvB-?@&2ecZGz4M~^qdwg7aXPqH`W{4&f&j_;V=}2%6<2EHQjf;ITowz z;HI$NS4}prwmpLVgZ?+SQjnXHY+u`xmrp%|OJkRvYAftw9Wpar(}UnS)z!!yX}bHI zrhm-$35WNVsX{eFpwbo#*#DrXlXb_W08ljNpD5)qr&|M=4JDe zXNl^zDG|Fo@2zV!=_|)xuyt}<8DD+W?AHtow}z?a1AyX{_M$_aFdJtHcXlh{LIKHf6ONl^6nH`u4W8vDAU$q`Fu*8I$huK{Ev*_d$`W%9fF~r4VMHgg%{EO6`>i!T z7XnWMxI=XYR7VLDb0UN>@jB`whNo#h0|Y<~5kG zSWr<jZB^q8xPc2H>fo*HJHHQ=v2VbydH9aSb8lTl zYEZaLF76URS9o(F*P%l776K^I(8at0oNawf+|9THn{t|VOB7fkt970d5J)EueixBC z@<#loE^<%q4hnlr*NNqgKfz8QwzPX%?CqK(m6h5Hr7(0rn-iie-f=hVHDf_&+v5Nk z@r~8uFK^>UANTD-v&e?68tf@=lW9ab@TsZmhY382+aZzUB8Z;EVZuHNnlCSjeD@Ah zM52d?_k!NUuzH#|LXf6^Xlb`dQ41SC*oKD+|Id+|zllFP4`=fu;>cU=Z8c9rvo&`K z-wx^*tTi!RyRxt98{M~f>S+7pC0L0dVo1m}>n+sgTQ6<$LaVKUTO25-KomQK!mxNj z2&;u38xGB++W+w2VBy1y?BjaOkzt9u7sVg7)vXFJe zvDZpNL$MIm znpc{O`K7jwG?<%O`zisHPnOF9Un%xOMd#dA!kr}Qkce%>UBLvT2LlA>Dcl7uk3)5C z6)j-My)O5D#;3PUb)k{TfwLw78v=Z+k>PkoCc)OYMO1@;ho$oWw|5?Jb`|B{zq|Kt zujxG@A&nY>K}sk|C@P6m1u6a!Pyq!+!~!BOq98?7K$>(EDT)vz2neAQdMF7kf%KkD zw(n+l@9z7X``n$JoHOU#UiWuD`$_JdGiS>8%$f4cGtYxj9M+uMcPr^Xbo#dPR;=h& z6+YX0sLHSc#Er6tvA%jC)_#x|3lJ>1@pc3Ic>hVzQ%mqDx3d;;hlmhRTBFr2ty_XJ z`$3Dv;tKkAs8>_h`gOrq+~P+cE@jZGFS$`>61G{OT(asZ+wO`!)6~T@8bs?AY-Ppr zz}Y{sZax<3u)6wrx&iLq`!)efwHutI*I`cZ>*7{J|xdcaVemwrH}& zi+(S0X%`A(%)*wV%ofD@t%v;4+h!5c6eG^~Qa5}JHvHsF7-Yxj|FMS(#Y`=WM8P0u z!APMcYcdZJdPZ)!7-%)cBQryz`D4^Qd`72s`!1lI_?AP;NvXTmlMo?PyHEK*mQSyt z)ov`y#lH|lT^Oe#wm>{D{Gt4MGBzS`D1^?%^-5JO;#NfT^=jT-P5EH&#ku_~GUe8t zy6|R+Cc8-LmkoP<&8YV=Yb|M2V&(E7lcLYgEoNB3&2+jS1jH82p8q;%-V98EM9B6#v*x!rb&!6;S}4(86cfe~3v1grNur^Hh*?LB zP`OxXwWDc8jHx5YR-E)^w!6Yd5V}`JlbWqVNDmgRQ{uMa(QCiLAak@yKc}jTe?`sg~y#W-5a;PI%J*d_u5D7 zppYwK*6RA9;$lHkXm3%cH#*AO+_ns(v0Gv-jMavTh)1j`8`sOWy5Qsul&n?x%bTp1 zMC$FFBRQ2btalCgXdoQ-A;d#iB<_o4Eu4sEp{*iG|0x45)U9;Na#krz1W-w@FB6Q9 zfMMnlUqX3vm+j0H9JXL_f_*k`*KoG#D^X79j6)()NUPdrcz-yRo(-aZf=&}r7{A5P zhmBHLG_&I|L)pl+$~gS>p#y-`>*KauAuB^C?W#iM^CTLhU~(_g5wVwZ+8R9{kC?LU zuVtxNP{CL&{)GrQ;^D`z?4Z}MspJBQA+)RZ+;XM@ShE4*QRgmhnhhUI!DJ30HlAXV z9piT6xkbECqIxWgJwyvB<0wTW9OtYXq2|rTGeLU&ysYZKhy&CjFWxn9HZ-`EQ<{Rz zxZxI1&VRL#1>B$;<&0np3G1XZsLmYiLF{mWiN`j0#555>X8B0m`uLEh_o-)j?opOJ znqnj|j`5g+Y%N4QgP+7=IFmApeVx%FhJ?F_mK}z5G>Jh4({S(V;Bz_!qgn0x;1Wd0 z-Sf^7`Q$+atI*I{otog->V}~RcN(0L$g;&N+r7@)QxPI>mQ06?hhwan+Du(pFO@G- z8y?Wq8&RVA{0%*?;ZIw9vMox(KH^Q1wN%tGBWZ@GVWIhecvQy08t3RQ#vi0x*5!=v z#J92k#FK?_?f$P7%M2>KVc(;U!%KGBAP<)1ko!Y+JU(zzlv>YWkyEd~dr4gM0X?=N zVtpLQMKnOG7Ac9I{^%VGv9&Fl?3gy}5;zN@bN;?X1lBih(Ixc7A33+gDtqgd;in!B~b_gz7hTknO-O ze+*N4(Hz%14e>SmBm&fLkf5f{*s5PB7%4Elp1;4}A zw0l+B#a5E>ylEB`mPN=I0g8_!pvSyW*520hk`eCd)pkTQyoa)Iig=4#1d-i{VR*6p z?q zvUS@Z1G6}bN5Aa!JnqcMW7D{*L1~m$Zqz&N z($y%bdg&BgO3-M#s5M!SJS&VrWuV5xoT!NYwY5Q8)iV1N@3nKE$*G!`{z7W8uhZXg zOoh=3KDN8CM}o$WGvhLwN6&_VNs0J}@31)`qfAWZP-7|{BPUM4Dl~Ma)^C$KzJtEb zxOIf(8CG;?3CU8|au&cDViogwEW)Mfdbk{royfMa-RQlo4k3*epTvreDEr7bF7qg7 z@p3mL-0g>s7sFA9Fu~|=lOT(69_f~)vRDmb?h(go(8&-gRDiqIMyF1KSTU=^YDO#W79A#AA5r5lsh{ z)bH9{|K-SAywOzIP2aY1Q2>J!#5Ax)v-X>9bu&8~4-9;<%WLoLc|VdhE-{K*OBMP4 zNf2sBQ}PtW37faxyhHNQ+xe9Ssi%u+Fmw=+gKkKodfYNWwYrFR=?K$+ccyW|}%22bL!z7ptEZW7j%ZqHYn=5wA#b?cvDrxXW4kWTgDauF68 zDju<0knWOCwNuZ&zpgSV}TJCG9tuev8R1 zxnkUCHQlsBm<(Dnw~)>etG*~zHX(#{$pCPq6{D~%Iw>sk9!jRLy;sHZNmJ0g}Fz+k- z#-WiLimAnMi{_&#n=_8gbiLi|IPa1Wt2(WOV9G11$Bk2!qZ{i-B*>kC_6@^6MR>!i z1+cCN0Xp6q{Na1g1|?8Nc_s%=cg_iHsb#}YEo8A79rh@j%`Df1${7kp&r+xEfJY*> zOX1a5$egkM$a%DyLRZJ-SRr7EyJfoC$;iTw?7`@x4^B;-%$8XSmdIMgct!!0lEV$+ zC9*7Jk>6ptVif{oHHVs6TzxQi4+#Qj$S77fXu0vgO8jCSb5jzdrih)s_M3(3P7a zTdr>ehW9*_ZpjWG*`IIODT9wr^unJ+@PD{H`oedxyrJ-x}BE zdM>&49~_0U2cQ{)0QNi}LAGCm13mv92$T-Wc~wI6>z{^_%ly!Gbi=J+xf1TNkknO> zi73R!&SwDwiLf(?Lr!A3LOcyv>n;OR&Bh_(mK7k5_T4Ha2O zOeB#$Mi%D^S9(hi@ryj%rW&<51$-t|U7Ca=sxwWneBjLBQ}b=R~>FT*z2`=vf7YRwKXB7rQqF zwMCpI^B(WQLptenpeMDkS*Axi)}9^xtk{nW^z+)8^v>OBPeaEq^C`{T#;*0=DOguo zM&k+Iw?}g|EE}p&&vZ@jIh(_uh$(o~G2B{ed$5*R5BPL*QV#tBooWMhR|!+3Fb$hpmswYxye5(0GC@xULx*EWnqc*%f~S+e^Q`9YWW zV3Li4e$iO2uo4sD5kkuRwPLj0=)59g0T4k=l0w!nth(MA(O!(Ew9&`0z1lWSoaoa@ zZcJ&_M(3ZgX5@B80q+Pz!?Fn)wp_8JN5uN>&ybfaL1WF7@zX}Y;{+wjAfs4Q?Rtza zuA}TMc>!PTQ0S3`5oCnaWOu7V?&bY^-T5 zNHIv#+_M~kumu-Wj>Z+cO*bm01U(`{mM0yCxTjY+&@b1RKe7{{WKJ|+XU znGgDN>=uY|((a90t!2=Xi(HxTxB(3BJSn58JA7*W6YyIs_S&ymeoKSY6PS$HaB~(< z>=z?ER@GzN;?!-jre9SU5+8T3aAs-^vF#@%*ZzZd*0?G?2L8p7g{qMCXX{5Cx_aw9 z=+{5#C3jB4WPX@*(-09Uc}K9$0rb+(`xfg}kAlK=ZOiJ#kgMt+$%q`XpTrM%4 zmMak6Yp$wL^i^>P5>KkAL!E~(S{xGWgBsM%0hVm=YHs_3hjVNB<$HKFUFqu#={3tT z-x|&BM6!+}c0YUprAx6X5kZQo&q!g6kX;ZAf?|@Q>a#MV0x}+x zj3zC$TQM=q=E;fexDuXt+D<1ppE5(TnE=Jd_NU|2jYSM-OhoTPPfK2)h=+UQQ^2$q ztF?Oreu{ZJdvP=I+lUASaXQeGbBoS(qg4kGDpCFGlsPl2peojC8SQCEB4V_mu``1B z*t*K{UZTfZHXUD|Gr~$9rfCswb@&r8S))k@xl0630uY)ha4!Q<5e7nx^m2MgW|k4N zNMZ!5(penSFRMB&=5Vs2!wFNj5@MxPFk&FC4qi8L=k9M{Wd&`0{De1yevM=CC6U(U zmTBt3At;yLBg!nqo_JvEb{7_6x=YRrN12EfBn}Yw$I{QJfvbI!|Fr8_J_dJ~1$Dy4MvDoWY z9*DruM6Kd2Z=Vfr=_EZ|9x)nQa#fE}PAz-&F0+gsGLB?KHUt7&r>jGRa8_w^Acp=y z>{mooEr;?=(xqC?UL{NBhqec56~ZRn5Ipjdg=(+@EowY|>Suw0V`bNq__uXX$Yheq zas>jlj8z6`Y+B<<6~K|F=cl4TnISfQjOMV#1U7~qIpz|FZN~6=e26NTWFZS2k^dS? zB94*daQTk1ifwt|X zoKRj&8yse2B|!0UwCy2!A9}JMh&i8|t(<7G>{W|XC&$y~*&v#NdBkx#&&4uc0ybV>tog3`L!+O=y; zOE@W;Oc$()hxea*?cC!MCSmYw4iPHwO79<^s*$q_(T7;4IL19^@1*2_l??FW&_ zk~!8Ozw*PDqaS&-we-z-vO81taxPusD~X2}J~RnP4+pIqhm>trkMVG^+l26#j+Vz) zLf(}K0a=?_bxw6^dLV#RR-8e>v$hJ6C!#w?zZz`w6)@qj$D!!4!Lvq z4Ex}OCKwU3%SZ$n)MT!x3n12<@Dmc`j{3Fu(psyQ(h-v279cvSEeCYK zLXqyZtU_LGoz}_(E9$|1yECF_pxMkHr_>aQI^I;%jh72@ThXny^^?&QIFUHw>|S1E zNY>DLLAZWjS4&W}L%xjca4@{NV=105-go@$Zc)~{f)zR6;L*HQ1MBeFS~#Z7;;Gxi zNUn(BwdV%W$j%1SOfVe_UGnDLVzYWIjY`a#xw-Ymv>#Z|2D~i*Se5tFVE@7RI-t8~ z+)GK2pWx-XYoZg#dVx4`C>b+R2Nj%t3AvWW=XMGjPw(r_}IX_*E-b> z+hrJ=qx7LC6BjJ=(4pW@DI?d%%voCv#%ut4cPM2{qDDilk{V=0gdF71hiu~Er^sZT zW1H@UxAc5i)~fpbVEJ~%$+$~u^xIxspmbrHx|9aD+eaRd*87ubtClId-DL|$d|7qK zPNVZKt&1%NWSy>Eowry+dN+0LphUYzvUckZldy<$DLho1BFw;5h%(gac9jN(?h^*@D*d_(tgn4j}M##PoY|f?0qUTr6rdF+eWA;b5ynk zLuZ_=s>jjXi&;l6DD%4zO(Izy$HP*M=pc7)QF}rgs~2tUUL^ZNSSn**Iqoe$v@R@? zp>%9BtYj1NA{XSV?2?5%(ZQD^R@Cv?QjnodTgDLiQ5@%)qI{I1fGnq-Y}VnUOd*kI z(qbXkP?O1!*$T)RrAv29R%We(H|>h&i_->j{u+_}uw$S5A2&B7gF}1Ro4VB*KI2C= zhDBQt5qeb=<1yG`Oh4{Gv}fp&H-`*u$NG_$Age0ly`qCDDkH`S@;*v4LxiN;e=ufh z3a%~Mgz9K$nfinKsf0c*tLi3Z$Wnl9rBh{FZw(EZDkF? znj-A$pZyDzdBOC5 zunUEkP7HT?k*I9^*bDMbwj{@Y}B{zL-R77-;`)^ie!C>NG zgnt(H5}?}!!&cZ=_E;f%LulT;3w9oz3IR4DuPo-giOe~1Kea@ozAq<40>iirgN z&<13WKh?*{Q4y_ioOJU75i6_L3)1ZI)F78wDx_*kTkl_BfEIsK7W&!YgAdN-gmL`Y^-KjdpG2NB_ozA ztfj(M4Q8#FYW90o`9YNrHkq7GbZm7A`dYD?i`xQ^k&Fb&?V~yR? zlg!&Nf{GX};wa@zA0bW=Ap)iFZi{n_-&ighQ%iNAmLMBN+uphB{eXy8kFDt-M?s_| z_}OEfz`MSQUk$%gI|`L#(Y~(x)tJ(k*|VNQ;9e}!AZNt%G1r~Bqb~Z@_SoNw30G1g z>vtq^RhRJU!XaKnIYq+QT(h}2FbGEzprVM$J={+25jY=H+qgwMNg=>Qq9hQ0)5GQm zx8LNp))gT#o^>>;Kv9+a7R5nyt_Y%fzpAQxQ6FczQs1 zRfAH<$VlO1uWp1pv>Jge9>f{iF_$w5?YTjktJa~*h$4lvc!`9FUW+Keol;sLtHnkc$P#M6%xfz+~%O%;ymQ(Y#ipVmmrED|8MFZWfriq7#MeXI={Zb^J zW^z-IrJr7BB_(lNn({2<GoaokS=^em3J%4lJZ!iOeB0-w^waQBwgwEoD^kg87;E}C_Xmumu)Mf#})6BHAo8`C8UQk znZ{3<{m7|OLr#%`&yUU$q*cGv4A1l=J>#|456Hbu^jqZL3knh%utX zC#f;Y;$^Qm3s(!;SCZSB)5*{pqGv@w8vP7OG|sgB3a8(B?@V*|YS^b%NEKawU~bYw zNyn|SLQgD#NE|Voiq%&h>_W?{jaS~PiQ|SMZQ)v1B5^sF+mUwEMP`RRBWfUPz*Z=F zAx!S`;F+fFF=azWMv;m>G2qr!;#tS7bDEx7%Mga)EaXC<7}9Wz>2)(YWJryp3`kJZ zNPJf&jsm3m7Vl%fY2F^Q3VF+XLr`~|Krif2hDZFxm5HFRTE@^GlM+eL`(CseYeryxrzS+~aRlh#-&n>7rrFM{po=rdtRNk#01eYqCjD%_iGre{1HG(pA$y*3D~dODQq#QMN% zVvt@4;5!VoVOr2st+oxvZ#$;AwFF-hmwp;WtCFdlSu^@?l?YC~EfGdXf9@6CF2)Ru z5aO!aX}?13W7OBEr|IF^Rm$V`uk)~~-YbqzMC+DOQo>~c6L-OMlZeUtxj1tWQ;86% z;8j8a+(ar#sb-cWB3ek&9(0ksm2})nF7&jvAeLuhu16MZZg=HMxHJa!!iMxW6YqJl zt>VsJLYJ^?ojMiKJ|epeu4Nm*EH6*kctyzWivBoH3}ksNoW;{4g*I4GH?t$b*E1%S zXJ?VJJVfBQy3*RHT8LEzJEhgJ3VF4lLDZiUR2G(pD5H`-ah%e+WH50U(8LMon5?zP zd1{fFV)`u#92u-a60=r=b)`}{w@qx21vbOPUI!eg*m4wo9ep6Lxm%qR&$bhs@lle& z-Kn0UQ>zSFDK+ZKV2r@#9J*NuAcgVVXRe4U3}5x)%Fr&%E)`vu+56Gf`G{*98il%;mMXoucAhr(@ts9 z^&w}8wohy5aCS+d@^57O7#Bo3j!3Ju&_H!21*4MEqGY)W3&`k-$NG<}T%)#5MXSkH zLa~xGZ1Y}NVSUzh58RO84{d&P&pQzN7+b!*lF9yU)kQ-Wfr6#fGQHo1lG9$K-6yhA}^ycIV#m#fYZFL1Ugh=~Zs&DuT0OgIfa zs9{$WerwJ0mBD!*2X8~4h|Uq;(IsKpS6Zc%jw?S^{yhYd8;vN#!y}f-yjD~6onEo~C?KFBTGGA=lIF)pa<+q)mKpYsN zk#{yJvnyk!=?v6cdc8*Kv*K`~Uh5_(F9S)py*;glf3B<*p+ z*jq?aTd3Y#(S(&UYr7(CJ)00Bhh2=-aSN2a0q5ChxA@VAi^Ek21f(&`t14PewnSud zGGgsM@Yjb+IG2n+sMaZq$z2aXpbU@JMv+DIg^4MqO&3k%^&-2EDIG@cBLpZuHazGk zZSfezG4cjl4Ztkm3Q zDcC)g<4|$99E`7QRv|A^m>f7A$AQb*mBGiv`&b!|WNb=M7#&~jviUBV7HSiD`R4Co zl439CW^7LZ(ob1jSe=>M&S60Q0ySHlhKy*{G@Bo>E*l!ZsHZsHt4JJ?2t!xKwmwy= z$D5Q?T^vHnSWJy+bI%cDdPi^@n2dLM934h{Im=>g(%Pgwj=CWnV z3>VrnURdLpB|E#&_}Qs@4ph7`T*CAaj&5V)1PXR&{CI^|2LBsV?ukUU9m38A<2H#@ zhxewM0L8}!!t$yc6*>^x+kS=93_`3{bdj%YSYe$nM>E9tsG*>l3o*m>q9VKLMNl3Z<9{35l{)5St=W`b+MeBVIYU+YW$=(qca8&}sDuw`U}t#KhvWj-yqN zv508sSpvyaHdwCE#lvC&QZ_v0%0HC~9#D0aild@iw`Hf8kAagr0+~!Qm8KPy!Y8T6=Tm)pH_OY|r zwh(=~M8Y95h8ZCAjQSJ|2y2BPeQ-NsvK|q_kF3Sqq@jI`z8GoP7=w zcQ7$&EP&0?GfE;Ve)@}kwd%Ps#3CS94$l@?}Sc-b+(YTYTV+X=GrlvOBD%bZ6~^AdqCvuH_B z1QUs*mVftJ#Sr;dySCw~8AF@TSv9!!5+RG8*ozBmeOkP^dj;;QDpVGM^W$SwPq9`_ ztUQawX9>5f9*4}x#$?Sl4d}#ROXbplK0gPAai|<2>y_P4iZZpVD@&_}r>Hzu!ZBy&|q>N3@+)-0GJ|#P;M#~j)*S3)%TQqA7JsU(Nvg}$J3^#sf zMjj#7twfJ#)=To<$qBZ`kjy$ujN3$6env|(0Yj@za|yCDI}hjeD6n`Vb=uN3+S*4~ zf=&uAvzsv5MnDeewU6x1^8Fu~uo^W2P@`zP*6L9z@w1J{(R;HI5&9SGfq$L$E8HZo z9v&2Jk4$=h842VP9v{Al5fXfnetFA)6@&ar4>XaFRC9+-U5g+-k(Bf4UcKK7TpqKQ ze5x|)A}v;Qu5DG5Q;Hk9U-hoCHk%{Sa3&NxF4*2rWY5Dp$BbOn`&IcWiIDM2Y<~-3 zIqQmLLyBh18F`L#VOlL*JP@Bl_kZ*W7 zT9bt14j9DsIPN?smd-k6XI?h*$JtrPxJ%VCNh#55Z47HV5VFX`epB!*X>ww-MYk5Q z(vSvQ2XWUf)*Df^u>Fd)27Ay*O{_f2*>g#}dZFqNaHd{H|E#iHp{oyhA3UAlr`3lZ zRE{wJ#4L1O@D)gqOInp(@6w7$=Z+dcP z^-(o3D>^$luU>tVbFvJ@+`Yp??gKHo_6@p9J%vQ>E0LZY*P?#B+r8<_bTtSY?(hjb zhoD-$LyJ38Nz@g}F z3n4z;(;38U?32%mB*9^rlfhXJoplOO3W9o! zPHirw;3No~aAMSI9q=F4Sge34q&+cXGHP(}?swQX80xaEedwFd}M3InGYih~HO9T3gLrJ8OO7AP*|(Vd2T3={!{RO}yF( z4bJ%zIqg9VCc@6{9+|3z*_FHi%DBS{@3;}A-P2$WY?Q==kEFolrjTeq$Yyi=-d5f> z68kzsPOf)6`Uk-YzE#n)I$!rZqP}3dbQ69IhzNo=w__|0OJOs%H1JvmBG#b0%h$=RqY1S%M@kTa(vF6JTZa-KzB<0;v4dSZxM* z&akEunx&u^1`81Ex^tNf?FdMg-ooM&i0cl6>zUZ+fx=Qtrhd;aqbjIbveVoCEKdQg zX-5KmA}USMo!+GGDy;Hi$C{{K1|>pvYCVkB%D20!!$a(aI%nL*8g}7+^UhvWfutW@wn9B>FD6XL{nv7h_vn{&Mgy&+ zxa!H0PjNa6^+xYF_9hn;R5BjKxRZDRc)PZ?pO~5zx_UP&=eX_NQ=Fw>5chpRTx$Oe zCBG;6TZQ_DnorvI@LE@+6U|eB2$}|qhbmm>YB1)m$_XR06&M>0ISmzhxWnW!d5tYSQ3!%SP zBh@$Kzc|X6^~&hda>$Ym9FnzEV18M?Dvp|TePPg5#GA&2Ed7oYD(Y{&7RDlxEVQ;+ zeXfnE;?W(D)$sY)ft=}16Jn+D@tGdNxZm_d&gy|{$3Xi-E1OZL$h`>5a*q0pKim)v zzGw1CRC&O&>eKzbo#o2ZjhXgCFk{x*4-E(5yQ!WdDQfFxqrl@1@fWV>_Rr=P%Bb56 zc+nEX@ctzx+!`tHM#F(Y>=FotQ2JyBP(1=fr|O4r1uj9g%?CCF@&0Yrk@_}nrHb-D zD!VyfG?_ zBV5vumlst&ix#FMejEp@ahVlia94KIN)vS72QAdJN&oJ$);fca&s`i+Cg0D1KJrDA;W07$L43ruPoT* z-nC7(67B_&n%|rjN@mmwHl}m|q)e(AX`x(OcIDLURc1ipkjLF299j{&J%5{khE55C zbCp1u{K{BbnVRnuI7*9nI;+3i9kYFZGGeNo5ZQ75?h&ImE)AL<`9}6xepioxfL0&8 z_uR)lMvMn%&{Xfh?h4Zt!vL4J>01^9DAro}`$6o}lkEqsn9{;1GfxQ*5dW;MPN|}z z#JAIisYF|1u?Af#F~dYABoP`9!vAJpYVh~nu6lz#`+T6G`WBHA)V01#f9>$|*_f$- zsY~8?e($*IXdlHZnQu+4vN!^$K2nl567scefqiDf$&rxc7TBzAG-LeUB9Z}bJCR;H z{=#;uZhih8=AKUCvF909Yb+|Hp0S9&SH!h#ZN>`dXID^ZbmF(E@X_+@E}V9cFJg58 zYVi8epkAmRo~9KauMAnXxS$(``)KAS4R>{NdoC15^pA87f)&Dp*q@}{=yhOzUFUN8cOj2yAEV$}V z9#9U5VxC~0@zuzDvaW)dKBkrEMzQ9vyc!S5U#$4PS_?&&aayO7W3|9lPgjSk1WTJ* zv3A%Mw*sF`ssKP%iU4t`JHzM-*3TtoHtKo$_TKg!zaF%lJIe-wvMtF!)YK<`mxIG2 zAH@(isb3F?G?heA@-*f_!*PXO%8UFoRN>(%?oGChY6r~~6HoCFPkkN|R~w{y?ExSKGm*kw3K@F}Ao(wCPgE7qERVe7Lw-0tOg_f#XRGB{)* zSCgmJ*VdZXipY}I+_E}#Y(M}tBQK84{E(i~95_dr?aep;MX=7M&i+)E8#A{5&3Lr0 z%ICEuHle*c+1p3d5pl!_BKMh;CyY!P#Wzz^#{`Sv0|e`$Fo4GEgQ*l6L1KR_f1Vi< z_!`=>q)?bN?Rfop;v-8TS1Gj`Mit_``Q(n=kTX8AVro%fub4e@Gro^iJ71gP-1+0Mv*f_(N|Z=Z0n@X@m#zQdaS; z=9OJf0VyeEf1pSs%u$A^=l}t^iQ1}Vr%2?2&>X}EB>O3_fQP`YVXa4e0u?AWSW(W4 zCH6k%+RDoqys6rQDVGwuSL?C1%Z|wzq7RDy%%tJrE#C;$?rcq%_UWwcn~)_PJRcz@QiVxB zYPUDXWIK8pZTgqH<;pJ-5H`iax)qkXLs-YLaH4ONaQjJbjRAf*9)6t!-1oM0PBsfo zSHz{tF~kaoQ@y+sz)h*yW(sZ|Hzt$biY?RBnT#ysR~&*--AViFI04 z??yMP%lxnt`Gb;_2tQa!{$l4-agn%~si6rx=XjMq>3yd&cYl#or~g`ZrZoc&QM+o` zq^8;8qv&QsoMruoyO8$|{>}1SD5?a6&6lP=&XI*Tg_us|c2mcm-#1$UT zMa%AtUh`34Ck1~pTd=w5NI;u7T*8VYdlZY`xqs=dE8~BT#ZY_72%VQcrB(Y*xu|Y` zOtZ%cc&*6blON;B<{;Zq@mWZzcOoZY06*xeyO`-|nc`IlpLo&gvd9}6Qrm}@iQ=_CN)6`09!;$)9pfi?@r$5C(1aS>ZFNRaB z;J~DI({8M>#-2T&ZW~33%$;trdALkmEn#&84}rimdu82sw2#DVBd3m8c(zU(NyT>_ z>Ht)}bU{a7L<@^BRj#?H5_3mc3guz^0IHp5s$R!DwIFUbR1b81peq;;ry<780|+f% zz-w~Bh2GAJZboPubV2}oe8d+o9pn#2VkbvX-!(ae^PN$0q4&oSNVnOMJ>?Q03wKU2 zU!hC8{0Z}a4B)fj6p8<6U>#}}Z|vZ8fyPoEwY_Jj&?f)@q)`@&yQnfXOf5@o{Ps}5 zIDdv;%-w(Pq%}M<&c}Wxak%Y_ow8_7Ymyo$$UjAsWz02%-{{LRIn%;H3jyA1LV)gf z{8}CI%M0eCSfId6a`sxl#U%r6$zZ_S%dKXx#}|k41dST4J6*>*ZsgJvm@sEc4SX~bxS-kvcQhmThP-z;>ssTfkFvxNh}FB zLLk3Vd1=@8^m7{tQgGk|p8T@{Fx5S48avyGU8_Xoc#ke|oHg~qe;3tJ?y*6O&}*J5 zfCHP%DQ7X0VX4fTY1wshH}>nZq&{v%UwSnRrp9{@6^H^vmTw?UbIh0M;j|g24~JO+ChGn7Hv$dT8veEzVH3tlG?iq^*9Cprz<@1WuK4!{Kx-H3lmwU*5uN@H9+INk8sxHNSGAa;qT%A@?Q1pN|4vc7I zxp=}IaF5hpq*3rnUAUVIAH%trc z%5&Wi4-hAim>ctPGBcp^^?PPy6^;vT9?e}LhC7vxC{ZS}cQ<;YiY1=YT}Ja4&6-*E z(7a8`KV}gLs!wCncN&Lp3dEd*;#Q^~1a#{c|5A0O|M}fR$J=}kl zYOFCx?67>ZZG&F1pz$+_vS3au`>LNBAhb(>mul|^riy}&6^pRtbyESTHO$vg_$rzh z8MHF98SpM{pL+h{b&w)J*F+p|8W?eka~#Qq)G51JCJmU47>G{5F8MA#9@;oaD;o@* zSF$1@N}y=yUk%4H6(A&FMJ#yL35^Uq2=c7#EUL+UEz8n(8+^N&c<;>P(^zCQG+@*P zmEU3&<}#aFq%K>Wf*W?`vNY8hDMQBmzZv*NiUm~E4_W{7VLZ|uW(!944bC(|g#ZzAxn9#rntm54HfeRGhevL^yFykFn3 zBulwoGgq5{`y5GsH-$)G#WDsbwnSU!cPdG09Ioh7cDH62vcLMf|6vpT#pW)KZgJr zq&p%ZS%R!1qyIBFl6BE|C=gsUnBH2s@gm+C=^T^}!}lK<C8W9W9h^k}O101Y~Mumv!}Z%n@@r^b2O1wiRSXfxF9# z`q_@5t%!}8&#oxbzE_Kp2xskkO-4aDuh>Ao3i8dsb{Kz@kgQ?Vsw@(S^e%IH0Wk2a zI53_{_z?&4F0kU*T|3K5orm^W3+Abj;DQu$`Ax~?KJ1f$&&g0fx1`+BRFYdwe`|GM z9;Y?%hq#`v=%=(wO5kr=T~k{R=ePVsc(9G`M#omCEbdiiW7N`b;?9T`3z>7|_BAb{ z?7DSqMZ)y~!)?2aasSiO7iAmqZc7t3eE8%C(?wQ7v)k(@$SW8M&}ns1PskaiYRx#F zC-wV0YkZ65Abs<$!pi7tm|5 z9v>bgqQcDNGrTRS$8U6TPR5`U6`c01>R;m^)2OY2^-nzx5;xUpKyRmZfS6DFfD2r5g?2N;yvMAAe_qKNPJzVc5aqA-gorh_D4zT7Cp zJIEVXGs4UmUsY0^Y=rBWW;IVK@bKl#t9OPF4oY^K=ti`ify55_%0?w~GL`Oqsn8}= zs=6ZpJ@xE0QT0i8I|UdKk8103M@QHwiL`>aW%=F_PRs!2WcRQ0Unz#F3d_n@9P*>l z2=grdDBae^s*;{5p`^zLx`PC2duI!>2Qb|Ld3s{dYE?eTNi2cbL*(Pu<_7O`Pt3Af z=<3HO82aS^|57B3O=;RThy{D>hs;k=kre|j2)5U(kNJ>ZKZ+;p@A6H|ECN`%%=@D+ zM$UZ{T_yto=;Q{xVCFC00vcGBYDhw~giOdAUt1CcA?L*Cz6)b!0~d|-RRe2o95*PK zoxc^^6-_qk7ajTJF58@GKduyW0MwBqjzxnb;(*@*pG;Gw6i z9~_+4HaG%rMhQS1<1yN^Xa5!40j?@DFo+CCA=0(JO#R{o>dPp9n=}cZ_;T%mi~j>Z z84}_5a-aGs9bbvTlu++6t0SmVoxINe-n)p3?S3HkHlFS)pt4AxYGH@AGB22ep+BKl zPkw3WGkiZHoCX>DCaFLH1`Z8PSi0HFii8s4?SAh`2b1pDc$IA9_ z+@IOdk%cEV((8HEX$*D`!{q1Wj;)8Lg_Bj9kd>`PKXzc>B#PrOx=2lGqwb7QU}#pg zW#q=Y1$@-=b$3Dfi~A5G+i!FmNv^R3v!u$}n)cE{@6BC@%qtP>E0eq4enyDhA$R*n zw~Wb@;zF#aK$%@oE7f=OE-NmE+lS)Ghvb6B>fdel)&emQPry)qODa3X7^%){CD0IHZs-c|}+pMWi^hg6RCOzp7Ov|_e8$W;F z^pQt6mWLOFKm63ql&T!dZ-HHA@jeY$AjnvER4%9U?%!`{GBulk*)XFdyx)qg$7?ewZFGTSd;9MAkf->zgJ)9Lz(}vGApT2^jTg=!AYziA zml#Pl$r-}>Oj>dTs`dvMz88leVKPHA)Z%i&XhN|m8@RDmNWY+a)abrZVXgJ0{g=hB zvA!I1GsDcD*Q^|mr?f<}A`sFP1~#BRUkYT4>=dTS5KpA6)P(0 zz6X#u(ND*Kqv4e1STMN%_E5xunGUL@+Ovr+IiP7{Cy;^vQQ9R{?Brl_r%xX^othoj z-s*;n3-kejPnVnGkF#-qb!k5+ssH@21H7<^^WqOO9q8X5+y4GvBg)vx0Xieo?neqC zh`&5Pg#=nBc8sb1^>&~a{KqFW4Xi$9M`95FZ!$@;KvibxlZq)Ws4( zmA{0_{Ubp5xU`UQC?Hy`p^bh|f^-1x2+l`GjB>*NVI zug?YbRn)YsdoNc`>ATL=s#B86PLsJ>_Cy2cVojz##lwfO@~L zG@lA#(rkEsBu9St6?}{SeK*&LwdMmvC-!b=YbrX7eJgz3UQH;a8_mFpTyvMTdMQ{~ zzw5EOP*qRLdOOQg;QO9@BM}@cBmqnB?s>)VFfQIp#99Pw>(nh6wVz-D-p-s{j82Y( z*KqEyZPRCJbJ}_#q&Kn!Ld__Gp@ZtIfzETwQ48Ey_3>hOMy&)0%$FW30QPyuT% zpi2}A1i5VtfOy(Vt1S+V(hAR|0|e4tGTF7YC&y_-LZ#~}>M^*F9_B=XR?jM723`o( zw~=d2E80TW6tPH9kxud7@XA3V<(Tm;mj_3M&UOUW!5r(K6<_VTdx0KX>nBV12!b6?C0VZ*IVV21Yddd2t`^J3E@?jZE82`)CxO^NZ*SmoNkqkK z>FQy!K?Q_S^G&Fqc3%526Huem0fFKp@`me@6I18S=IT>}jGNoT>tQ^8mHhRHF=yuG z9qxhNtGQG<>L5cmpV2_cE;IPh^aTITV&yoZELJ|%3CC}5<9pJ>%Zv6cGCB6j<|A-( zq_vi-QoHBDZVWa3m&<@V*TQ^I*2b+p#}tjOu&bwz-sakq;p_2voV0{ zW!gbPJzdqS*HRhPC5GZ8{Max3b2%GM>YN(&d!;P}IbxGF;#a5`;ui5ppBz!64ywUjy zulP3`QwRS=^TO3yIlf!k?k*O3G6xf!N@B|U@!&=>H0?d?^sw*k5`1y-6~m?p6;qn< zMscEp#nHSAB*H>T^9l!zz{HyQLZNJj^U}}Z9Z3ZLVRVTdg4Kp-1;qAPJVAE1_m0}h zr)63}-^Z&1N)hds22UcNlImt?K~c`=ID08F%Mv=28GKvCDn)X$z1m=qA)g%`RVO

CLz8o1U8Dr=!D`r6ufzSh$S!FWYCieMFEQ`j3 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

7~F&+3=jsBOlDVmviow#^mN$wy&R@DI=8t$%( z4dZ;O0iSC$B4B8VO6yDNQf71lwcW{cX=;MS%DNDSwyM5KZq6z9YO5`5^;8%Mo*61G zuU>xH2N1gKYA-(bpduQGfg#7RnU`ht>tW)ah9*GE=IoJxnVZU&vhc1Ra?-Ct$O@uW zwuJ56!rci`OyQ~5FDhvZ;_}Gsmh|T)PCULiE1TZSB@fl%lVmapwsr95&&NOhm=Lxc ztP4uzAvd}Bu98S(v}CPzwRff8fW^aA$b2QWsc9+uMZUg_1A`illZjC)JBr;tJ`3J92_RS^I^M}C`5#~ zG*TgCoiASwbrfAT+@wM>tyFZWJH3JXbuIf zS}wBqrJ5=mT+GTntU^-O^}#o+mo)`(h6cPhIfWm{$I2 zS}||$Hjl}6$6~Bdb2VSv8;-rKs>zdn*s4UhPMppJw6jhMA2O59>LW2%UOMbq!*+c$ z{cLhY%d0p%r#qyaCAI3^+>YUgOnk;o!dWjdD|67V(tVd_l~~ipJAXvZM@S=R zv-_|i264z;{uv>Y{qpPE!`R68w(1GPEHR@*)TOk?jcq zy&mEtD4Auyw!erB5uf3j+sX+$vM>wK3yzfub%gi5E(+Mhb_B<=h?vVOvFw$NEHmnF zwk3A;l)DXz?{Co1Ovoe{Z+6fhuX!7FfR{v^sy5?j+^z84>4(H|O(%Js6Fm06a;HAK z-}<(r#RUu+FaM=Ev?k*dT(vjA0P6Sz8hx_evuaO?vt3Es?hbor$O5HNqoq5)cIk5z=m3uETy6?aI583D|9>t7g2ZV3n$)T zVm%~ePCEbH<$CCI5?(m)Ewwz2!C+0$>;@uA?zQ=aWQ(?^U-p%t^=8UQ887*TIvQ?6 zqXgYKU%g#l)rS$`uJT@i*YNFv~LK#LyYioKUp5 zFf)9`Hjnf*Yrv5ijroy1R2(wq#uWVlWGb%tuR6j#s*WcN*`5Cye2~#(dE9jc^t?Zw z0K=7O!=u$Fj>#NVGF>xT8dlxi6PA?W5G5beK5i&a8NSYcZDZC!Zfuggl1ag??lH@} z!sGJ@AG^UlEfKGTn)cR1H}S`x9M$2V;^_jjUA@TZy$)GT`U<(?#{d@n)I65kMAM>d zC5QcBK%hRC{j3-GQI+Gsrc^&sSBvB{Y1Dw-2d58>;&P7jxFJ zU?Zh4jJVo#K%K6P>{mHf&1e=wnaFNP1Qsg)<5VMP1=NhW138N5;L_9r`w!5A$kkBb zA2}vnJg8+Mbv+!7E_iOc)YKt4bJpal%k;eL2Db%)Mb~?pI4jES zEPE^_UP#2AY7gR{{Pb@a1W9q+u0kP)qH&o?SRh1+wLo`SwokiE3;(-PSY1bA>4&&8) zUFcJKWio@cm{Aw!OsWred0uin6!+%ouQVM?U$;u;NDDh=#P>r6pKWl9Ck)X@@s4r2 zem9mVAJF^t?(~k|rk>F>HCy?*z}4eJmLs~#!bXk2s98{y=)cVUr3Q|MIJ+KDEw?#)ySI(hSM;LP&<$wY;>wU!L{ zecgRSjAKa%EPivK#M)K&z*5da&_UhY5kp`YflJ29Lq;MXymXB51AuN?J;S@*$~QS@TG{m6!cq4tWQX)F&}3IC7TF&=s{+=wIP4FCqyP==IIR) z?Hxi}3-D4oL^K`r^}b&c+3(7nu^VJ$vfx|SZ`d1Re3J|u;b$L701jZOQ?4}Zn3-8-T<-xaZL5BfVvmJYu!mt7jfY{e2`zaA*-X= z9$>YZS6pOKFE$Y?<5H?qduQbS)#s%C)Ut=QB!$3gTlQxRJZ*Db-?LN~U)z!`3oO&g zi{M5t=*x@;drcw-Qa9^!rp*I~Q{6@qGP>2s9Ivk1B+Ea}c#FD0xukesf8EX0q!Ucs zOm>UrzNQ%>{S+JXLuHV)&k=E_gvcA3j(X-(W7L@kZfFUnf5K_xFN&R+Qgkl+!a`XJ zx*2{yYjZCe&G}=aQ&bKcACx4O_c*%>A?imcn7?VpR&6ycUZM|N%4xgIi2klrT$()W zDAqgnPpg%DKdm2fx5a5?nUY`G>E6fZS-Y`gGjGw&iN<`rhFy4=Ya z)8q`4kLs-2U`iP2LQ6)$jf2MF^kzrIm-W2Vj*SAgD3LUX;9%;NRTtu&qgo06=3YlX6ir55mOA~a zj_bbn_@l(#3-AytB+QVx&Zw7yILD768khI!@ZV{6#EGb-hZRCD*~`Xz8Bz6XogPGU z+*EXRA|g2!-?G)HC7622YvkiAC=;U6Or_foK0$UJMofY)Gy9-EF;N|j6sspmwchM6 zQ#f5j_31qYOKwh2F0Qo?d*SNJYm)~1bLsa`;jQbcaU)bzrwEeL$rVIe{w1 zZmRx`_9k^A&2J|)Xm{UyN)4NJAGqG=X>2|%Q?o|q-i%`hb7GEW@VM-Zq&6H7x&M3w zP4?+Hz2s$_X}gLv`A@}mo$uH?n`rhBOX@VXS^<`N=wXGw ze~UKLSJWpB-OEY=ohcARFh{&XA( z`?A%s%0MGuLW)mBNKU41t6F43n<`K`LiB+IM{ehL<-krizgM7K3b(8xrPE8R4_m!@ z**$tVd8M2#MCO9y1t;*vWd|db8%yuquhli>Xm5(rC1|P+Xe~iHFAuBgWt5TpT%J3n zknBY%(pS|wp6t`xmZ&w~TpE~wECW5~)O#l$oIm0}OE{{{+7}KnQT?GVDw75NbY|Ny~Vx95rnlXV3&9 z0Sxf0UkfiV6U-SMnJ(tvc?Ie)Dz@_P1hZAqw`8_bYXfUGH#e%1o!QOZ_2GOxlDUoH zDleGp2z;SAlhUnf!4vd2wB@2Pbuh`k45J3dwwyiM)FET_WNVjLU3N`;quAOuL2n^$ zrfO;Z=-J(OlHhPtOfP_B*P297eq-Ty6nSb4K)t?+D%C?$IC(30d3@6$s@xqk|9i}bs z7EKSNodI!0CtDekfUry!EL5(?{ZLswjCJX20#;XS^Wrd+KMaK`_ZaORMy61iV%Gwq zWE%7yRU9{WyY!amalGWf|3F@X1 z6JopWl{6Dj*8Z6K^n;0+9x$=y=Kqri=ZiT=z;t1g4WlxotSfd}p58K{1empJdf zRnUs3rc%r1j;MXn1as+EHbJ9aW8%+@W!k*TR+*C{#g8W8dk>CI+7Fq_|9x{gD3cY< zMvlCQQ)mqb;FE2GKP&eZr``;SOKSaFVk5TloD_l1&nDjo3uIjPpANbl2-kujtDJNZ z7>jSOU5xKu;10{ug_E#UNGR*oepb6pUKVb-fnNG>aa+`{+010JR!DrM;kr3y#N@JB zO@-f0of*rRc}UK~x#iM-DQ(L;=}{feeFQa1if0O!siK(lyOt!I5aURHYf_J+)ZhG8 zshu-ivJo!f)iZ(dB%pP^nA&ZUL2Rp+4eKb>_eSh;<(D=Yz#sUpoV}BWpQF5>!SOg? zx4S3P`+PmvC_?^QB)>hM&+>Z3eY=;ww9?JUOd4o@u%A2EZ8g02@+*y_nI1D8WAT|$ z{>|o$o&K~X7bjGhPEd2kZuuA?`|HQpZ&+C-xj*l^)@RnAprJZHcIT{a5zNqrEx_6$ zg-#=SayTbq4x2B>$GTCTa&WLSC#p%7DOFRcO7%TYly=R2R~I*;0@-yCgo zJ`*45oq!^is?*fkS0f41^PcQ`Y4qMa{0UQGm)@rZ1A`#jmYWE7^ib&`UF$j4UR2x$ z|2Fjx%T-?mQQiy2Y`9#B!?5As>~n*U`mpVa541f#UeQZ&{~s+t*8y0#i`n^g8$4Wz zl6WbXwm+%M*@SuOWZk{3tgdv&oAi|~6_yiHOw#O5tP0kYnzyz8!NKRwKQaMglE?@N zjs&^z=fRnh+>_B=pG33xLEANELAcBrEWZRiy>s@0w48t!M~iMJ1nJOrVObq$Gh+ zoo=lL@hOZ@9w|h{4hDvrDx9G(;rRpw!x^_(>+JNZ3CyyV^xuN3Nts%q`@TZ>1+Y5=W zE#M~RkN@!6Vp-it2n~Ee2G>c3~ey_#htjQq!_=^$73MZ3D0>;`c?IUN_ab+y(U$uoD&OUVRt=LDWQF)vlfP)2_x zss!-kP}IUJja`^CMM~Q0gtSE%Wu<<(*Goa_@?+S5`IIfe_$FzG9?oTS`hE2}B-nXa zsM3$6B-d;F*{VhhxBpdlXz4^0^e;As0e1rX@1P&4fk!o%%dpXYeV^M7eW|r?*QUC{ zh5Dm`{-oU2E5SLDB8SbO31!@VfKS-&x`Ld%o5hb(L>HzcvAWfy__MQSctwO~{bLXo z?ZL%(Ps&;J7P0@qHz%}mF0;@u4imUzUT)&h`=VPSDxR0*YI9@3niHH>&&bMxYt7@c zKd!e&@T~WGw1?Ta1Bto9ed&-l*qwsHLv-&7J~lh577qjDh`f@3@A~>!AG;aWS^QaJ zLdEby^vPd%U0S{DpRdvGV^p|l8~Y7tz7D+Ntg&m8RovL*D{ueJ1x@uCxs~zq3mwg% zV1+i!Epe(d>;3j*#fGY9HkPz&_;$RO-J3=-`7HzQGi#g*5M^);KZ5#CTSf>-=#iy1 zc;8r@gbcYe8l2Ylc**3rk{W>zppYa`PVhiYB{diADF22SMbA?vo@?@)p$*gv0dMl+ zQt2YiZG!Lbo1=CI`hnV)Ron}B>F7_;kGV~*{%||KtWP~$chx*56%lChUTaudVa5W@ z&cjsG-f5T}th2A?<)b1$MvuL-5@D!CMXFGa&M5q<&a%pTEzb8j?r`TBfof8DFZA%z zXk;7ru|B%S{t&spvOtOG}$+^BVSVTlo2E<7AOO=m*`Tf-1CF`0B(-6NL$=L?}qF znLe4Q?oTuJ5qM)@OuzXW(RyD-CbBHYBtCX(v@rk0{^cM4B9?WEUYXkHZ)GhdQ_;G@ zP*kcYsf8OWFdH&javt`H>qlGc>|4``Ucrs-`RCl1X)|-*muY*L-w)hyQ8$0+wk~guQu28Z~d_tBSPG({lj8EhMT+QWX&o! zU_M{tye$4jnw2mm_0s#57yV_?vn8>rW4(&Ud5_KQD(BGnn(CTWFs%KKm`O~0x&0#s z*jNl8t;Bh=4n4mR$r4MZ{IH}rRGW2(;Ttwa)81v~*5rZGA5~Qi$)|d%(Yd&KHkp0@ zBJWtJ_K1$v1C}VE2&odK`FWw4A9~b2JfM9UU=QVf2qLnz7~L1^ z(m>`@$z+ScIshBm5v}9Q*ILmZo#{Yn8*rZvS%$f zgV0?7;L>QqP`NgJ)4#Sa|KF;qf3yk#!3#K+yUoqb3?_$nIH~K=vN2xol(p8jaHpsf zNOBaZuSj#8J#F08b!*rm&9fmll9chP1T8}E7^JCQ&imh1IfqZbb-`skZepjuytHAC z(k~wlG}L^Lfh-W-dHA(Obnz-(7TP1ckQO_>523Le`YD~E$vy~GCleTAjtH8k38Ftv z5j|bKV3eygZvI9iyZGHX_h0&DF}iB0RDOXfLGN;T3Fi@y=qU!*BAgq7sXhsSG8>KeHK}_T*rr`bQ@+ zk8EU9hyU;@h=M&ELX7W%fRIQ#{15C9^5YaUKzViPBUpI2{1n)!`S6d$-< z6Rno=a!!UJla9?fS}Ud&ArDzSr_a+Zm0(By^0qU-uz}8{VjB4@;toTMn5-p<|IeZm zGLlSI{74szEpK^dWRF3n$9DH<$8Aw=DF-*d!QQtY@R8>E^%}30L0-u1hPDL{1Bc;f z$N|Eqdx~Wql%G{QoaeWGSp$fAspTjh&N{wf=2o;M<4f~dc7~VVRxcHy>ugsk5+R-+ zB4(8@T`aFUb#^J|gZDz2aa({!ucS~FykxnjY1LP$TVRc!tRzC4N7403W2ro)ouRa$ zxNENTkkRJq*st?z^Gl-QkR&|kx6Z|H7v>CmkjzWH1l|A+E>`ri(f_D8bh0AZ-M~vs zN_bk?d`u(DxB1;ah?Xs^H$Bjqk z4L1esxDHKIr_?~%Orj`AKj@D@WBE;thou0}_jaz4MsC@vH%s^+-nu5*E_1mC&r7+A zp4Yq)T3Bhy)~1sZsp}2GDNUX9f84|)M0fv%*L6GMIWzp-6>ZICL&N-ZHFGC>B>*4T zxdJ!sX%Db}+4GNdke^{UrI@EB*evpv&obOYcKXs$m+~s30tkT ztLr3z=?jcw(e<;3LCX@AgNLD=j|5mgDJtJhtR9j~L(ZYRJeTM)iifHvu%Uu1vO}sP zOXB^VLNPfLTsN(-KVcFoho4c<**`Ejd3%s5;s8=$Mu@g0KzH<$5patTCV*JM@m$!5 z9LDyXy6Dw{TwxRJkrei7MAoURXekKV_HQ%C}X zOxXDwsd#hT8QIE8-FQ5CO_noN4%ayNv9t`mO#z5dsKdJ z2gUE)*Nn#JR?8GH%dR}b^US6W#h(QL28fS#J^XD=tL7xvk5qY|h3c-_ebBdQxdw0QO#*TItyk+*U@u%YV?9WSu{fp^yk+c6Y! zQ@d6Wj_64Buw0{p%R0(C4$=3^glR0>Ejecu=IVGPlJ!@cT-3%&4oYnKd4Vo8ax7eL z{1I-ae{=w5AoVFNzs5?+ZVuQBn_P^}egPgG@~NQ&`B_tXn|Fo5RA3%+mL)jD3Q04` z+nu3Ez*RJ(=CD`{rv*FNaFshVV&R`SkP3=+E6?zlrjbyx>mrLBT@k4RmFt{aWT}Qf z{G%Af^8wgu4P9h>;*{mJ>E^uPp-&Zp%z1&F%L>OK?)T_B^X3^h)7Em~MI&Rwwh$kY z<3POF@WBdEXV;vQ*uIw?j(zu1)B+3~t#?Y6)l@H-B@Gmdgfip}d%$)r#<_d*u8oT5 z-j@j!33PLtE<+BbB6H7#isrSn1(gvItZt>uX3lv|F`Pgd0UK(hN0CL%GTCP1W~U`a zxskt!i`lR!a3983c^d&lWP#L~14|;4X&xUHi?d&Xb6LyesGU#y%qKkP4di4wFhtwy zvhUhy>3eU5k+1&Me|XgFD@1F1a3zO-sF z0LaO=7E?Wq{hECZ{uiUFpH%TO4NG|LcI3$!Id%GZm+Pyq>(h`N>w4<4I-xe>;F_Gp zq3jR4qAu;N3w7vai7EJ@)WA(Kih-w;&&fpf8B3q+Kn=Kq$c8ehA%Ur?3wG0BXuS6>`g1>Opi` z(~F`eSn_3!Ztumy*JOL$ zUoEQ>FXvF~uAztrAKgJJj3w$sJ7Hjvw~I#e}% zkN&M5`wQ@Oi@Dc`XlBJ>4HNYj)T$wUL)qG;K$a|%~uJFd(t#Y z?JuKLdjB7`zB(wbuE{$>Ah^2)_YmCOJ-9<~8Qh)V?t@#f!QDN$yF0<%eUNXS-P*7A z$-7nepF1^GQ*&;g?%O}xKucVAy`3*LrTS9!Zm;nsEi|t$aep)cE&GFw>EN%H7&JsRj#|n7jXUvu zcyW!+cCT6Q_fC9FX3Rc4XbmPv?)FWAeuD2c(sjQ>nkWcE@eF;@bp!F7|0EdJwF?Nk zIs%)XK|JU7NK1M<(D1R%rF+f5`8ob%efZna@amB%mgu@IMn7zf<5ZL6bs&NSI4TU%{;+yQXqNtCYZxY-Qy;4{I^ zp?){LK6>w4{@!&l@1&@nx8*CdFc*KEw$SfND<6Gq_vvi$9cysy$x1Qpn5xxnnn~-c zz(`3%XrOKhkkloHJE0r#ep`qs5YgS;iA~tNK~TL5l@m!)6Ga~Lxo^oTjxbWbGD?i8nMYbpdNKEz z*5uES1Gg|Q>poSrctSDdY=K?;yTZkY^V*%_-a)RCe1a6j#&>}KDdOSZj02p$yRDm$Y& ztcxE+ES+iv2M&ALlu!Ow&VKjd6$|35=v4pt%18A@Av^*u#%F-rrtRq-VwN#A$=F}M z6O;*wELm41G7q6dxoG$~ujL-^vhO9PshfA4w$Qk$gP!9(YR<$3egP-T>_iE9_QHG{ z@9nM0;iNih0uRUN0*=@0Vj;S6h{#=M&Eln{GXbN~`gfLQI=Fr3RMV-+J3tOIk3>#3 z_}3=^|wgB7Dw9P`)#PcKI*ODn(fkN`k3qD@Hzihw{%0DF*ACRH?C4qbs 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

tCyNkFHRuu3cx_|_Dl<&EA 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%0Ahi< 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 Z{Fj}KN`_uxy Date: Wed, 8 Jan 2020 19:35:00 +0100 Subject: [PATCH 0241/1106] Add plot_config to optional plot --- docs/plotting.md | 2 ++ freqtrade/templates/base_strategy.py.j2 | 2 +- freqtrade/templates/sample_strategy.py | 16 ++++++++++++++++ .../templates/subtemplates/plot_config_full.j2 | 18 ++++++++++++++++++ .../subtemplates/plot_config_minimal.j2 | 0 freqtrade/utils.py | 2 ++ 6 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 freqtrade/templates/subtemplates/plot_config_full.j2 create mode 100644 freqtrade/templates/subtemplates/plot_config_minimal.j2 diff --git a/docs/plotting.md b/docs/plotting.md index a3d886473..2f084b66a 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -161,6 +161,8 @@ Sample configuration with inline comments explaining the process: # Specifies `ema10` to be red, and `ema50` to be a shade of gray 'ema10': {'color': 'red'}, 'ema50': {'color': '#CCCCCC'}, + # By omitting color, a random color is selected. + 'sar': {}, }, 'subplots': { # Create subplot MACD diff --git a/freqtrade/templates/base_strategy.py.j2 b/freqtrade/templates/base_strategy.py.j2 index 32573ec9e..fbf083387 100644 --- a/freqtrade/templates/base_strategy.py.j2 +++ b/freqtrade/templates/base_strategy.py.j2 @@ -78,7 +78,7 @@ class {{ strategy }}(IStrategy): 'buy': 'gtc', 'sell': 'gtc' } - + {{ plot_config | indent(4) }} def informative_pairs(self): """ Define additional, informative pair/interval combinations to be cached from the exchange. diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index 228e56b82..92f6aefba 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -80,6 +80,22 @@ class SampleStrategy(IStrategy): 'sell': 'gtc' } + plot_config = { + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } + } + def informative_pairs(self): """ Define additional, informative pair/interval combinations to be cached from the exchange. diff --git a/freqtrade/templates/subtemplates/plot_config_full.j2 b/freqtrade/templates/subtemplates/plot_config_full.j2 new file mode 100644 index 000000000..ab02c7892 --- /dev/null +++ b/freqtrade/templates/subtemplates/plot_config_full.j2 @@ -0,0 +1,18 @@ + +plot_config = { + # Main plot indicators (Moving averages, ...) + 'main_plot': { + 'tema': {}, + 'sar': {'color': 'white'}, + }, + 'subplots': { + # Subplots - each dict defines one additional plot + "MACD": { + 'macd': {'color': 'blue'}, + 'macdsignal': {'color': 'orange'}, + }, + "RSI": { + 'rsi': {'color': 'red'}, + } + } +} diff --git a/freqtrade/templates/subtemplates/plot_config_minimal.j2 b/freqtrade/templates/subtemplates/plot_config_minimal.j2 new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 9fe15aea6..2f7b2d717 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -102,12 +102,14 @@ def deploy_new_strategy(strategy_name, strategy_path: Path, subtemplate: str): indicators = render_template(templatefile=f"subtemplates/indicators_{subtemplate}.j2",) buy_trend = render_template(templatefile=f"subtemplates/buy_trend_{subtemplate}.j2",) sell_trend = render_template(templatefile=f"subtemplates/sell_trend_{subtemplate}.j2",) + plot_config = render_template(templatefile=f"subtemplates/plot_config_{subtemplate}.j2",) strategy_text = render_template(templatefile='base_strategy.py.j2', arguments={"strategy": strategy_name, "indicators": indicators, "buy_trend": buy_trend, "sell_trend": sell_trend, + "plot_config": plot_config, }) logger.info(f"Writing strategy to `{strategy_path}`.") From db34cb1b75bb64f61bba371e43661dd8f67937b8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 8 Jan 2020 19:41:34 +0100 Subject: [PATCH 0242/1106] Do some adjustments to the wording of the index.md section --- docs/index.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/index.md b/docs/index.md index 5871479d9..3bde10707 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,13 +22,13 @@ Freqtrade is a crypto-currency algorithmic trading software develop in python (3 ## Features - 1. Download markets datas : download historical datas of the exchange and the markets your may want to trade with. - 2. Select markets : create your list or use an automatic one based on top traded volume (not available during backtesting). You can blacklist markets you don't want to trade. - 3. Backtest : Test your strategy on past datas (based on [ohcl](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles). - 4. Optimize : Find the best parameters for your strategy (use machining learning). You can optimize buy, sell, take profit and stop-loss. - 5. Run : Run the bot on exchange without playing money (dry-run) or with money (live). - 6. Run using edge (optionnal module) : the concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade (the sizing of the trade is based on a risk of a percentage of your capital) - 7. Control/Monitor/Analyse : use Telegram or a REST API (start/stop the bot, profit/loss, daily summary, current open trades results...). Futher analysis can be done as trades are saved (SQLite database) + 1. Download market data: Download historical data of the exchange and the markets your may want to trade with. + 2. Select markets: Create your list or use an automatic one based on top traded volume (not available during backtesting). You can blacklist markets you don't want to trade. + 3. Backtest: Test your strategy on past data (based on [ohlcv](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles). + 4. Optimize: Find the best parameters for your strategy using machining learning. You can optimize buy, sell, take profit (ROI) and stop-loss. + 5. Run: Run the bot on exchange with simulated money (dry-run) or with real money (live). + 6. Run using edge (optional module): The concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade (the sizing of the trade is based on a risk of a percentage of your capital). + 7. Control/Monitor/Analyse: Use Telegram or a REST API (start/stop the bot, profit/loss, daily summary, current open trades results...). Futher analysis can be done as trades are saved (SQLite database). ## Requirements From 9559cb988ef49b68374373f6da8c9d1c88cd7d0e Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 9 Jan 2020 04:12:43 +0300 Subject: [PATCH 0243/1106] reworked --- docs/index.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/index.md b/docs/index.md index 3bde10707..3293999b7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,8 +11,11 @@ Download Follow @freqtrade + ## Introduction -Freqtrade is a crypto-currency algorithmic trading software develop in python (3.6+) supported on windows, macOs and Linux. + +Freqtrade is a crypto-currency algorithmic trading software developed in python (3.6+) and supported on Windows, macOS and Linux. + !!! Danger "DISCLAIMER" This software is for educational purposes only. Do not risk money which you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS. @@ -22,13 +25,13 @@ Freqtrade is a crypto-currency algorithmic trading software develop in python (3 ## Features - 1. Download market data: Download historical data of the exchange and the markets your may want to trade with. - 2. Select markets: Create your list or use an automatic one based on top traded volume (not available during backtesting). You can blacklist markets you don't want to trade. - 3. Backtest: Test your strategy on past data (based on [ohlcv](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles). - 4. Optimize: Find the best parameters for your strategy using machining learning. You can optimize buy, sell, take profit (ROI) and stop-loss. - 5. Run: Run the bot on exchange with simulated money (dry-run) or with real money (live). - 6. Run using edge (optional module): The concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade (the sizing of the trade is based on a risk of a percentage of your capital). - 7. Control/Monitor/Analyse: Use Telegram or a REST API (start/stop the bot, profit/loss, daily summary, current open trades results...). Futher analysis can be done as trades are saved (SQLite database). +- Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). +- Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade. +- Backtest: Test your strategy on downloaded historical data. +- Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy. +- Run: Run the bot on exchange with simulated money (Dry-Run mode) or with real money (Live-Trade mode). +- Run using Edge (optional module): The concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. +- Control/Monitor/Analyse: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.) Further analysis can be done as trades are saved (SQLite persistence database). ## Requirements @@ -55,10 +58,10 @@ To run this bot we recommend you a cloud instance with a minimum of: ## Support -Help / Slack -For any questions not covered by the documentation or for further information about the bot, we encourage you to join our Slack channel. +### Help / Slack +For any questions not covered by the documentation or for further information about the bot, we encourage you to join our passionate Slack community. -Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) to join Slack channel. +Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) to join the Freqtrade Slack channel. ## Ready to try? From cee8f3349e043b721d2c2b8ae6a6536544609d57 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 9 Jan 2020 04:16:57 +0300 Subject: [PATCH 0244/1106] rearrange features -- move Run to the top --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 3293999b7..8c1a8fcc6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,11 +25,11 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python ## Features -- Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). +- Run: Run the bot on exchange with simulated money (Dry-Run mode) or with real money (Live-Trade mode). - Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade. +- Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). - Backtest: Test your strategy on downloaded historical data. - Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy. -- Run: Run the bot on exchange with simulated money (Dry-Run mode) or with real money (Live-Trade mode). - Run using Edge (optional module): The concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. - Control/Monitor/Analyse: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.) Further analysis can be done as trades are saved (SQLite persistence database). From 135487b2c98b541bb1ba45c96ddabe975fb77a52 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:35:05 +0100 Subject: [PATCH 0245/1106] SPlit control and Analyse feature into 2 seperate points --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8c1a8fcc6..1c292b21d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,8 +30,9 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python - Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). - Backtest: Test your strategy on downloaded historical data. - Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy. -- Run using Edge (optional module): The concept is to find the best historical [trade expectancy](https://www.freqtrade.io/en/latest/edge/#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. -- Control/Monitor/Analyse: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.) Further analysis can be done as trades are saved (SQLite persistence database). +- Run using Edge (optional module): The concept is to find the best historical [trade expectancy](edge.md#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. +- Control/Monitor: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.). +- Analyse: Further analysis can be possibilities on either Backtesting data or Freqtrade trading history (SQL database), including automated standard plots, and methods to load the data into [interactive environments](data-analysis.md). ## Requirements From 7461b5dc02b14b5ce731188e8d0f3215d3da0fd3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:37:18 +0100 Subject: [PATCH 0246/1106] Mention custom strategy in features --- docs/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.md b/docs/index.md index 1c292b21d..b664552bc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,7 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python - Run: Run the bot on exchange with simulated money (Dry-Run mode) or with real money (Live-Trade mode). - Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade. - Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). +- Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies). - Backtest: Test your strategy on downloaded historical data. - Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy. - Run using Edge (optional module): The concept is to find the best historical [trade expectancy](edge.md#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. From 989ab646a9ec1367b3eef17d8740c6bc7c84a4f2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:46:39 +0100 Subject: [PATCH 0247/1106] Add profit % to sell_reason table --- freqtrade/optimize/backtest_reports.py | 10 ++++++---- tests/optimize/test_backtest_reports.py | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/backtest_reports.py index 5778747cf..555250760 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/backtest_reports.py @@ -66,11 +66,13 @@ def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) - :return: pretty printed table with tabulate as string """ tabular_data = [] - headers = ['Sell Reason', 'Count', 'Profit', 'Loss'] + headers = ['Sell Reason', 'Count', 'Profit', 'Loss', 'Profit %'] for reason, count in results['sell_reason'].value_counts().iteritems(): - profit = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] >= 0)]) - loss = len(results[(results['sell_reason'] == reason) & (results['profit_abs'] < 0)]) - tabular_data.append([reason.value, count, profit, loss]) + result = results.loc[results['sell_reason'] == reason] + profit = len(result[result['profit_abs'] >= 0]) + loss = len(result[results['profit_abs'] < 0]) + profit_mean = round(result['profit_percent'].mean() * 100.0, 2) + tabular_data.append([reason.value, count, profit, loss, profit_mean]) return tabulate(tabular_data, headers=headers, tablefmt="pipe") diff --git a/tests/optimize/test_backtest_reports.py b/tests/optimize/test_backtest_reports.py index 726202517..107389a42 100644 --- a/tests/optimize/test_backtest_reports.py +++ b/tests/optimize/test_backtest_reports.py @@ -39,8 +39,8 @@ def test_generate_text_table_sell_reason(default_conf, mocker): results = pd.DataFrame( { 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], - 'profit_percent': [0.1, 0.2, -0.3], - 'profit_abs': [0.2, 0.4, -0.5], + 'profit_percent': [0.1, 0.2, -0.1], + 'profit_abs': [0.2, 0.4, -0.2], 'trade_duration': [10, 30, 10], 'profit': [2, 0, 0], 'loss': [0, 0, 1], @@ -49,10 +49,10 @@ def test_generate_text_table_sell_reason(default_conf, mocker): ) result_str = ( - '| Sell Reason | Count | Profit | Loss |\n' - '|:--------------|--------:|---------:|-------:|\n' - '| roi | 2 | 2 | 0 |\n' - '| stop_loss | 1 | 0 | 1 |' + '| Sell Reason | Count | Profit | Loss | Profit % |\n' + '|:--------------|--------:|---------:|-------:|-----------:|\n' + '| roi | 2 | 2 | 0 | 15 |\n' + '| stop_loss | 1 | 0 | 1 | -10 |' ) assert generate_text_table_sell_reason( data={'ETH/BTC': {}}, results=results) == result_str From c475729c13c22b404c469dec6dbdb9256a312fb8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:52:34 +0100 Subject: [PATCH 0248/1106] Extract edge reporting to optimize_reports --- freqtrade/optimize/backtesting.py | 2 +- freqtrade/optimize/edge_cli.py | 32 ++----------------- ...acktest_reports.py => optimize_reports.py} | 26 +++++++++++++++ tests/optimize/test_backtest_reports.py | 16 ++++++++-- tests/optimize/test_edge_cli.py | 14 -------- 5 files changed, 44 insertions(+), 46 deletions(-) rename freqtrade/optimize/{backtest_reports.py => optimize_reports.py} (83%) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ae3fbed0a..18cc27ff4 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -18,7 +18,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.misc import file_dump_json -from freqtrade.optimize.backtest_reports import ( +from freqtrade.optimize.optimize_reports import ( generate_text_table, generate_text_table_sell_reason, generate_text_table_strategy) from freqtrade.persistence import Trade diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index 4944f1dbb..be19688d8 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -6,13 +6,12 @@ This module contains the edge backtesting interface import logging from typing import Any, Dict -from tabulate import tabulate - from freqtrade import constants from freqtrade.configuration import (TimeRange, remove_credentials, validate_config_consistency) from freqtrade.edge import Edge -from freqtrade.resolvers import StrategyResolver, ExchangeResolver +from freqtrade.optimize.optimize_reports import generate_edge_table +from freqtrade.resolvers import ExchangeResolver, StrategyResolver logger = logging.getLogger(__name__) @@ -44,33 +43,8 @@ class EdgeCli: self.edge._timerange = TimeRange.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) - def _generate_edge_table(self, results: dict) -> str: - - floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') - tabular_data = [] - headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', - 'required risk reward', 'expectancy', 'total number of trades', - 'average duration (min)'] - - for result in results.items(): - if result[1].nb_trades > 0: - tabular_data.append([ - result[0], - result[1].stoploss, - result[1].winrate, - result[1].risk_reward_ratio, - result[1].required_risk_reward, - result[1].expectancy, - result[1].nb_trades, - round(result[1].avg_trade_duration) - ]) - - # Ignore type as floatfmt does allow tuples but mypy does not know that - return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore - def start(self) -> None: result = self.edge.calculate() if result: print('') # blank line for readability - print(self._generate_edge_table(self.edge._cached_pairs)) + print(generate_edge_table(self.edge._cached_pairs)) diff --git a/freqtrade/optimize/backtest_reports.py b/freqtrade/optimize/optimize_reports.py similarity index 83% rename from freqtrade/optimize/backtest_reports.py rename to freqtrade/optimize/optimize_reports.py index 555250760..ffc8c53d4 100644 --- a/freqtrade/optimize/backtest_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -107,3 +107,29 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, floatfmt=floatfmt, tablefmt="pipe") # type: ignore + + +def generate_edge_table(results: dict) -> str: + + floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') + tabular_data = [] + headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', + 'required risk reward', 'expectancy', 'total number of trades', + 'average duration (min)'] + + for result in results.items(): + if result[1].nb_trades > 0: + tabular_data.append([ + result[0], + result[1].stoploss, + result[1].winrate, + result[1].risk_reward_ratio, + result[1].required_risk_reward, + result[1].expectancy, + result[1].nb_trades, + round(result[1].avg_trade_duration) + ]) + + # Ignore type as floatfmt does allow tuples but mypy does not know that + return tabulate(tabular_data, headers=headers, + floatfmt=floatfmt, tablefmt="pipe") # type: ignore diff --git a/tests/optimize/test_backtest_reports.py b/tests/optimize/test_backtest_reports.py index 107389a42..518b50d0f 100644 --- a/tests/optimize/test_backtest_reports.py +++ b/tests/optimize/test_backtest_reports.py @@ -1,7 +1,8 @@ import pandas as pd -from freqtrade.optimize.backtest_reports import ( - generate_text_table, generate_text_table_sell_reason, +from freqtrade.edge import PairInfo +from freqtrade.optimize.optimize_reports import ( + generate_edge_table, generate_text_table, generate_text_table_sell_reason, generate_text_table_strategy) from freqtrade.strategy.interface import SellType @@ -94,3 +95,14 @@ def test_generate_text_table_strategy(default_conf, mocker): '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str + + +def test_generate_edge_table(edge_conf, mocker): + + results = {} + results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60) + + assert generate_edge_table(results).count(':|') == 7 + assert generate_edge_table(results).count('| ETH/BTC |') == 1 + assert generate_edge_table(results).count( + '| risk reward ratio | required risk reward | expectancy |') == 1 diff --git a/tests/optimize/test_edge_cli.py b/tests/optimize/test_edge_cli.py index ddfa7156e..acc0d2d16 100644 --- a/tests/optimize/test_edge_cli.py +++ b/tests/optimize/test_edge_cli.py @@ -3,7 +3,6 @@ from unittest.mock import MagicMock -from freqtrade.edge import PairInfo from freqtrade.optimize import setup_configuration, start_edge from freqtrade.optimize.edge_cli import EdgeCli from freqtrade.state import RunMode @@ -106,16 +105,3 @@ def test_edge_init_fee(mocker, edge_conf) -> None: edge_cli = EdgeCli(edge_conf) assert edge_cli.edge.fee == 0.1234 assert fee_mock.call_count == 0 - - -def test_generate_edge_table(edge_conf, mocker): - patch_exchange(mocker) - edge_cli = EdgeCli(edge_conf) - - results = {} - results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60) - - assert edge_cli._generate_edge_table(results).count(':|') == 7 - assert edge_cli._generate_edge_table(results).count('| ETH/BTC |') == 1 - assert edge_cli._generate_edge_table(results).count( - '| risk reward ratio | required risk reward | expectancy |') == 1 From 785cd2a640bda12ef39a1391e9f07f2b89dc229d Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 06:52:56 +0100 Subject: [PATCH 0249/1106] Rename test module --- freqtrade/optimize/optimize_reports.py | 4 ++-- .../{test_backtest_reports.py => test_optimize_reports.py} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename tests/optimize/{test_backtest_reports.py => test_optimize_reports.py} (100%) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index ffc8c53d4..3801546b1 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -114,8 +114,8 @@ def generate_edge_table(results: dict) -> str: floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') tabular_data = [] headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', - 'required risk reward', 'expectancy', 'total number of trades', - 'average duration (min)'] + 'required risk reward', 'expectancy', 'total number of trades', + 'average duration (min)'] for result in results.items(): if result[1].nb_trades > 0: diff --git a/tests/optimize/test_backtest_reports.py b/tests/optimize/test_optimize_reports.py similarity index 100% rename from tests/optimize/test_backtest_reports.py rename to tests/optimize/test_optimize_reports.py From b748ed34358466e3925f547f23a343a996d2b3c2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 19:59:13 +0100 Subject: [PATCH 0250/1106] UPdate documentaiton wording --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9a05eea2d..f242a4744 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -149,7 +149,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have a `balance=1000` (USDT), `stake_amount=400`, and `max_open_trades=3`. +Assuming we have the tradable balance of 1000 USDT (`balance=1000`), `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. From 9713dc8d94c181d293b6994b2587280dde60e71b Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 20:09:21 +0100 Subject: [PATCH 0251/1106] Ensure wallets.update is called before buy closes #2756 --- freqtrade/freqtradebot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5aacdc587..06f435421 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -257,6 +257,9 @@ class FreqtradeBot: :raise: DependencyException if the available stake amount is too low """ stake_amount: float + # Ensure wallets are uptodate. + self.wallets.update() + if self.edge: stake_amount = self.edge.stake_amount( pair, From e94dfdeff24def65c0a52f2fb1690c4a5ca5845e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 20:13:14 +0100 Subject: [PATCH 0252/1106] UPdate documentation to remove inexisting setting --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index f242a4744..a0e7610f6 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -149,7 +149,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have the tradable balance of 1000 USDT (`balance=1000`), `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). +Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. From fab19ae3a7e0bf554f102ba292fc7199268aa847 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 10 Jan 2020 06:36:28 +0100 Subject: [PATCH 0253/1106] Implement last_stake_amount_min_ratio --- config_full.json.example | 1 + docs/configuration.md | 6 +++++- freqtrade/constants.py | 4 ++++ freqtrade/freqtradebot.py | 7 ++++++- tests/test_freqtradebot.py | 18 ++++++++++++------ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/config_full.json.example b/config_full.json.example index f39abb00c..82d8bd04a 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -6,6 +6,7 @@ "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, "amend_last_stake_amount": false, + "last_stake_amount_min_ratio": 0.5, "dry_run": false, "ticker_interval": "5m", "trailing_stop": false, diff --git a/docs/configuration.md b/docs/configuration.md index a0e7610f6..e609f89d9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -45,6 +45,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `last_stake_amount_min_ratio` | **Required.** Minimum amount that has to be left. Applies only to "last_stake_amount" if `amend_last_stake_amount=True` [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -149,7 +150,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). +Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3`. The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. @@ -163,6 +164,9 @@ In the example above this would mean: !!! Note This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. +!!! Note + The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake-amount that's ever used is `stake_amount * 0.5`. This avoids very low stake-amounts, close to the minimum tradable amount. + #### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index a1bd70183..e9c103db9 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -80,6 +80,9 @@ CONF_SCHEMA = { 'default': 0.99 }, 'amend_last_stake_amount': {'type': 'boolean', 'default': False}, + 'last_stake_amount_min_ratio': { + 'type': 'number', 'minimum': 0.0, 'maximum': 1.0, 'default': 0.5 + }, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, @@ -284,6 +287,7 @@ SCHEMA_TRADE_REQUIRED = [ 'stake_currency', 'stake_amount', 'tradable_balance_ratio', + 'last_stake_amount_min_ratio', 'dry_run', 'dry_run_wallet', 'bid_strategy', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 06f435421..e3f2616a2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -312,7 +312,12 @@ class FreqtradeBot: available_amount = self._get_available_stake_amount() if self.config['amend_last_stake_amount']: - stake_amount = min(stake_amount, available_amount) + # Remaining amount needs to be at least stake_amount * last_stake_amount_min_ratio + # Otherwise the remaining amount is too low to trade. + if available_amount > (stake_amount * self.config['last_stake_amount_min_ratio']): + stake_amount = min(stake_amount, available_amount) + else: + stake_amount = 0 if available_amount < stake_amount: raise DependencyException( diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6d794fc05..58f88198a 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -140,14 +140,18 @@ def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: assert result == default_conf['stake_amount'] -@pytest.mark.parametrize("amend_last,wallet,max_open,expected", [ - (False, 0.002, 2, [0.001, None]), - (True, 0.002, 2, [0.001, 0.00098]), - (False, 0.003, 3, [0.001, 0.001, None]), - (True, 0.003, 3, [0.001, 0.001, 0.00097]), +@pytest.mark.parametrize("amend_last,wallet,max_open,lsamr,expected", [ + (False, 0.002, 2, 0.5, [0.001, None]), + (True, 0.002, 2, 0.5, [0.001, 0.00098]), + (False, 0.003, 3, 0.5, [0.001, 0.001, None]), + (True, 0.003, 3, 0.5, [0.001, 0.001, 0.00097]), + (False, 0.0022, 3, 0.5, [0.001, 0.001, None]), + (True, 0.0022, 3, 0.5, [0.001, 0.001, 0.0]), + (True, 0.0027, 3, 0.5, [0.001, 0.001, 0.000673]), + (True, 0.0022, 3, 1, [0.001, 0.001, 0.0]), ]) def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_buy_order, - amend_last, wallet, max_open, expected) -> None: + amend_last, wallet, max_open, lsamr, expected) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -160,6 +164,8 @@ def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_b default_conf['dry_run_wallet'] = wallet default_conf['amend_last_stake_amount'] = amend_last + default_conf['last_stake_amount_min_ratio'] = lsamr + freqtrade = FreqtradeBot(default_conf) for i in range(0, max_open): From 3faa2d0eb9f579658e7d081fdb31720ad1838a97 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:59:02 +0300 Subject: [PATCH 0254/1106] Refine description for last_stake_amount_min_ratio --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index e609f89d9..9aa3a7585 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -45,7 +45,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `last_stake_amount_min_ratio` | **Required.** Minimum amount that has to be left. Applies only to "last_stake_amount" if `amend_last_stake_amount=True` [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* +| `last_stake_amount_min_ratio` | **Required.** Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From 83b88e791642d49b96edf55323f5b11ba4b097e6 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 10 Jan 2020 23:14:17 +0300 Subject: [PATCH 0255/1106] Remove Required marks for new settings --- docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9aa3a7585..f83072b03 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -44,8 +44,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* -| `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `last_stake_amount_min_ratio` | **Required.** Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* +| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From d3de3983950fdc7e8dbc0159dfb5c979c2b8c623 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 10 Jan 2020 23:43:09 +0300 Subject: [PATCH 0256/1106] Docs adjusted --- docs/configuration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index f83072b03..fe692eacb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -143,10 +143,10 @@ Freqtrade will reserve 1% for eventual fees when entering a trade and will there You can configure the "untouched" amount by using the `tradable_balance_ratio` setting. -For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. +For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. The rest of the wallet is untouched by the trades. !!! Warning - `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + The `tradable_balance_ratio` setting applies to the current balance (free balance + tied up in trades). Therefore, assuming the starting balance of 1000, a configuration with `tradable_balance_ratio=0.99` will not guarantee that 10 currency units will always remain available on the exchange. For example, the free amount may reduce to 5 units if the total balance is reduced to 500 (either by a losing streak, or by withdrawing balance). #### Amend last stake amount @@ -162,10 +162,10 @@ In the example above this would mean: - Trade3: 200 USDT !!! Note - This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. + This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. !!! Note - The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake-amount that's ever used is `stake_amount * 0.5`. This avoids very low stake-amounts, close to the minimum tradable amount. + The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake amount that's ever used is `stake_amount * 0.5`. This avoids very low stake amounts, that are close to the minimum tradable amount for the pair and can be refused by the exchange. #### Static stake amount From 5faebad863a59ed6436fc9351efd93df9908e428 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 11:16:05 +0100 Subject: [PATCH 0257/1106] Don't hardcode TimeFrames - they can differ by exchange. --- freqtrade/constants.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index e9c103db9..598a64337 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -33,12 +33,6 @@ USER_DATA_FILES = { 'strategy_analysis_example.ipynb': 'notebooks', } -TIMEFRAMES = [ - '1m', '3m', '5m', '15m', '30m', - '1h', '2h', '4h', '6h', '8h', '12h', - '1d', '3d', '1w', -] - SUPPORTED_FIAT = [ "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", @@ -66,7 +60,7 @@ CONF_SCHEMA = { 'type': 'object', 'properties': { 'max_open_trades': {'type': ['integer', 'number'], 'minimum': -1}, - 'ticker_interval': {'type': 'string', 'enum': TIMEFRAMES}, + 'ticker_interval': {'type': 'string'}, 'stake_currency': {'type': 'string', 'enum': ['BTC', 'XBT', 'ETH', 'USDT', 'EUR', 'USD']}, 'stake_amount': { 'type': ['number', 'string'], From 235a10ab860d887342635a45d73d3ce1e9b83871 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 11:36:28 +0100 Subject: [PATCH 0258/1106] Don't suppport <1m timeframes --- freqtrade/exchange/exchange.py | 4 ++++ tests/exchange/test_exchange.py | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3ef32db62..1ee6c2f1c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -319,6 +319,10 @@ class Exchange: raise OperationalException( f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}") + if timeframe_to_minutes(timeframe) < 1: + raise OperationalException( + f"Timeframes < 1m are currently not supported by Freqtrade.") + def validate_ordertypes(self, order_types: Dict) -> None: """ Checks if order-types configured in strategy/config are supported diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index cb40bdbd9..288c10187 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -377,8 +377,11 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog): f"on the exchange and eventually remove XRP/BTC from your whitelist.", caplog) -def test_validate_timeframes(default_conf, mocker): - default_conf["ticker_interval"] = "5m" +@pytest.mark.parametrize("timeframe", [ + ('5m'), ("1m"), ("15m"), ("1h") +]) +def test_validate_timeframes(default_conf, mocker, timeframe): + default_conf["ticker_interval"] = timeframe api_mock = MagicMock() id_mock = PropertyMock(return_value='test_exchange') type(api_mock).id = id_mock @@ -399,7 +402,8 @@ def test_validate_timeframes_failed(default_conf, mocker): api_mock = MagicMock() id_mock = PropertyMock(return_value='test_exchange') type(api_mock).id = id_mock - timeframes = PropertyMock(return_value={'1m': '1m', + timeframes = PropertyMock(return_value={'15s': '15s', + '1m': '1m', '5m': '5m', '15m': '15m', '1h': '1h'}) @@ -411,6 +415,11 @@ def test_validate_timeframes_failed(default_conf, mocker): with pytest.raises(OperationalException, match=r"Invalid ticker interval '3m'. This exchange supports.*"): Exchange(default_conf) + default_conf["ticker_interval"] = "15s" + + with pytest.raises(OperationalException, + match=r"Timeframes < 1m are currently not supported by Freqtrade."): + Exchange(default_conf) def test_validate_timeframes_emulated_ohlcv_1(default_conf, mocker): From 13274964a94a38975e66b8963c1c5622a7cec022 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 11:53:44 +0100 Subject: [PATCH 0259/1106] Implement validation for valid stake currency --- freqtrade/constants.py | 2 +- freqtrade/exchange/exchange.py | 25 +++++++++++++++++++++++-- tests/conftest.py | 1 + 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 598a64337..53bc4af53 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -61,7 +61,7 @@ CONF_SCHEMA = { 'properties': { 'max_open_trades': {'type': ['integer', 'number'], 'minimum': -1}, 'ticker_interval': {'type': 'string'}, - 'stake_currency': {'type': 'string', 'enum': ['BTC', 'XBT', 'ETH', 'USDT', 'EUR', 'USD']}, + 'stake_currency': {'type': 'string'}, 'stake_amount': { 'type': ['number', 'string'], 'minimum': 0.0001, diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 1ee6c2f1c..e15f6885c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -116,6 +116,7 @@ class Exchange: self._load_markets() # Check if all pairs are available + self.validate_stakecurrency(config['stake_currency']) self.validate_pairs(config['exchange']['pair_whitelist']) self.validate_ordertypes(config.get('order_types', {})) self.validate_order_time_in_force(config.get('order_time_in_force', {})) @@ -210,6 +211,14 @@ class Exchange: markets = {k: v for k, v in markets.items() if market_is_active(v)} return markets + def get_quote_currencies(self) -> List[str]: + """ + Return a list of supported quote currencies + """ + markets = self.markets + currencies = set([x['quote'] for _, x in markets.items()]) + return list(currencies) + def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: if pair_interval in self._klines: return self._klines[pair_interval].copy() if copy else self._klines[pair_interval] @@ -259,11 +268,23 @@ class Exchange: except ccxt.BaseError: logger.exception("Could not reload markets.") + def validate_stakecurrency(self, stake_currency) -> None: + """ + Checks stake-currency against available currencies on the exchange. + :param stake_currency: Stake-currency to validate + :raise: OperationalException if stake-currency is not available. + """ + quote_currencies = self.get_quote_currencies() + if stake_currency not in quote_currencies: + raise OperationalException( + f"{stake_currency} is not available as stake on {self.name}." + f"Available currencies are: {','.join(quote_currencies)}") + def validate_pairs(self, pairs: List[str]) -> None: """ Checks if all given pairs are tradable on the current exchange. - Raises OperationalException if one pair is not available. :param pairs: list of pairs + :raise: OperationalException if one pair is not available :return: None """ @@ -319,7 +340,7 @@ class Exchange: raise OperationalException( f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}") - if timeframe_to_minutes(timeframe) < 1: + if timeframe and timeframe_to_minutes(timeframe) < 1: raise OperationalException( f"Timeframes < 1m are currently not supported by Freqtrade.") diff --git a/tests/conftest.py b/tests/conftest.py index 7bb4cf4c9..ac1b10284 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -60,6 +60,7 @@ def patch_exchange(mocker, api_mock=None, id='bittrex', mock_markets=True) -> No mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id)) mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title())) if mock_markets: From ca2880537d6a95bdee468aa4bb0f1463e3ab8d1c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 11:54:11 +0100 Subject: [PATCH 0260/1106] Modify tests to skip stake_currency validations --- tests/exchange/test_exchange.py | 66 ++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 288c10187..bd73a98de 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -73,6 +73,7 @@ def test_init(default_conf, mocker, caplog): def test_init_ccxt_kwargs(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') caplog.set_level(logging.INFO) conf = copy.deepcopy(default_conf) conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True} @@ -121,9 +122,10 @@ def test_init_exception(default_conf, mocker): def test_exchange_resolver(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=MagicMock())) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') exchange = ExchangeResolver.load_exchange('Bittrex', default_conf) assert isinstance(exchange, Exchange) assert log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) @@ -257,9 +259,10 @@ def test__load_markets(default_conf, mocker, caplog): api_mock = MagicMock() api_mock.load_markets = MagicMock(side_effect=ccxt.BaseError("SomeError")) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) assert log_has('Unable to initialize markets. Reason: SomeError', caplog) @@ -324,8 +327,9 @@ def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs d type(api_mock).id = id_mock mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) @@ -335,8 +339,9 @@ def test_validate_pairs_not_available(default_conf, mocker): 'XRP/BTC': {'inactive': True} }) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') with pytest.raises(OperationalException, match=r'not available'): Exchange(default_conf) @@ -349,8 +354,9 @@ def test_validate_pairs_exception(default_conf, mocker, caplog): type(api_mock).markets = PropertyMock(return_value={}) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') with pytest.raises(OperationalException, match=r'Pair ETH/BTC is not available on Binance'): Exchange(default_conf) @@ -368,8 +374,9 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog): 'NEO/BTC': {'info': 'TestString'}, # info can also be a string ... }) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) assert log_has(f"Pair XRP/BTC is restricted for some users on this exchange." @@ -393,7 +400,8 @@ def test_validate_timeframes(default_conf, mocker, timeframe): mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) @@ -433,7 +441,8 @@ def test_validate_timeframes_emulated_ohlcv_1(default_conf, mocker): mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') with pytest.raises(OperationalException, match=r'The ccxt library does not provide the list of timeframes ' r'for the exchange ".*" and this exchange ' @@ -454,6 +463,7 @@ def test_validate_timeframes_emulated_ohlcvi_2(default_conf, mocker): mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={'timeframes': None})) mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') with pytest.raises(OperationalException, match=r'The ccxt library does not provide the list of timeframes ' r'for the exchange ".*" and this exchange ' @@ -474,7 +484,8 @@ def test_validate_timeframes_not_in_config(default_conf, mocker): mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) @@ -484,8 +495,9 @@ def test_validate_order_types(default_conf, mocker): type(api_mock).has = PropertyMock(return_value={'createMarketOrder': True}) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') mocker.patch('freqtrade.exchange.Exchange.name', 'Bittrex') default_conf['order_types'] = { 'buy': 'limit', @@ -526,8 +538,9 @@ def test_validate_order_types_not_in_config(default_conf, mocker): api_mock = MagicMock() mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') conf = copy.deepcopy(default_conf) Exchange(conf) @@ -538,9 +551,10 @@ def test_validate_required_startup_candles(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='Binance')) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock) - mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock()) - mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') default_conf['startup_candle_count'] = 20 ex = Exchange(default_conf) @@ -1674,7 +1688,9 @@ def test_merge_ft_has_dict(default_conf, mocker): _init_ccxt=MagicMock(return_value=MagicMock()), _load_async_markets=MagicMock(), validate_pairs=MagicMock(), - validate_timeframes=MagicMock()) + validate_timeframes=MagicMock(), + validate_stakecurrency=MagicMock() + ) ex = Exchange(default_conf) assert ex._ft_has == Exchange._ft_has_default From 60b47b6eeca7ae9267bbdd951bebda9f6235240c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 12:01:34 +0100 Subject: [PATCH 0261/1106] Add tests for get_quote_currencies --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index e15f6885c..a5c10776c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -216,7 +216,7 @@ class Exchange: Return a list of supported quote currencies """ markets = self.markets - currencies = set([x['quote'] for _, x in markets.items()]) + currencies = set([x.get('quote') for _, x in markets.items()]) return list(currencies) def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index bd73a98de..5924d4b40 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -318,6 +318,27 @@ def test__reload_markets_exception(default_conf, mocker, caplog): assert log_has_re(r"Could not reload markets.*", caplog) +@pytest.mark.parametrize("stake_currency", ['ETH', 'BTC', 'USDT']) +def test_validate_stake_currency(default_conf, stake_currency, mocker, caplog): + default_conf['stake_currency'] = stake_currency + api_mock = MagicMock() + type(api_mock).markets = PropertyMock(return_value={ + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/ETH': {'quote': 'ETH'}, 'NEO/USDT': {'quote': 'USDT'}, + }) + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + Exchange(default_conf) + + +def test_get_quote_currencies(default_conf, mocker): + ex = get_patched_exchange(mocker, default_conf) + + assert set(ex.get_quote_currencies()) == set(['USD', 'BTC', 'USDT']) + + def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ From a7246ba1ecfd96f12e1fd2bbe252b569e12ed872 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 12:51:42 +0100 Subject: [PATCH 0262/1106] No need to "fix" stake_currency enum anymore --- freqtrade/configuration/config_validation.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 54941043d..5183ad0b4 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -48,11 +48,6 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]: conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED else: conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED - # Dynamically allow empty stake-currency - # Since the minimal config specifies this too. - # It's not allowed for Dry-run or live modes - conf_schema['properties']['stake_currency']['enum'] += [''] # type: ignore - try: FreqtradeValidator(conf_schema).validate(conf) return conf From 3519cebf66e31aa799ae9422ab31e17c20153844 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Jan 2020 13:14:19 +0100 Subject: [PATCH 0263/1106] Add test for failing stake_validation --- freqtrade/exchange/exchange.py | 9 +++++---- tests/exchange/test_exchange.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a5c10776c..3735dac8a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -216,8 +216,9 @@ class Exchange: Return a list of supported quote currencies """ markets = self.markets - currencies = set([x.get('quote') for _, x in markets.items()]) - return list(currencies) + currencies = list(set([x.get('quote') for _, x in markets.items()])) + currencies.sort() + return currencies def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: if pair_interval in self._klines: @@ -277,8 +278,8 @@ class Exchange: quote_currencies = self.get_quote_currencies() if stake_currency not in quote_currencies: raise OperationalException( - f"{stake_currency} is not available as stake on {self.name}." - f"Available currencies are: {','.join(quote_currencies)}") + f"{stake_currency} is not available as stake on {self.name}. " + f"Available currencies are: {', '.join(quote_currencies)}") def validate_pairs(self, pairs: List[str]) -> None: """ diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 5924d4b40..150ba3ea7 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -333,6 +333,23 @@ def test_validate_stake_currency(default_conf, stake_currency, mocker, caplog): Exchange(default_conf) +def test_validate_stake_currency_error(default_conf, mocker, caplog): + default_conf['stake_currency'] = 'XRP' + api_mock = MagicMock() + type(api_mock).markets = PropertyMock(return_value={ + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/ETH': {'quote': 'ETH'}, 'NEO/USDT': {'quote': 'USDT'}, + }) + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs') + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + with pytest.raises(OperationalException, + match=r'XRP is not available as stake on .*' + 'Available currencies are: BTC, ETH, USDT'): + Exchange(default_conf) + + def test_get_quote_currencies(default_conf, mocker): ex = get_patched_exchange(mocker, default_conf) From 53abfdbcbf032de93994fb2965b6d0192660df6a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Jan 2020 12:48:29 +0100 Subject: [PATCH 0264/1106] Use sorted on set instead of explicit list conversion --- freqtrade/exchange/exchange.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3735dac8a..714bb40e4 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -216,9 +216,7 @@ class Exchange: Return a list of supported quote currencies """ markets = self.markets - currencies = list(set([x.get('quote') for _, x in markets.items()])) - currencies.sort() - return currencies + return sorted(set([x['quote'] for _, x in markets.items()])) def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: if pair_interval in self._klines: From fa1f9bcdbd697274c50489a06c7c42e586db4999 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Jan 2020 14:37:45 +0100 Subject: [PATCH 0265/1106] expose precisionMode from exchange class --- freqtrade/exchange/exchange.py | 5 +++++ tests/conftest.py | 1 + 2 files changed, 6 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3ef32db62..f29bc3c6f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -188,6 +188,11 @@ class Exchange: self._load_markets() return self._api.markets + @property + def precisionMode(self) -> str: + """exchange ccxt precisionMode""" + return self._api.precisionMode + def get_markets(self, base_currencies: List[str] = None, quote_currencies: List[str] = None, pairs_only: bool = False, active_only: bool = False) -> Dict: """ diff --git a/tests/conftest.py b/tests/conftest.py index 7bb4cf4c9..ec53141c1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -62,6 +62,7 @@ def patch_exchange(mocker, api_mock=None, id='bittrex', mock_markets=True) -> No mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id)) mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title())) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) if mock_markets: mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=get_markets())) From b60d7ad42fde62614c934abf14931b1103b04962 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Jan 2020 14:40:58 +0100 Subject: [PATCH 0266/1106] Use ccxt.decimal_to_precision instead of our own calculation --- freqtrade/exchange/exchange.py | 24 ++++++++++++++---------- tests/exchange/test_exchange.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f29bc3c6f..e1b5c411d 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -7,14 +7,15 @@ import inspect import logging from copy import deepcopy from datetime import datetime, timezone -from math import ceil, floor +from math import ceil from random import randint from typing import Any, Dict, List, Optional, Tuple import arrow import ccxt import ccxt.async_support as ccxt_async -from ccxt.base.decimal_to_precision import ROUND_DOWN, ROUND_UP +from ccxt.base.decimal_to_precision import (ROUND, ROUND_DOWN, ROUND_UP, + TRUNCATE, decimal_to_precision) from pandas import DataFrame from freqtrade.data.converter import parse_ticker_dataframe @@ -367,26 +368,29 @@ class Exchange: """ return endpoint in self._api.has and self._api.has[endpoint] - def symbol_amount_prec(self, pair, amount: float): + def symbol_amount_prec(self, pair, amount: float) -> float: ''' Returns the amount to buy or sell to a precision the Exchange accepts Rounded down ''' if self.markets[pair]['precision']['amount']: - symbol_prec = self.markets[pair]['precision']['amount'] - big_amount = amount * pow(10, symbol_prec) - amount = floor(big_amount) / pow(10, symbol_prec) + amount = float(decimal_to_precision(amount, rounding_mode=TRUNCATE, + precision=self.markets[pair]['precision']['amount'], + counting_mode=self.precisionMode, + )) + return amount - def symbol_price_prec(self, pair, price: float): + def symbol_price_prec(self, pair, price: float) -> float: ''' Returns the price buying or selling with to the precision the Exchange accepts Rounds up ''' if self.markets[pair]['precision']['price']: - symbol_prec = self.markets[pair]['precision']['price'] - big_price = price * pow(10, symbol_prec) - price = ceil(big_price) / pow(10, symbol_prec) + price = float(decimal_to_precision(price, rounding_mode=ROUND, + precision=self.markets[pair]['precision']['price'], + counting_mode=self.precisionMode, + )) return price def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float, diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index cb40bdbd9..b90e94547 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -181,6 +181,11 @@ def test_symbol_amount_prec(default_conf, mocker): markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}}) exchange = get_patched_exchange(mocker, default_conf, id="binance") + # digits counting mode + # DECIMAL_PLACES = 2 + # SIGNIFICANT_DIGITS = 3 + # TICK_SIZE = 4 + mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) amount = 2.34559 @@ -188,6 +193,12 @@ def test_symbol_amount_prec(default_conf, mocker): amount = exchange.symbol_amount_prec(pair, amount) assert amount == 2.3455 + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 0.0001}}}) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) + mocker.patch('freqtrade.exchange.Exchange.markets', markets) + amount = exchange.symbol_amount_prec(pair, amount) + assert amount == 2.3455 + def test_symbol_price_prec(default_conf, mocker): ''' @@ -197,12 +208,20 @@ def test_symbol_price_prec(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, id="binance") mocker.patch('freqtrade.exchange.Exchange.markets', markets) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) price = 2.34559 pair = 'ETH/BTC' price = exchange.symbol_price_prec(pair, price) assert price == 2.3456 + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 0.0001}}}) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) + mocker.patch('freqtrade.exchange.Exchange.markets', markets) + + price = exchange.symbol_price_prec(pair, price) + assert price == 2.3456 + def test_set_sandbox(default_conf, mocker): """ From 5fcab1eee8efce5bfa17d43f70542da65dcc4449 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Jan 2020 14:55:05 +0100 Subject: [PATCH 0267/1106] Align method names to internal ccxt names These methods are reimplemented from ccxt so we can test their behaviour. --- freqtrade/exchange/binance.py | 6 ++--- freqtrade/exchange/exchange.py | 19 ++++++++-------- freqtrade/pairlist/PrecisionFilter.py | 4 ++-- tests/exchange/test_binance.py | 8 +++---- tests/exchange/test_exchange.py | 32 +++++++++++++-------------- tests/exchange/test_kraken.py | 8 +++---- tests/test_freqtradebot.py | 8 +++---- tests/test_integration.py | 8 +++---- 8 files changed, 47 insertions(+), 46 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 96f72fcf5..12326f083 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -41,7 +41,7 @@ class Binance(Exchange): """ ordertype = "stop_loss_limit" - stop_price = self.symbol_price_prec(pair, stop_price) + stop_price = self.price_to_precision(pair, stop_price) # Ensure rate is less than stop price if stop_price <= rate: @@ -57,9 +57,9 @@ class Binance(Exchange): params = self._params.copy() params.update({'stopPrice': stop_price}) - amount = self.symbol_amount_prec(pair, amount) + amount = self.amount_to_precision(pair, amount) - rate = self.symbol_price_prec(pair, rate) + rate = self.price_to_precision(pair, rate) order = self._api.create_order(pair, ordertype, 'sell', amount, rate, params) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index e1b5c411d..dd6f257fe 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -7,7 +7,6 @@ import inspect import logging from copy import deepcopy from datetime import datetime, timezone -from math import ceil from random import randint from typing import Any, Dict, List, Optional, Tuple @@ -368,10 +367,11 @@ class Exchange: """ return endpoint in self._api.has and self._api.has[endpoint] - def symbol_amount_prec(self, pair, amount: float) -> float: + def amount_to_precision(self, pair, amount: float) -> float: ''' Returns the amount to buy or sell to a precision the Exchange accepts - Rounded down + Reimplementation of ccxt internal methods - ensuring we can test the result is correct + based on our definitions. ''' if self.markets[pair]['precision']['amount']: amount = float(decimal_to_precision(amount, rounding_mode=TRUNCATE, @@ -381,10 +381,11 @@ class Exchange: return amount - def symbol_price_prec(self, pair, price: float) -> float: + def price_to_precision(self, pair, price: float) -> float: ''' Returns the price buying or selling with to the precision the Exchange accepts - Rounds up + Reimplementation of ccxt internal methods - ensuring we can test the result is correct + based on our definitions. ''' if self.markets[pair]['precision']['price']: price = float(decimal_to_precision(price, rounding_mode=ROUND, @@ -396,7 +397,7 @@ class Exchange: def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float, rate: float, params: Dict = {}) -> Dict[str, Any]: order_id = f'dry_run_{side}_{randint(0, 10**6)}' - _amount = self.symbol_amount_prec(pair, amount) + _amount = self.amount_to_precision(pair, amount) dry_order = { "id": order_id, 'pair': pair, @@ -431,13 +432,13 @@ class Exchange: rate: float, params: Dict = {}) -> Dict: try: # Set the precision for amount and price(rate) as accepted by the exchange - amount = self.symbol_amount_prec(pair, amount) + amount = self.amount_to_precision(pair, amount) needs_price = (ordertype != 'market' or self._api.options.get("createMarketBuyOrderRequiresPrice", False)) - rate = self.symbol_price_prec(pair, rate) if needs_price else None + rate_for_order = self.price_to_precision(pair, rate) if needs_price else None return self._api.create_order(pair, ordertype, side, - amount, rate, params) + amount, rate_for_order, params) except ccxt.InsufficientFunds as e: raise DependencyException( diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index aedcc5a88..5d364795d 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -35,8 +35,8 @@ class PrecisionFilter(IPairList): """ stop_price = ticker['ask'] * stoploss # Adjust stop-prices to precision - sp = self._exchange.symbol_price_prec(ticker["symbol"], stop_price) - stop_gap_price = self._exchange.symbol_price_prec(ticker["symbol"], stop_price * 0.99) + sp = self._exchange.price_to_precision(ticker["symbol"], stop_price) + stop_gap_price = self._exchange.price_to_precision(ticker["symbol"], stop_price * 0.99) logger.debug(f"{ticker['symbol']} - {sp} : {stop_gap_price}") if sp <= stop_gap_price: logger.info(f"Removed {ticker['symbol']} from whitelist, " diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 0a12c1cb1..4bc918c3d 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -22,8 +22,8 @@ def test_stoploss_limit_order(default_conf, mocker): }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') @@ -71,8 +71,8 @@ def test_stoploss_limit_order_dry_run(default_conf, mocker): api_mock = MagicMock() order_type = 'stop_loss_limit' default_conf['dry_run'] = True - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index b90e94547..d666d29ac 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -173,7 +173,7 @@ def test_validate_order_time_in_force(default_conf, mocker, caplog): ex.validate_order_time_in_force(tif2) -def test_symbol_amount_prec(default_conf, mocker): +def test_amount_to_precision(default_conf, mocker): ''' Test rounds down to 4 Decimal places ''' @@ -190,17 +190,17 @@ def test_symbol_amount_prec(default_conf, mocker): amount = 2.34559 pair = 'ETH/BTC' - amount = exchange.symbol_amount_prec(pair, amount) + amount = exchange.amount_to_precision(pair, amount) assert amount == 2.3455 markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 0.0001}}}) mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) - amount = exchange.symbol_amount_prec(pair, amount) + amount = exchange.amount_to_precision(pair, amount) assert amount == 2.3455 -def test_symbol_price_prec(default_conf, mocker): +def test_sprice_to_precision(default_conf, mocker): ''' Test rounds up to 4 decimal places ''' @@ -212,14 +212,14 @@ def test_symbol_price_prec(default_conf, mocker): price = 2.34559 pair = 'ETH/BTC' - price = exchange.symbol_price_prec(pair, price) + price = exchange.price_to_precision(pair, price) assert price == 2.3456 markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 0.0001}}}) mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) - price = exchange.symbol_price_prec(pair, price) + price = exchange.price_to_precision(pair, price) assert price == 2.3456 @@ -615,8 +615,8 @@ def test_create_order(default_conf, mocker, side, ordertype, rate, marketprice, } }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order = exchange.create_order( @@ -656,8 +656,8 @@ def test_buy_prod(default_conf, mocker, exchange_name): } }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order = exchange.buy(pair='ETH/BTC', ordertype=order_type, @@ -730,8 +730,8 @@ def test_buy_considers_time_in_force(default_conf, mocker, exchange_name): } }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order_type = 'limit' @@ -792,8 +792,8 @@ def test_sell_prod(default_conf, mocker, exchange_name): }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order = exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200) @@ -856,8 +856,8 @@ def test_sell_considers_time_in_force(default_conf, mocker, exchange_name): }) api_mock.options = {} default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) order_type = 'limit' diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 3ad62d85a..8490ee1a2 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -21,8 +21,8 @@ def test_buy_kraken_trading_agreement(default_conf, mocker): }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken") order = exchange.buy(pair='ETH/BTC', ordertype=order_type, @@ -53,8 +53,8 @@ def test_sell_kraken_trading_agreement(default_conf, mocker): }) default_conf['dry_run'] = False - mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) - mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken") order = exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 58f88198a..5267a267b 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2435,8 +2435,8 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, - symbol_amount_prec=lambda s, x, y: y, - symbol_price_prec=lambda s, x, y: y, + amount_to_precision=lambda s, x, y: y, + price_to_precision=lambda s, x, y: y, stoploss_limit=stoploss_limit, cancel_order=cancel_order, ) @@ -2478,8 +2478,8 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, - symbol_amount_prec=lambda s, x, y: y, - symbol_price_prec=lambda s, x, y: y, + amount_to_precision=lambda s, x, y: y, + price_to_precision=lambda s, x, y: y, ) stoploss_limit = MagicMock(return_value={ diff --git a/tests/test_integration.py b/tests/test_integration.py index 98bf1862b..2b4a1b946 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -58,8 +58,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, - symbol_amount_prec=lambda s, x, y: y, - symbol_price_prec=lambda s, x, y: y, + amount_to_precision=lambda s, x, y: y, + price_to_precision=lambda s, x, y: y, get_order=stoploss_order_mock, cancel_order=cancel_order_mock, ) @@ -137,8 +137,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, - symbol_amount_prec=lambda s, x, y: y, - symbol_price_prec=lambda s, x, y: y, + amount_to_precision=lambda s, x, y: y, + price_to_precision=lambda s, x, y: y, ) mocker.patch.multiple( From 495728f50215b19bc9ba165b0df10f0a76411898 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 13 Jan 2020 06:31:15 +0300 Subject: [PATCH 0268/1106] Refine docs --- docs/plotting.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index 2f084b66a..bc4ca8ae0 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -124,34 +124,34 @@ freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/ ![plot-dataframe2](assets/plot-dataframe2.png) -plot-dataframe will require backtesting data, a strategy as well as either a backtesting-results file or a Database file, containing trades corresponding to the strategy. +The plot-dataframe subcommand requires backtesting data, a strategy and either a backtesting-results file or a database, containing trades corresponding to the strategy. The resulting plot will have the following elements: -* Green triangles: Buy signals from the strategy. (Note: not every Buy-signal also generates a trade) -* Red triangles: Sell signals from the strategy. -* Cyan Circles: Trade entry -* Red Square: Trade exit for loss or 0% profit -* Green Square: Trade exit for profit -* Indicators corresponding to the candle scale (e.g. SMA/EMA), as specified with `--indicators1`. -* Indicators with different scales (e.g. MACD, RSI) below the volume bars, as specified via `--indicators2`. -* Volume (bar chart at the bottom of the main chart) +* Green triangles: Buy signals from the strategy. (Note: not every buy signal generates a trade, compare to cyan circles.) +* Red triangles: Sell signals from the strategy. (Also, not every sell signal terminates a trade, compare to red and green squares.) +* Cyan circles: Trade entry points. +* Red squares: Trade exit points for trades with loss or 0% profit. +* Green squares: Trade exit points for profitable trades. +* Indicators with values corresponding to the candle scale (e.g. SMA/EMA), as specified with `--indicators1`. +* Volume (bar chart at the bottom of the main chart). +* Indicators with values in different scales (e.g. MACD, RSI) below the volume bars, as specified with `--indicators2`. !!! Note "Bollinger Bands" - Bollinger bands are automatically added to the plot if the columns `bb_lowerband` and `bb_upperband` exist, and are painted as a light blue Area spanning from the lower band to the upper band. + Bollinger bands are automatically added to the plot if the columns `bb_lowerband` and `bb_upperband` exist, and are painted as a light blue area spanning from the lower band to the upper band. -#### Advanced Plot configuration +#### Advanced plot configuration -An advanced plot-configuration can be specified in the strategy. +An advanced plot configuration can be specified in the strategy in the `plot_config` parameter. -This configuration allows to specify fixed colors (otherwise consecutive plots may produce different colorschemes each time, making comparisons diffiult.). -It also allows multiple subplots to display both MACD and RSI at the same time. - -Additional features when using plot_config: +Additional features when using plot_config include: * Specify colors per indicator * Specify additional subplots +The sample plot configuration below specifies fixed colors for the indicators. Otherwise consecutive plots may produce different colorschemes each time, making comparisons difficult. +It also allows multiple subplots to display both MACD and RSI at the same time. + Sample configuration with inline comments explaining the process: ``` python From af366357698e24742219d7ff2ed18d65fe382be3 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 13 Jan 2020 06:36:05 +0300 Subject: [PATCH 0269/1106] Minor changes in the docs --- docs/plotting.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index bc4ca8ae0..ecd5e1603 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -124,7 +124,7 @@ freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/ ![plot-dataframe2](assets/plot-dataframe2.png) -The plot-dataframe subcommand requires backtesting data, a strategy and either a backtesting-results file or a database, containing trades corresponding to the strategy. +The `plot-dataframe` subcommand requires backtesting data, a strategy and either a backtesting-results file or a database, containing trades corresponding to the strategy. The resulting plot will have the following elements: @@ -185,12 +185,12 @@ Sample configuration with inline comments explaining the process: ![plot-profit](assets/plot-profit.png) -The `freqtrade plot-profit` subcommand shows an interactive graph with three plots: +The `plot-profit` subcommand shows an interactive graph with three plots: -1) Average closing price for all pairs -2) The summarized profit made by backtesting. - Note that this is not the real-world profit, but more of an estimate. -3) Profit for each individual pair +* Average closing price for all pairs. +* The summarized profit made by backtesting. +Note that this is not the real-world profit, but more of an estimate. +* Profit for each individual pair. The first graph is good to get a grip of how the overall market progresses. From 2f8ed7ed191b02fca21b138b26d1cda8f02eb44f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2020 07:55:35 +0000 Subject: [PATCH 0270/1106] Bump numpy from 1.18.0 to 1.18.1 Bumps [numpy](https://github.com/numpy/numpy) from 1.18.0 to 1.18.1. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt) - [Commits](https://github.com/numpy/numpy/compare/v1.18.0...v1.18.1) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e0e2942b1..c7dd07ee4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Load common requirements -r requirements-common.txt -numpy==1.18.0 +numpy==1.18.1 pandas==0.25.3 From b3938a86c3b5961c66c33eb3e1b45e3c22056f62 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2020 07:56:20 +0000 Subject: [PATCH 0271/1106] Bump python-telegram-bot from 12.2.0 to 12.3.0 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.2.0 to 12.3.0. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.2.0...v12.3.0) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index c10536603..dc693a25f 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.21.32 SQLAlchemy==1.3.12 -python-telegram-bot==12.2.0 +python-telegram-bot==12.3.0 arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 From c67b2530999cd95c4d3b8155b6fee4ac4d5c0b5c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2020 10:38:34 +0000 Subject: [PATCH 0272/1106] Bump ccxt from 1.21.32 to 1.21.56 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.32 to 1.21.56. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.32...1.21.56) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index dc693a25f..15a9d687f 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.32 +ccxt==1.21.56 SQLAlchemy==1.3.12 python-telegram-bot==12.3.0 arrow==0.15.5 From 797dc8a4dacf526e859af144d501d1732f935ca5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 15:54:53 +0100 Subject: [PATCH 0273/1106] Add more detailed tests for amount_to_precision --- tests/exchange/test_exchange.py | 45 ++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index d666d29ac..379e7d091 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -173,12 +173,19 @@ def test_validate_order_time_in_force(default_conf, mocker, caplog): ex.validate_order_time_in_force(tif2) -def test_amount_to_precision(default_conf, mocker): +@pytest.mark.parametrize("amount,precision,expected", [ + (2.34559, 4, 2.3455), + (2.34559, 5, 2.34559), + (2.34559, 3, 2.345), + (2.9999, 3, 2.999), + (2.9909, 3, 2.990), +]) +def test_amount_to_precision_decimal_places(default_conf, mocker, amount, precision, expected): ''' - Test rounds down to 4 Decimal places + Test rounds down ''' - markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}}) + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': precision}}}) exchange = get_patched_exchange(mocker, default_conf, id="binance") # digits counting mode @@ -188,16 +195,36 @@ def test_amount_to_precision(default_conf, mocker): mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) - amount = 2.34559 pair = 'ETH/BTC' - amount = exchange.amount_to_precision(pair, amount) - assert amount == 2.3455 + assert exchange.amount_to_precision(pair, amount) == expected - markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 0.0001}}}) + +@pytest.mark.parametrize("amount,precision,expected", [ + (2.34559, 0.0001, 2.3455), + (2.34559, 0.00001, 2.34559), + (2.34559, 0.001, 2.345), + (2.9999, 0.001, 2.999), + (2.9909, 0.001, 2.990), + (2.9909, 0.005, 2.990), + (2.9999, 0.005, 2.995), +]) +def test_amount_to_precision_tick_size(default_conf, mocker, amount, precision, expected): + ''' + Test rounds down + ''' + + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': precision}}}) + + exchange = get_patched_exchange(mocker, default_conf, id="binance") + # digits counting mode + # DECIMAL_PLACES = 2 + # SIGNIFICANT_DIGITS = 3 + # TICK_SIZE = 4 mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) - amount = exchange.amount_to_precision(pair, amount) - assert amount == 2.3455 + + pair = 'ETH/BTC' + assert exchange.amount_to_precision(pair, amount) == expected def test_sprice_to_precision(default_conf, mocker): From 425ec53b28ec7d4b463f2f36b6b6c97fa10a99e8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 16:01:35 +0100 Subject: [PATCH 0274/1106] Combine amount_to_precision tests into one --- tests/exchange/test_exchange.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 379e7d091..a131aaab5 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -173,14 +173,22 @@ def test_validate_order_time_in_force(default_conf, mocker, caplog): ex.validate_order_time_in_force(tif2) -@pytest.mark.parametrize("amount,precision,expected", [ - (2.34559, 4, 2.3455), - (2.34559, 5, 2.34559), - (2.34559, 3, 2.345), - (2.9999, 3, 2.999), - (2.9909, 3, 2.990), +@pytest.mark.parametrize("amount,precision_mode,precision,expected", [ + (2.34559, 2, 4, 2.3455), + (2.34559, 2, 5, 2.34559), + (2.34559, 2, 3, 2.345), + (2.9999, 2, 3, 2.999), + (2.9909, 2, 3, 2.990), + # Tests for Tick-size + (2.34559, 4, 0.0001, 2.3455), + (2.34559, 4, 0.00001, 2.34559), + (2.34559, 4, 0.001, 2.345), + (2.9999, 4, 0.001, 2.999), + (2.9909, 4, 0.001, 2.990), + (2.9909, 4, 0.005, 2.990), + (2.9999, 4, 0.005, 2.995), ]) -def test_amount_to_precision_decimal_places(default_conf, mocker, amount, precision, expected): +def test_amount_to_precision(default_conf, mocker, amount, precision_mode, precision, expected): ''' Test rounds down ''' @@ -192,7 +200,8 @@ def test_amount_to_precision_decimal_places(default_conf, mocker, amount, precis # DECIMAL_PLACES = 2 # SIGNIFICANT_DIGITS = 3 # TICK_SIZE = 4 - mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', + PropertyMock(return_value=precision_mode)) mocker.patch('freqtrade.exchange.Exchange.markets', markets) pair = 'ETH/BTC' From d7957bd7916b4a72e24c94018f0dd0aede45a9f9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 16:04:39 +0100 Subject: [PATCH 0275/1106] add advanced tests for price_to_precision --- tests/exchange/test_exchange.py | 60 ++++++++++++--------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index a131aaab5..04cf2ff22 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -208,55 +208,39 @@ def test_amount_to_precision(default_conf, mocker, amount, precision_mode, preci assert exchange.amount_to_precision(pair, amount) == expected -@pytest.mark.parametrize("amount,precision,expected", [ - (2.34559, 0.0001, 2.3455), - (2.34559, 0.00001, 2.34559), - (2.34559, 0.001, 2.345), - (2.9999, 0.001, 2.999), - (2.9909, 0.001, 2.990), - (2.9909, 0.005, 2.990), - (2.9999, 0.005, 2.995), +@pytest.mark.parametrize("price,precision_mode,precision,expected", [ + (2.34559, 2, 4, 2.3456), + (2.34559, 2, 5, 2.34559), + (2.34559, 2, 3, 2.346), + (2.9999, 2, 3, 3.000), + (2.9909, 2, 3, 2.991), + # Tests for Tick_size + (2.34559, 4, 0.0001, 2.3456), + (2.34559, 4, 0.00001, 2.34559), + (2.34559, 4, 0.001, 2.346), + (2.9999, 4, 0.001, 3.000), + (2.9909, 4, 0.001, 2.991), + (2.9909, 4, 0.005, 2.99), + (2.9973, 4, 0.005, 2.995), + (2.9977, 4, 0.005, 3.0), ]) -def test_amount_to_precision_tick_size(default_conf, mocker, amount, precision, expected): +def test_price_to_precision(default_conf, mocker, price, precision_mode, precision, expected): ''' - Test rounds down + Test price to precision ''' - - markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': precision}}}) + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': precision}}}) exchange = get_patched_exchange(mocker, default_conf, id="binance") + mocker.patch('freqtrade.exchange.Exchange.markets', markets) # digits counting mode # DECIMAL_PLACES = 2 # SIGNIFICANT_DIGITS = 3 # TICK_SIZE = 4 - mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) - mocker.patch('freqtrade.exchange.Exchange.markets', markets) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', + PropertyMock(return_value=precision_mode)) pair = 'ETH/BTC' - assert exchange.amount_to_precision(pair, amount) == expected - - -def test_sprice_to_precision(default_conf, mocker): - ''' - Test rounds up to 4 decimal places - ''' - markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 4}}}) - - exchange = get_patched_exchange(mocker, default_conf, id="binance") - mocker.patch('freqtrade.exchange.Exchange.markets', markets) - mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2)) - - price = 2.34559 - pair = 'ETH/BTC' - price = exchange.price_to_precision(pair, price) - assert price == 2.3456 - - markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 0.0001}}}) - mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4)) - mocker.patch('freqtrade.exchange.Exchange.markets', markets) - - price = exchange.price_to_precision(pair, price) - assert price == 2.3456 + assert exchange.price_to_precision(pair, price) == expected def test_set_sandbox(default_conf, mocker): From bea4ad8effa97626de4ae51d7f0e6c06c963a00f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 20:16:20 +0100 Subject: [PATCH 0276/1106] Revert price_to_precision to rounding up --- freqtrade/exchange/exchange.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index dd6f257fe..a7243d4d2 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -7,6 +7,7 @@ import inspect import logging from copy import deepcopy from datetime import datetime, timezone +from math import ceil from random import randint from typing import Any, Dict, List, Optional, Tuple @@ -14,7 +15,7 @@ import arrow import ccxt import ccxt.async_support as ccxt_async from ccxt.base.decimal_to_precision import (ROUND, ROUND_DOWN, ROUND_UP, - TRUNCATE, decimal_to_precision) + TRUNCATE, TICK_SIZE, decimal_to_precision) from pandas import DataFrame from freqtrade.data.converter import parse_ticker_dataframe @@ -383,15 +384,27 @@ class Exchange: def price_to_precision(self, pair, price: float) -> float: ''' - Returns the price buying or selling with to the precision the Exchange accepts - Reimplementation of ccxt internal methods - ensuring we can test the result is correct - based on our definitions. + Returns the price rounded up to the precision the Exchange accepts. + Partial Reimplementation of ccxt internal method decimal_to_precision(), + which does not support rounding up + TODO: If ccxt supports ROUND_UP for decimal_to_precision(), we could remove this and + align with amount_to_precision(). + Rounds up ''' if self.markets[pair]['precision']['price']: - price = float(decimal_to_precision(price, rounding_mode=ROUND, - precision=self.markets[pair]['precision']['price'], - counting_mode=self.precisionMode, - )) + # price = float(decimal_to_precision(price, rounding_mode=ROUND, + # precision=self.markets[pair]['precision']['price'], + # counting_mode=self.precisionMode, + # )) + if self.precisionMode == TICK_SIZE: + precision = self.markets[pair]['precision']['price'] + missing = price % precision + if missing != 0: + price = price - missing + precision + else: + symbol_prec = self.markets[pair]['precision']['price'] + big_price = price * pow(10, symbol_prec) + price = ceil(big_price) / pow(10, symbol_prec) return price def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float, From 1e58cd70ad1253784a3f6d76997cf090c54362ab Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 20:16:47 +0100 Subject: [PATCH 0277/1106] Adapt tests to round price up --- tests/exchange/test_exchange.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 04cf2ff22..c3cf7ae58 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -220,9 +220,13 @@ def test_amount_to_precision(default_conf, mocker, amount, precision_mode, preci (2.34559, 4, 0.001, 2.346), (2.9999, 4, 0.001, 3.000), (2.9909, 4, 0.001, 2.991), - (2.9909, 4, 0.005, 2.99), - (2.9973, 4, 0.005, 2.995), + (2.9909, 4, 0.005, 2.995), + (2.9973, 4, 0.005, 3.0), (2.9977, 4, 0.005, 3.0), + (234.43, 4, 0.5, 234.5), + (234.53, 4, 0.5, 235.0), + (0.891534, 4, 0.0001, 0.8916), + ]) def test_price_to_precision(default_conf, mocker, price, precision_mode, precision, expected): ''' @@ -240,7 +244,7 @@ def test_price_to_precision(default_conf, mocker, price, precision_mode, precisi PropertyMock(return_value=precision_mode)) pair = 'ETH/BTC' - assert exchange.price_to_precision(pair, price) == expected + assert pytest.approx(exchange.price_to_precision(pair, price)) == expected def test_set_sandbox(default_conf, mocker): From 4c823f12e3d740e274f80cbff4e6f37ef9e676ac Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Jan 2020 20:25:58 +0100 Subject: [PATCH 0278/1106] Sort imports --- freqtrade/exchange/exchange.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a7243d4d2..4c5c9194c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -14,8 +14,8 @@ from typing import Any, Dict, List, Optional, Tuple import arrow import ccxt import ccxt.async_support as ccxt_async -from ccxt.base.decimal_to_precision import (ROUND, ROUND_DOWN, ROUND_UP, - TRUNCATE, TICK_SIZE, decimal_to_precision) +from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, + TRUNCATE, decimal_to_precision) from pandas import DataFrame from freqtrade.data.converter import parse_ticker_dataframe From 4013701bdb42b4d42dd0ea9db2fed733c187e756 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 06:42:53 +0100 Subject: [PATCH 0279/1106] allow wallet update to be skipped if the value is fresh enough. Value is NOT configurable, having this wrong can result in bans on the exchange. --- freqtrade/wallets.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index 54c3f9138..c52767162 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -2,7 +2,10 @@ """ Wallet """ import logging -from typing import Dict, NamedTuple, Any +from typing import Any, Dict, NamedTuple + +import arrow + from freqtrade.exchange import Exchange from freqtrade.persistence import Trade @@ -24,7 +27,7 @@ class Wallets: self._exchange = exchange self._wallets: Dict[str, Wallet] = {} self.start_cap = config['dry_run_wallet'] - + self._last_wallet_refresh = 0 self.update() def get_free(self, currency) -> float: @@ -95,12 +98,21 @@ class Wallets: balances[currency].get('total', None) ) - def update(self) -> None: - if self._config['dry_run']: - self._update_dry() - else: - self._update_live() - logger.info('Wallets synced.') + def update(self, require_update: bool = True) -> None: + """ + Updates wallets from the configured version. + By default, updates from the exchange. + Update-skipping should only be used for user-invoked /balance calls, since + for trading operations, the latest balance is needed. + :param require_update: Allow skipping an update if balances were recently refreshed + """ + if (require_update or (self._last_wallet_refresh + 3600 < arrow.utcnow().timestamp)): + if self._config['dry_run']: + self._update_dry() + else: + self._update_live() + logger.info('Wallets synced.') + self._last_wallet_refresh = arrow.utcnow().timestamp def get_all_balances(self) -> Dict[str, Any]: return self._wallets From c8806a16a12fad76485f92e2babbe0a9de25c262 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 06:43:41 +0100 Subject: [PATCH 0280/1106] Allow wallet update from /balance --- freqtrade/rpc/rpc.py | 2 ++ tests/test_wallets.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index c187dae4f..0469d418d 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -306,6 +306,8 @@ class RPC: except (TemporaryError, DependencyException): raise RPCException('Error getting current tickers.') + self._freqtrade.wallets.update(require_update=False) + for coin, balance in self._freqtrade.wallets.get_all_balances().items(): if not balance.total: continue diff --git a/tests/test_wallets.py b/tests/test_wallets.py index 3177edc05..884470014 100644 --- a/tests/test_wallets.py +++ b/tests/test_wallets.py @@ -32,7 +32,7 @@ def test_sync_wallet_at_boot(mocker, default_conf): assert freqtrade.wallets._wallets['GAS'].used == 0.0 assert freqtrade.wallets._wallets['GAS'].total == 0.260739 assert freqtrade.wallets.get_free('BNT') == 1.0 - + assert freqtrade.wallets._last_wallet_refresh > 0 mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_balances=MagicMock(return_value={ @@ -61,6 +61,11 @@ def test_sync_wallet_at_boot(mocker, default_conf): assert freqtrade.wallets.get_free('GAS') == 0.270739 assert freqtrade.wallets.get_used('GAS') == 0.1 assert freqtrade.wallets.get_total('GAS') == 0.260439 + update_mock = mocker.patch('freqtrade.wallets.Wallets._update_live') + freqtrade.wallets.update(False) + assert update_mock.call_count == 0 + freqtrade.wallets.update() + assert update_mock.call_count == 1 def test_sync_wallet_missing_data(mocker, default_conf): From f73f0b1653b8914218c326776a4adffa0cf75fa7 Mon Sep 17 00:00:00 2001 From: Tejesh Date: Wed, 15 Jan 2020 19:29:00 +0530 Subject: [PATCH 0281/1106] Update comments on backtesting --- 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 18cc27ff4..1070f2481 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -296,7 +296,7 @@ class Backtesting: """ # Arguments are long and noisy, so this is commented out. # Uncomment if you need to debug the backtest() method. -# logger.debug(f"Start backtest, args: {args}") + # logger.debug(f"Start backtest, args: {args}") processed = args['processed'] stake_amount = args['stake_amount'] max_open_trades = args.get('max_open_trades', 0) From 6feb68b18da6f1edbdbd9a7cde05e8a262ab5568 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 19:51:33 +0100 Subject: [PATCH 0282/1106] Change feature sorting to tell more of a story --- docs/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index b664552bc..c88c73619 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,15 +25,15 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python ## Features -- Run: Run the bot on exchange with simulated money (Dry-Run mode) or with real money (Live-Trade mode). -- Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade. -- Download market data: Download historical data of the exchange and the markets your may want to trade with. The historical data can be based on [OHLCV](https://en.wikipedia.org/wiki/Open-high-low-close_chart) candles or be trade ticks (for exchanges that support this). -- Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies). +- Develop your Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies). +- Download market data: Download historical data of the exchange and the markets your may want to trade with. - Backtest: Test your strategy on downloaded historical data. - Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy. +- Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade. +- Run: Test your strategy with simulated money (Dry-Run mode) or deploy it with real money (Live-Trade mode). - Run using Edge (optional module): The concept is to find the best historical [trade expectancy](edge.md#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital. - Control/Monitor: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.). -- Analyse: Further analysis can be possibilities on either Backtesting data or Freqtrade trading history (SQL database), including automated standard plots, and methods to load the data into [interactive environments](data-analysis.md). +- Analyse: Further analysis can be performed on either Backtesting data or Freqtrade trading history (SQL database), including automated standard plots, and methods to load the data into [interactive environments](data-analysis.md). ## Requirements From d1bf388b0edfdf2cab6d9800cdddf50c9b771654 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 19:56:14 +0100 Subject: [PATCH 0283/1106] Wallet amount must be compared with >= --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e3f2616a2..a5d980504 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -904,7 +904,7 @@ class FreqtradeBot: """ wallet_amount = self.wallets.get_free(pair.split('/')[0]) logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") - if wallet_amount > amount: + if wallet_amount >= amount: return amount elif wallet_amount > amount * 0.98: logger.info(f"{pair} - Falling back to wallet-amount.") From 90ed4c665bf21f3388f7bd90a16f5f02d5062621 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 19:59:08 +0100 Subject: [PATCH 0284/1106] Cover equal case via test --- tests/test_freqtradebot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 58f88198a..eedf79553 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2764,6 +2764,9 @@ def test__safe_sell_amount(default_conf, fee, caplog, mocker): assert freqtrade._safe_sell_amount(trade.pair, trade.amount) == amount_wallet assert log_has_re(r'.*Falling back to wallet-amount.', caplog) + caplog.clear() + assert freqtrade._safe_sell_amount(trade.pair, amount_wallet) == amount_wallet + assert not log_has_re(r'.*Falling back to wallet-amount.', caplog) def test__safe_sell_amount_error(default_conf, fee, caplog, mocker): From 8bcfe4a6aaa370a1dc2f0554c4309d1a713ce152 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 21:01:36 +0100 Subject: [PATCH 0285/1106] Up log level of safe_sell_amount message --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a5d980504..4db5f08b1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -903,7 +903,7 @@ class FreqtradeBot: :raise: DependencyException: if available balance is not within 2% of the available amount. """ wallet_amount = self.wallets.get_free(pair.split('/')[0]) - logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") + logger.info(f"Selling {pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount >= amount: return amount elif wallet_amount > amount * 0.98: From 29a5e4fba15a8f269cacd04ff53937fa78fad01a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 21:52:10 +0100 Subject: [PATCH 0286/1106] Update wallets before getting amount --- freqtrade/freqtradebot.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4db5f08b1..e712892f1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -902,15 +902,19 @@ class FreqtradeBot: :return: amount to sell :raise: DependencyException: if available balance is not within 2% of the available amount. """ + # Update wallets to ensure amounts tied up in a stoploss is now free! + self.wallets.update() + wallet_amount = self.wallets.get_free(pair.split('/')[0]) - logger.info(f"Selling {pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") + logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount >= amount: return amount elif wallet_amount > amount * 0.98: logger.info(f"{pair} - Falling back to wallet-amount.") return wallet_amount else: - raise DependencyException("Not enough amount to sell.") + raise DependencyException( + f"Not enough amount to sell. Trade-amount: {amount}, Wallet: {wallet_amount}") def execute_sell(self, trade: Trade, limit: float, sell_reason: SellType) -> None: """ From fa1e9dd70d1e48298ddc0c2603ae4ef351e93e85 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jan 2020 21:53:04 +0100 Subject: [PATCH 0287/1106] Adjust tests to allow updating within safe_sell_amount --- tests/rpc/test_rpc.py | 1 + tests/test_freqtradebot.py | 5 +++++ tests/test_integration.py | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index ac959cb0e..36fce1797 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -513,6 +513,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None: ), get_fee=fee, ) + mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=1000) freqtradebot = get_patched_freqtradebot(mocker, default_conf) patch_get_signal(freqtradebot, (True, False)) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index eedf79553..1cba39c58 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2750,6 +2750,7 @@ def test__safe_sell_amount(default_conf, fee, caplog, mocker): amount = 95.33 amount_wallet = 95.29 mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=amount_wallet)) + wallet_update = mocker.patch('freqtrade.wallets.Wallets.update') trade = Trade( pair='LTC/ETH', amount=amount, @@ -2762,11 +2763,15 @@ def test__safe_sell_amount(default_conf, fee, caplog, mocker): freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) + wallet_update.reset_mock() assert freqtrade._safe_sell_amount(trade.pair, trade.amount) == amount_wallet assert log_has_re(r'.*Falling back to wallet-amount.', caplog) + assert wallet_update.call_count == 1 caplog.clear() + wallet_update.reset_mock() assert freqtrade._safe_sell_amount(trade.pair, amount_wallet) == amount_wallet assert not log_has_re(r'.*Falling back to wallet-amount.', caplog) + assert wallet_update.call_count == 1 def test__safe_sell_amount_error(default_conf, fee, caplog, mocker): diff --git a/tests/test_integration.py b/tests/test_integration.py index 98bf1862b..ad3e897f8 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -97,8 +97,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, # Only order for 3rd trade needs to be cancelled assert cancel_order_mock.call_count == 1 - # Wallets should only be called once per sell cycle - assert wallets_mock.call_count == 1 + # Wallets must be updated between stoploss cancellation and selling. + assert wallets_mock.call_count == 2 trade = trades[0] assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value From 8d2e0bfd628c13ff51e5962107b7c0fed5db78b3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 13:12:28 +0100 Subject: [PATCH 0288/1106] Move rate-calcuation for stoploss-limit order to exchange --- freqtrade/exchange/binance.py | 8 ++++++-- freqtrade/exchange/exchange.py | 3 ++- freqtrade/freqtradebot.py | 5 +---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 12326f083..15796bdcb 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -32,13 +32,17 @@ class Binance(Exchange): return super().get_order_book(pair, limit) - def stoploss_limit(self, pair: str, amount: float, stop_price: float, rate: float) -> Dict: + def stoploss_limit(self, pair: str, amount: float, stop_price: float, + order_types: Dict) -> Dict: """ creates a stoploss limit order. this stoploss-limit is binance-specific. It may work with a limited number of other exchanges, but this has not been tested yet. - """ + # Limit price threshold: As limit price should always be below stop-price + LIMIT_PRICE_PCT = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) + rate = stop_price * LIMIT_PRICE_PCT + ordertype = "stop_loss_limit" stop_price = self.price_to_precision(pair, stop_price) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 87c189457..4c5ef823b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -519,7 +519,8 @@ class Exchange: return self.create_order(pair, ordertype, 'sell', amount, rate, params) - def stoploss_limit(self, pair: str, amount: float, stop_price: float, rate: float) -> Dict: + def stoploss_limit(self, pair: str, amount: float, stop_price: float, + order_types: Dict) -> Dict: """ creates a stoploss limit order. Since ccxt does not unify stoploss-limit orders yet, this needs to be implemented in each diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e712892f1..1a3097c25 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -636,13 +636,10 @@ class FreqtradeBot: Force-sells the pair (using EmergencySell reason) in case of Problems creating the order. :return: True if the order succeeded, and False in case of problems. """ - # Limit price threshold: As limit price should always be below stop-price - LIMIT_PRICE_PCT = self.strategy.order_types.get('stoploss_on_exchange_limit_ratio', 0.99) - try: stoploss_order = self.exchange.stoploss_limit(pair=trade.pair, amount=trade.amount, stop_price=stop_price, - rate=rate * LIMIT_PRICE_PCT) + order_types=self.strategy.order_types) trade.stoploss_order_id = str(stoploss_order['id']) return True except InvalidOrderException as e: From da0af489a2cd8cc437752e308cab9e44ffc38c7a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 13:25:41 +0100 Subject: [PATCH 0289/1106] Adjust tests to pass in order_types instead of rate --- tests/exchange/test_binance.py | 19 ++++++++++--------- tests/exchange/test_exchange.py | 2 +- tests/test_freqtradebot.py | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 4bc918c3d..bda4946b4 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -28,11 +28,12 @@ def test_stoploss_limit_order(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, rate=200) + order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, + order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order @@ -41,30 +42,29 @@ def test_stoploss_limit_order(default_conf, mocker): assert api_mock.create_order.call_args[0][1] == order_type assert api_mock.create_order.call_args[0][2] == 'sell' assert api_mock.create_order.call_args[0][3] == 1 - assert api_mock.create_order.call_args[0][4] == 200 assert api_mock.create_order.call_args[0][5] == {'stopPrice': 220} # test exception handling with pytest.raises(DependencyException): api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(InvalidOrderException): api_mock.create_order = MagicMock( side_effect=ccxt.InvalidOrder("binance Order would trigger immediately.")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(TemporaryError): api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(OperationalException, match=r".*DeadBeef.*"): api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) def test_stoploss_limit_order_dry_run(default_conf, mocker): @@ -77,11 +77,12 @@ def test_stoploss_limit_order_dry_run(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, rate=200) + order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, + order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 7064d76e1..be40f2192 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1761,7 +1761,7 @@ def test_get_fee(default_conf, mocker, exchange_name): def test_stoploss_limit_order_unsupported_exchange(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, 'bittrex') with pytest.raises(OperationalException, match=r"stoploss_limit is not implemented .*"): - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) + exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) def test_merge_ft_has_dict(default_conf, mocker): diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5a4820f2f..2aa1548f8 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1315,7 +1315,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, cancel_order_mock.assert_called_once_with(100, 'ETH/BTC') stoploss_order_mock.assert_called_once_with(amount=85.25149190110828, pair='ETH/BTC', - rate=0.00002344 * 0.95 * 0.99, + order_types=freqtrade.strategy.order_types, stop_price=0.00002344 * 0.95) @@ -1492,7 +1492,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, cancel_order_mock.assert_called_once_with(100, 'NEO/BTC') stoploss_order_mock.assert_called_once_with(amount=2131074.168797954, pair='NEO/BTC', - rate=0.00002344 * 0.99 * 0.99, + order_types=freqtrade.strategy.order_types, stop_price=0.00002344 * 0.99) From 256fc2e78cc532714b6a8f91d0783b809349bb0c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 13:30:56 +0100 Subject: [PATCH 0290/1106] Rename stoploss_limit to stoploss --- freqtrade/exchange/binance.py | 3 +-- freqtrade/exchange/exchange.py | 6 +++--- freqtrade/freqtradebot.py | 6 +++--- tests/exchange/test_binance.py | 20 ++++++++++---------- tests/exchange/test_exchange.py | 2 +- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 15796bdcb..d08726cf0 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -32,8 +32,7 @@ class Binance(Exchange): return super().get_order_book(pair, limit) - def stoploss_limit(self, pair: str, amount: float, stop_price: float, - order_types: Dict) -> Dict: + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: """ creates a stoploss limit order. this stoploss-limit is binance-specific. diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 4c5ef823b..121a8c636 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -519,10 +519,10 @@ class Exchange: return self.create_order(pair, ordertype, 'sell', amount, rate, params) - def stoploss_limit(self, pair: str, amount: float, stop_price: float, - order_types: Dict) -> Dict: + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: """ - creates a stoploss limit order. + creates a stoploss order. + The precise ordertype is determined by the order_types dict or exchange default. Since ccxt does not unify stoploss-limit orders yet, this needs to be implemented in each exchange's subclass. The exception below should never raise, since we disallow diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 1a3097c25..a4b0ab806 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -637,9 +637,9 @@ class FreqtradeBot: :return: True if the order succeeded, and False in case of problems. """ try: - stoploss_order = self.exchange.stoploss_limit(pair=trade.pair, amount=trade.amount, - stop_price=stop_price, - order_types=self.strategy.order_types) + stoploss_order = self.exchange.stoploss(pair=trade.pair, amount=trade.amount, + stop_price=stop_price, + order_types=self.strategy.order_types) trade.stoploss_order_id = str(stoploss_order['id']) return True except InvalidOrderException as e: diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index bda4946b4..fdf3d7435 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -28,12 +28,12 @@ def test_stoploss_limit_order(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, - order_types={'stoploss_on_exchange_limit_ratio': 1.05}) + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, + order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order @@ -48,23 +48,23 @@ def test_stoploss_limit_order(default_conf, mocker): with pytest.raises(DependencyException): api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(InvalidOrderException): api_mock.create_order = MagicMock( side_effect=ccxt.InvalidOrder("binance Order would trigger immediately.")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(TemporaryError): api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(OperationalException, match=r".*DeadBeef.*"): api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) def test_stoploss_limit_order_dry_run(default_conf, mocker): @@ -77,12 +77,12 @@ def test_stoploss_limit_order_dry_run(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, - order_types={'stoploss_on_exchange_limit_ratio': 1.05}) + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, + order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() - order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index be40f2192..7c0c72491 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1761,7 +1761,7 @@ def test_get_fee(default_conf, mocker, exchange_name): def test_stoploss_limit_order_unsupported_exchange(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, 'bittrex') with pytest.raises(OperationalException, match=r"stoploss_limit is not implemented .*"): - exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) def test_merge_ft_has_dict(default_conf, mocker): From 16b34e11cad56216d7a8afde5a4ad73e98cc513b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 14:39:51 +0100 Subject: [PATCH 0291/1106] Complete rename of stoploss_limit to stoploss --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 4 +-- tests/test_freqtradebot.py | 60 ++++++++++++++++----------------- tests/test_integration.py | 4 +-- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 121a8c636..bef92750c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -530,7 +530,7 @@ class Exchange: Note: Changes to this interface need to be applied to all sub-classes too. """ - raise OperationalException(f"stoploss_limit is not implemented for {self.name}.") + raise OperationalException(f"stoploss is not implemented for {self.name}.") @retrier def get_balance(self, currency: str) -> float: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 7c0c72491..680e69764 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1758,9 +1758,9 @@ def test_get_fee(default_conf, mocker, exchange_name): 'get_fee', 'calculate_fee', symbol="ETH/BTC") -def test_stoploss_limit_order_unsupported_exchange(default_conf, mocker): +def test_stoploss_order_unsupported_exchange(default_conf, mocker): exchange = get_patched_exchange(mocker, default_conf, 'bittrex') - with pytest.raises(OperationalException, match=r"stoploss_limit is not implemented .*"): + with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"): exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 2aa1548f8..a33d47f34 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1031,8 +1031,8 @@ def test_add_stoploss_on_exchange(mocker, default_conf, limit_buy_order) -> None mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=limit_buy_order['amount']) - stoploss_limit = MagicMock(return_value={'id': 13434334}) - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + stoploss = MagicMock(return_value={'id': 13434334}) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss) freqtrade = FreqtradeBot(default_conf) freqtrade.strategy.order_types['stoploss_on_exchange'] = True @@ -1045,13 +1045,13 @@ def test_add_stoploss_on_exchange(mocker, default_conf, limit_buy_order) -> None freqtrade.exit_positions(trades) assert trade.stoploss_order_id == '13434334' - assert stoploss_limit.call_count == 1 + assert stoploss.call_count == 1 assert trade.is_open is True def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: - stoploss_limit = MagicMock(return_value={'id': 13434334}) + stoploss = MagicMock(return_value={'id': 13434334}) patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -1064,7 +1064,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss_limit=stoploss_limit + stoploss=stoploss ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) @@ -1078,7 +1078,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, trade.stoploss_order_id = None assert freqtrade.handle_stoploss_on_exchange(trade) is False - assert stoploss_limit.call_count == 1 + assert stoploss.call_count == 1 assert trade.stoploss_order_id == "13434334" # Second case: when stoploss is set but it is not yet hit @@ -1102,10 +1102,10 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, canceled_stoploss_order = MagicMock(return_value={'status': 'canceled'}) mocker.patch('freqtrade.exchange.Exchange.get_order', canceled_stoploss_order) - stoploss_limit.reset_mock() + stoploss.reset_mock() assert freqtrade.handle_stoploss_on_exchange(trade) is False - assert stoploss_limit.call_count == 1 + assert stoploss.call_count == 1 assert trade.stoploss_order_id == "13434334" # Fourth case: when stoploss is set and it is hit @@ -1132,7 +1132,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, assert trade.is_open is False mocker.patch( - 'freqtrade.exchange.Exchange.stoploss_limit', + 'freqtrade.exchange.Exchange.stoploss', side_effect=DependencyException() ) freqtrade.handle_stoploss_on_exchange(trade) @@ -1142,11 +1142,11 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # Fifth case: get_order returns InvalidOrder # It should try to add stoploss order trade.stoploss_order_id = 100 - stoploss_limit.reset_mock() + stoploss.reset_mock() mocker.patch('freqtrade.exchange.Exchange.get_order', side_effect=InvalidOrderException()) - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss) freqtrade.handle_stoploss_on_exchange(trade) - assert stoploss_limit.call_count == 1 + assert stoploss.call_count == 1 def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, @@ -1165,7 +1165,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, get_order=MagicMock(return_value={'status': 'canceled'}), - stoploss_limit=MagicMock(side_effect=DependencyException()), + stoploss=MagicMock(side_effect=DependencyException()), ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) @@ -1199,7 +1199,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee, sell=sell_mock, get_fee=fee, get_order=MagicMock(return_value={'status': 'canceled'}), - stoploss_limit=MagicMock(side_effect=InvalidOrderException()), + stoploss=MagicMock(side_effect=InvalidOrderException()), ) freqtrade = FreqtradeBot(default_conf) patch_get_signal(freqtrade) @@ -1229,7 +1229,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee, def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: # When trailing stoploss is set - stoploss_limit = MagicMock(return_value={'id': 13434334}) + stoploss = MagicMock(return_value={'id': 13434334}) patch_RPCManager(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -1241,7 +1241,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss_limit=stoploss_limit + stoploss=stoploss ) # enabling TSL @@ -1296,7 +1296,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, cancel_order_mock = MagicMock() stoploss_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock) - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_order_mock) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss_order_mock) # stoploss should not be updated as the interval is 60 seconds assert freqtrade.handle_trade(trade) is False @@ -1322,7 +1322,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: # When trailing stoploss is set - stoploss_limit = MagicMock(return_value={'id': 13434334}) + stoploss = MagicMock(return_value={'id': 13434334}) patch_exchange(mocker) mocker.patch.multiple( @@ -1335,7 +1335,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss_limit=stoploss_limit + stoploss=stoploss ) # enabling TSL @@ -1375,12 +1375,12 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c assert log_has_re(r"Could not cancel stoploss order abcd for pair ETH/BTC.*", caplog) # Still try to create order - assert stoploss_limit.call_count == 1 + assert stoploss.call_count == 1 # Fail creating stoploss order caplog.clear() cancel_mock = mocker.patch("freqtrade.exchange.Exchange.cancel_order", MagicMock()) - mocker.patch("freqtrade.exchange.Exchange.stoploss_limit", side_effect=DependencyException()) + mocker.patch("freqtrade.exchange.Exchange.stoploss", side_effect=DependencyException()) freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging) assert cancel_mock.call_count == 1 assert log_has_re(r"Could not create trailing stoploss order for pair ETH/BTC\..*", caplog) @@ -1390,7 +1390,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: # When trailing stoploss is set - stoploss_limit = MagicMock(return_value={'id': 13434334}) + stoploss = MagicMock(return_value={'id': 13434334}) patch_RPCManager(mocker) patch_exchange(mocker) patch_edge(mocker) @@ -1406,7 +1406,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss_limit=stoploss_limit + stoploss=stoploss ) # enabling TSL @@ -1459,7 +1459,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, cancel_order_mock = MagicMock() stoploss_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock) - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_order_mock) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss_order_mock) # price goes down 5% mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ @@ -2423,7 +2423,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke default_conf['exchange']['name'] = 'binance' rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) - stoploss_limit = MagicMock(return_value={ + stoploss = MagicMock(return_value={ 'id': 123, 'info': { 'foo': 'bar' @@ -2437,7 +2437,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke get_fee=fee, amount_to_precision=lambda s, x, y: y, price_to_precision=lambda s, x, y: y, - stoploss_limit=stoploss_limit, + stoploss=stoploss, cancel_order=cancel_order, ) @@ -2482,14 +2482,14 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f price_to_precision=lambda s, x, y: y, ) - stoploss_limit = MagicMock(return_value={ + stoploss = MagicMock(return_value={ 'id': 123, 'info': { 'foo': 'bar' } }) - mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit) + mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) freqtrade = FreqtradeBot(default_conf) freqtrade.strategy.order_types['stoploss_on_exchange'] = True @@ -2507,7 +2507,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f # Assuming stoploss on exchnage is hit # stoploss_order_id should become None # and trade should be sold at the price of stoploss - stoploss_limit_executed = MagicMock(return_value={ + stoploss_executed = MagicMock(return_value={ "id": "123", "timestamp": 1542707426845, "datetime": "2018-11-20T09:50:26.845Z", @@ -2525,7 +2525,7 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f "fee": None, "trades": None }) - mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_limit_executed) + mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_executed) freqtrade.exit_positions(trades) assert trade.stoploss_order_id is None diff --git a/tests/test_integration.py b/tests/test_integration.py index 9cb071bb8..c40da7e9d 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -20,7 +20,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, default_conf['max_open_trades'] = 3 default_conf['exchange']['name'] = 'binance' - stoploss_limit = { + stoploss = { 'id': 123, 'info': {} } @@ -53,7 +53,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL)] ) cancel_order_mock = MagicMock() - mocker.patch('freqtrade.exchange.Binance.stoploss_limit', stoploss_limit) + mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss) mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, From e6f1912443fa4a1229ac53ee2f1af3f5be3804ec Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 14:07:59 +0100 Subject: [PATCH 0292/1106] Use named arguments for stoploss create_order call --- freqtrade/exchange/binance.py | 4 ++-- tests/exchange/test_binance.py | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index d08726cf0..8a3e28379 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -64,8 +64,8 @@ class Binance(Exchange): rate = self.price_to_precision(pair, rate) - order = self._api.create_order(pair, ordertype, 'sell', - amount, rate, params) + order = self._api.create_order(symbol=pair, type=ordertype, side='sell', + amount=amount, price=stop_price, params=params) logger.info('stoploss limit order added for %s. ' 'stop price: %s. limit: %s', pair, stop_price, rate) return order diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index fdf3d7435..a1b24913e 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -9,7 +9,7 @@ from freqtrade.exceptions import (DependencyException, InvalidOrderException, from tests.conftest import get_patched_exchange -def test_stoploss_limit_order(default_conf, mocker): +def test_stoploss_order_binance(default_conf, mocker): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'stop_loss_limit' @@ -38,11 +38,12 @@ def test_stoploss_limit_order(default_conf, mocker): assert 'id' in order assert 'info' in order assert order['id'] == order_id - assert api_mock.create_order.call_args[0][0] == 'ETH/BTC' - assert api_mock.create_order.call_args[0][1] == order_type - assert api_mock.create_order.call_args[0][2] == 'sell' - assert api_mock.create_order.call_args[0][3] == 1 - assert api_mock.create_order.call_args[0][5] == {'stopPrice': 220} + assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' + assert api_mock.create_order.call_args_list[0][1]['type'] == order_type + assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' + assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 + assert api_mock.create_order.call_args_list[0][1]['price'] == 220 + assert api_mock.create_order.call_args_list[0][1]['params'] == {'stopPrice': 220} # test exception handling with pytest.raises(DependencyException): @@ -67,7 +68,7 @@ def test_stoploss_limit_order(default_conf, mocker): exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) -def test_stoploss_limit_order_dry_run(default_conf, mocker): +def test_stoploss_order_dry_run_binance(default_conf, mocker): api_mock = MagicMock() order_type = 'stop_loss_limit' default_conf['dry_run'] = True From f1629c907a3ea88d08c2976223d25c2ce82e56f4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 14:08:47 +0100 Subject: [PATCH 0293/1106] Implement stoploss for kraken --- freqtrade/exchange/kraken.py | 45 +++++++++++++++++- tests/exchange/test_kraken.py | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 9bcd9cc1f..88c414772 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -4,7 +4,8 @@ from typing import Dict import ccxt -from freqtrade.exceptions import OperationalException, TemporaryError +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from freqtrade.exchange import Exchange from freqtrade.exchange.exchange import retrier @@ -15,6 +16,7 @@ class Kraken(Exchange): _params: Dict = {"trading_agreement": "agree"} _ft_has: Dict = { + "stoploss_on_exchange": True, "trades_pagination": "id", "trades_pagination_arg": "since", } @@ -48,3 +50,44 @@ class Kraken(Exchange): f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e except ccxt.BaseError as e: raise OperationalException(e) from e + + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: + """ + Creates a stoploss market order. + Stoploss market orders is the only stoploss type supported by kraken. + """ + + ordertype = "stop-loss" + + stop_price = self.price_to_precision(pair, stop_price) + + if self._config['dry_run']: + dry_order = self.dry_run_order( + pair, ordertype, "sell", amount, stop_price) + return dry_order + + try: + params = self._params.copy() + + amount = self.amount_to_precision(pair, amount) + + order = self._api.create_order(symbol=pair, type=ordertype, side='sell', + amount=amount, price=stop_price, params=params) + logger.info('stoploss order added for %s. ' + 'stop price: %s.', pair, stop_price) + return order + except ccxt.InsufficientFunds as e: + raise DependencyException( + f'Insufficient funds to create {ordertype} sell order on market {pair}.' + f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. ' + f'Message: {e}') from e + except ccxt.InvalidOrder as e: + raise InvalidOrderException( + f'Could not create {ordertype} sell order on market {pair}. ' + f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. ' + f'Message: {e}') from e + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e + except ccxt.BaseError as e: + raise OperationalException(e) from e diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 8490ee1a2..241d15772 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -3,6 +3,11 @@ from random import randint from unittest.mock import MagicMock +import ccxt +import pytest + +from freqtrade.exceptions import (DependencyException, InvalidOrderException, + OperationalException, TemporaryError) from tests.conftest import get_patched_exchange from tests.exchange.test_exchange import ccxt_exceptionhandlers @@ -149,3 +154,85 @@ def test_get_balances_prod(default_conf, mocker): assert balances['4ST']['used'] == 0.0 ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken", "get_balances", "fetch_balance") + + +def test_stoploss_order_kraken(default_conf, mocker): + api_mock = MagicMock() + order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) + order_type = 'stop-loss' + + api_mock.create_order = MagicMock(return_value={ + 'id': order_id, + 'info': { + 'foo': 'bar' + } + }) + + default_conf['dry_run'] = False + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) + + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + + # stoploss_on_exchange_limit_ratio is irrelevant for kraken market orders + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, + order_types={'stoploss_on_exchange_limit_ratio': 1.05}) + assert api_mock.create_order.call_count == 1 + + api_mock.create_order.reset_mock() + + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + assert 'id' in order + assert 'info' in order + assert order['id'] == order_id + assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' + assert api_mock.create_order.call_args_list[0][1]['type'] == order_type + assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' + assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 + assert api_mock.create_order.call_args_list[0][1]['price'] == 220 + assert api_mock.create_order.call_args_list[0][1]['params'] == {'trading_agreement': 'agree'} + + # test exception handling + with pytest.raises(DependencyException): + api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance")) + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + with pytest.raises(InvalidOrderException): + api_mock.create_order = MagicMock( + side_effect=ccxt.InvalidOrder("kraken Order would trigger immediately.")) + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + with pytest.raises(TemporaryError): + api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection")) + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + with pytest.raises(OperationalException, match=r".*DeadBeef.*"): + api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef")) + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + +def test_stoploss_order_dry_run_kraken(default_conf, mocker): + api_mock = MagicMock() + order_type = 'stop-loss' + default_conf['dry_run'] = True + mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) + + exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') + + api_mock.create_order.reset_mock() + + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + + assert 'id' in order + assert 'info' in order + assert 'type' in order + + assert order['type'] == order_type + assert order['price'] == 220 + assert order['amount'] == 1 From 7a22aaa11144dc95cb1f855642fdac555d866537 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 14:30:09 +0100 Subject: [PATCH 0294/1106] UPdate documentation to reflect that stoploss-on-exchange is also available for kraken --- docs/configuration.md | 2 +- docs/exchanges.md | 5 ++++- docs/stoploss.md | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index fe692eacb..f2d0fa5f2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -278,7 +278,7 @@ If this is configured, the following 4 values (`buy`, `sell`, `stoploss` and The below is the default which is used if this is not configured in either strategy or configuration file. Since `stoploss_on_exchange` uses limit orders, the exchange needs 2 prices, the stoploss_price and the Limit price. -`stoploss` defines the stop-price - and limit should be slightly below this. This defaults to 0.99 / 1%. +`stoploss` defines the stop-price - and limit should be slightly below this. This defaults to 0.99 / 1% (configurable via `stoploss_on_exchange_limit_ratio`). Calculation example: we bought the asset at 100$. Stop-price is 95$, then limit would be `95 * 0.99 = 94.05$` - so the stoploss will happen between 95$ and 94.05$. diff --git a/docs/exchanges.md b/docs/exchanges.md index 76fa81f4a..18a9f1cba 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -5,7 +5,7 @@ This page combines common gotchas and informations which are exchange-specific a ## Binance !!! Tip "Stoploss on Exchange" - Binance is currently the only exchange supporting `stoploss_on_exchange`. It provides great advantages, so we recommend to benefit from it. + Binance supports `stoploss_on_exchange` and uses stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it. ### Blacklists @@ -22,6 +22,9 @@ Binance has been split into 3, and users must use the correct ccxt exchange ID f ## Kraken +!!! Tip "Stoploss on Exchange" + Kraken supports `stoploss_on_exchange` and uses stop-loss-market orders. It provides great advantages, so we recommend to benefit from it, however since the resulting order is a stoploss-market order, sell-rates are not guaranteed, which makes this feature less secure than on other exchanges. This limitation is based on kraken's policy [source](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) and [source2](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) - which has stoploss-limit orders disabled. + ### Historic Kraken data The Kraken API does only provide 720 historic candles, which is sufficient for Freqtrade dry-run and live trade modes, but is a problem for backtesting. diff --git a/docs/stoploss.md b/docs/stoploss.md index 105488296..f6d56fd41 100644 --- a/docs/stoploss.md +++ b/docs/stoploss.md @@ -27,7 +27,7 @@ So this parameter will tell the bot how often it should update the stoploss orde This same logic will reapply a stoploss order on the exchange should you cancel it accidentally. !!! Note - Stoploss on exchange is only supported for Binance as of now. + Stoploss on exchange is only supported for Binance (stop-loss-limit) and Kraken (stop-loss-market) as of now. ## Static Stop Loss From cf9331919fdf658ee86a0b21642c8c717cf0d1b3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 19:54:30 +0100 Subject: [PATCH 0295/1106] move exchange-specific order-parsing to exchange class Related to stoploss_on_exchange in combination with trailing stoploss. Binance contains stopPrice in the info, while kraken returns the same value as "price". --- freqtrade/exchange/binance.py | 7 +++++++ freqtrade/exchange/exchange.py | 13 ++++++++++--- freqtrade/exchange/kraken.py | 7 +++++++ freqtrade/freqtradebot.py | 3 +-- tests/exchange/test_binance.py | 14 ++++++++++++++ tests/exchange/test_exchange.py | 3 +++ tests/exchange/test_kraken.py | 13 +++++++++++++ 7 files changed, 55 insertions(+), 5 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 8a3e28379..45102359d 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -32,6 +32,13 @@ class Binance(Exchange): return super().get_order_book(pair, limit) + def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: + """ + Verify stop_loss against stoploss-order value (limit or price) + Returns True if adjustment is necessary. + """ + return order['type'] == 'stop_loss_limit' and stop_loss > float(order['info']['stopPrice']) + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: """ creates a stoploss limit order. diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index bef92750c..a8df4c1bb 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -282,8 +282,8 @@ class Exchange: quote_currencies = self.get_quote_currencies() if stake_currency not in quote_currencies: raise OperationalException( - f"{stake_currency} is not available as stake on {self.name}. " - f"Available currencies are: {', '.join(quote_currencies)}") + f"{stake_currency} is not available as stake on {self.name}. " + f"Available currencies are: {', '.join(quote_currencies)}") def validate_pairs(self, pairs: List[str]) -> None: """ @@ -460,7 +460,7 @@ class Exchange: "status": "closed", "filled": closed_order["amount"], "remaining": 0 - }) + }) if closed_order["type"] in ["stop_loss_limit"]: closed_order["info"].update({"stopPrice": closed_order["price"]}) self._dry_run_open_orders[closed_order["id"]] = closed_order @@ -519,6 +519,13 @@ class Exchange: return self.create_order(pair, ordertype, 'sell', amount, rate, params) + def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: + """ + Verify stop_loss against stoploss-order value (limit or price) + Returns True if adjustment is necessary. + """ + raise OperationalException(f"stoploss is not implemented for {self.name}.") + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: """ creates a stoploss order. diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 88c414772..243f1a6d6 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -51,6 +51,13 @@ class Kraken(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e + def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: + """ + Verify stop_loss against stoploss-order value (limit or price) + Returns True if adjustment is necessary. + """ + return order['type'] == 'stop-loss' and stop_loss > float(order['price']) + def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: """ Creates a stoploss market order. diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a4b0ab806..fa9a8424a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -718,8 +718,7 @@ class FreqtradeBot: :param order: Current on exchange stoploss order :return: None """ - - if trade.stop_loss > float(order['info']['stopPrice']): + if self.exchange.stoploss_adjust(trade.stop_loss, order): # we check if the update is neccesary update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60) if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() >= update_beat: diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index a1b24913e..e4599dcd7 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -92,3 +92,17 @@ def test_stoploss_order_dry_run_binance(default_conf, mocker): assert order['type'] == order_type assert order['price'] == 220 assert order['amount'] == 1 + + +def test_stoploss_adjust_binance(mocker, default_conf): + exchange = get_patched_exchange(mocker, default_conf, id='binance') + order = { + 'type': 'stop_loss_limit', + 'price': 1500, + 'info': {'stopPrice': 1500}, + } + assert exchange.stoploss_adjust(1501, order) + assert not exchange.stoploss_adjust(1499, order) + # Test with invalid order case + order['type'] = 'stop_loss' + assert not exchange.stoploss_adjust(1501, order) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 680e69764..3a664a9ec 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1763,6 +1763,9 @@ def test_stoploss_order_unsupported_exchange(default_conf, mocker): with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"): exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"): + exchange.stoploss_adjust(1, {}) + def test_merge_ft_has_dict(default_conf, mocker): mocker.patch.multiple('freqtrade.exchange.Exchange', diff --git a/tests/exchange/test_kraken.py b/tests/exchange/test_kraken.py index 241d15772..d63dd66cc 100644 --- a/tests/exchange/test_kraken.py +++ b/tests/exchange/test_kraken.py @@ -236,3 +236,16 @@ def test_stoploss_order_dry_run_kraken(default_conf, mocker): assert order['type'] == order_type assert order['price'] == 220 assert order['amount'] == 1 + + +def test_stoploss_adjust_kraken(mocker, default_conf): + exchange = get_patched_exchange(mocker, default_conf, id='kraken') + order = { + 'type': 'stop-loss', + 'price': 1500, + } + assert exchange.stoploss_adjust(1501, order) + assert not exchange.stoploss_adjust(1499, order) + # Test with invalid order case ... + order['type'] = 'stop_loss_limit' + assert not exchange.stoploss_adjust(1501, order) From 10d9db72a851769c1996f132e170588b4f708ee2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 19 Jan 2020 20:06:04 +0100 Subject: [PATCH 0296/1106] Adjust tests slightly --- tests/test_freqtradebot.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a33d47f34..48bd2deb5 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1241,7 +1241,8 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss=stoploss + stoploss=stoploss, + stoploss_adjust=MagicMock(return_value=True), ) # enabling TSL @@ -1335,7 +1336,8 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss=stoploss + stoploss=stoploss, + stoploss_adjust=MagicMock(return_value=True), ) # enabling TSL @@ -1396,6 +1398,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, patch_edge(mocker) edge_conf['max_open_trades'] = float('inf') edge_conf['dry_run_wallet'] = 999.9 + edge_conf['exchange']['name'] = 'binance' mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=MagicMock(return_value={ @@ -1406,7 +1409,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, buy=MagicMock(return_value={'id': limit_buy_order['id']}), sell=MagicMock(return_value={'id': limit_sell_order['id']}), get_fee=fee, - stoploss=stoploss + stoploss=stoploss, ) # enabling TSL @@ -1459,7 +1462,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, cancel_order_mock = MagicMock() stoploss_order_mock = MagicMock() mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock) - mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss_order_mock) + mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock) # price goes down 5% mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ From 9474cb17922ac4b6a0969bf1617a42c1caa210d0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 07:48:46 +0000 Subject: [PATCH 0297/1106] Bump ccxt from 1.21.56 to 1.21.76 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.56 to 1.21.76. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.56...1.21.76) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 15a9d687f..daf4984c0 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.56 +ccxt==1.21.76 SQLAlchemy==1.3.12 python-telegram-bot==12.3.0 arrow==0.15.5 From 8d4515935ae9ac849798a7111b4aa3bff0a39802 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 07:49:18 +0000 Subject: [PATCH 0298/1106] Bump pytest from 5.3.2 to 5.3.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.2 to 5.3.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.3.2...5.3.3) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 16f9baf95..e602bf184 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 mypy==0.761 -pytest==5.3.2 +pytest==5.3.3 pytest-asyncio==0.10.0 pytest-cov==2.8.1 pytest-mock==2.0.0 From 6e3336cb30aee9a279d9fda3659695e916d36560 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 20 Jan 2020 20:10:06 +0100 Subject: [PATCH 0299/1106] Adapt test to verify behaviour of stoploss_on_exchange in dry-run --- tests/test_freqtradebot.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5a4820f2f..6c6bd1753 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1318,6 +1318,14 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, rate=0.00002344 * 0.95 * 0.99, stop_price=0.00002344 * 0.95) + # price fell below stoploss, so dry-run sells trade. + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ + 'bid': 0.00002144, + 'ask': 0.00002146, + 'last': 0.00002144 + })) + assert freqtrade.handle_trade(trade) is True + def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: From 099bbc5c7f56df2ce193c42c60c99c7c45ea7b85 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 20 Jan 2020 20:14:40 +0100 Subject: [PATCH 0300/1106] Fix bug when stoploss_on_exchange in combination with dry-run does not sell orders --- freqtrade/strategy/interface.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 7bd6a9ac5..27bc8280e 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -389,9 +389,11 @@ class IStrategy(ABC): trade.adjust_stop_loss(high or current_rate, stop_loss_value) # evaluate if the stoploss was hit if stoploss is not on exchange + # in Dry-Run, this handles stoploss logic as well, as the logic will not be different to + # regular stoploss handling. if ((self.stoploss is not None) and (trade.stop_loss >= current_rate) and - (not self.order_types.get('stoploss_on_exchange'))): + (not self.order_types.get('stoploss_on_exchange') or self.config['dry_run'])): sell_type = SellType.STOP_LOSS From 1bf475fa1a1f5281f01b1b6a8ab3104f7553c1e8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 20 Jan 2020 20:24:40 +0100 Subject: [PATCH 0301/1106] Remove .get calls for dry_run - it's a mandatory property --- freqtrade/freqtradebot.py | 5 ++--- freqtrade/rpc/rpc.py | 6 +++--- freqtrade/rpc/rpc_manager.py | 2 +- tests/test_configuration.py | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e712892f1..acff2b2ad 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -63,8 +63,7 @@ class FreqtradeBot: self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) - persistence.init(self.config.get('db_url', None), - clean_open_orders=self.config.get('dry_run', False)) + persistence.init(self.config.get('db_url', None), clean_open_orders=self.config['dry_run']) self.wallets = Wallets(self.config, self.exchange) @@ -930,7 +929,7 @@ class FreqtradeBot: # if stoploss is on exchange and we are on dry_run mode, # we consider the sell price stop price - if self.config.get('dry_run', False) and sell_type == 'stoploss' \ + if self.config['dry_run'] and sell_type == 'stoploss' \ and self.strategy.order_types['stoploss_on_exchange']: limit = trade.stop_loss diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 0469d418d..d58b99f39 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -88,7 +88,7 @@ class RPC: """ config = self._freqtrade.config val = { - 'dry_run': config.get('dry_run', False), + 'dry_run': config['dry_run'], 'stake_currency': config['stake_currency'], 'stake_amount': config['stake_amount'], 'minimal_roi': config['minimal_roi'].copy(), @@ -337,7 +337,7 @@ class RPC: 'stake': stake_currency, }) if total == 0.0: - if self._freqtrade.config.get('dry_run', False): + if self._freqtrade.config['dry_run']: raise RPCException('Running in Dry Run, balances are not available.') else: raise RPCException('All balances are zero.') @@ -351,7 +351,7 @@ class RPC: 'symbol': symbol, 'value': value, 'stake': stake_currency, - 'note': 'Simulated balances' if self._freqtrade.config.get('dry_run', False) else '' + 'note': 'Simulated balances' if self._freqtrade.config['dry_run'] else '' } def _rpc_start(self) -> Dict[str, str]: diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index cb9e697e9..f687fe4d1 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -62,7 +62,7 @@ class RPCManager: logger.error(f"Message type {msg['type']} not implemented by handler {mod.name}.") def startup_messages(self, config, pairlist) -> None: - if config.get('dry_run', False): + if config['dry_run']: self.send_msg({ 'type': RPCMessageType.WARNING_NOTIFICATION, 'status': 'Dry run is enabled. All trades are simulated.' diff --git a/tests/test_configuration.py b/tests/test_configuration.py index a4d4c4abc..cbcd6416a 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -323,7 +323,7 @@ def test_load_dry_run(default_conf, mocker, config_value, expected, arglist) -> configuration = Configuration(Arguments(arglist).get_parsed_arg()) validated_conf = configuration.load_config() - assert validated_conf.get('dry_run') is expected + assert validated_conf['dry_run'] is expected def test_load_custom_strategy(default_conf, mocker) -> None: From c1c2717bc9a9216c042a7bec2efe94c15bfc4f18 Mon Sep 17 00:00:00 2001 From: Daniel Goller Date: Tue, 21 Jan 2020 15:49:24 +0000 Subject: [PATCH 0302/1106] added missing word in hyperopt loss example --- freqtrade/templates/sample_hyperopt_loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/templates/sample_hyperopt_loss.py b/freqtrade/templates/sample_hyperopt_loss.py index 5a2fb72b6..ee2c28bc9 100644 --- a/freqtrade/templates/sample_hyperopt_loss.py +++ b/freqtrade/templates/sample_hyperopt_loss.py @@ -27,7 +27,7 @@ class SampleHyperOptLoss(IHyperOptLoss): Defines the default loss function for hyperopt This is intended to give you some inspiration for your own loss function. - The Function needs to return a number (float) - which becomes for better backtest results. + The Function needs to return a number (float) - which becomes smaller for better backtest results. """ @staticmethod From bff0a0953794c1de68c582c8ba50a6f25845086f Mon Sep 17 00:00:00 2001 From: Daniel Goller Date: Tue, 21 Jan 2020 16:14:19 +0000 Subject: [PATCH 0303/1106] line was too long --- freqtrade/templates/sample_hyperopt_loss.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/templates/sample_hyperopt_loss.py b/freqtrade/templates/sample_hyperopt_loss.py index ee2c28bc9..4173d97f5 100644 --- a/freqtrade/templates/sample_hyperopt_loss.py +++ b/freqtrade/templates/sample_hyperopt_loss.py @@ -27,7 +27,8 @@ class SampleHyperOptLoss(IHyperOptLoss): Defines the default loss function for hyperopt This is intended to give you some inspiration for your own loss function. - The Function needs to return a number (float) - which becomes smaller for better backtest results. + The Function needs to return a number (float) - which becomes smaller for better backtest + results. """ @staticmethod From 7d2d0235a0407b564038f02b4834ab365cc72f8a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 06:08:34 +0100 Subject: [PATCH 0304/1106] Fix typo in sell-reason table generation --- freqtrade/optimize/optimize_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 3801546b1..67056eaa9 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -70,7 +70,7 @@ def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) - for reason, count in results['sell_reason'].value_counts().iteritems(): result = results.loc[results['sell_reason'] == reason] profit = len(result[result['profit_abs'] >= 0]) - loss = len(result[results['profit_abs'] < 0]) + loss = len(result[result['profit_abs'] < 0]) profit_mean = round(result['profit_percent'].mean() * 100.0, 2) tabular_data.append([reason.value, count, profit, loss, profit_mean]) return tabulate(tabular_data, headers=headers, tablefmt="pipe") From e13045b599f921e749e494dd49b13cc00d1d9e57 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 06:17:13 +0100 Subject: [PATCH 0305/1106] upgrade pip in windows environment --- build_helpers/install_windows.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/build_helpers/install_windows.ps1 b/build_helpers/install_windows.ps1 index 30427c3cc..138fba208 100644 --- a/build_helpers/install_windows.ps1 +++ b/build_helpers/install_windows.ps1 @@ -2,6 +2,7 @@ # Downloaded from https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib # Invoke-WebRequest -Uri "https://download.lfd.uci.edu/pythonlibs/xxxxxxx/TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl" -OutFile "TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl" +python -m pip install --upgrade pip pip install build_helpers\TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl pip install -r requirements-dev.txt From 8a940eb0c1d7cc15bb7cc559875259f819dc2ad2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 14:46:28 +0100 Subject: [PATCH 0306/1106] Align price finding function name on buy side with get_sell_rate --- freqtrade/freqtradebot.py | 4 ++-- tests/test_freqtradebot.py | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index acff2b2ad..387ddb063 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -218,7 +218,7 @@ class FreqtradeBot: return trades_created - def get_target_bid(self, pair: str, tick: Dict = None) -> float: + def get_buy_rate(self, pair: str, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price :return: float: Price @@ -435,7 +435,7 @@ class FreqtradeBot: buy_limit_requested = price else: # Calculate price - buy_limit_requested = self.get_target_bid(pair) + buy_limit_requested = self.get_buy_rate(pair) min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested) if min_stake_amount is not None and min_stake_amount > stake_amount: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6c6bd1753..d00fab9c7 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -912,7 +912,7 @@ def test_balance_fully_ask_side(mocker, default_conf) -> None: mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 20, 'last': 10})) - assert freqtrade.get_target_bid('ETH/BTC') == 20 + assert freqtrade.get_buy_rate('ETH/BTC') == 20 def test_balance_fully_last_side(mocker, default_conf) -> None: @@ -921,7 +921,7 @@ def test_balance_fully_last_side(mocker, default_conf) -> None: mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 20, 'last': 10})) - assert freqtrade.get_target_bid('ETH/BTC') == 10 + assert freqtrade.get_buy_rate('ETH/BTC') == 10 def test_balance_bigger_last_ask(mocker, default_conf) -> None: @@ -929,7 +929,7 @@ def test_balance_bigger_last_ask(mocker, default_conf) -> None: freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': 5, 'last': 10})) - assert freqtrade.get_target_bid('ETH/BTC') == 5 + assert freqtrade.get_buy_rate('ETH/BTC') == 5 def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: @@ -938,10 +938,10 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: freqtrade = FreqtradeBot(default_conf) stake_amount = 2 bid = 0.11 - get_bid = MagicMock(return_value=bid) + buy_rate_mock = MagicMock(return_value=bid) mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', - get_target_bid=get_bid, + get_buy_rate=buy_rate_mock, _get_min_pair_stake_amount=MagicMock(return_value=1) ) buy_mm = MagicMock(return_value={'id': limit_buy_order['id']}) @@ -958,7 +958,7 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: pair = 'ETH/BTC' assert freqtrade.execute_buy(pair, stake_amount) - assert get_bid.call_count == 1 + assert buy_rate_mock.call_count == 1 assert buy_mm.call_count == 1 call_args = buy_mm.call_args_list[0][1] assert call_args['pair'] == pair @@ -975,8 +975,8 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: # Test calling with price fix_price = 0.06 assert freqtrade.execute_buy(pair, stake_amount, fix_price) - # Make sure get_target_bid wasn't called again - assert get_bid.call_count == 1 + # Make sure get_buy_rate wasn't called again + assert buy_rate_mock.call_count == 1 assert buy_mm.call_count == 2 call_args = buy_mm.call_args_list[1][1] @@ -3500,7 +3500,7 @@ def test_order_book_depth_of_market_high_delta(default_conf, ticker, limit_buy_o def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2) -> None: """ - test if function get_target_bid will return the order book price + test if function get_buy_rate will return the order book price instead of the ask rate """ patch_exchange(mocker) @@ -3518,13 +3518,13 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2) -> None: default_conf['telegram']['enabled'] = False freqtrade = FreqtradeBot(default_conf) - assert freqtrade.get_target_bid('ETH/BTC') == 0.043935 + assert freqtrade.get_buy_rate('ETH/BTC') == 0.043935 assert ticker_mock.call_count == 0 def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2) -> None: """ - test if function get_target_bid will return the ask rate (since its value is lower) + test if function get_buy_rate will return the ask rate (since its value is lower) instead of the order book rate (even if enabled) """ patch_exchange(mocker) @@ -3543,7 +3543,7 @@ def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2) -> None: freqtrade = FreqtradeBot(default_conf) # orderbook shall be used even if tickers would be lower. - assert freqtrade.get_target_bid('ETH/BTC') != 0.042 + assert freqtrade.get_buy_rate('ETH/BTC') != 0.042 assert ticker_mock.call_count == 0 From f36bc80ad12a9784e2d20a9b9b9a7d10e2d62208 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 19:43:02 +0100 Subject: [PATCH 0307/1106] Add parametrized tests for get_buy_rate --- tests/test_freqtradebot.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index d00fab9c7..e0f2ecd3a 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -906,30 +906,22 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: assert ("ETH/BTC", default_conf["ticker_interval"]) in refresh_mock.call_args[0][0] -def test_balance_fully_ask_side(mocker, default_conf) -> None: - default_conf['bid_strategy']['ask_last_balance'] = 0.0 +@pytest.mark.parametrize("ask,last,last_ab,expected", [ + (20, 10, 0.0, 20), # Full ask side + (20, 10, 1.0, 10), # Full last side + (20, 10, 0.5, 15), # Between ask and last + (20, 10, 0.7, 13), # Between ask and last + (20, 10, 0.3, 17), # Between ask and last + (5, 10, 1.0, 5), # last bigger than ask + (5, 10, 0.5, 5), # last bigger than ask +]) +def test_get_buy_rate(mocker, default_conf, ask, last, last_ab, expected) -> None: + default_conf['bid_strategy']['ask_last_balance'] = last_ab freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', - MagicMock(return_value={'ask': 20, 'last': 10})) + MagicMock(return_value={'ask': ask, 'last': last})) - assert freqtrade.get_buy_rate('ETH/BTC') == 20 - - -def test_balance_fully_last_side(mocker, default_conf) -> None: - default_conf['bid_strategy']['ask_last_balance'] = 1.0 - freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', - MagicMock(return_value={'ask': 20, 'last': 10})) - - assert freqtrade.get_buy_rate('ETH/BTC') == 10 - - -def test_balance_bigger_last_ask(mocker, default_conf) -> None: - default_conf['bid_strategy']['ask_last_balance'] = 1.0 - freqtrade = get_patched_freqtradebot(mocker, default_conf) - mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', - MagicMock(return_value={'ask': 5, 'last': 10})) - assert freqtrade.get_buy_rate('ETH/BTC') == 5 + assert freqtrade.get_buy_rate('ETH/BTC') == expected def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: From 58ceda4b903172d153d34337c9bb4f72a2dda4dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 19:54:55 +0100 Subject: [PATCH 0308/1106] update wallets after forcesell --- freqtrade/rpc/rpc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index d58b99f39..c38f36c1d 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -425,6 +425,7 @@ class RPC: for trade in Trade.get_open_trades(): _exec_forcesell(trade) Trade.session.flush() + self._freqtrade.wallets.update() return {'result': 'Created sell orders for all open trades.'} # Query for trade @@ -437,6 +438,7 @@ class RPC: _exec_forcesell(trade) Trade.session.flush() + self._freqtrade.wallets.update() return {'result': f'Created sell order for trade {trade_id}.'} def _rpc_forcebuy(self, pair: str, price: Optional[float]) -> Optional[Trade]: From aad10ceee35303370c4a01a1b88e92691b01b615 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Jan 2020 20:50:09 +0100 Subject: [PATCH 0309/1106] Add threading lock object for /forcesell Protects against stoploss_on_exchange order recreation in case of /forcesell (it's a timing issue, so may or may not happen). --- freqtrade/freqtradebot.py | 16 +++++++++++----- freqtrade/rpc/rpc.py | 37 +++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 387ddb063..e3856e200 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -7,6 +7,7 @@ import traceback from datetime import datetime from math import isclose from os import getpid +from threading import Lock from typing import Any, Dict, List, Optional, Tuple import arrow @@ -27,7 +28,6 @@ from freqtrade.state import State from freqtrade.strategy.interface import IStrategy, SellType from freqtrade.wallets import Wallets - logger = logging.getLogger(__name__) @@ -92,6 +92,8 @@ class FreqtradeBot: # the initial state of the bot. # Keep this at the end of this initialization method. self.rpc: RPCManager = RPCManager(self) + # Protect sell-logic from forcesell and viceversa + self._sell_lock = Lock() def cleanup(self) -> None: """ @@ -132,8 +134,12 @@ class FreqtradeBot: self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist), self.strategy.informative_pairs()) - # First process current opened trades (positions) - self.exit_positions(trades) + # Protect from collisions with forcesell. + # Without this, freqtrade my try to recreate stoploss_on_exchange orders + # while selling is in process, since telegram messages arrive in an different thread. + with self._sell_lock: + # First process current opened trades (positions) + self.exit_positions(trades) # Then looking for buy opportunities if self.get_free_open_trades(): @@ -748,8 +754,8 @@ class FreqtradeBot: Check and execute sell """ should_sell = self.strategy.should_sell( - trade, sell_rate, datetime.utcnow(), buy, sell, - force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0 + trade, sell_rate, datetime.utcnow(), buy, sell, + force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0 ) if should_sell.sell_flag: diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index c38f36c1d..41097c211 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -420,26 +420,27 @@ class RPC: if self._freqtrade.state != State.RUNNING: raise RPCException('trader is not running') - if trade_id == 'all': - # Execute sell for all open orders - for trade in Trade.get_open_trades(): - _exec_forcesell(trade) + with self._freqtrade._sell_lock: + if trade_id == 'all': + # Execute sell for all open orders + for trade in Trade.get_open_trades(): + _exec_forcesell(trade) + Trade.session.flush() + self._freqtrade.wallets.update() + return {'result': 'Created sell orders for all open trades.'} + + # Query for trade + trade = Trade.get_trades( + trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ] + ).first() + if not trade: + logger.warning('forcesell: Invalid argument received') + raise RPCException('invalid argument') + + _exec_forcesell(trade) Trade.session.flush() self._freqtrade.wallets.update() - return {'result': 'Created sell orders for all open trades.'} - - # Query for trade - trade = Trade.get_trades( - trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ] - ).first() - if not trade: - logger.warning('forcesell: Invalid argument received') - raise RPCException('invalid argument') - - _exec_forcesell(trade) - Trade.session.flush() - self._freqtrade.wallets.update() - return {'result': f'Created sell order for trade {trade_id}.'} + return {'result': f'Created sell order for trade {trade_id}.'} def _rpc_forcebuy(self, pair: str, price: Optional[float]) -> Optional[Trade]: """ From f5a44e4fc440ff4bedeb07617d33928d3017d858 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Jan 2020 19:38:35 +0100 Subject: [PATCH 0310/1106] open_order_id should be None when handling stoploss orders --- tests/test_freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e0f2ecd3a..a80bb7452 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1165,7 +1165,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, freqtrade.enter_positions() trade = Trade.query.first() trade.is_open = True - trade.open_order_id = '12345' + trade.open_order_id = None trade.stoploss_order_id = 100 assert trade From a83de241e41155dbef49ffd858e994033c5a1cfa Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Jan 2020 19:40:31 +0100 Subject: [PATCH 0311/1106] Check for closed stoploss-orders first --- freqtrade/freqtradebot.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e3856e200..5505005ff 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -679,6 +679,16 @@ class FreqtradeBot: except InvalidOrderException as exception: logger.warning('Unable to fetch stoploss order: %s', exception) + # We check if stoploss order is fulfilled + if stoploss_order and stoploss_order['status'] == 'closed': + trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value + trade.update(stoploss_order) + # Lock pair for one candle to prevent immediate rebuys + self.strategy.lock_pair(trade.pair, + timeframe_to_next_date(self.config['ticker_interval'])) + self._notify_sell(trade, "stoploss") + return True + # If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange if (not trade.open_order_id and not stoploss_order): @@ -699,16 +709,6 @@ class FreqtradeBot: trade.stoploss_order_id = None logger.warning('Stoploss order was cancelled, but unable to recreate one.') - # We check if stoploss order is fulfilled - if stoploss_order and stoploss_order['status'] == 'closed': - trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value - trade.update(stoploss_order) - # Lock pair for one candle to prevent immediate rebuys - self.strategy.lock_pair(trade.pair, - timeframe_to_next_date(self.config['ticker_interval'])) - self._notify_sell(trade, "stoploss") - return True - # Finally we check if stoploss on exchange should be moved up because of trailing. if stoploss_order and self.config.get('trailing_stop', False): # if trailing stoploss is enabled we check if stoploss value has changed From ea5ac1efb531058cf4ed67ba4fccd4306cad8af5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Jan 2020 20:24:23 +0100 Subject: [PATCH 0312/1106] Don't handle stoploss if there is an open regular order --- freqtrade/freqtradebot.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5505005ff..c150d1aa9 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -689,8 +689,13 @@ class FreqtradeBot: self._notify_sell(trade, "stoploss") return True + if trade.open_order_id: + # Trade has an open Buy or Sell order, Stoploss-handling can't happen in this case + # as the Amount on the exchange is tied up in another trade. + return False + # If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange - if (not trade.open_order_id and not stoploss_order): + if (not stoploss_order): stoploss = self.edge.stoploss(pair=trade.pair) if self.edge else self.strategy.stoploss From 70b9bd9c0e7d2b37a4386f0809af7237a9dada6a Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Jan 2020 20:36:48 +0100 Subject: [PATCH 0313/1106] Verify if trade is closed before acting on Stoploss_on_exchange --- freqtrade/freqtradebot.py | 3 ++- tests/test_freqtradebot.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c150d1aa9..9f06cbb67 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -689,9 +689,10 @@ class FreqtradeBot: self._notify_sell(trade, "stoploss") return True - if trade.open_order_id: + if trade.open_order_id or not trade.is_open: # Trade has an open Buy or Sell order, Stoploss-handling can't happen in this case # as the Amount on the exchange is tied up in another trade. + # The trade can be closed already (sell-order fill confirmation came in this iteration) return False # If buy order is fulfilled but there is no stoploss, we add a stoploss on exchange diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a80bb7452..65b5adda5 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1127,6 +1127,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, 'freqtrade.exchange.Exchange.stoploss_limit', side_effect=DependencyException() ) + trade.is_open = True freqtrade.handle_stoploss_on_exchange(trade) assert log_has('Unable to place a stoploss order on exchange.', caplog) assert trade.stoploss_order_id is None From 72c273aaedc237e70e049a67db4d469faf116c03 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Jan 2020 21:07:11 +0100 Subject: [PATCH 0314/1106] Add test for closed trade case --- tests/test_freqtradebot.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 65b5adda5..147ad9d7c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1141,6 +1141,16 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, freqtrade.handle_stoploss_on_exchange(trade) assert stoploss_limit.call_count == 1 + # Sixth case: Closed Trade + # Should not create new order + trade.stoploss_order_id = None + trade.is_open = False + stoploss_limit.reset_mock() + mocker.patch('freqtrade.exchange.Exchange.get_order') + mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + assert freqtrade.handle_stoploss_on_exchange(trade) is False + assert stoploss_limit.call_count == 0 + def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, limit_buy_order, limit_sell_order) -> None: From f8db7f170981898fcc7509b59acdb25b1f01550b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 25 Jan 2020 04:17:41 +0100 Subject: [PATCH 0315/1106] added ask price, bid price, immediate ask quantity, and immediate bid quantity to check_depth_of_market_buy. also added a line that mentions if delta condition was satisfied or not. --- freqtrade/freqtradebot.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e3856e200..f1584c731 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -423,11 +423,14 @@ class FreqtradeBot: order_book_bids = order_book_data_frame['b_size'].sum() order_book_asks = order_book_data_frame['a_size'].sum() bids_ask_delta = order_book_bids / order_book_asks - logger.info('bids: %s, asks: %s, delta: %s', order_book_bids, - order_book_asks, bids_ask_delta) + logger.info('bids: %s, asks: %s, delta: %s, askprice: %s, bidprice: %s, immediate askquantity: %s, immediate bidquantity: %s', + order_book_bids, order_book_asks, bids_ask_delta, order_book['asks'][0][0], order_book['bids'][0][0], order_book['asks'][0][1], order_book['bids'][0][1]) if bids_ask_delta >= conf_bids_to_ask_delta: + logger.info('bids to ask delta DOES satisfy condition.') return True - return False + else: + logger.info('bids to ask delta DOES NOT satisfy condition.') + return False def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = None) -> bool: """ From f4c7edf551442f369c5f451d5cd66000f196d728 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 14 Dec 2019 02:12:16 +0300 Subject: [PATCH 0316/1106] No args for backtest(), use arguments --- freqtrade/optimize/backtesting.py | 53 +++++++++++++++---------------- freqtrade/optimize/hyperopt.py | 14 ++++---- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 1070f2481..92129b324 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -279,30 +279,28 @@ class Backtesting: return bt_res return None - def backtest(self, args: Dict) -> DataFrame: + def backtest(self, processed: Dict, stake_amount: int, + start_date, end_date, + max_open_trades: int = 0, position_stacking: bool = False) -> DataFrame: """ - Implements backtesting functionality + Implement backtesting functionality NOTE: This method is used by Hyperopt at each iteration. Please keep it optimized. Of course try to not have ugly code. By some accessor are sometime slower than functions. - Avoid, logging on this method + Avoid extensive logging in this method and functions it calls. - :param args: a dict containing: - stake_amount: btc amount to use for each trade - processed: a processed dictionary with format {pair, data} - max_open_trades: maximum number of concurrent trades (default: 0, disabled) - position_stacking: do we allow position stacking? (default: False) - :return: DataFrame + :param processed: a processed dictionary with format {pair, data} + :param stake_amount: amount to use for each trade + :param start_date: backtesting timerange start datetime + :param end_date: backtesting timerange end datetime + :param max_open_trades: maximum number of concurrent trades, <= 0 means unlimited + :param position_stacking: do we allow position stacking? + :return: DataFrame with trades (results of backtesting) """ - # Arguments are long and noisy, so this is commented out. - # Uncomment if you need to debug the backtest() method. - # logger.debug(f"Start backtest, args: {args}") - processed = args['processed'] - stake_amount = args['stake_amount'] - max_open_trades = args.get('max_open_trades', 0) - position_stacking = args.get('position_stacking', False) - start_date = args['start_date'] - end_date = args['end_date'] + logger.debug(f"Run backtest, stake_amount: {stake_amount}, " + f"start_date: {start_date}, end_date: {end_date}, " + f"max_open_trades: {max_open_trades}, position_stacking: {position_stacking}" + ) trades = [] trade_count_lock: Dict = {} @@ -369,18 +367,21 @@ class Backtesting: def start(self) -> None: """ - Run a backtesting end-to-end + Run backtesting end-to-end :return: None """ data: Dict[str, Any] = {} + logger.info('Using stake_currency: %s ...', self.config['stake_currency']) logger.info('Using stake_amount: %s ...', self.config['stake_amount']) + # Use max_open_trades in backtesting, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): max_open_trades = self.config['max_open_trades'] else: logger.info('Ignoring max_open_trades (--disable-max-market-positions was used) ...') max_open_trades = 0 + position_stacking = self.config.get('position_stacking', False) data, timerange = self.load_bt_data() @@ -403,14 +404,12 @@ class Backtesting: ) # Execute backtest and print results all_results[self.strategy.get_strategy_name()] = self.backtest( - { - 'stake_amount': self.config.get('stake_amount'), - 'processed': preprocessed, - 'max_open_trades': max_open_trades, - 'position_stacking': self.config.get('position_stacking', False), - 'start_date': min_date, - 'end_date': max_date, - } + processed=preprocessed, + stake_amount=self.config.get('stake_amount'), + start_date=min_date, + end_date=max_date, + max_open_trades=max_open_trades, + position_stacking=position_stacking, ) for strategy, results in all_results.items(): diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a8f1a71ef..525f491f3 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -372,14 +372,12 @@ class Hyperopt: min_date, max_date = get_timerange(processed) backtesting_results = self.backtesting.backtest( - { - 'stake_amount': self.config['stake_amount'], - 'processed': processed, - 'max_open_trades': self.max_open_trades, - 'position_stacking': self.position_stacking, - 'start_date': min_date, - 'end_date': max_date, - } + processed=processed, + stake_amount=self.config['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=self.max_open_trades, + position_stacking=self.position_stacking, ) return self._get_results_dict(backtesting_results, min_date, max_date, params_dict, params_details) From 52f0ed53109e1a4aa8429510321b4a6fe1f08660 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 14 Dec 2019 02:12:44 +0300 Subject: [PATCH 0317/1106] Adjust tests --- tests/optimize/test_backtest_detail.py | 12 ++--- tests/optimize/test_backtesting.py | 73 ++++++++++++-------------- 2 files changed, 38 insertions(+), 47 deletions(-) diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 47cb9f353..bd2765430 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -382,13 +382,11 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None: data_processed = {pair: frame.copy()} min_date, max_date = get_timerange({pair: frame}) results = backtesting.backtest( - { - 'stake_amount': default_conf['stake_amount'], - 'processed': data_processed, - 'max_open_trades': 10, - 'start_date': min_date, - 'end_date': max_date, - } + processed=data_processed, + stake_amount=default_conf['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=10, ) assert len(results) == len(data.trades) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 83d212e3d..acbc44e21 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -103,14 +103,12 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None: min_date, max_date = get_timerange(processed) assert isinstance(processed, dict) results = backtesting.backtest( - { - 'stake_amount': config['stake_amount'], - 'processed': processed, - 'max_open_trades': 1, - 'position_stacking': False, - 'start_date': min_date, - 'end_date': max_date, - } + processed=processed, + stake_amount=config['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=1, + position_stacking=False, ) # results :: assert len(results) == num_results @@ -132,7 +130,7 @@ def _load_pair_as_ticks(pair, tickfreq): # FIX: fixturize this? -def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC', record=None): +def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'): data = history.load_data(datadir=datadir, timeframe='1m', pairs=[pair]) data = trim_dictlist(data, -201) patch_exchange(mocker) @@ -140,13 +138,12 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC', record= processed = backtesting.strategy.tickerdata_to_dataframe(data) min_date, max_date = get_timerange(processed) return { - 'stake_amount': conf['stake_amount'], 'processed': processed, - 'max_open_trades': 10, - 'position_stacking': False, - 'record': record, + 'stake_amount': conf['stake_amount'], 'start_date': min_date, 'end_date': max_date, + 'max_open_trades': 10, + 'position_stacking': False, } @@ -422,14 +419,12 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None: data_processed = backtesting.strategy.tickerdata_to_dataframe(data) min_date, max_date = get_timerange(data_processed) results = backtesting.backtest( - { - 'stake_amount': default_conf['stake_amount'], - 'processed': data_processed, - 'max_open_trades': 10, - 'position_stacking': False, - 'start_date': min_date, - 'end_date': max_date, - } + processed=data_processed, + stake_amount=default_conf['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=10, + position_stacking=False, ) assert not results.empty assert len(results) == 2 @@ -478,14 +473,12 @@ def test_backtest_1min_ticker_interval(default_conf, fee, mocker, testdatadir) - processed = backtesting.strategy.tickerdata_to_dataframe(data) min_date, max_date = get_timerange(processed) results = backtesting.backtest( - { - 'stake_amount': default_conf['stake_amount'], - 'processed': processed, - 'max_open_trades': 1, - 'position_stacking': False, - 'start_date': min_date, - 'end_date': max_date, - } + processed=processed, + stake_amount=default_conf['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=1, + position_stacking=False, ) assert not results.empty assert len(results) == 1 @@ -525,7 +518,7 @@ def test_backtest_clash_buy_sell(mocker, default_conf, testdatadir): backtesting = Backtesting(default_conf) backtesting.strategy.advise_buy = fun # Override backtesting.strategy.advise_sell = fun # Override - results = backtesting.backtest(backtest_conf) + results = backtesting.backtest(**backtest_conf) assert results.empty @@ -540,7 +533,7 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir): backtesting = Backtesting(default_conf) backtesting.strategy.advise_buy = fun # Override backtesting.strategy.advise_sell = fun # Override - results = backtesting.backtest(backtest_conf) + results = backtesting.backtest(**backtest_conf) assert results.empty @@ -553,7 +546,7 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir): backtesting = Backtesting(default_conf) backtesting.strategy.advise_buy = _trend_alternate # Override backtesting.strategy.advise_sell = _trend_alternate # Override - results = backtesting.backtest(backtest_conf) + results = backtesting.backtest(**backtest_conf) backtesting._store_backtest_result("test_.json", results) # 200 candles in backtest data # won't buy on first (shifted by 1) @@ -598,15 +591,15 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) data_processed = backtesting.strategy.tickerdata_to_dataframe(data) min_date, max_date = get_timerange(data_processed) backtest_conf = { - 'stake_amount': default_conf['stake_amount'], 'processed': data_processed, - 'max_open_trades': 3, - 'position_stacking': False, + 'stake_amount': default_conf['stake_amount'], 'start_date': min_date, 'end_date': max_date, + 'max_open_trades': 3, + 'position_stacking': False, } - results = backtesting.backtest(backtest_conf) + results = backtesting.backtest(**backtest_conf) # Make sure we have parallel trades assert len(evaluate_result_multi(results, '5m', 2)) > 0 @@ -614,14 +607,14 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) assert len(evaluate_result_multi(results, '5m', 3)) == 0 backtest_conf = { - 'stake_amount': default_conf['stake_amount'], 'processed': data_processed, - 'max_open_trades': 1, - 'position_stacking': False, + 'stake_amount': default_conf['stake_amount'], 'start_date': min_date, 'end_date': max_date, + 'max_open_trades': 1, + 'position_stacking': False, } - results = backtesting.backtest(backtest_conf) + results = backtesting.backtest(**backtest_conf) assert len(evaluate_result_multi(results, '5m', 1)) == 0 From bd4dd8403b0b6223bff4ef494f28c15c506caf75 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Jan 2020 12:48:13 +0100 Subject: [PATCH 0318/1106] Fix type-errors with stake_amount --- freqtrade/optimize/backtesting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 92129b324..cdf74f65f 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -279,7 +279,7 @@ class Backtesting: return bt_res return None - def backtest(self, processed: Dict, stake_amount: int, + def backtest(self, processed: Dict, stake_amount: float, start_date, end_date, max_open_trades: int = 0, position_stacking: bool = False) -> DataFrame: """ @@ -300,7 +300,7 @@ class Backtesting: logger.debug(f"Run backtest, stake_amount: {stake_amount}, " f"start_date: {start_date}, end_date: {end_date}, " f"max_open_trades: {max_open_trades}, position_stacking: {position_stacking}" - ) + ) trades = [] trade_count_lock: Dict = {} @@ -405,7 +405,7 @@ class Backtesting: # Execute backtest and print results all_results[self.strategy.get_strategy_name()] = self.backtest( processed=preprocessed, - stake_amount=self.config.get('stake_amount'), + stake_amount=self.config['stake_amount'], start_date=min_date, end_date=max_date, max_open_trades=max_open_trades, From a3ac05cc16f3b9fd684fd0330f9b5e3191a34d4a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Jan 2020 13:38:13 +0100 Subject: [PATCH 0319/1106] Fix missed mock --- tests/test_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index e145a8470..7ca2cac5a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -665,11 +665,11 @@ def test_start_list_strategies(mocker, caplog, capsys): assert "DefaultStrategy" in captured.out -def test_start_test_pairlist(mocker, caplog, markets, tickers, default_conf, capsys): +def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): + patch_exchange(mocker, mock_markets=True) mocker.patch.multiple('freqtrade.exchange.Exchange', - markets=PropertyMock(return_value=markets), exchange_has=MagicMock(return_value=True), - get_tickers=tickers + get_tickers=tickers, ) default_conf['pairlists'] = [ From 3f2542fcbcf185ac61668f1394c781da5c7ef421 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 10:44:42 +0100 Subject: [PATCH 0320/1106] Move edge-module out of __init__.py --- freqtrade/edge/__init__.py | 465 +---------------------------- freqtrade/edge/edge_positioning.py | 464 ++++++++++++++++++++++++++++ 2 files changed, 465 insertions(+), 464 deletions(-) create mode 100644 freqtrade/edge/edge_positioning.py diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 15883357b..d275a80e3 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -1,464 +1 @@ -# pragma pylint: disable=W0603 -""" Edge positioning package """ -import logging -from typing import Any, Dict, NamedTuple - -import arrow -import numpy as np -import utils_find_1st as utf1st -from pandas import DataFrame - -from freqtrade import constants -from freqtrade.configuration import TimeRange -from freqtrade.data import history -from freqtrade.exceptions import OperationalException -from freqtrade.strategy.interface import SellType - -logger = logging.getLogger(__name__) - - -class PairInfo(NamedTuple): - stoploss: float - winrate: float - risk_reward_ratio: float - required_risk_reward: float - expectancy: float - nb_trades: int - avg_trade_duration: float - - -class Edge: - """ - Calculates Win Rate, Risk Reward Ratio, Expectancy - against historical data for a give set of markets and a strategy - it then adjusts stoploss and position size accordingly - and force it into the strategy - Author: https://github.com/mishaker - """ - - config: Dict = {} - _cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs - - def __init__(self, config: Dict[str, Any], exchange, strategy) -> None: - - self.config = config - self.exchange = exchange - self.strategy = strategy - - self.edge_config = self.config.get('edge', {}) - self._cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs - self._final_pairs: list = [] - - # checking max_open_trades. it should be -1 as with Edge - # the number of trades is determined by position size - if self.config['max_open_trades'] != float('inf'): - logger.critical('max_open_trades should be -1 in config !') - - if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: - raise OperationalException('Edge works only with unlimited stake amount') - - # Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future. - self._capital_percentage: float = self.edge_config.get( - 'capital_available_percentage', self.config['tradable_balance_ratio']) - self._allowed_risk: float = self.edge_config.get('allowed_risk') - self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14) - self._last_updated: int = 0 # Timestamp of pairs last updated time - self._refresh_pairs = True - - self._stoploss_range_min = float(self.edge_config.get('stoploss_range_min', -0.01)) - self._stoploss_range_max = float(self.edge_config.get('stoploss_range_max', -0.05)) - self._stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001)) - - # calculating stoploss range - self._stoploss_range = np.arange( - self._stoploss_range_min, - self._stoploss_range_max, - self._stoploss_range_step - ) - - self._timerange: TimeRange = TimeRange.parse_timerange("%s-" % arrow.now().shift( - days=-1 * self._since_number_of_days).format('YYYYMMDD')) - if config.get('fee'): - self.fee = config['fee'] - else: - self.fee = self.exchange.get_fee(symbol=self.config['exchange']['pair_whitelist'][0]) - - def calculate(self) -> bool: - pairs = self.config['exchange']['pair_whitelist'] - heartbeat = self.edge_config.get('process_throttle_secs') - - if (self._last_updated > 0) and ( - self._last_updated + heartbeat > arrow.utcnow().timestamp): - return False - - data: Dict[str, Any] = {} - logger.info('Using stake_currency: %s ...', self.config['stake_currency']) - logger.info('Using local backtesting data (using whitelist in given config) ...') - - if self._refresh_pairs: - history.refresh_data( - datadir=self.config['datadir'], - pairs=pairs, - exchange=self.exchange, - timeframe=self.strategy.ticker_interval, - timerange=self._timerange, - ) - - data = history.load_data( - datadir=self.config['datadir'], - pairs=pairs, - timeframe=self.strategy.ticker_interval, - timerange=self._timerange, - startup_candles=self.strategy.startup_candle_count, - ) - - if not data: - # Reinitializing cached pairs - self._cached_pairs = {} - logger.critical("No data found. Edge is stopped ...") - return False - - preprocessed = self.strategy.tickerdata_to_dataframe(data) - - # Print timeframe - min_date, max_date = history.get_timerange(preprocessed) - logger.info( - 'Measuring data from %s up to %s (%s days) ...', - min_date.isoformat(), - max_date.isoformat(), - (max_date - min_date).days - ) - headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low'] - - trades: list = [] - for pair, pair_data in preprocessed.items(): - # Sorting dataframe by date and reset index - pair_data = pair_data.sort_values(by=['date']) - pair_data = pair_data.reset_index(drop=True) - - ticker_data = self.strategy.advise_sell( - self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() - - trades += self._find_trades_for_stoploss_range(ticker_data, pair, self._stoploss_range) - - # If no trade found then exit - if len(trades) == 0: - logger.info("No trades found.") - return False - - # Fill missing, calculable columns, profit, duration , abs etc. - trades_df = self._fill_calculable_fields(DataFrame(trades)) - self._cached_pairs = self._process_expectancy(trades_df) - self._last_updated = arrow.utcnow().timestamp - - return True - - def stake_amount(self, pair: str, free_capital: float, - total_capital: float, capital_in_trade: float) -> float: - stoploss = self.stoploss(pair) - available_capital = (total_capital + capital_in_trade) * self._capital_percentage - allowed_capital_at_risk = available_capital * self._allowed_risk - max_position_size = abs(allowed_capital_at_risk / stoploss) - position_size = min(max_position_size, free_capital) - if pair in self._cached_pairs: - logger.info( - 'winrate: %s, expectancy: %s, position size: %s, pair: %s,' - ' capital in trade: %s, free capital: %s, total capital: %s,' - ' stoploss: %s, available capital: %s.', - self._cached_pairs[pair].winrate, - self._cached_pairs[pair].expectancy, - position_size, pair, - capital_in_trade, free_capital, total_capital, - stoploss, available_capital - ) - return round(position_size, 15) - - def stoploss(self, pair: str) -> float: - if pair in self._cached_pairs: - return self._cached_pairs[pair].stoploss - else: - logger.warning('tried to access stoploss of a non-existing pair, ' - 'strategy stoploss is returned instead.') - return self.strategy.stoploss - - def adjust(self, pairs) -> list: - """ - Filters out and sorts "pairs" according to Edge calculated pairs - """ - final = [] - for pair, info in self._cached_pairs.items(): - if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ - info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)) and \ - pair in pairs: - final.append(pair) - - if self._final_pairs != final: - self._final_pairs = final - if self._final_pairs: - logger.info( - 'Minimum expectancy and minimum winrate are met only for %s,' - ' so other pairs are filtered out.', - self._final_pairs - ) - else: - logger.info( - 'Edge removed all pairs as no pair with minimum expectancy ' - 'and minimum winrate was found !' - ) - - return self._final_pairs - - def accepted_pairs(self) -> list: - """ - return a list of accepted pairs along with their winrate, expectancy and stoploss - """ - final = [] - for pair, info in self._cached_pairs.items(): - if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ - info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)): - final.append({ - 'Pair': pair, - 'Winrate': info.winrate, - 'Expectancy': info.expectancy, - 'Stoploss': info.stoploss, - }) - return final - - def _fill_calculable_fields(self, result: DataFrame) -> DataFrame: - """ - The result frame contains a number of columns that are calculable - from other columns. These are left blank till all rows are added, - to be populated in single vector calls. - - Columns to be populated are: - - Profit - - trade duration - - profit abs - :param result Dataframe - :return: result Dataframe - """ - - # stake and fees - # stake = 0.015 - # 0.05% is 0.0005 - # fee = 0.001 - - # we set stake amount to an arbitrary amount. - # as it doesn't change the calculation. - # all returned values are relative. they are percentages. - stake = 0.015 - fee = self.fee - open_fee = fee / 2 - close_fee = fee / 2 - - result['trade_duration'] = result['close_time'] - result['open_time'] - - result['trade_duration'] = result['trade_duration'].map( - lambda x: int(x.total_seconds() / 60)) - - # Spends, Takes, Profit, Absolute Profit - - # Buy Price - result['buy_vol'] = stake / result['open_rate'] # How many target are we buying - result['buy_fee'] = stake * open_fee - result['buy_spend'] = stake + result['buy_fee'] # How much we're spending - - # Sell price - result['sell_sum'] = result['buy_vol'] * result['close_rate'] - result['sell_fee'] = result['sell_sum'] * close_fee - result['sell_take'] = result['sell_sum'] - result['sell_fee'] - - # profit_percent - result['profit_percent'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend'] - - # Absolute profit - result['profit_abs'] = result['sell_take'] - result['buy_spend'] - - return result - - def _process_expectancy(self, results: DataFrame) -> Dict[str, Any]: - """ - This calculates WinRate, Required Risk Reward, Risk Reward and Expectancy of all pairs - The calulation will be done per pair and per strategy. - """ - # Removing pairs having less than min_trades_number - min_trades_number = self.edge_config.get('min_trade_number', 10) - results = results.groupby(['pair', 'stoploss']).filter(lambda x: len(x) > min_trades_number) - ################################### - - # Removing outliers (Only Pumps) from the dataset - # The method to detect outliers is to calculate standard deviation - # Then every value more than (standard deviation + 2*average) is out (pump) - # - # Removing Pumps - if self.edge_config.get('remove_pumps', False): - results = results.groupby(['pair', 'stoploss']).apply( - lambda x: x[x['profit_abs'] < 2 * x['profit_abs'].std() + x['profit_abs'].mean()]) - ########################################################################## - - # Removing trades having a duration more than X minutes (set in config) - max_trade_duration = self.edge_config.get('max_trade_duration_minute', 1440) - results = results[results.trade_duration < max_trade_duration] - ####################################################################### - - if results.empty: - return {} - - groupby_aggregator = { - 'profit_abs': [ - ('nb_trades', 'count'), # number of all trades - ('profit_sum', lambda x: x[x > 0].sum()), # cumulative profit of all winning trades - ('loss_sum', lambda x: abs(x[x < 0].sum())), # cumulative loss of all losing trades - ('nb_win_trades', lambda x: x[x > 0].count()) # number of winning trades - ], - 'trade_duration': [('avg_trade_duration', 'mean')] - } - - # Group by (pair and stoploss) by applying above aggregator - df = results.groupby(['pair', 'stoploss'])['profit_abs', 'trade_duration'].agg( - groupby_aggregator).reset_index(col_level=1) - - # Dropping level 0 as we don't need it - df.columns = df.columns.droplevel(0) - - # Calculating number of losing trades, average win and average loss - df['nb_loss_trades'] = df['nb_trades'] - df['nb_win_trades'] - df['average_win'] = df['profit_sum'] / df['nb_win_trades'] - df['average_loss'] = df['loss_sum'] / df['nb_loss_trades'] - - # Win rate = number of profitable trades / number of trades - df['winrate'] = df['nb_win_trades'] / df['nb_trades'] - - # risk_reward_ratio = average win / average loss - df['risk_reward_ratio'] = df['average_win'] / df['average_loss'] - - # required_risk_reward = (1 / winrate) - 1 - df['required_risk_reward'] = (1 / df['winrate']) - 1 - - # expectancy = (risk_reward_ratio * winrate) - (lossrate) - df['expectancy'] = (df['risk_reward_ratio'] * df['winrate']) - (1 - df['winrate']) - - # sort by expectancy and stoploss - df = df.sort_values(by=['expectancy', 'stoploss'], ascending=False).groupby( - 'pair').first().sort_values(by=['expectancy'], ascending=False).reset_index() - - final = {} - for x in df.itertuples(): - final[x.pair] = PairInfo( - x.stoploss, - x.winrate, - x.risk_reward_ratio, - x.required_risk_reward, - x.expectancy, - x.nb_trades, - x.avg_trade_duration - ) - - # Returning a list of pairs in order of "expectancy" - return final - - def _find_trades_for_stoploss_range(self, ticker_data, pair, stoploss_range): - buy_column = ticker_data['buy'].values - sell_column = ticker_data['sell'].values - date_column = ticker_data['date'].values - ohlc_columns = ticker_data[['open', 'high', 'low', 'close']].values - - result: list = [] - for stoploss in stoploss_range: - result += self._detect_next_stop_or_sell_point( - buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair - ) - - return result - - def _detect_next_stop_or_sell_point(self, buy_column, sell_column, date_column, - ohlc_columns, stoploss, pair): - """ - Iterate through ohlc_columns in order to find the next trade - Next trade opens from the first buy signal noticed to - The sell or stoploss signal after it. - It then cuts OHLC, buy_column, sell_column and date_column. - Cut from (the exit trade index) + 1. - - Author: https://github.com/mishaker - """ - - result: list = [] - start_point = 0 - - while True: - open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal) - - # Return empty if we don't find trade entry (i.e. buy==1) or - # we find a buy but at the end of array - if open_trade_index == -1 or open_trade_index == len(buy_column) - 1: - break - else: - # When a buy signal is seen, - # trade opens in reality on the next candle - open_trade_index += 1 - - stop_price_percentage = stoploss + 1 - open_price = ohlc_columns[open_trade_index, 0] - stop_price = (open_price * stop_price_percentage) - - # Searching for the index where stoploss is hit - stop_index = utf1st.find_1st( - ohlc_columns[open_trade_index:, 2], stop_price, utf1st.cmp_smaller) - - # If we don't find it then we assume stop_index will be far in future (infinite number) - if stop_index == -1: - stop_index = float('inf') - - # Searching for the index where sell is hit - sell_index = utf1st.find_1st(sell_column[open_trade_index:], 1, utf1st.cmp_equal) - - # If we don't find it then we assume sell_index will be far in future (infinite number) - if sell_index == -1: - sell_index = float('inf') - - # Check if we don't find any stop or sell point (in that case trade remains open) - # It is not interesting for Edge to consider it so we simply ignore the trade - # And stop iterating there is no more entry - if stop_index == sell_index == float('inf'): - break - - if stop_index <= sell_index: - exit_index = open_trade_index + stop_index - exit_type = SellType.STOP_LOSS - exit_price = stop_price - elif stop_index > sell_index: - # If exit is SELL then we exit at the next candle - exit_index = open_trade_index + sell_index + 1 - - # Check if we have the next candle - if len(ohlc_columns) - 1 < exit_index: - break - - exit_type = SellType.SELL_SIGNAL - exit_price = ohlc_columns[exit_index, 0] - - trade = {'pair': pair, - 'stoploss': stoploss, - 'profit_percent': '', - 'profit_abs': '', - 'open_time': date_column[open_trade_index], - 'close_time': date_column[exit_index], - 'open_index': start_point + open_trade_index, - 'close_index': start_point + exit_index, - 'trade_duration': '', - 'open_rate': round(open_price, 15), - 'close_rate': round(exit_price, 15), - 'exit_type': exit_type - } - - result.append(trade) - - # Giving a view of exit_index till the end of array - buy_column = buy_column[exit_index:] - sell_column = sell_column[exit_index:] - date_column = date_column[exit_index:] - ohlc_columns = ohlc_columns[exit_index:] - start_point += exit_index - - return result +from .edge_positioning import Edge, PairInfo # noqa: F401 diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py new file mode 100644 index 000000000..15883357b --- /dev/null +++ b/freqtrade/edge/edge_positioning.py @@ -0,0 +1,464 @@ +# pragma pylint: disable=W0603 +""" Edge positioning package """ +import logging +from typing import Any, Dict, NamedTuple + +import arrow +import numpy as np +import utils_find_1st as utf1st +from pandas import DataFrame + +from freqtrade import constants +from freqtrade.configuration import TimeRange +from freqtrade.data import history +from freqtrade.exceptions import OperationalException +from freqtrade.strategy.interface import SellType + +logger = logging.getLogger(__name__) + + +class PairInfo(NamedTuple): + stoploss: float + winrate: float + risk_reward_ratio: float + required_risk_reward: float + expectancy: float + nb_trades: int + avg_trade_duration: float + + +class Edge: + """ + Calculates Win Rate, Risk Reward Ratio, Expectancy + against historical data for a give set of markets and a strategy + it then adjusts stoploss and position size accordingly + and force it into the strategy + Author: https://github.com/mishaker + """ + + config: Dict = {} + _cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs + + def __init__(self, config: Dict[str, Any], exchange, strategy) -> None: + + self.config = config + self.exchange = exchange + self.strategy = strategy + + self.edge_config = self.config.get('edge', {}) + self._cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs + self._final_pairs: list = [] + + # checking max_open_trades. it should be -1 as with Edge + # the number of trades is determined by position size + if self.config['max_open_trades'] != float('inf'): + logger.critical('max_open_trades should be -1 in config !') + + if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: + raise OperationalException('Edge works only with unlimited stake amount') + + # Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future. + self._capital_percentage: float = self.edge_config.get( + 'capital_available_percentage', self.config['tradable_balance_ratio']) + self._allowed_risk: float = self.edge_config.get('allowed_risk') + self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14) + self._last_updated: int = 0 # Timestamp of pairs last updated time + self._refresh_pairs = True + + self._stoploss_range_min = float(self.edge_config.get('stoploss_range_min', -0.01)) + self._stoploss_range_max = float(self.edge_config.get('stoploss_range_max', -0.05)) + self._stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001)) + + # calculating stoploss range + self._stoploss_range = np.arange( + self._stoploss_range_min, + self._stoploss_range_max, + self._stoploss_range_step + ) + + self._timerange: TimeRange = TimeRange.parse_timerange("%s-" % arrow.now().shift( + days=-1 * self._since_number_of_days).format('YYYYMMDD')) + if config.get('fee'): + self.fee = config['fee'] + else: + self.fee = self.exchange.get_fee(symbol=self.config['exchange']['pair_whitelist'][0]) + + def calculate(self) -> bool: + pairs = self.config['exchange']['pair_whitelist'] + heartbeat = self.edge_config.get('process_throttle_secs') + + if (self._last_updated > 0) and ( + self._last_updated + heartbeat > arrow.utcnow().timestamp): + return False + + data: Dict[str, Any] = {} + logger.info('Using stake_currency: %s ...', self.config['stake_currency']) + logger.info('Using local backtesting data (using whitelist in given config) ...') + + if self._refresh_pairs: + history.refresh_data( + datadir=self.config['datadir'], + pairs=pairs, + exchange=self.exchange, + timeframe=self.strategy.ticker_interval, + timerange=self._timerange, + ) + + data = history.load_data( + datadir=self.config['datadir'], + pairs=pairs, + timeframe=self.strategy.ticker_interval, + timerange=self._timerange, + startup_candles=self.strategy.startup_candle_count, + ) + + if not data: + # Reinitializing cached pairs + self._cached_pairs = {} + logger.critical("No data found. Edge is stopped ...") + return False + + preprocessed = self.strategy.tickerdata_to_dataframe(data) + + # Print timeframe + min_date, max_date = history.get_timerange(preprocessed) + logger.info( + 'Measuring data from %s up to %s (%s days) ...', + min_date.isoformat(), + max_date.isoformat(), + (max_date - min_date).days + ) + headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low'] + + trades: list = [] + for pair, pair_data in preprocessed.items(): + # Sorting dataframe by date and reset index + pair_data = pair_data.sort_values(by=['date']) + pair_data = pair_data.reset_index(drop=True) + + ticker_data = self.strategy.advise_sell( + self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() + + trades += self._find_trades_for_stoploss_range(ticker_data, pair, self._stoploss_range) + + # If no trade found then exit + if len(trades) == 0: + logger.info("No trades found.") + return False + + # Fill missing, calculable columns, profit, duration , abs etc. + trades_df = self._fill_calculable_fields(DataFrame(trades)) + self._cached_pairs = self._process_expectancy(trades_df) + self._last_updated = arrow.utcnow().timestamp + + return True + + def stake_amount(self, pair: str, free_capital: float, + total_capital: float, capital_in_trade: float) -> float: + stoploss = self.stoploss(pair) + available_capital = (total_capital + capital_in_trade) * self._capital_percentage + allowed_capital_at_risk = available_capital * self._allowed_risk + max_position_size = abs(allowed_capital_at_risk / stoploss) + position_size = min(max_position_size, free_capital) + if pair in self._cached_pairs: + logger.info( + 'winrate: %s, expectancy: %s, position size: %s, pair: %s,' + ' capital in trade: %s, free capital: %s, total capital: %s,' + ' stoploss: %s, available capital: %s.', + self._cached_pairs[pair].winrate, + self._cached_pairs[pair].expectancy, + position_size, pair, + capital_in_trade, free_capital, total_capital, + stoploss, available_capital + ) + return round(position_size, 15) + + def stoploss(self, pair: str) -> float: + if pair in self._cached_pairs: + return self._cached_pairs[pair].stoploss + else: + logger.warning('tried to access stoploss of a non-existing pair, ' + 'strategy stoploss is returned instead.') + return self.strategy.stoploss + + def adjust(self, pairs) -> list: + """ + Filters out and sorts "pairs" according to Edge calculated pairs + """ + final = [] + for pair, info in self._cached_pairs.items(): + if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ + info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)) and \ + pair in pairs: + final.append(pair) + + if self._final_pairs != final: + self._final_pairs = final + if self._final_pairs: + logger.info( + 'Minimum expectancy and minimum winrate are met only for %s,' + ' so other pairs are filtered out.', + self._final_pairs + ) + else: + logger.info( + 'Edge removed all pairs as no pair with minimum expectancy ' + 'and minimum winrate was found !' + ) + + return self._final_pairs + + def accepted_pairs(self) -> list: + """ + return a list of accepted pairs along with their winrate, expectancy and stoploss + """ + final = [] + for pair, info in self._cached_pairs.items(): + if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ + info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)): + final.append({ + 'Pair': pair, + 'Winrate': info.winrate, + 'Expectancy': info.expectancy, + 'Stoploss': info.stoploss, + }) + return final + + def _fill_calculable_fields(self, result: DataFrame) -> DataFrame: + """ + The result frame contains a number of columns that are calculable + from other columns. These are left blank till all rows are added, + to be populated in single vector calls. + + Columns to be populated are: + - Profit + - trade duration + - profit abs + :param result Dataframe + :return: result Dataframe + """ + + # stake and fees + # stake = 0.015 + # 0.05% is 0.0005 + # fee = 0.001 + + # we set stake amount to an arbitrary amount. + # as it doesn't change the calculation. + # all returned values are relative. they are percentages. + stake = 0.015 + fee = self.fee + open_fee = fee / 2 + close_fee = fee / 2 + + result['trade_duration'] = result['close_time'] - result['open_time'] + + result['trade_duration'] = result['trade_duration'].map( + lambda x: int(x.total_seconds() / 60)) + + # Spends, Takes, Profit, Absolute Profit + + # Buy Price + result['buy_vol'] = stake / result['open_rate'] # How many target are we buying + result['buy_fee'] = stake * open_fee + result['buy_spend'] = stake + result['buy_fee'] # How much we're spending + + # Sell price + result['sell_sum'] = result['buy_vol'] * result['close_rate'] + result['sell_fee'] = result['sell_sum'] * close_fee + result['sell_take'] = result['sell_sum'] - result['sell_fee'] + + # profit_percent + result['profit_percent'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend'] + + # Absolute profit + result['profit_abs'] = result['sell_take'] - result['buy_spend'] + + return result + + def _process_expectancy(self, results: DataFrame) -> Dict[str, Any]: + """ + This calculates WinRate, Required Risk Reward, Risk Reward and Expectancy of all pairs + The calulation will be done per pair and per strategy. + """ + # Removing pairs having less than min_trades_number + min_trades_number = self.edge_config.get('min_trade_number', 10) + results = results.groupby(['pair', 'stoploss']).filter(lambda x: len(x) > min_trades_number) + ################################### + + # Removing outliers (Only Pumps) from the dataset + # The method to detect outliers is to calculate standard deviation + # Then every value more than (standard deviation + 2*average) is out (pump) + # + # Removing Pumps + if self.edge_config.get('remove_pumps', False): + results = results.groupby(['pair', 'stoploss']).apply( + lambda x: x[x['profit_abs'] < 2 * x['profit_abs'].std() + x['profit_abs'].mean()]) + ########################################################################## + + # Removing trades having a duration more than X minutes (set in config) + max_trade_duration = self.edge_config.get('max_trade_duration_minute', 1440) + results = results[results.trade_duration < max_trade_duration] + ####################################################################### + + if results.empty: + return {} + + groupby_aggregator = { + 'profit_abs': [ + ('nb_trades', 'count'), # number of all trades + ('profit_sum', lambda x: x[x > 0].sum()), # cumulative profit of all winning trades + ('loss_sum', lambda x: abs(x[x < 0].sum())), # cumulative loss of all losing trades + ('nb_win_trades', lambda x: x[x > 0].count()) # number of winning trades + ], + 'trade_duration': [('avg_trade_duration', 'mean')] + } + + # Group by (pair and stoploss) by applying above aggregator + df = results.groupby(['pair', 'stoploss'])['profit_abs', 'trade_duration'].agg( + groupby_aggregator).reset_index(col_level=1) + + # Dropping level 0 as we don't need it + df.columns = df.columns.droplevel(0) + + # Calculating number of losing trades, average win and average loss + df['nb_loss_trades'] = df['nb_trades'] - df['nb_win_trades'] + df['average_win'] = df['profit_sum'] / df['nb_win_trades'] + df['average_loss'] = df['loss_sum'] / df['nb_loss_trades'] + + # Win rate = number of profitable trades / number of trades + df['winrate'] = df['nb_win_trades'] / df['nb_trades'] + + # risk_reward_ratio = average win / average loss + df['risk_reward_ratio'] = df['average_win'] / df['average_loss'] + + # required_risk_reward = (1 / winrate) - 1 + df['required_risk_reward'] = (1 / df['winrate']) - 1 + + # expectancy = (risk_reward_ratio * winrate) - (lossrate) + df['expectancy'] = (df['risk_reward_ratio'] * df['winrate']) - (1 - df['winrate']) + + # sort by expectancy and stoploss + df = df.sort_values(by=['expectancy', 'stoploss'], ascending=False).groupby( + 'pair').first().sort_values(by=['expectancy'], ascending=False).reset_index() + + final = {} + for x in df.itertuples(): + final[x.pair] = PairInfo( + x.stoploss, + x.winrate, + x.risk_reward_ratio, + x.required_risk_reward, + x.expectancy, + x.nb_trades, + x.avg_trade_duration + ) + + # Returning a list of pairs in order of "expectancy" + return final + + def _find_trades_for_stoploss_range(self, ticker_data, pair, stoploss_range): + buy_column = ticker_data['buy'].values + sell_column = ticker_data['sell'].values + date_column = ticker_data['date'].values + ohlc_columns = ticker_data[['open', 'high', 'low', 'close']].values + + result: list = [] + for stoploss in stoploss_range: + result += self._detect_next_stop_or_sell_point( + buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair + ) + + return result + + def _detect_next_stop_or_sell_point(self, buy_column, sell_column, date_column, + ohlc_columns, stoploss, pair): + """ + Iterate through ohlc_columns in order to find the next trade + Next trade opens from the first buy signal noticed to + The sell or stoploss signal after it. + It then cuts OHLC, buy_column, sell_column and date_column. + Cut from (the exit trade index) + 1. + + Author: https://github.com/mishaker + """ + + result: list = [] + start_point = 0 + + while True: + open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal) + + # Return empty if we don't find trade entry (i.e. buy==1) or + # we find a buy but at the end of array + if open_trade_index == -1 or open_trade_index == len(buy_column) - 1: + break + else: + # When a buy signal is seen, + # trade opens in reality on the next candle + open_trade_index += 1 + + stop_price_percentage = stoploss + 1 + open_price = ohlc_columns[open_trade_index, 0] + stop_price = (open_price * stop_price_percentage) + + # Searching for the index where stoploss is hit + stop_index = utf1st.find_1st( + ohlc_columns[open_trade_index:, 2], stop_price, utf1st.cmp_smaller) + + # If we don't find it then we assume stop_index will be far in future (infinite number) + if stop_index == -1: + stop_index = float('inf') + + # Searching for the index where sell is hit + sell_index = utf1st.find_1st(sell_column[open_trade_index:], 1, utf1st.cmp_equal) + + # If we don't find it then we assume sell_index will be far in future (infinite number) + if sell_index == -1: + sell_index = float('inf') + + # Check if we don't find any stop or sell point (in that case trade remains open) + # It is not interesting for Edge to consider it so we simply ignore the trade + # And stop iterating there is no more entry + if stop_index == sell_index == float('inf'): + break + + if stop_index <= sell_index: + exit_index = open_trade_index + stop_index + exit_type = SellType.STOP_LOSS + exit_price = stop_price + elif stop_index > sell_index: + # If exit is SELL then we exit at the next candle + exit_index = open_trade_index + sell_index + 1 + + # Check if we have the next candle + if len(ohlc_columns) - 1 < exit_index: + break + + exit_type = SellType.SELL_SIGNAL + exit_price = ohlc_columns[exit_index, 0] + + trade = {'pair': pair, + 'stoploss': stoploss, + 'profit_percent': '', + 'profit_abs': '', + 'open_time': date_column[open_trade_index], + 'close_time': date_column[exit_index], + 'open_index': start_point + open_trade_index, + 'close_index': start_point + exit_index, + 'trade_duration': '', + 'open_rate': round(open_price, 15), + 'close_rate': round(exit_price, 15), + 'exit_type': exit_type + } + + result.append(trade) + + # Giving a view of exit_index till the end of array + buy_column = buy_column[exit_index:] + sell_column = sell_column[exit_index:] + date_column = date_column[exit_index:] + ohlc_columns = ohlc_columns[exit_index:] + start_point += exit_index + + return result From 80ed1c3e146da9c3f36f978ceae0df250acc4131 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 10:51:09 +0100 Subject: [PATCH 0321/1106] Move utils to commands --- freqtrade/commands/__init__.py | 0 freqtrade/{ => commands}/utils.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 freqtrade/commands/__init__.py rename freqtrade/{ => commands}/utils.py (100%) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/utils.py b/freqtrade/commands/utils.py similarity index 100% rename from freqtrade/utils.py rename to freqtrade/commands/utils.py From 6e852804671efa0546341b5db5f35b79bc9e9278 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 10:55:39 +0100 Subject: [PATCH 0322/1106] Adjust imports --- freqtrade/commands/__init__.py | 6 ++++++ freqtrade/configuration/arguments.py | 12 +++++------ freqtrade/optimize/__init__.py | 2 +- freqtrade/plot/plot_utils.py | 2 +- tests/test_utils.py | 30 ++++++++++++++-------------- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index e69de29bb..0c31048f2 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -0,0 +1,6 @@ +from .utils import (setup_utils_configuration, start_create_userdir, # noqa: F401 + start_download_data, start_hyperopt_list, + start_hyperopt_show, start_list_exchanges, + start_list_markets, start_list_strategies, + start_list_timeframes, start_new_hyperopt, + start_new_strategy, start_test_pairlist, start_trading) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index b2197619d..3c71fa548 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -131,12 +131,12 @@ class Arguments: self._build_args(optionlist=['version'], parser=self.parser) from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge - from freqtrade.utils import (start_create_userdir, start_download_data, - start_hyperopt_list, start_hyperopt_show, - start_list_exchanges, start_list_markets, - start_list_strategies, start_new_hyperopt, - start_new_strategy, start_list_timeframes, - start_test_pairlist, start_trading) + from freqtrade.commands import (start_create_userdir, start_download_data, + start_hyperopt_list, start_hyperopt_show, + start_list_exchanges, start_list_markets, + start_list_strategies, start_new_hyperopt, + start_new_strategy, start_list_timeframes, + start_test_pairlist, start_trading) from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit subparsers = self.parser.add_subparsers(dest='command', diff --git a/freqtrade/optimize/__init__.py b/freqtrade/optimize/__init__.py index 34760372f..98b521d4e 100644 --- a/freqtrade/optimize/__init__.py +++ b/freqtrade/optimize/__init__.py @@ -4,7 +4,7 @@ from typing import Any, Dict from freqtrade import constants from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.state import RunMode -from freqtrade.utils import setup_utils_configuration +from freqtrade.commands import setup_utils_configuration logger = logging.getLogger(__name__) diff --git a/freqtrade/plot/plot_utils.py b/freqtrade/plot/plot_utils.py index 9eff08396..b2f16dff0 100644 --- a/freqtrade/plot/plot_utils.py +++ b/freqtrade/plot/plot_utils.py @@ -2,7 +2,7 @@ from typing import Any, Dict from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from freqtrade.utils import setup_utils_configuration +from freqtrade.commands import setup_utils_configuration def validate_plot_args(args: Dict[str, Any]): diff --git a/tests/test_utils.py b/tests/test_utils.py index 7ca2cac5a..91009ec42 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -4,15 +4,15 @@ from unittest.mock import MagicMock, PropertyMock import pytest +from freqtrade.commands import (setup_utils_configuration, + start_create_userdir, start_download_data, + start_hyperopt_list, start_hyperopt_show, + start_list_exchanges, start_list_markets, + start_list_strategies, start_list_timeframes, + start_new_hyperopt, start_new_strategy, + start_test_pairlist, start_trading) from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from freqtrade.utils import (setup_utils_configuration, start_create_userdir, - start_download_data, start_hyperopt_list, - start_hyperopt_show, start_list_exchanges, - start_list_markets, start_list_strategies, - start_list_timeframes, start_new_hyperopt, - start_new_strategy, start_test_pairlist, - start_trading) from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) @@ -451,8 +451,8 @@ def test_create_datadir(caplog, mocker): # Added assert here to analyze random test-failures ... assert len(caplog.record_tuples) == 0 - cud = mocker.patch("freqtrade.utils.create_userdata_dir", MagicMock()) - csf = mocker.patch("freqtrade.utils.copy_sample_files", MagicMock()) + cud = mocker.patch("freqtrade.commands.create_userdata_dir", MagicMock()) + csf = mocker.patch("freqtrade.commands.copy_sample_files", MagicMock()) args = [ "create-userdir", "--userdir", @@ -538,7 +538,7 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): def test_download_data_keyboardInterrupt(mocker, caplog, markets): - dl_mock = mocker.patch('freqtrade.utils.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) patch_exchange(mocker) mocker.patch( @@ -556,7 +556,7 @@ def test_download_data_keyboardInterrupt(mocker, caplog, markets): def test_download_data_no_markets(mocker, caplog): - dl_mock = mocker.patch('freqtrade.utils.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker, id='binance') mocker.patch( @@ -574,7 +574,7 @@ def test_download_data_no_markets(mocker, caplog): def test_download_data_no_exchange(mocker, caplog): - mocker.patch('freqtrade.utils.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -594,7 +594,7 @@ def test_download_data_no_pairs(mocker, caplog): mocker.patch.object(Path, "exists", MagicMock(return_value=False)) - mocker.patch('freqtrade.utils.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -613,9 +613,9 @@ def test_download_data_no_pairs(mocker, caplog): def test_download_data_trades(mocker, caplog): - dl_mock = mocker.patch('freqtrade.utils.refresh_backtest_trades_data', + dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_trades_data', MagicMock(return_value=[])) - convert_mock = mocker.patch('freqtrade.utils.convert_trades_to_ohlcv', + convert_mock = mocker.patch('freqtrade.commands.convert_trades_to_ohlcv', MagicMock(return_value=[])) patch_exchange(mocker) mocker.patch( From 926bf07df1420c2e08dadbb53e8359a1ffa20900 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:08:58 +0100 Subject: [PATCH 0323/1106] Seperate a few commands into specific files --- freqtrade/commands/__init__.py | 16 +- freqtrade/commands/deploy_commands.py | 113 ++++++++ freqtrade/commands/hyperopt_commands.py | 114 ++++++++ freqtrade/commands/list_commands.py | 157 +++++++++++ freqtrade/commands/trade_commands.py | 25 ++ freqtrade/commands/utils.py | 356 ------------------------ 6 files changed, 419 insertions(+), 362 deletions(-) create mode 100644 freqtrade/commands/deploy_commands.py create mode 100644 freqtrade/commands/hyperopt_commands.py create mode 100644 freqtrade/commands/list_commands.py create mode 100644 freqtrade/commands/trade_commands.py diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 0c31048f2..4c57efeae 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -1,6 +1,10 @@ -from .utils import (setup_utils_configuration, start_create_userdir, # noqa: F401 - start_download_data, start_hyperopt_list, - start_hyperopt_show, start_list_exchanges, - start_list_markets, start_list_strategies, - start_list_timeframes, start_new_hyperopt, - start_new_strategy, start_test_pairlist, start_trading) +from .hyperopt_commands import (start_hyperopt_list, start_hyperopt_show) # noqa: 401 + +from .list_commands import (start_list_exchanges, # noqa: F401 + start_list_markets, start_list_strategies, + start_list_timeframes) +from .utils import setup_utils_configuration # noqa: F401 +from .utils import (start_download_data, # noqa: F401 + start_test_pairlist) +from .deploy_commands import (start_new_hyperopt, start_new_strategy, start_create_userdir) # noqa: F401 +from .trade_commands import start_trading # noqa: F401 diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py new file mode 100644 index 000000000..892e15db1 --- /dev/null +++ b/freqtrade/commands/deploy_commands.py @@ -0,0 +1,113 @@ +import logging +import sys +from pathlib import Path +from typing import Any, Dict + +from freqtrade.configuration.directory_operations import (copy_sample_files, + create_userdata_dir) +from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY +from freqtrade.exceptions import OperationalException +from freqtrade.misc import render_template +from freqtrade.state import RunMode + +from .utils import setup_utils_configuration + +logger = logging.getLogger(__name__) + + +def start_create_userdir(args: Dict[str, Any]) -> None: + """ + Create "user_data" directory to contain user data strategies, hyperopt, ...) + :param args: Cli args from Arguments() + :return: None + """ + if "user_data_dir" in args and args["user_data_dir"]: + userdir = create_userdata_dir(args["user_data_dir"], create_dir=True) + copy_sample_files(userdir, overwrite=args["reset"]) + else: + logger.warning("`create-userdir` requires --userdir to be set.") + sys.exit(1) + + +def deploy_new_strategy(strategy_name, strategy_path: Path, subtemplate: str): + """ + Deploy new strategy from template to strategy_path + """ + indicators = render_template(templatefile=f"subtemplates/indicators_{subtemplate}.j2",) + buy_trend = render_template(templatefile=f"subtemplates/buy_trend_{subtemplate}.j2",) + sell_trend = render_template(templatefile=f"subtemplates/sell_trend_{subtemplate}.j2",) + plot_config = render_template(templatefile=f"subtemplates/plot_config_{subtemplate}.j2",) + + strategy_text = render_template(templatefile='base_strategy.py.j2', + arguments={"strategy": strategy_name, + "indicators": indicators, + "buy_trend": buy_trend, + "sell_trend": sell_trend, + "plot_config": plot_config, + }) + + logger.info(f"Writing strategy to `{strategy_path}`.") + strategy_path.write_text(strategy_text) + + +def start_new_strategy(args: Dict[str, Any]) -> None: + + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + if "strategy" in args and args["strategy"]: + if args["strategy"] == "DefaultStrategy": + raise OperationalException("DefaultStrategy is not allowed as name.") + + new_path = config['user_data_dir'] / USERPATH_STRATEGY / (args["strategy"] + ".py") + + if new_path.exists(): + raise OperationalException(f"`{new_path}` already exists. " + "Please choose another Strategy Name.") + + deploy_new_strategy(args['strategy'], new_path, args['template']) + + else: + raise OperationalException("`new-strategy` requires --strategy to be set.") + + +def deploy_new_hyperopt(hyperopt_name, hyperopt_path: Path, subtemplate: str): + """ + Deploys a new hyperopt template to hyperopt_path + """ + buy_guards = render_template( + templatefile=f"subtemplates/hyperopt_buy_guards_{subtemplate}.j2",) + sell_guards = render_template( + templatefile=f"subtemplates/hyperopt_sell_guards_{subtemplate}.j2",) + buy_space = render_template( + templatefile=f"subtemplates/hyperopt_buy_space_{subtemplate}.j2",) + sell_space = render_template( + templatefile=f"subtemplates/hyperopt_sell_space_{subtemplate}.j2",) + + strategy_text = render_template(templatefile='base_hyperopt.py.j2', + arguments={"hyperopt": hyperopt_name, + "buy_guards": buy_guards, + "sell_guards": sell_guards, + "buy_space": buy_space, + "sell_space": sell_space, + }) + + logger.info(f"Writing hyperopt to `{hyperopt_path}`.") + hyperopt_path.write_text(strategy_text) + + +def start_new_hyperopt(args: Dict[str, Any]) -> None: + + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + if "hyperopt" in args and args["hyperopt"]: + if args["hyperopt"] == "DefaultHyperopt": + raise OperationalException("DefaultHyperopt is not allowed as name.") + + new_path = config['user_data_dir'] / USERPATH_HYPEROPTS / (args["hyperopt"] + ".py") + + if new_path.exists(): + raise OperationalException(f"`{new_path}` already exists. " + "Please choose another Strategy Name.") + deploy_new_hyperopt(args['hyperopt'], new_path, args['template']) + else: + raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py new file mode 100644 index 000000000..db3f69050 --- /dev/null +++ b/freqtrade/commands/hyperopt_commands.py @@ -0,0 +1,114 @@ +import logging +from operator import itemgetter +from typing import Any, Dict, List + +from colorama import init as colorama_init + +from .utils import setup_utils_configuration +from freqtrade.exceptions import OperationalException +from freqtrade.state import RunMode + +logger = logging.getLogger(__name__) + + +def start_hyperopt_list(args: Dict[str, Any]) -> None: + """ + List hyperopt epochs previously evaluated + """ + from freqtrade.optimize.hyperopt import Hyperopt + + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + only_best = config.get('hyperopt_list_best', False) + only_profitable = config.get('hyperopt_list_profitable', False) + print_colorized = config.get('print_colorized', False) + print_json = config.get('print_json', False) + no_details = config.get('hyperopt_list_no_details', False) + no_header = False + + trials_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') + + # Previous evaluations + trials = Hyperopt.load_previous_results(trials_file) + total_epochs = len(trials) + + trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + + # TODO: fetch the interval for epochs to print from the cli option + epoch_start, epoch_stop = 0, None + + if print_colorized: + colorama_init(autoreset=True) + + try: + # Human-friendly indexes used here (starting from 1) + for val in trials[epoch_start:epoch_stop]: + Hyperopt.print_results_explanation(val, total_epochs, not only_best, print_colorized) + + except KeyboardInterrupt: + print('User interrupted..') + + if trials and not no_details: + sorted_trials = sorted(trials, key=itemgetter('loss')) + results = sorted_trials[0] + Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) + + +def start_hyperopt_show(args: Dict[str, Any]) -> None: + """ + Show details of a hyperopt epoch previously evaluated + """ + from freqtrade.optimize.hyperopt import Hyperopt + + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + only_best = config.get('hyperopt_list_best', False) + only_profitable = config.get('hyperopt_list_profitable', False) + no_header = config.get('hyperopt_show_no_header', False) + + trials_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') + + # Previous evaluations + trials = Hyperopt.load_previous_results(trials_file) + total_epochs = len(trials) + + trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + trials_epochs = len(trials) + + n = config.get('hyperopt_show_index', -1) + if n > trials_epochs: + raise OperationalException( + f"The index of the epoch to show should be less than {trials_epochs + 1}.") + if n < -trials_epochs: + raise OperationalException( + f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") + + # Translate epoch index from human-readable format to pythonic + if n > 0: + n -= 1 + + print_json = config.get('print_json', False) + + if trials: + val = trials[n] + Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, + header_str="Epoch details") + + +def _hyperopt_filter_trials(trials: List, only_best: bool, only_profitable: bool) -> List: + """ + Filter our items from the list of hyperopt results + """ + if only_best: + trials = [x for x in trials if x['is_best']] + if only_profitable: + trials = [x for x in trials if x['results_metrics']['profit'] > 0] + + logger.info(f"{len(trials)} " + + ("best " if only_best else "") + + ("profitable " if only_profitable else "") + + "epochs found.") + + return trials diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py new file mode 100644 index 000000000..90efaf66f --- /dev/null +++ b/freqtrade/commands/list_commands.py @@ -0,0 +1,157 @@ +import csv +import logging +import sys +from collections import OrderedDict +from pathlib import Path +from typing import Any, Dict + +import rapidjson +from tabulate import tabulate + +from freqtrade.constants import USERPATH_STRATEGY +from freqtrade.exceptions import OperationalException +from freqtrade.exchange import (available_exchanges, ccxt_exchanges, + market_is_active, symbol_is_pair) +from freqtrade.misc import plural +from freqtrade.resolvers import ExchangeResolver, StrategyResolver +from freqtrade.state import RunMode + +from .utils import setup_utils_configuration + +logger = logging.getLogger(__name__) + + +def start_list_exchanges(args: Dict[str, Any]) -> None: + """ + Print available exchanges + :param args: Cli args from Arguments() + :return: None + """ + exchanges = ccxt_exchanges() if args['list_exchanges_all'] else available_exchanges() + if args['print_one_column']: + print('\n'.join(exchanges)) + else: + if args['list_exchanges_all']: + print(f"All exchanges supported by the ccxt library: {', '.join(exchanges)}") + else: + print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}") + + +def start_list_strategies(args: Dict[str, Any]) -> None: + """ + Print Strategies available in a directory + """ + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGY)) + strategies = StrategyResolver.search_all_objects(directory) + # Sort alphabetically + strategies = sorted(strategies, key=lambda x: x['name']) + strats_to_print = [{'name': s['name'], 'location': s['location'].name} for s in strategies] + + if args['print_one_column']: + print('\n'.join([s['name'] for s in strategies])) + else: + print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) + + +def start_list_timeframes(args: Dict[str, Any]) -> None: + """ + Print ticker intervals (timeframes) available on Exchange + """ + config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) + # Do not use ticker_interval set in the config + config['ticker_interval'] = None + + # Init exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + + if args['print_one_column']: + print('\n'.join(exchange.timeframes)) + else: + print(f"Timeframes available for the exchange `{exchange.name}`: " + f"{', '.join(exchange.timeframes)}") + + +def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: + """ + Print pairs/markets on the exchange + :param args: Cli args from Arguments() + :param pairs_only: if True print only pairs, otherwise print all instruments (markets) + :return: None + """ + config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) + + # Init exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + + # By default only active pairs/markets are to be shown + active_only = not args.get('list_pairs_all', False) + + base_currencies = args.get('base_currencies', []) + quote_currencies = args.get('quote_currencies', []) + + try: + pairs = exchange.get_markets(base_currencies=base_currencies, + quote_currencies=quote_currencies, + pairs_only=pairs_only, + active_only=active_only) + # Sort the pairs/markets by symbol + pairs = OrderedDict(sorted(pairs.items())) + except Exception as e: + raise OperationalException(f"Cannot get markets. Reason: {e}") from e + + else: + summary_str = ((f"Exchange {exchange.name} has {len(pairs)} ") + + ("active " if active_only else "") + + (plural(len(pairs), "pair" if pairs_only else "market")) + + (f" with {', '.join(base_currencies)} as base " + f"{plural(len(base_currencies), 'currency', 'currencies')}" + if base_currencies else "") + + (" and" if base_currencies and quote_currencies else "") + + (f" with {', '.join(quote_currencies)} as quote " + f"{plural(len(quote_currencies), 'currency', 'currencies')}" + if quote_currencies else "")) + + headers = ["Id", "Symbol", "Base", "Quote", "Active", + *(['Is pair'] if not pairs_only else [])] + + tabular_data = [] + for _, v in pairs.items(): + tabular_data.append({'Id': v['id'], 'Symbol': v['symbol'], + 'Base': v['base'], 'Quote': v['quote'], + 'Active': market_is_active(v), + **({'Is pair': symbol_is_pair(v['symbol'])} + if not pairs_only else {})}) + + if (args.get('print_one_column', False) or + args.get('list_pairs_print_json', False) or + args.get('print_csv', False)): + # Print summary string in the log in case of machine-readable + # regular formats. + logger.info(f"{summary_str}.") + else: + # Print empty string separating leading logs and output in case of + # human-readable formats. + print() + + if len(pairs): + if args.get('print_list', False): + # print data as a list, with human-readable summary + print(f"{summary_str}: {', '.join(pairs.keys())}.") + elif args.get('print_one_column', False): + print('\n'.join(pairs.keys())) + elif args.get('list_pairs_print_json', False): + print(rapidjson.dumps(list(pairs.keys()), default=str)) + elif args.get('print_csv', False): + writer = csv.DictWriter(sys.stdout, fieldnames=headers) + writer.writeheader() + writer.writerows(tabular_data) + else: + # print data as a table, with the human-readable summary + print(f"{summary_str}:") + print(tabulate(tabular_data, headers='keys', tablefmt='pipe')) + elif not (args.get('print_one_column', False) or + args.get('list_pairs_print_json', False) or + args.get('print_csv', False)): + print(f"{summary_str}.") diff --git a/freqtrade/commands/trade_commands.py b/freqtrade/commands/trade_commands.py new file mode 100644 index 000000000..2c0c4c9c1 --- /dev/null +++ b/freqtrade/commands/trade_commands.py @@ -0,0 +1,25 @@ +import logging + +from typing import Any, Dict + + +logger = logging.getLogger(__name__) + + +def start_trading(args: Dict[str, Any]) -> int: + """ + Main entry point for trading mode + """ + from freqtrade.worker import Worker + # Load and run worker + worker = None + try: + worker = Worker(args) + worker.run() + except KeyboardInterrupt: + logger.info('SIGINT received, aborting ...') + finally: + if worker: + logger.info("worker found ... calling exit") + worker.exit() + return 0 diff --git a/freqtrade/commands/utils.py b/freqtrade/commands/utils.py index 2f7b2d717..ba9173cf2 100644 --- a/freqtrade/commands/utils.py +++ b/freqtrade/commands/utils.py @@ -46,139 +46,6 @@ def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str return config -def start_trading(args: Dict[str, Any]) -> int: - """ - Main entry point for trading mode - """ - from freqtrade.worker import Worker - # Load and run worker - worker = None - try: - worker = Worker(args) - worker.run() - except KeyboardInterrupt: - logger.info('SIGINT received, aborting ...') - finally: - if worker: - logger.info("worker found ... calling exit") - worker.exit() - return 0 - - -def start_list_exchanges(args: Dict[str, Any]) -> None: - """ - Print available exchanges - :param args: Cli args from Arguments() - :return: None - """ - exchanges = ccxt_exchanges() if args['list_exchanges_all'] else available_exchanges() - if args['print_one_column']: - print('\n'.join(exchanges)) - else: - if args['list_exchanges_all']: - print(f"All exchanges supported by the ccxt library: {', '.join(exchanges)}") - else: - print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}") - - -def start_create_userdir(args: Dict[str, Any]) -> None: - """ - Create "user_data" directory to contain user data strategies, hyperopt, ...) - :param args: Cli args from Arguments() - :return: None - """ - if "user_data_dir" in args and args["user_data_dir"]: - userdir = create_userdata_dir(args["user_data_dir"], create_dir=True) - copy_sample_files(userdir, overwrite=args["reset"]) - else: - logger.warning("`create-userdir` requires --userdir to be set.") - sys.exit(1) - - -def deploy_new_strategy(strategy_name, strategy_path: Path, subtemplate: str): - """ - Deploy new strategy from template to strategy_path - """ - indicators = render_template(templatefile=f"subtemplates/indicators_{subtemplate}.j2",) - buy_trend = render_template(templatefile=f"subtemplates/buy_trend_{subtemplate}.j2",) - sell_trend = render_template(templatefile=f"subtemplates/sell_trend_{subtemplate}.j2",) - plot_config = render_template(templatefile=f"subtemplates/plot_config_{subtemplate}.j2",) - - strategy_text = render_template(templatefile='base_strategy.py.j2', - arguments={"strategy": strategy_name, - "indicators": indicators, - "buy_trend": buy_trend, - "sell_trend": sell_trend, - "plot_config": plot_config, - }) - - logger.info(f"Writing strategy to `{strategy_path}`.") - strategy_path.write_text(strategy_text) - - -def start_new_strategy(args: Dict[str, Any]) -> None: - - config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - - if "strategy" in args and args["strategy"]: - if args["strategy"] == "DefaultStrategy": - raise OperationalException("DefaultStrategy is not allowed as name.") - - new_path = config['user_data_dir'] / USERPATH_STRATEGY / (args["strategy"] + ".py") - - if new_path.exists(): - raise OperationalException(f"`{new_path}` already exists. " - "Please choose another Strategy Name.") - - deploy_new_strategy(args['strategy'], new_path, args['template']) - - else: - raise OperationalException("`new-strategy` requires --strategy to be set.") - - -def deploy_new_hyperopt(hyperopt_name, hyperopt_path: Path, subtemplate: str): - """ - Deploys a new hyperopt template to hyperopt_path - """ - buy_guards = render_template( - templatefile=f"subtemplates/hyperopt_buy_guards_{subtemplate}.j2",) - sell_guards = render_template( - templatefile=f"subtemplates/hyperopt_sell_guards_{subtemplate}.j2",) - buy_space = render_template( - templatefile=f"subtemplates/hyperopt_buy_space_{subtemplate}.j2",) - sell_space = render_template( - templatefile=f"subtemplates/hyperopt_sell_space_{subtemplate}.j2",) - - strategy_text = render_template(templatefile='base_hyperopt.py.j2', - arguments={"hyperopt": hyperopt_name, - "buy_guards": buy_guards, - "sell_guards": sell_guards, - "buy_space": buy_space, - "sell_space": sell_space, - }) - - logger.info(f"Writing hyperopt to `{hyperopt_path}`.") - hyperopt_path.write_text(strategy_text) - - -def start_new_hyperopt(args: Dict[str, Any]) -> None: - - config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - - if "hyperopt" in args and args["hyperopt"]: - if args["hyperopt"] == "DefaultHyperopt": - raise OperationalException("DefaultHyperopt is not allowed as name.") - - new_path = config['user_data_dir'] / USERPATH_HYPEROPTS / (args["hyperopt"] + ".py") - - if new_path.exists(): - raise OperationalException(f"`{new_path}` already exists. " - "Please choose another Strategy Name.") - deploy_new_hyperopt(args['hyperopt'], new_path, args['template']) - else: - raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") - - def start_download_data(args: Dict[str, Any]) -> None: """ Download data (former download_backtest_data.py script) @@ -227,126 +94,6 @@ def start_download_data(args: Dict[str, Any]) -> None: f"on exchange {exchange.name}.") -def start_list_strategies(args: Dict[str, Any]) -> None: - """ - Print Strategies available in a directory - """ - config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - - directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGY)) - strategies = StrategyResolver.search_all_objects(directory) - # Sort alphabetically - strategies = sorted(strategies, key=lambda x: x['name']) - strats_to_print = [{'name': s['name'], 'location': s['location'].name} for s in strategies] - - if args['print_one_column']: - print('\n'.join([s['name'] for s in strategies])) - else: - print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) - - -def start_list_timeframes(args: Dict[str, Any]) -> None: - """ - Print ticker intervals (timeframes) available on Exchange - """ - config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - # Do not use ticker_interval set in the config - config['ticker_interval'] = None - - # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) - - if args['print_one_column']: - print('\n'.join(exchange.timeframes)) - else: - print(f"Timeframes available for the exchange `{exchange.name}`: " - f"{', '.join(exchange.timeframes)}") - - -def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: - """ - Print pairs/markets on the exchange - :param args: Cli args from Arguments() - :param pairs_only: if True print only pairs, otherwise print all instruments (markets) - :return: None - """ - config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - - # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) - - # By default only active pairs/markets are to be shown - active_only = not args.get('list_pairs_all', False) - - base_currencies = args.get('base_currencies', []) - quote_currencies = args.get('quote_currencies', []) - - try: - pairs = exchange.get_markets(base_currencies=base_currencies, - quote_currencies=quote_currencies, - pairs_only=pairs_only, - active_only=active_only) - # Sort the pairs/markets by symbol - pairs = OrderedDict(sorted(pairs.items())) - except Exception as e: - raise OperationalException(f"Cannot get markets. Reason: {e}") from e - - else: - summary_str = ((f"Exchange {exchange.name} has {len(pairs)} ") + - ("active " if active_only else "") + - (plural(len(pairs), "pair" if pairs_only else "market")) + - (f" with {', '.join(base_currencies)} as base " - f"{plural(len(base_currencies), 'currency', 'currencies')}" - if base_currencies else "") + - (" and" if base_currencies and quote_currencies else "") + - (f" with {', '.join(quote_currencies)} as quote " - f"{plural(len(quote_currencies), 'currency', 'currencies')}" - if quote_currencies else "")) - - headers = ["Id", "Symbol", "Base", "Quote", "Active", - *(['Is pair'] if not pairs_only else [])] - - tabular_data = [] - for _, v in pairs.items(): - tabular_data.append({'Id': v['id'], 'Symbol': v['symbol'], - 'Base': v['base'], 'Quote': v['quote'], - 'Active': market_is_active(v), - **({'Is pair': symbol_is_pair(v['symbol'])} - if not pairs_only else {})}) - - if (args.get('print_one_column', False) or - args.get('list_pairs_print_json', False) or - args.get('print_csv', False)): - # Print summary string in the log in case of machine-readable - # regular formats. - logger.info(f"{summary_str}.") - else: - # Print empty string separating leading logs and output in case of - # human-readable formats. - print() - - if len(pairs): - if args.get('print_list', False): - # print data as a list, with human-readable summary - print(f"{summary_str}: {', '.join(pairs.keys())}.") - elif args.get('print_one_column', False): - print('\n'.join(pairs.keys())) - elif args.get('list_pairs_print_json', False): - print(rapidjson.dumps(list(pairs.keys()), default=str)) - elif args.get('print_csv', False): - writer = csv.DictWriter(sys.stdout, fieldnames=headers) - writer.writeheader() - writer.writerows(tabular_data) - else: - # print data as a table, with the human-readable summary - print(f"{summary_str}:") - print(tabulate(tabular_data, headers='keys', tablefmt='pipe')) - elif not (args.get('print_one_column', False) or - args.get('list_pairs_print_json', False) or - args.get('print_csv', False)): - print(f"{summary_str}.") - - def start_test_pairlist(args: Dict[str, Any]) -> None: """ Test Pairlist configuration @@ -377,106 +124,3 @@ def start_test_pairlist(args: Dict[str, Any]) -> None: print(rapidjson.dumps(list(pairlist), default=str)) else: print(pairlist) - - -def start_hyperopt_list(args: Dict[str, Any]) -> None: - """ - List hyperopt epochs previously evaluated - """ - from freqtrade.optimize.hyperopt import Hyperopt - - config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) - print_colorized = config.get('print_colorized', False) - print_json = config.get('print_json', False) - no_details = config.get('hyperopt_list_no_details', False) - no_header = False - - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') - - # Previous evaluations - trials = Hyperopt.load_previous_results(trials_file) - total_epochs = len(trials) - - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) - - # TODO: fetch the interval for epochs to print from the cli option - epoch_start, epoch_stop = 0, None - - if print_colorized: - colorama_init(autoreset=True) - - try: - # Human-friendly indexes used here (starting from 1) - for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, not only_best, print_colorized) - - except KeyboardInterrupt: - print('User interrupted..') - - if trials and not no_details: - sorted_trials = sorted(trials, key=itemgetter('loss')) - results = sorted_trials[0] - Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) - - -def start_hyperopt_show(args: Dict[str, Any]) -> None: - """ - Show details of a hyperopt epoch previously evaluated - """ - from freqtrade.optimize.hyperopt import Hyperopt - - config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) - no_header = config.get('hyperopt_show_no_header', False) - - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') - - # Previous evaluations - trials = Hyperopt.load_previous_results(trials_file) - total_epochs = len(trials) - - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) - trials_epochs = len(trials) - - n = config.get('hyperopt_show_index', -1) - if n > trials_epochs: - raise OperationalException( - f"The index of the epoch to show should be less than {trials_epochs + 1}.") - if n < -trials_epochs: - raise OperationalException( - f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") - - # Translate epoch index from human-readable format to pythonic - if n > 0: - n -= 1 - - print_json = config.get('print_json', False) - - if trials: - val = trials[n] - Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, - header_str="Epoch details") - - -def _hyperopt_filter_trials(trials: List, only_best: bool, only_profitable: bool) -> List: - """ - Filter our items from the list of hyperopt results - """ - if only_best: - trials = [x for x in trials if x['is_best']] - if only_profitable: - trials = [x for x in trials if x['results_metrics']['profit'] > 0] - - logger.info(f"{len(trials)} " + - ("best " if only_best else "") + - ("profitable " if only_profitable else "") + - "epochs found.") - - return trials From 7e233041877d7c4976735e10269a2f3421c530f1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:09:13 +0100 Subject: [PATCH 0324/1106] Adjust tests to new paths --- tests/test_utils.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 91009ec42..c686d2117 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -451,8 +451,8 @@ def test_create_datadir(caplog, mocker): # Added assert here to analyze random test-failures ... assert len(caplog.record_tuples) == 0 - cud = mocker.patch("freqtrade.commands.create_userdata_dir", MagicMock()) - csf = mocker.patch("freqtrade.commands.copy_sample_files", MagicMock()) + cud = mocker.patch("freqtrade.commands.deploy_commands.create_userdata_dir", MagicMock()) + csf = mocker.patch("freqtrade.commands.deploy_commands.copy_sample_files", MagicMock()) args = [ "create-userdir", "--userdir", @@ -538,7 +538,7 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): def test_download_data_keyboardInterrupt(mocker, caplog, markets): - dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) patch_exchange(mocker) mocker.patch( @@ -556,7 +556,7 @@ def test_download_data_keyboardInterrupt(mocker, caplog, markets): def test_download_data_no_markets(mocker, caplog): - dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker, id='binance') mocker.patch( @@ -574,7 +574,7 @@ def test_download_data_no_markets(mocker, caplog): def test_download_data_no_exchange(mocker, caplog): - mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -594,7 +594,7 @@ def test_download_data_no_pairs(mocker, caplog): mocker.patch.object(Path, "exists", MagicMock(return_value=False)) - mocker.patch('freqtrade.commands.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -613,9 +613,9 @@ def test_download_data_no_pairs(mocker, caplog): def test_download_data_trades(mocker, caplog): - dl_mock = mocker.patch('freqtrade.commands.refresh_backtest_trades_data', + dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_trades_data', MagicMock(return_value=[])) - convert_mock = mocker.patch('freqtrade.commands.convert_trades_to_ohlcv', + convert_mock = mocker.patch('freqtrade.commands.utils.convert_trades_to_ohlcv', MagicMock(return_value=[])) patch_exchange(mocker) mocker.patch( From 70a0346b0a2b781dda480dc1a00da9215ac80eea Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:17:26 +0100 Subject: [PATCH 0325/1106] Move data-stuff to data-commands --- freqtrade/commands/__init__.py | 16 +++---- freqtrade/commands/data_commands.py | 64 +++++++++++++++++++++++++ freqtrade/commands/utils.py | 73 ++--------------------------- tests/test_utils.py | 12 ++--- 4 files changed, 81 insertions(+), 84 deletions(-) create mode 100644 freqtrade/commands/data_commands.py diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 4c57efeae..5fa667ccc 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -1,10 +1,10 @@ -from .hyperopt_commands import (start_hyperopt_list, start_hyperopt_show) # noqa: 401 - -from .list_commands import (start_list_exchanges, # noqa: F401 +from freqtrade.commands.data_commands import start_download_data # noqa: F401 +from freqtrade.commands.deploy_commands import (start_create_userdir, # noqa: F401 + start_new_hyperopt, start_new_strategy) +from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, # noqa: F401 + start_hyperopt_show) +from freqtrade.commands.list_commands import (start_list_exchanges, # noqa: F401 start_list_markets, start_list_strategies, start_list_timeframes) -from .utils import setup_utils_configuration # noqa: F401 -from .utils import (start_download_data, # noqa: F401 - start_test_pairlist) -from .deploy_commands import (start_new_hyperopt, start_new_strategy, start_create_userdir) # noqa: F401 -from .trade_commands import start_trading # noqa: F401 +from freqtrade.commands.trade_commands import start_trading # noqa: F401 +from freqtrade.commands.utils import setup_utils_configuration, start_test_pairlist # noqa: F401 diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py new file mode 100644 index 000000000..b1c847d1d --- /dev/null +++ b/freqtrade/commands/data_commands.py @@ -0,0 +1,64 @@ +import logging +import sys +from typing import Any, Dict, List + +import arrow + +from freqtrade.configuration import TimeRange +from freqtrade.data.history import (convert_trades_to_ohlcv, + refresh_backtest_ohlcv_data, + refresh_backtest_trades_data) +from freqtrade.exceptions import OperationalException +from freqtrade.resolvers import ExchangeResolver +from freqtrade.state import RunMode +from .utils import setup_utils_configuration + +logger = logging.getLogger(__name__) + + +def start_download_data(args: Dict[str, Any]) -> None: + """ + Download data (former download_backtest_data.py script) + """ + config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) + + timerange = TimeRange() + if 'days' in config: + time_since = arrow.utcnow().shift(days=-config['days']).strftime("%Y%m%d") + timerange = TimeRange.parse_timerange(f'{time_since}-') + + if 'pairs' not in config: + raise OperationalException( + "Downloading data requires a list of pairs. " + "Please check the documentation on how to configure this.") + + logger.info(f'About to download pairs: {config["pairs"]}, ' + f'intervals: {config["timeframes"]} to {config["datadir"]}') + + pairs_not_available: List[str] = [] + + # Init exchange + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) + try: + + if config.get('download_trades'): + pairs_not_available = refresh_backtest_trades_data( + exchange, pairs=config["pairs"], datadir=config['datadir'], + timerange=timerange, erase=config.get("erase")) + + # Convert downloaded trade data to different timeframes + convert_trades_to_ohlcv( + pairs=config["pairs"], timeframes=config["timeframes"], + datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + else: + pairs_not_available = refresh_backtest_ohlcv_data( + exchange, pairs=config["pairs"], timeframes=config["timeframes"], + datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + + except KeyboardInterrupt: + sys.exit("SIGINT received, aborting ...") + + finally: + if pairs_not_available: + logger.info(f"Pairs [{','.join(pairs_not_available)}] not available " + f"on exchange {exchange.name}.") diff --git a/freqtrade/commands/utils.py b/freqtrade/commands/utils.py index ba9173cf2..a597d5335 100644 --- a/freqtrade/commands/utils.py +++ b/freqtrade/commands/utils.py @@ -1,30 +1,11 @@ -import csv import logging -import sys -from collections import OrderedDict -from operator import itemgetter -from pathlib import Path -from typing import Any, Dict, List +from typing import Any, Dict -import arrow import rapidjson -from colorama import init as colorama_init -from tabulate import tabulate -from freqtrade.configuration import (Configuration, TimeRange, - remove_credentials, +from freqtrade.configuration import (Configuration, remove_credentials, validate_config_consistency) -from freqtrade.configuration.directory_operations import (copy_sample_files, - create_userdata_dir) -from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY -from freqtrade.data.history import (convert_trades_to_ohlcv, - refresh_backtest_ohlcv_data, - refresh_backtest_trades_data) -from freqtrade.exceptions import OperationalException -from freqtrade.exchange import (available_exchanges, ccxt_exchanges, - market_is_active, symbol_is_pair) -from freqtrade.misc import plural, render_template -from freqtrade.resolvers import ExchangeResolver, StrategyResolver +from freqtrade.resolvers import ExchangeResolver from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -46,54 +27,6 @@ def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str return config -def start_download_data(args: Dict[str, Any]) -> None: - """ - Download data (former download_backtest_data.py script) - """ - config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - - timerange = TimeRange() - if 'days' in config: - time_since = arrow.utcnow().shift(days=-config['days']).strftime("%Y%m%d") - timerange = TimeRange.parse_timerange(f'{time_since}-') - - if 'pairs' not in config: - raise OperationalException( - "Downloading data requires a list of pairs. " - "Please check the documentation on how to configure this.") - - logger.info(f'About to download pairs: {config["pairs"]}, ' - f'intervals: {config["timeframes"]} to {config["datadir"]}') - - pairs_not_available: List[str] = [] - - # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) - try: - - if config.get('download_trades'): - pairs_not_available = refresh_backtest_trades_data( - exchange, pairs=config["pairs"], datadir=config['datadir'], - timerange=timerange, erase=config.get("erase")) - - # Convert downloaded trade data to different timeframes - convert_trades_to_ohlcv( - pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) - else: - pairs_not_available = refresh_backtest_ohlcv_data( - exchange, pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) - - except KeyboardInterrupt: - sys.exit("SIGINT received, aborting ...") - - finally: - if pairs_not_available: - logger.info(f"Pairs [{','.join(pairs_not_available)}] not available " - f"on exchange {exchange.name}.") - - def start_test_pairlist(args: Dict[str, Any]) -> None: """ Test Pairlist configuration diff --git a/tests/test_utils.py b/tests/test_utils.py index c686d2117..1328e3981 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -538,7 +538,7 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): def test_download_data_keyboardInterrupt(mocker, caplog, markets): - dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) patch_exchange(mocker) mocker.patch( @@ -556,7 +556,7 @@ def test_download_data_keyboardInterrupt(mocker, caplog, markets): def test_download_data_no_markets(mocker, caplog): - dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', + dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker, id='binance') mocker.patch( @@ -574,7 +574,7 @@ def test_download_data_no_markets(mocker, caplog): def test_download_data_no_exchange(mocker, caplog): - mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -594,7 +594,7 @@ def test_download_data_no_pairs(mocker, caplog): mocker.patch.object(Path, "exists", MagicMock(return_value=False)) - mocker.patch('freqtrade.commands.utils.refresh_backtest_ohlcv_data', + mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch( @@ -613,9 +613,9 @@ def test_download_data_no_pairs(mocker, caplog): def test_download_data_trades(mocker, caplog): - dl_mock = mocker.patch('freqtrade.commands.utils.refresh_backtest_trades_data', + dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_trades_data', MagicMock(return_value=[])) - convert_mock = mocker.patch('freqtrade.commands.utils.convert_trades_to_ohlcv', + convert_mock = mocker.patch('freqtrade.commands.data_commands.convert_trades_to_ohlcv', MagicMock(return_value=[])) patch_exchange(mocker) mocker.patch( From b254bdfea31c95b237b2642c6b55050d1e727b45 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:20:34 +0100 Subject: [PATCH 0326/1106] Move plot_utils to plot_commands --- freqtrade/commands/__init__.py | 1 + freqtrade/{plot/plot_utils.py => commands/plot_commands.py} | 2 +- freqtrade/configuration/arguments.py | 2 +- tests/test_plotting.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename freqtrade/{plot/plot_utils.py => commands/plot_commands.py} (94%) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 5fa667ccc..45088e8a3 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -6,5 +6,6 @@ from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, # noqa: from freqtrade.commands.list_commands import (start_list_exchanges, # noqa: F401 start_list_markets, start_list_strategies, start_list_timeframes) +from freqtrade.commands.plot_commands import start_plot_dataframe, start_plot_profit # noqa: F401 from freqtrade.commands.trade_commands import start_trading # noqa: F401 from freqtrade.commands.utils import setup_utils_configuration, start_test_pairlist # noqa: F401 diff --git a/freqtrade/plot/plot_utils.py b/freqtrade/commands/plot_commands.py similarity index 94% rename from freqtrade/plot/plot_utils.py rename to freqtrade/commands/plot_commands.py index b2f16dff0..4c68cc3c5 100644 --- a/freqtrade/plot/plot_utils.py +++ b/freqtrade/commands/plot_commands.py @@ -2,7 +2,7 @@ from typing import Any, Dict from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from freqtrade.commands import setup_utils_configuration +from freqtrade.commands.utils import setup_utils_configuration def validate_plot_args(args: Dict[str, Any]): diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 3c71fa548..c61e4ec13 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -136,8 +136,8 @@ class Arguments: start_list_exchanges, start_list_markets, start_list_strategies, start_new_hyperopt, start_new_strategy, start_list_timeframes, + start_plot_dataframe, start_plot_profit, start_test_pairlist, start_trading) - from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit subparsers = self.parser.add_subparsers(dest='command', # Use custom message when no subhandler is added diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 78c01eb97..e7ec4ce46 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -11,7 +11,7 @@ from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data from freqtrade.exceptions import OperationalException -from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit +from freqtrade.commands import start_plot_dataframe, start_plot_profit from freqtrade.plot.plotting import (add_indicators, add_profit, create_plotconfig, generate_candlestick_graph, From e033df6a2fce1d50333e70e599cd7dfde187b162 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:32:52 +0100 Subject: [PATCH 0327/1106] Move optimize_commands to commands module --- .../__init__.py => commands/optimize_commands.py} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename freqtrade/{optimize/__init__.py => commands/optimize_commands.py} (89%) diff --git a/freqtrade/optimize/__init__.py b/freqtrade/commands/optimize_commands.py similarity index 89% rename from freqtrade/optimize/__init__.py rename to freqtrade/commands/optimize_commands.py index 98b521d4e..e635e61fd 100644 --- a/freqtrade/optimize/__init__.py +++ b/freqtrade/commands/optimize_commands.py @@ -2,14 +2,14 @@ import logging from typing import Any, Dict from freqtrade import constants +from freqtrade.commands.utils import setup_utils_configuration from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.state import RunMode -from freqtrade.commands import setup_utils_configuration logger = logging.getLogger(__name__) -def setup_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]: +def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]: """ Prepare the configuration for the Hyperopt module :param args: Cli args from Arguments() @@ -35,7 +35,7 @@ def start_backtesting(args: Dict[str, Any]) -> None: from freqtrade.optimize.backtesting import Backtesting # Initialize configuration - config = setup_configuration(args, RunMode.BACKTEST) + config = setup_optimize_configuration(args, RunMode.BACKTEST) logger.info('Starting freqtrade in Backtesting mode') @@ -58,7 +58,7 @@ def start_hyperopt(args: Dict[str, Any]) -> None: raise OperationalException( f"{e}. Please ensure that the hyperopt dependencies are installed.") from e # Initialize configuration - config = setup_configuration(args, RunMode.HYPEROPT) + config = setup_optimize_configuration(args, RunMode.HYPEROPT) logger.info('Starting freqtrade in Hyperopt mode') @@ -94,7 +94,7 @@ def start_edge(args: Dict[str, Any]) -> None: """ from freqtrade.optimize.edge_cli import EdgeCli # Initialize configuration - config = setup_configuration(args, RunMode.EDGE) + config = setup_optimize_configuration(args, RunMode.EDGE) logger.info('Starting freqtrade in Edge mode') # Initialize Edge object From f347e5934a6be5d515c983daac4755ee3a8ec9ca Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:33:13 +0100 Subject: [PATCH 0328/1106] Small adjustments for moved commands --- freqtrade/commands/__init__.py | 30 ++++++++++++++++++---------- freqtrade/configuration/arguments.py | 2 +- freqtrade/optimize/__init__.py | 0 tests/optimize/test_backtesting.py | 12 +++++------ tests/optimize/test_edge_cli.py | 8 ++++---- tests/optimize/test_hyperopt.py | 8 ++++---- tests/test_main.py | 4 ++-- 7 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 freqtrade/optimize/__init__.py diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 45088e8a3..8339486fb 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -1,11 +1,19 @@ -from freqtrade.commands.data_commands import start_download_data # noqa: F401 -from freqtrade.commands.deploy_commands import (start_create_userdir, # noqa: F401 - start_new_hyperopt, start_new_strategy) -from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, # noqa: F401 - start_hyperopt_show) -from freqtrade.commands.list_commands import (start_list_exchanges, # noqa: F401 - start_list_markets, start_list_strategies, - start_list_timeframes) -from freqtrade.commands.plot_commands import start_plot_dataframe, start_plot_profit # noqa: F401 -from freqtrade.commands.trade_commands import start_trading # noqa: F401 -from freqtrade.commands.utils import setup_utils_configuration, start_test_pairlist # noqa: F401 +# flake8: noqa: F401 + +from freqtrade.commands.data_commands import start_download_data +from freqtrade.commands.deploy_commands import (start_create_userdir, + start_new_hyperopt, + start_new_strategy) +from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, + start_hyperopt_show) +from freqtrade.commands.list_commands import (start_list_exchanges, + start_list_markets, + start_list_strategies, + start_list_timeframes) +from freqtrade.commands.optimize_commands import (start_backtesting, + start_edge, start_hyperopt) +from freqtrade.commands.plot_commands import (start_plot_dataframe, + start_plot_profit) +from freqtrade.commands.trade_commands import start_trading +from freqtrade.commands.utils import (setup_utils_configuration, + start_test_pairlist) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index c61e4ec13..21800e821 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -130,13 +130,13 @@ class Arguments: self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot') self._build_args(optionlist=['version'], parser=self.parser) - from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, start_list_strategies, start_new_hyperopt, start_new_strategy, start_list_timeframes, start_plot_dataframe, start_plot_profit, + start_backtesting, start_hyperopt, start_edge, start_test_pairlist, start_trading) subparsers = self.parser.add_subparsers(dest='command', diff --git a/freqtrade/optimize/__init__.py b/freqtrade/optimize/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index acbc44e21..07872da57 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -12,13 +12,13 @@ from arrow import Arrow from freqtrade import constants from freqtrade.configuration import TimeRange +from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_backtesting from freqtrade.data import history from freqtrade.data.btanalysis import evaluate_result_multi from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException -from freqtrade.optimize import setup_configuration, start_backtesting from freqtrade.optimize.backtesting import Backtesting from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy @@ -177,7 +177,7 @@ def _trend_alternate(dataframe=None, metadata=None): # Unit tests -def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None: +def test_setup_optimize_configuration_without_arguments(mocker, default_conf, caplog) -> None: patched_configuration_load_config_file(mocker, default_conf) args = [ @@ -186,7 +186,7 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> '--strategy', 'DefaultStrategy', ] - config = setup_configuration(get_args(args), RunMode.BACKTEST) + config = setup_optimize_configuration(get_args(args), RunMode.BACKTEST) assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config @@ -227,7 +227,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> '--fee', '0', ] - config = setup_configuration(get_args(args), RunMode.BACKTEST) + config = setup_optimize_configuration(get_args(args), RunMode.BACKTEST) assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config @@ -260,7 +260,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> assert log_has('Parameter --fee detected, setting fee to: {} ...'.format(config['fee']), caplog) -def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None: +def test_setup_optimize_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None: default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT patched_configuration_load_config_file(mocker, default_conf) @@ -272,7 +272,7 @@ def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog ] with pytest.raises(DependencyException, match=r'.*stake amount.*'): - setup_configuration(get_args(args), RunMode.BACKTEST) + setup_optimize_configuration(get_args(args), RunMode.BACKTEST) def test_start(mocker, fee, default_conf, caplog) -> None: diff --git a/tests/optimize/test_edge_cli.py b/tests/optimize/test_edge_cli.py index acc0d2d16..96dd0899d 100644 --- a/tests/optimize/test_edge_cli.py +++ b/tests/optimize/test_edge_cli.py @@ -3,14 +3,14 @@ from unittest.mock import MagicMock -from freqtrade.optimize import setup_configuration, start_edge +from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_edge from freqtrade.optimize.edge_cli import EdgeCli from freqtrade.state import RunMode from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) -def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None: +def test_setup_optimize_configuration_without_arguments(mocker, default_conf, caplog) -> None: patched_configuration_load_config_file(mocker, default_conf) args = [ @@ -19,7 +19,7 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> '--strategy', 'DefaultStrategy', ] - config = setup_configuration(get_args(args), RunMode.EDGE) + config = setup_optimize_configuration(get_args(args), RunMode.EDGE) assert config['runmode'] == RunMode.EDGE assert 'max_open_trades' in config @@ -53,7 +53,7 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N '--stoplosses=-0.01,-0.10,-0.001' ] - config = setup_configuration(get_args(args), RunMode.EDGE) + config = setup_optimize_configuration(get_args(args), RunMode.EDGE) assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 473d760ac..69d110649 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -9,10 +9,10 @@ import pytest from arrow import Arrow from filelock import Timeout -from freqtrade.exceptions import OperationalException +from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_hyperopt from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file -from freqtrade.optimize import setup_configuration, start_hyperopt +from freqtrade.exceptions import OperationalException from freqtrade.optimize.default_hyperopt import DefaultHyperOpt from freqtrade.optimize.default_hyperopt_loss import DefaultHyperOptLoss from freqtrade.optimize.hyperopt import Hyperopt @@ -77,7 +77,7 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca '--hyperopt', 'DefaultHyperOpt', ] - config = setup_configuration(get_args(args), RunMode.HYPEROPT) + config = setup_optimize_configuration(get_args(args), RunMode.HYPEROPT) assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config @@ -117,7 +117,7 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo '--print-all' ] - config = setup_configuration(get_args(args), RunMode.HYPEROPT) + config = setup_optimize_configuration(get_args(args), RunMode.HYPEROPT) assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config diff --git a/tests/test_main.py b/tests/test_main.py index 76b1bf658..462ac6427 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -26,7 +26,7 @@ def test_parse_args_backtesting(mocker) -> None: Test that main() can start backtesting and also ensure we can pass some specific arguments further argument parsing is done in test_arguments.py """ - backtesting_mock = mocker.patch('freqtrade.optimize.start_backtesting', MagicMock()) + backtesting_mock = mocker.patch('freqtrade.commands.start_backtesting') backtesting_mock.__name__ = PropertyMock("start_backtesting") # it's sys.exit(0) at the end of backtesting with pytest.raises(SystemExit): @@ -42,7 +42,7 @@ def test_parse_args_backtesting(mocker) -> None: def test_main_start_hyperopt(mocker) -> None: - hyperopt_mock = mocker.patch('freqtrade.optimize.start_hyperopt', MagicMock()) + hyperopt_mock = mocker.patch('freqtrade.commands.start_hyperopt', MagicMock()) hyperopt_mock.__name__ = PropertyMock("start_hyperopt") # it's sys.exit(0) at the end of hyperopt with pytest.raises(SystemExit): From a1c684f67ca3dcf0c6293d71511c72a0dcbd2cb3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:36:33 +0100 Subject: [PATCH 0329/1106] Simplify noqa setup for module imports --- freqtrade/configuration/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/configuration/__init__.py b/freqtrade/configuration/__init__.py index 63c38d8c5..a631609d7 100644 --- a/freqtrade/configuration/__init__.py +++ b/freqtrade/configuration/__init__.py @@ -1,5 +1,7 @@ -from freqtrade.configuration.arguments import Arguments # noqa: F401 -from freqtrade.configuration.check_exchange import check_exchange, remove_credentials # noqa: F401 -from freqtrade.configuration.timerange import TimeRange # noqa: F401 -from freqtrade.configuration.configuration import Configuration # noqa: F401 -from freqtrade.configuration.config_validation import validate_config_consistency # noqa: F401 +# flake8: noqa: F401 + +from freqtrade.configuration.arguments import Arguments +from freqtrade.configuration.check_exchange import check_exchange, remove_credentials +from freqtrade.configuration.timerange import TimeRange +from freqtrade.configuration.configuration import Configuration +from freqtrade.configuration.config_validation import validate_config_consistency From 7f851ad8d950d5c26da08f76ad239610136af51c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:38:56 +0100 Subject: [PATCH 0330/1106] Move arguments and cli_options to commands module --- freqtrade/{configuration => commands}/arguments.py | 0 freqtrade/{configuration => commands}/cli_options.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename freqtrade/{configuration => commands}/arguments.py (100%) rename freqtrade/{configuration => commands}/cli_options.py (100%) diff --git a/freqtrade/configuration/arguments.py b/freqtrade/commands/arguments.py similarity index 100% rename from freqtrade/configuration/arguments.py rename to freqtrade/commands/arguments.py diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/commands/cli_options.py similarity index 100% rename from freqtrade/configuration/cli_options.py rename to freqtrade/commands/cli_options.py From a3e9d04383bdc37aea465561306334042adc801a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:41:04 +0100 Subject: [PATCH 0331/1106] Adjust imports to new place for arguments --- freqtrade/commands/__init__.py | 1 + freqtrade/commands/arguments.py | 2 +- freqtrade/commands/cli_options.py | 6 +++--- freqtrade/configuration/__init__.py | 1 - freqtrade/main.py | 2 +- tests/conftest.py | 2 +- tests/test_arguments.py | 4 ++-- tests/test_configuration.py | 3 ++- tests/test_main.py | 2 +- 9 files changed, 12 insertions(+), 11 deletions(-) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 8339486fb..dcb814c50 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -1,5 +1,6 @@ # flake8: noqa: F401 +from freqtrade.commands.arguments import Arguments from freqtrade.commands.data_commands import start_download_data from freqtrade.commands.deploy_commands import (start_create_userdir, start_new_hyperopt, diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 21800e821..724814554 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -7,7 +7,7 @@ from pathlib import Path from typing import Any, Dict, List, Optional from freqtrade import constants -from freqtrade.configuration.cli_options import AVAILABLE_CLI_OPTIONS +from freqtrade.commands.cli_options import AVAILABLE_CLI_OPTIONS ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 1807cd591..490f26cfa 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -1,7 +1,7 @@ """ Definition of cli arguments used in arguments.py """ -import argparse +from argparse import ArgumentTypeError from freqtrade import __version__, constants @@ -12,7 +12,7 @@ def check_int_positive(value: str) -> int: if uint <= 0: raise ValueError except ValueError: - raise argparse.ArgumentTypeError( + raise ArgumentTypeError( f"{value} is invalid for this parameter, should be a positive integer value" ) return uint @@ -24,7 +24,7 @@ def check_int_nonzero(value: str) -> int: if uint == 0: raise ValueError except ValueError: - raise argparse.ArgumentTypeError( + raise ArgumentTypeError( f"{value} is invalid for this parameter, should be a non-zero integer value" ) return uint diff --git a/freqtrade/configuration/__init__.py b/freqtrade/configuration/__init__.py index a631609d7..54fc4e427 100644 --- a/freqtrade/configuration/__init__.py +++ b/freqtrade/configuration/__init__.py @@ -1,6 +1,5 @@ # flake8: noqa: F401 -from freqtrade.configuration.arguments import Arguments from freqtrade.configuration.check_exchange import check_exchange, remove_credentials from freqtrade.configuration.timerange import TimeRange from freqtrade.configuration.configuration import Configuration diff --git a/freqtrade/main.py b/freqtrade/main.py index 811e29864..a75eeebed 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -14,7 +14,7 @@ if sys.version_info < (3, 6): import logging from typing import Any, List -from freqtrade.configuration import Arguments +from freqtrade.commands import Arguments logger = logging.getLogger('freqtrade') diff --git a/tests/conftest.py b/tests/conftest.py index 295c91f56..395388f73 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,7 +14,7 @@ import pytest from telegram import Chat, Message, Update from freqtrade import constants, persistence -from freqtrade.configuration import Arguments +from freqtrade.commands import Arguments from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.edge import Edge, PairInfo from freqtrade.exchange import Exchange diff --git a/tests/test_arguments.py b/tests/test_arguments.py index d8fbace0f..60da0082a 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -5,8 +5,8 @@ from unittest.mock import MagicMock import pytest -from freqtrade.configuration import Arguments -from freqtrade.configuration.cli_options import check_int_positive +from freqtrade.commands import Arguments +from freqtrade.commands.cli_options import check_int_positive # Parse common command-line-arguments. Used for all tools diff --git a/tests/test_configuration.py b/tests/test_configuration.py index cbcd6416a..74de166c1 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -10,7 +10,8 @@ from unittest.mock import MagicMock import pytest from jsonschema import ValidationError -from freqtrade.configuration import (Arguments, Configuration, check_exchange, +from freqtrade.commands import Arguments +from freqtrade.configuration import (Configuration, check_exchange, remove_credentials, validate_config_consistency) from freqtrade.configuration.config_validation import validate_config_schema diff --git a/tests/test_main.py b/tests/test_main.py index 462ac6427..1229f748a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade.configuration import Arguments +from freqtrade.commands import Arguments from freqtrade.exceptions import OperationalException, FreqtradeException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.main import main From 2d02c3f2a4097aa56182ff9d56bf4f631ac06696 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:43:30 +0100 Subject: [PATCH 0332/1106] Split out pairlist_commands --- freqtrade/commands/__init__.py | 4 +-- freqtrade/commands/pairlist_commands.py | 43 +++++++++++++++++++++++++ freqtrade/commands/utils.py | 35 -------------------- 3 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 freqtrade/commands/pairlist_commands.py diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index dcb814c50..e16a6f203 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -13,8 +13,8 @@ from freqtrade.commands.list_commands import (start_list_exchanges, start_list_timeframes) from freqtrade.commands.optimize_commands import (start_backtesting, start_edge, start_hyperopt) +from freqtrade.commands.pairlist_commands import start_test_pairlist from freqtrade.commands.plot_commands import (start_plot_dataframe, start_plot_profit) from freqtrade.commands.trade_commands import start_trading -from freqtrade.commands.utils import (setup_utils_configuration, - start_test_pairlist) +from freqtrade.commands.utils import setup_utils_configuration diff --git a/freqtrade/commands/pairlist_commands.py b/freqtrade/commands/pairlist_commands.py new file mode 100644 index 000000000..06ba2e680 --- /dev/null +++ b/freqtrade/commands/pairlist_commands.py @@ -0,0 +1,43 @@ +import logging +from typing import Any, Dict + +import rapidjson + +from freqtrade.resolvers import ExchangeResolver +from freqtrade.state import RunMode + +from .utils import setup_utils_configuration + +logger = logging.getLogger(__name__) + + +def start_test_pairlist(args: Dict[str, Any]) -> None: + """ + Test Pairlist configuration + """ + from freqtrade.pairlist.pairlistmanager import PairListManager + config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) + + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + + quote_currencies = args.get('quote_currencies') + if not quote_currencies: + quote_currencies = [config.get('stake_currency')] + results = {} + for curr in quote_currencies: + config['stake_currency'] = curr + # Do not use ticker_interval set in the config + pairlists = PairListManager(exchange, config) + pairlists.refresh_pairlist() + results[curr] = pairlists.whitelist + + for curr, pairlist in results.items(): + if not args.get('print_one_column', False): + print(f"Pairs for {curr}: ") + + if args.get('print_one_column', False): + print('\n'.join(pairlist)) + elif args.get('list_pairs_print_json', False): + print(rapidjson.dumps(list(pairlist), default=str)) + else: + print(pairlist) diff --git a/freqtrade/commands/utils.py b/freqtrade/commands/utils.py index a597d5335..f77a35383 100644 --- a/freqtrade/commands/utils.py +++ b/freqtrade/commands/utils.py @@ -1,11 +1,8 @@ import logging from typing import Any, Dict -import rapidjson - from freqtrade.configuration import (Configuration, remove_credentials, validate_config_consistency) -from freqtrade.resolvers import ExchangeResolver from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -25,35 +22,3 @@ def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str validate_config_consistency(config) return config - - -def start_test_pairlist(args: Dict[str, Any]) -> None: - """ - Test Pairlist configuration - """ - from freqtrade.pairlist.pairlistmanager import PairListManager - config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) - - quote_currencies = args.get('quote_currencies') - if not quote_currencies: - quote_currencies = [config.get('stake_currency')] - results = {} - for curr in quote_currencies: - config['stake_currency'] = curr - # Do not use ticker_interval set in the config - pairlists = PairListManager(exchange, config) - pairlists.refresh_pairlist() - results[curr] = pairlists.whitelist - - for curr, pairlist in results.items(): - if not args.get('print_one_column', False): - print(f"Pairs for {curr}: ") - - if args.get('print_one_column', False): - print('\n'.join(pairlist)) - elif args.get('list_pairs_print_json', False): - print(rapidjson.dumps(list(pairlist), default=str)) - else: - print(pairlist) From 8c9119b4710e467d4833638d582aba5914d61d2b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:45:37 +0100 Subject: [PATCH 0333/1106] Add docustring to commands module --- freqtrade/commands/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index e16a6f203..1dadbec1e 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -1,5 +1,11 @@ # flake8: noqa: F401 +""" +Commands module. +Contains all start-commands, subcommands and CLI Interface creation. +Note: Be careful with file-scoped imports in these subfiles. + as they are parsed on startup, nothing containing optional modules should be loaded. +""" from freqtrade.commands.arguments import Arguments from freqtrade.commands.data_commands import start_download_data from freqtrade.commands.deploy_commands import (start_create_userdir, From 02563019fc84d559584ae007c6c9d5f4055da911 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 26 Jan 2020 13:55:48 +0100 Subject: [PATCH 0334/1106] move setup_utils_config to configuration module --- freqtrade/commands/__init__.py | 1 - freqtrade/commands/data_commands.py | 3 +-- freqtrade/commands/deploy_commands.py | 3 +-- freqtrade/commands/hyperopt_commands.py | 2 +- freqtrade/commands/list_commands.py | 3 +-- freqtrade/commands/optimize_commands.py | 2 +- freqtrade/commands/pairlist_commands.py | 3 +-- freqtrade/commands/plot_commands.py | 2 +- freqtrade/configuration/__init__.py | 1 + .../{commands/utils.py => configuration/config_setup.py} | 5 +++-- tests/commands/__init__.py | 0 tests/{test_utils.py => commands/test_commands.py} | 8 ++++---- 12 files changed, 15 insertions(+), 18 deletions(-) rename freqtrade/{commands/utils.py => configuration/config_setup.py} (79%) create mode 100644 tests/commands/__init__.py rename tests/{test_utils.py => commands/test_commands.py} (99%) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 1dadbec1e..990c1107a 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -23,4 +23,3 @@ from freqtrade.commands.pairlist_commands import start_test_pairlist from freqtrade.commands.plot_commands import (start_plot_dataframe, start_plot_profit) from freqtrade.commands.trade_commands import start_trading -from freqtrade.commands.utils import setup_utils_configuration diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index b1c847d1d..c01772023 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -4,14 +4,13 @@ from typing import Any, Dict, List import arrow -from freqtrade.configuration import TimeRange +from freqtrade.configuration import TimeRange, setup_utils_configuration from freqtrade.data.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data, refresh_backtest_trades_data) from freqtrade.exceptions import OperationalException from freqtrade.resolvers import ExchangeResolver from freqtrade.state import RunMode -from .utils import setup_utils_configuration logger = logging.getLogger(__name__) diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 892e15db1..99ae63244 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -3,6 +3,7 @@ import sys from pathlib import Path from typing import Any, Dict +from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY @@ -10,8 +11,6 @@ from freqtrade.exceptions import OperationalException from freqtrade.misc import render_template from freqtrade.state import RunMode -from .utils import setup_utils_configuration - logger = logging.getLogger(__name__) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index db3f69050..5c6f25848 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -4,7 +4,7 @@ from typing import Any, Dict, List from colorama import init as colorama_init -from .utils import setup_utils_configuration +from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 90efaf66f..022822782 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -8,6 +8,7 @@ from typing import Any, Dict import rapidjson from tabulate import tabulate +from freqtrade.configuration import setup_utils_configuration from freqtrade.constants import USERPATH_STRATEGY from freqtrade.exceptions import OperationalException from freqtrade.exchange import (available_exchanges, ccxt_exchanges, @@ -16,8 +17,6 @@ from freqtrade.misc import plural from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode -from .utils import setup_utils_configuration - logger = logging.getLogger(__name__) diff --git a/freqtrade/commands/optimize_commands.py b/freqtrade/commands/optimize_commands.py index e635e61fd..a2d1b4601 100644 --- a/freqtrade/commands/optimize_commands.py +++ b/freqtrade/commands/optimize_commands.py @@ -2,7 +2,7 @@ import logging from typing import Any, Dict from freqtrade import constants -from freqtrade.commands.utils import setup_utils_configuration +from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.state import RunMode diff --git a/freqtrade/commands/pairlist_commands.py b/freqtrade/commands/pairlist_commands.py index 06ba2e680..bf0b217a5 100644 --- a/freqtrade/commands/pairlist_commands.py +++ b/freqtrade/commands/pairlist_commands.py @@ -3,11 +3,10 @@ from typing import Any, Dict import rapidjson +from freqtrade.configuration import setup_utils_configuration from freqtrade.resolvers import ExchangeResolver from freqtrade.state import RunMode -from .utils import setup_utils_configuration - logger = logging.getLogger(__name__) diff --git a/freqtrade/commands/plot_commands.py b/freqtrade/commands/plot_commands.py index 4c68cc3c5..028933ba7 100644 --- a/freqtrade/commands/plot_commands.py +++ b/freqtrade/commands/plot_commands.py @@ -1,8 +1,8 @@ from typing import Any, Dict +from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from freqtrade.commands.utils import setup_utils_configuration def validate_plot_args(args: Dict[str, Any]): diff --git a/freqtrade/configuration/__init__.py b/freqtrade/configuration/__init__.py index 54fc4e427..d41ac97ec 100644 --- a/freqtrade/configuration/__init__.py +++ b/freqtrade/configuration/__init__.py @@ -1,5 +1,6 @@ # flake8: noqa: F401 +from freqtrade.configuration.config_setup import setup_utils_configuration from freqtrade.configuration.check_exchange import check_exchange, remove_credentials from freqtrade.configuration.timerange import TimeRange from freqtrade.configuration.configuration import Configuration diff --git a/freqtrade/commands/utils.py b/freqtrade/configuration/config_setup.py similarity index 79% rename from freqtrade/commands/utils.py rename to freqtrade/configuration/config_setup.py index f77a35383..64f283e42 100644 --- a/freqtrade/commands/utils.py +++ b/freqtrade/configuration/config_setup.py @@ -1,8 +1,9 @@ import logging from typing import Any, Dict -from freqtrade.configuration import (Configuration, remove_credentials, - validate_config_consistency) +from .config_validation import validate_config_consistency +from .configuration import Configuration +from .check_exchange import remove_credentials from freqtrade.state import RunMode logger = logging.getLogger(__name__) diff --git a/tests/commands/__init__.py b/tests/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_utils.py b/tests/commands/test_commands.py similarity index 99% rename from tests/test_utils.py rename to tests/commands/test_commands.py index 1328e3981..65d7f6eaf 100644 --- a/tests/test_utils.py +++ b/tests/commands/test_commands.py @@ -4,13 +4,13 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade.commands import (setup_utils_configuration, - start_create_userdir, start_download_data, +from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, start_list_strategies, start_list_timeframes, start_new_hyperopt, start_new_strategy, start_test_pairlist, start_trading) +from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, @@ -639,7 +639,7 @@ def test_start_list_strategies(mocker, caplog, capsys): args = [ "list-strategies", "--strategy-path", - str(Path(__file__).parent / "strategy"), + str(Path(__file__).parent.parent / "strategy"), "-1" ] pargs = get_args(args) @@ -654,7 +654,7 @@ def test_start_list_strategies(mocker, caplog, capsys): args = [ "list-strategies", "--strategy-path", - str(Path(__file__).parent / "strategy"), + str(Path(__file__).parent.parent / "strategy"), ] pargs = get_args(args) # pargs['config'] = None From 33645e45fd3902a673ead1fbaf4f1a521134eaae Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 27 Jan 2020 02:49:25 +0300 Subject: [PATCH 0335/1106] Minor cosmetics in start_trading --- freqtrade/commands/trade_commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/commands/trade_commands.py b/freqtrade/commands/trade_commands.py index 2c0c4c9c1..352fac26d 100644 --- a/freqtrade/commands/trade_commands.py +++ b/freqtrade/commands/trade_commands.py @@ -10,8 +10,10 @@ def start_trading(args: Dict[str, Any]) -> int: """ Main entry point for trading mode """ + # Import here to avoid loading worker module when it's not used from freqtrade.worker import Worker - # Load and run worker + + # Create and run worker worker = None try: worker = Worker(args) From 30e3e434abc76e6c0af40b256540cc32479c410c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 27 Jan 2020 03:34:53 +0300 Subject: [PATCH 0336/1106] Add notify_status() to FreqtradeBot --- freqtrade/freqtradebot.py | 10 ++++++++++ freqtrade/worker.py | 24 +++++++----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e3856e200..6c519280d 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -95,6 +95,16 @@ class FreqtradeBot: # Protect sell-logic from forcesell and viceversa self._sell_lock = Lock() + def notify_status(self, msg: str) -> None: + """ + Public method for users of this class (worker, etc.) to send notifications + via RPC about changes in the bot status. + """ + self.rpc.send_msg({ + 'type': RPCMessageType.STATUS_NOTIFICATION, + 'status': msg + }) + def cleanup(self) -> None: """ Cleanup pending resources on an already stopped bot diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 22651d269..972ff0d61 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -12,7 +12,6 @@ from freqtrade import __version__, constants from freqtrade.configuration import Configuration from freqtrade.exceptions import OperationalException, TemporaryError from freqtrade.freqtradebot import FreqtradeBot -from freqtrade.rpc import RPCMessageType from freqtrade.state import State logger = logging.getLogger(__name__) @@ -84,10 +83,8 @@ class Worker: # Log state transition if state != old_state: - self.freqtrade.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'{state.name.lower()}' - }) + self.freqtrade.notify_status(f'{state.name.lower()}') + logger.info('Changing state to: %s', state.name) if state == State.RUNNING: self.freqtrade.startup() @@ -136,10 +133,9 @@ class Worker: except OperationalException: tb = traceback.format_exc() hint = 'Issue `/start` if you think it is safe to restart.' - self.freqtrade.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'OperationalException:\n```\n{tb}```{hint}' - }) + + self.freqtrade.notify_status(f'OperationalException:\n```\n{tb}```{hint}') + logger.exception('OperationalException. Stopping trader ...') self.freqtrade.state = State.STOPPED @@ -159,10 +155,7 @@ class Worker: # Load and validate config and create new instance of the bot self._init(True) - self.freqtrade.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': 'config reloaded' - }) + self.freqtrade.notify_status('config reloaded') # Tell systemd that we completed reconfiguration if self._sd_notify: @@ -176,8 +169,5 @@ class Worker: self._sd_notify.notify("STOPPING=1") if self.freqtrade: - self.freqtrade.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': 'process died' - }) + self.freqtrade.notify_status('process died') self.freqtrade.cleanup() From 161c06fd4ef5afdd3deec036f1d1be94bc4621ab Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 07:42:52 +0000 Subject: [PATCH 0337/1106] Bump plotly from 4.4.1 to 4.5.0 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.4.1 to 4.5.0. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.4.1...v4.5.0) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 415d4b888..26467d90b 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.4.1 +plotly==4.5.0 From 184a6005a6db67918a62b84896813302451880ed Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 07:43:11 +0000 Subject: [PATCH 0338/1106] Bump urllib3 from 1.25.7 to 1.25.8 Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.7 to 1.25.8. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/master/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.25.7...1.25.8) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index daf4984c0..e358c8445 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -6,7 +6,7 @@ python-telegram-bot==12.3.0 arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 -urllib3==1.25.7 +urllib3==1.25.8 wrapt==1.11.2 jsonschema==3.2.0 TA-Lib==0.4.17 From 66939bdcf636204c963aae75df9ccb5cc919fdb5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 07:43:41 +0000 Subject: [PATCH 0339/1106] Bump ccxt from 1.21.76 to 1.21.91 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.76 to 1.21.91. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.76...1.21.91) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index daf4984c0..c826541a6 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.76 +ccxt==1.21.91 SQLAlchemy==1.3.12 python-telegram-bot==12.3.0 arrow==0.15.5 From a3b0f752896f6f88efdf33099787f56cde32a26a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 07:44:27 +0000 Subject: [PATCH 0340/1106] Bump pytest from 5.3.3 to 5.3.4 Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.3.3...5.3.4) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e602bf184..6330d93e5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 mypy==0.761 -pytest==5.3.3 +pytest==5.3.4 pytest-asyncio==0.10.0 pytest-cov==2.8.1 pytest-mock==2.0.0 From c9ee678a52fcdc0cf2a08ea88baa4263d8b40576 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 08:36:41 +0000 Subject: [PATCH 0341/1106] Bump sqlalchemy from 1.3.12 to 1.3.13 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.12 to 1.3.13. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index c826541a6..14fee6e80 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,7 +1,7 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs ccxt==1.21.91 -SQLAlchemy==1.3.12 +SQLAlchemy==1.3.13 python-telegram-bot==12.3.0 arrow==0.15.5 cachetools==4.0.0 From 4c0e586354f3f4cd87138c51ee695136d45f8caf Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 27 Jan 2020 22:39:04 +0300 Subject: [PATCH 0342/1106] Advise to use https method for git clone i.o ssh --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 267d91c8d..cbe000da4 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -42,7 +42,7 @@ The easiest way to install and run Freqtrade is to clone the bot GitHub reposito This can be achieved with the following commands: ```bash -git clone git@github.com:freqtrade/freqtrade.git +git clone https://github.com/freqtrade/freqtrade.git cd freqtrade git checkout master # Optional, see (1) ./setup.sh --install From 328a9ffafdad4953c71fb20f4bd8b18251f3f737 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 25 Jan 2020 20:53:02 +0100 Subject: [PATCH 0343/1106] fixed typo in false statement --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f1584c731..323d4d14c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -429,7 +429,7 @@ class FreqtradeBot: logger.info('bids to ask delta DOES satisfy condition.') return True else: - logger.info('bids to ask delta DOES NOT satisfy condition.') + logger.info(f"bids to ask delta for {pair} does not satisfy condition.") return False def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = None) -> bool: From a0b92fe0b12f26514e3b623eb91f44022604e67f Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 28 Jan 2020 17:09:44 +0100 Subject: [PATCH 0344/1106] removed typo --- freqtrade/freqtradebot.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 323d4d14c..9df2acaf0 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -423,8 +423,12 @@ class FreqtradeBot: order_book_bids = order_book_data_frame['b_size'].sum() order_book_asks = order_book_data_frame['a_size'].sum() bids_ask_delta = order_book_bids / order_book_asks - logger.info('bids: %s, asks: %s, delta: %s, askprice: %s, bidprice: %s, immediate askquantity: %s, immediate bidquantity: %s', - order_book_bids, order_book_asks, bids_ask_delta, order_book['asks'][0][0], order_book['bids'][0][0], order_book['asks'][0][1], order_book['bids'][0][1]) + logger.info( + f"bids: {order_book_bids}, asks: {order_book_asks}, delta: {bids_ask_delta}, " + f"askprice: {order_book['asks'][0][0]}, bidprice: {order_book['bids'][0][0]}, " + f"immediate ask quantity: {order_book['asks'][0][1]}, " + f"immediate bid quantity: {order_book['bids'][0][1]}", + ) if bids_ask_delta >= conf_bids_to_ask_delta: logger.info('bids to ask delta DOES satisfy condition.') return True From b384ca8fd28bfc41226718451f9dfcc58a0ce70b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 28 Jan 2020 20:30:03 +0100 Subject: [PATCH 0345/1106] Create new-config command --- freqtrade/commands/__init__.py | 1 + freqtrade/commands/arguments.py | 13 +++++++++++-- freqtrade/commands/deploy_commands.py | 8 ++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 990c1107a..81467cf61 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -9,6 +9,7 @@ Note: Be careful with file-scoped imports in these subfiles. from freqtrade.commands.arguments import Arguments from freqtrade.commands.data_commands import start_download_data from freqtrade.commands.deploy_commands import (start_create_userdir, + start_new_config, start_new_hyperopt, start_new_strategy) from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 724814554..504c6b0b5 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -43,6 +43,8 @@ ARGS_TEST_PAIRLIST = ["config", "quote_currencies", "print_one_column", "list_pa ARGS_CREATE_USERDIR = ["user_data_dir", "reset"] +ARGS_BUILD_CONFIG = ["config"] + ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"] @@ -133,8 +135,9 @@ class Arguments: from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, - start_list_strategies, start_new_hyperopt, - start_new_strategy, start_list_timeframes, + start_list_strategies, start_list_timeframes, + start_new_config, + start_new_hyperopt, start_new_strategy, start_plot_dataframe, start_plot_profit, start_backtesting, start_hyperopt, start_edge, start_test_pairlist, start_trading) @@ -177,6 +180,12 @@ class Arguments: create_userdir_cmd.set_defaults(func=start_create_userdir) self._build_args(optionlist=ARGS_CREATE_USERDIR, parser=create_userdir_cmd) + # add new-config subcommand + build_config_cmd = subparsers.add_parser('new-config', + help="Create new config") + build_config_cmd.set_defaults(func=start_new_config) + self._build_args(optionlist=ARGS_BUILD_CONFIG, parser=build_config_cmd) + # add new-strategy subcommand build_strategy_cmd = subparsers.add_parser('new-strategy', help="Create new strategy") diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 99ae63244..34755932c 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -110,3 +110,11 @@ def start_new_hyperopt(args: Dict[str, Any]) -> None: deploy_new_hyperopt(args['hyperopt'], new_path, args['template']) else: raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") + + +def start_new_config(args: Dict[str, Any]) -> None: + """ + Create a new strategy from a template + Asking the user questions to fill out the templateaccordingly. + """ + pass From 9f291282056fde93c3cab74470764a9cdf80f89b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 07:01:17 +0100 Subject: [PATCH 0346/1106] Fix small json formatting issue --- config.json.example | 2 +- config_binance.json.example | 2 +- config_full.json.example | 2 +- config_kraken.json.example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config.json.example b/config.json.example index 8b85e71eb..a03ab6c2a 100644 --- a/config.json.example +++ b/config.json.example @@ -4,7 +4,7 @@ "stake_amount": 0.05, "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", - "ticker_interval" : "5m", + "ticker_interval": "5m", "dry_run": false, "trailing_stop": false, "unfilledtimeout": { diff --git a/config_binance.json.example b/config_binance.json.example index 0521a3a35..e2c9879b0 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -4,7 +4,7 @@ "stake_amount": 0.05, "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", - "ticker_interval" : "5m", + "ticker_interval": "5m", "dry_run": true, "trailing_stop": false, "unfilledtimeout": { diff --git a/config_full.json.example b/config_full.json.example index 82d8bd04a..f543604e7 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -4,7 +4,7 @@ "stake_amount": 0.05, "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", - "amount_reserve_percent" : 0.05, + "amount_reserve_percent": 0.05, "amend_last_stake_amount": false, "last_stake_amount_min_ratio": 0.5, "dry_run": false, diff --git a/config_kraken.json.example b/config_kraken.json.example index a527b569d..4f74d0b7d 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -4,7 +4,7 @@ "stake_amount": 10, "tradable_balance_ratio": 0.99, "fiat_display_currency": "EUR", - "ticker_interval" : "5m", + "ticker_interval": "5m", "dry_run": true, "trailing_stop": false, "unfilledtimeout": { From 122c9163566acfbbf2d2a18e86dfcfac3a772dab Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 07:01:32 +0100 Subject: [PATCH 0347/1106] Add first version of config_deploy --- freqtrade/commands/deploy_commands.py | 28 ++++++++- freqtrade/templates/base_config.json.j2 | 82 +++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 freqtrade/templates/base_config.json.j2 diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 34755932c..4e114a6d8 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -112,9 +112,35 @@ def start_new_hyperopt(args: Dict[str, Any]) -> None: raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") +def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: + """ + Applies selections to the template and writes the result to config_path + :param config_path: Path object for new config file. Should not exist yet + :param selecions: Dict containing selections taken by the user. + """ + config_text = render_template(templatefile='base_config.json.j2', + arguments=selections) + + config_path.write_text(config_text) + + def start_new_config(args: Dict[str, Any]) -> None: """ Create a new strategy from a template Asking the user questions to fill out the templateaccordingly. """ - pass + sample_selections = { + 'stake_currency': 'USDT', + 'stake_amount': 100, + 'fiat_display_currency': 'EUR', + 'ticker_interval': '15m', + 'dry_run': True, + 'exchange': 'binance', + 'exchange_key': 'sampleKey', + 'exchange_secret': 'Samplesecret', + 'telegram': True, + 'telegram_token': 'asdf1244', + 'telegram_chat_id': '1144444', + } + config_path = Path(args['config'][0]) + deploy_new_config(config_path, sample_selections) diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 new file mode 100644 index 000000000..ad8a762ec --- /dev/null +++ b/freqtrade/templates/base_config.json.j2 @@ -0,0 +1,82 @@ +{ + "max_open_trades": 3, + "stake_currency": "{{ stake_currency }}", + "stake_amount": {{ stake_amount }}, + "tradable_balance_ratio": 0.99, + "fiat_display_currency": "{{ fiat_display_currency }}", + "ticker_interval": "{{ ticker_interval }}", + "dry_run": {{ dry_run | lower }}, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "ask_last_balance": 0.0, + "use_order_book": false, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 9, + "use_sell_signal": true, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "exchange": { + "name": "bittrex", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 500 + }, + "pair_whitelist": [ + "ETH/BTC", + "LTC/BTC", + "ETC/BTC", + "DASH/BTC", + "ZEC/BTC", + "XLM/BTC", + "NXT/BTC", + "TRX/BTC", + "ADA/BTC", + "XMR/BTC" + ], + "pair_blacklist": [ + "DOGE/BTC" + ] + }, + "pairlists": [ + {"method": "StaticPairList"} + ], + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": {{ telegram | lower }}, + "token": "{{ telegram_token }}", + "chat_id": "{{ telegram_chat_id }}" + }, + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} From c80d8f432acc07665353947acae84a4d09cd3ced Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 07:13:38 +0100 Subject: [PATCH 0348/1106] Add exchange templates --- freqtrade/commands/deploy_commands.py | 19 +++++++++-- freqtrade/misc.py | 1 - freqtrade/templates/base_config.json.j2 | 24 +------------- .../subtemplates/exchange_binance.j2 | 28 ++++++++++++++++ .../subtemplates/exchange_generic.j2 | 13 ++++++++ .../templates/subtemplates/exchange_kraken.j2 | 33 +++++++++++++++++++ 6 files changed, 92 insertions(+), 26 deletions(-) create mode 100644 freqtrade/templates/subtemplates/exchange_binance.j2 create mode 100644 freqtrade/templates/subtemplates/exchange_generic.j2 create mode 100644 freqtrade/templates/subtemplates/exchange_kraken.j2 diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 4e114a6d8..065703faa 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -118,9 +118,22 @@ def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: :param config_path: Path object for new config file. Should not exist yet :param selecions: Dict containing selections taken by the user. """ + from jinja2.exceptions import TemplateNotFound + try: + selections['exchange'] = render_template( + templatefile=f"subtemplates/exchange_{selections['exchange_name']}.j2", + arguments=selections + ) + except TemplateNotFound: + selections['exchange'] = render_template( + templatefile=f"subtemplates/exchange_generic.j2", + arguments=selections + ) + config_text = render_template(templatefile='base_config.json.j2', arguments=selections) + logger.info(f"Writing config to `{config_path}`.") config_path.write_text(config_text) @@ -135,12 +148,14 @@ def start_new_config(args: Dict[str, Any]) -> None: 'fiat_display_currency': 'EUR', 'ticker_interval': '15m', 'dry_run': True, - 'exchange': 'binance', + 'exchange_name': 'binance', 'exchange_key': 'sampleKey', 'exchange_secret': 'Samplesecret', - 'telegram': True, + 'telegram': False, 'telegram_token': 'asdf1244', 'telegram_chat_id': '1144444', } config_path = Path(args['config'][0]) deploy_new_config(config_path, sample_selections) + + diff --git a/freqtrade/misc.py b/freqtrade/misc.py index bcba78cf0..40e1fdf17 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -138,5 +138,4 @@ def render_template(templatefile: str, arguments: dict = {}): autoescape=select_autoescape(['html', 'xml']) ) template = env.get_template(templatefile) - return template.render(**arguments) diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index ad8a762ec..f2f919e1f 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -28,29 +28,7 @@ "ignore_roi_if_buy_signal": false }, "exchange": { - "name": "bittrex", - "key": "your_exchange_key", - "secret": "your_exchange_secret", - "ccxt_config": {"enableRateLimit": true}, - "ccxt_async_config": { - "enableRateLimit": true, - "rateLimit": 500 - }, - "pair_whitelist": [ - "ETH/BTC", - "LTC/BTC", - "ETC/BTC", - "DASH/BTC", - "ZEC/BTC", - "XLM/BTC", - "NXT/BTC", - "TRX/BTC", - "ADA/BTC", - "XMR/BTC" - ], - "pair_blacklist": [ - "DOGE/BTC" - ] + {{ exchange | indent(8) }} }, "pairlists": [ {"method": "StaticPairList"} diff --git a/freqtrade/templates/subtemplates/exchange_binance.j2 b/freqtrade/templates/subtemplates/exchange_binance.j2 new file mode 100644 index 000000000..082af45c4 --- /dev/null +++ b/freqtrade/templates/subtemplates/exchange_binance.j2 @@ -0,0 +1,28 @@ +"name": "{{ exchange_name | lower }}", +"key": "{{ exchange_key }}", +"secret": "{{ exchange_secret }}", +"ccxt_config": {"enableRateLimit": true}, +"ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 +}, +"pair_whitelist": [ + "ALGO/BTC", + "ATOM/BTC", + "BAT/BTC", + "BCH/BTC", + "BRD/BTC", + "EOS/BTC", + "ETH/BTC", + "IOTA/BTC", + "LINK/BTC", + "LTC/BTC", + "NEO/BTC", + "NXS/BTC", + "XMR/BTC", + "XRP/BTC", + "XTZ/BTC" +], +"pair_blacklist": [ + "BNB/BTC" +] diff --git a/freqtrade/templates/subtemplates/exchange_generic.j2 b/freqtrade/templates/subtemplates/exchange_generic.j2 new file mode 100644 index 000000000..5d5bee2b2 --- /dev/null +++ b/freqtrade/templates/subtemplates/exchange_generic.j2 @@ -0,0 +1,13 @@ +"name": "{{ exchange_name | lower }}", +"key": "{{ exchange_key }}", +"secret": "{{ exchange_secret }}", +"ccxt_config": {"enableRateLimit": true}, +"ccxt_async_config": { + "enableRateLimit": true, +}, +"pair_whitelist": [ + +], +"pair_blacklist": [ + +] diff --git a/freqtrade/templates/subtemplates/exchange_kraken.j2 b/freqtrade/templates/subtemplates/exchange_kraken.j2 new file mode 100644 index 000000000..690828887 --- /dev/null +++ b/freqtrade/templates/subtemplates/exchange_kraken.j2 @@ -0,0 +1,33 @@ +"name": "kraken", +"key": "{{ exchange_key }}", +"secret": "{{ exchange_secret }}", +"ccxt_config": {"enableRateLimit": true}, +"ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 1000 +}, +"pair_whitelist": [ + "ADA/EUR", + "ATOM/EUR", + "BAT/EUR", + "BCH/EUR", + "BTC/EUR", + "DAI/EUR", + "DASH/EUR", + "EOS/EUR", + "ETC/EUR", + "ETH/EUR", + "LINK/EUR", + "LTC/EUR", + "QTUM/EUR", + "REP/EUR", + "WAVES/EUR", + "XLM/EUR", + "XMR/EUR", + "XRP/EUR", + "XTZ/EUR", + "ZEC/EUR" +], +"pair_blacklist": [ + +] From 68771a78617b6ff4af6baca08df1f54d76ba9338 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Wed, 29 Jan 2020 17:08:36 +0300 Subject: [PATCH 0349/1106] Remove state attr from Worker --- freqtrade/worker.py | 8 -------- tests/test_freqtradebot.py | 6 +++--- tests/test_worker.py | 6 +++--- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 972ff0d61..6da04b4a2 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -56,14 +56,6 @@ class Worker: self._sd_notify = sdnotify.SystemdNotifier() if \ self._config.get('internals', {}).get('sd_notify', False) else None - @property - def state(self) -> State: - return self.freqtrade.state - - @state.setter - def state(self, value: State) -> None: - self.freqtrade.state = value - def run(self) -> None: state = None while True: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e0f2ecd3a..128d9c9ee 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -797,10 +797,10 @@ def test_process_operational_exception(default_conf, ticker, mocker) -> None: worker = Worker(args=None, config=default_conf) patch_get_signal(worker.freqtrade) - assert worker.state == State.RUNNING + assert worker.freqtrade.state == State.RUNNING worker._process() - assert worker.state == State.STOPPED + assert worker.freqtrade.state == State.STOPPED assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]['status'] @@ -3631,7 +3631,7 @@ def test_startup_state(default_conf, mocker): } mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True)) worker = get_patched_worker(mocker, default_conf) - assert worker.state is State.RUNNING + assert worker.freqtrade.state is State.RUNNING def test_startup_trade_reinit(default_conf, edge_conf, mocker): diff --git a/tests/test_worker.py b/tests/test_worker.py index 72e215210..2fb42d47e 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -11,11 +11,11 @@ from tests.conftest import get_patched_worker, log_has def test_worker_state(mocker, default_conf, markets) -> None: mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)) worker = get_patched_worker(mocker, default_conf) - assert worker.state is State.RUNNING + assert worker.freqtrade.state is State.RUNNING default_conf.pop('initial_state') worker = Worker(args=None, config=default_conf) - assert worker.state is State.STOPPED + assert worker.freqtrade.state is State.STOPPED def test_worker_running(mocker, default_conf, caplog) -> None: @@ -41,7 +41,7 @@ def test_worker_stopped(mocker, default_conf, caplog) -> None: mock_sleep = mocker.patch('time.sleep', return_value=None) worker = get_patched_worker(mocker, default_conf) - worker.state = State.STOPPED + worker.freqtrade.state = State.STOPPED state = worker._worker(old_state=State.RUNNING) assert state is State.STOPPED assert log_has('Changing state to: STOPPED', caplog) From dd83cb1b95fb2a0f3790d7c83a377ed72b659fd3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 20:27:38 +0100 Subject: [PATCH 0350/1106] Extract selection generation to a seperate method --- freqtrade/commands/deploy_commands.py | 38 ++++++++++++++++--------- freqtrade/templates/base_config.json.j2 | 2 +- tests/commands/test_commands.py | 21 ++++++++++++-- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 065703faa..87aea7492 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -112,6 +112,28 @@ def start_new_hyperopt(args: Dict[str, Any]) -> None: raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") +def ask_user_config() -> Dict[str, Any]: + """ + Ask user a few questions to build the configuration. + :returns: Dict with keys to put into template + """ + sample_selections = { + 'max_open_trades': 3, + 'stake_currency': 'USDT', + 'stake_amount': 100, + 'fiat_display_currency': 'EUR', + 'ticker_interval': '15m', + 'dry_run': True, + 'exchange_name': 'binance', + 'exchange_key': 'sampleKey', + 'exchange_secret': 'Samplesecret', + 'telegram': False, + 'telegram_token': 'asdf1244', + 'telegram_chat_id': '1144444', + } + return sample_selections + + def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: """ Applies selections to the template and writes the result to config_path @@ -142,20 +164,8 @@ def start_new_config(args: Dict[str, Any]) -> None: Create a new strategy from a template Asking the user questions to fill out the templateaccordingly. """ - sample_selections = { - 'stake_currency': 'USDT', - 'stake_amount': 100, - 'fiat_display_currency': 'EUR', - 'ticker_interval': '15m', - 'dry_run': True, - 'exchange_name': 'binance', - 'exchange_key': 'sampleKey', - 'exchange_secret': 'Samplesecret', - 'telegram': False, - 'telegram_token': 'asdf1244', - 'telegram_chat_id': '1144444', - } + selections = ask_user_config() config_path = Path(args['config'][0]) - deploy_new_config(config_path, sample_selections) + deploy_new_config(config_path, selections) diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index f2f919e1f..1370bfa80 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -1,5 +1,5 @@ { - "max_open_trades": 3, + "max_open_trades": {{ max_open_trades }}, "stake_currency": "{{ stake_currency }}", "stake_amount": {{ stake_amount }}, "tradable_balance_ratio": 0.99, diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 65d7f6eaf..f8efdfd3c 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -8,8 +8,9 @@ from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, start_list_strategies, start_list_timeframes, - start_new_hyperopt, start_new_strategy, - start_test_pairlist, start_trading) + start_new_config, start_new_hyperopt, + start_new_strategy, start_test_pairlist, + start_trading) from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode @@ -537,6 +538,22 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): start_new_hyperopt(get_args(args)) +def test_start_new_config(mocker, caplog): + wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) + mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + + args = [ + "new-config", + "--config", + "coolconfig.json" + ] + start_new_config(get_args(args)) + + assert wt_mock.call_count == 1 + assert "binance" in wt_mock.call_args_list[0][0][0] + assert log_has_re("Writing config to .*", caplog) + + def test_download_data_keyboardInterrupt(mocker, caplog, markets): dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) From 49c9258a088e42db46656b24fc90d1227d604dc1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 20:32:27 +0100 Subject: [PATCH 0351/1106] enhance test --- tests/commands/test_commands.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index f8efdfd3c..19999f319 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1,3 +1,4 @@ +import json import re from pathlib import Path from unittest.mock import MagicMock, PropertyMock @@ -538,10 +539,26 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): start_new_hyperopt(get_args(args)) -def test_start_new_config(mocker, caplog): +@pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken', 'ftx']) +def test_start_new_config(mocker, caplog, exchange): wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) mocker.patch.object(Path, "exists", MagicMock(return_value=False)) - + sample_selections = { + 'max_open_trades': 3, + 'stake_currency': 'USDT', + 'stake_amount': 100, + 'fiat_display_currency': 'EUR', + 'ticker_interval': '15m', + 'dry_run': True, + 'exchange_name': exchange, + 'exchange_key': 'sampleKey', + 'exchange_secret': 'Samplesecret', + 'telegram': False, + 'telegram_token': 'asdf1244', + 'telegram_chat_id': '1144444', + } + mocker.patch('freqtrade.commands.deploy_commands.ask_user_config', + return_value=sample_selections) args = [ "new-config", "--config", @@ -549,9 +566,11 @@ def test_start_new_config(mocker, caplog): ] start_new_config(get_args(args)) - assert wt_mock.call_count == 1 - assert "binance" in wt_mock.call_args_list[0][0][0] assert log_has_re("Writing config to .*", caplog) + assert wt_mock.call_count == 1 + result = json.loads(wt_mock.call_args_list[0][0][0]) + assert result['exchange']['name'] == exchange + assert result['ticker_interval'] == '15m' def test_download_data_keyboardInterrupt(mocker, caplog, markets): From e250c56829e74445e6177d4b61c17e57a0af21e0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 21:21:38 +0100 Subject: [PATCH 0352/1106] Add Questionaire workflow --- freqtrade/commands/deploy_commands.py | 98 ++++++++++++++++++++++++++- requirements-common.txt | 3 + setup.py | 2 + 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 87aea7492..670f272ce 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -3,11 +3,14 @@ import sys from pathlib import Path from typing import Any, Dict +from questionary import Separator, prompt + from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY from freqtrade.exceptions import OperationalException +from freqtrade.exchange import available_exchanges from freqtrade.misc import render_template from freqtrade.state import RunMode @@ -117,6 +120,99 @@ def ask_user_config() -> Dict[str, Any]: Ask user a few questions to build the configuration. :returns: Dict with keys to put into template """ + questions = [ + { + "type": "confirm", + "name": "dry_run", + "message": "Do you want to enable Dry-run (simulated trades)?", + "default": True, + }, + { + "type": "text", + "name": "stake_currency", + "message": "Please insert your stake currency:", + "default": 'BTC', + }, + { + "type": "text", + "name": "stake_amount", + "message": "Please insert your stake amount:", + "default": "0.01", + }, + { + "type": "text", + "name": "max_open_trades", + "message": "Please insert max_open_trades:", + "default": "3", + }, + { + "type": "text", + "name": "ticker_interval", + "message": "Please insert your ticker interval:", + "default": "5m", + }, + { + "type": "text", + "name": "fiat_display_currency", + "message": "Please insert your display Currency (for reporting):", + "default": 'USD', + }, + { + "type": "select", + "name": "exchange_name", + "message": "Select exchange", + "choices": [ + "bittrex", + "binance", + "binanceje", + "binanceus", + "kraken", + Separator(), + "other", + ], + }, + { + "type": "autocomplete", + "name": "exchange_name", + "message": "Type your exchange name (Must be supported by ccxt)", + "choices": available_exchanges(), + "when": lambda x: x["exchange_name"] == 'other' + }, + { + "type": "password", + "name": "exchange_key", + "message": "Insert Exchange Key", + "when": lambda x: not x['dry_run'] + }, + { + "type": "password", + "name": "exchange_secret", + "message": "Insert Exchange Secret", + "when": lambda x: not x['dry_run'] + }, + { + "type": "confirm", + "name": "telegram", + "message": "Do you want to enable Telegram?", + "default": False, + }, + { + "type": "password", + "name": "telegram_token", + "message": "Insert Telegram token", + "when": lambda x: x['telegram'] + }, + { + "type": "text", + "name": "telegram_chat_id", + "message": "Insert Telegram chat id", + "when": lambda x: x['telegram'] + }, + ] + answers = prompt(questions) + + print(answers) + sample_selections = { 'max_open_trades': 3, 'stake_currency': 'USDT', @@ -167,5 +263,3 @@ def start_new_config(args: Dict[str, Any]) -> None: selections = ask_user_config() config_path = Path(args['config'][0]) deploy_new_config(config_path, selections) - - diff --git a/requirements-common.txt b/requirements-common.txt index e4fe54721..80f18892b 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -28,3 +28,6 @@ flask==1.1.1 # Support for colorized terminal output colorama==0.4.3 +# Building config files interactively +questionary==1.5.1 +prompt-toolkit==3.0.3 diff --git a/setup.py b/setup.py index 7d8d7b68d..63a595f32 100644 --- a/setup.py +++ b/setup.py @@ -79,6 +79,8 @@ setup(name='freqtrade', 'sdnotify', 'colorama', 'jinja2', + 'questionary', + 'prompt-toolkit', # from requirements.txt 'numpy', 'pandas', From 940bfbee96eef00e56d7f5097f1c59099b34bb37 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 21:28:01 +0100 Subject: [PATCH 0353/1106] Move start_config out of build_commands file --- freqtrade/commands/__init__.py | 2 +- freqtrade/commands/build_config_commands.py | 160 ++++++++++++++++++ freqtrade/commands/deploy_commands.py | 153 ----------------- .../subtemplates/exchange_generic.j2 | 2 +- tests/commands/test_commands.py | 2 +- 5 files changed, 163 insertions(+), 156 deletions(-) create mode 100644 freqtrade/commands/build_config_commands.py diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 81467cf61..6ea325e63 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -7,9 +7,9 @@ Note: Be careful with file-scoped imports in these subfiles. as they are parsed on startup, nothing containing optional modules should be loaded. """ from freqtrade.commands.arguments import Arguments +from freqtrade.commands.build_config_commands import start_new_config from freqtrade.commands.data_commands import start_download_data from freqtrade.commands.deploy_commands import (start_create_userdir, - start_new_config, start_new_hyperopt, start_new_strategy) from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py new file mode 100644 index 000000000..393416f53 --- /dev/null +++ b/freqtrade/commands/build_config_commands.py @@ -0,0 +1,160 @@ +import logging +from pathlib import Path +from typing import Any, Dict + +from questionary import Separator, prompt + +from freqtrade.exchange import available_exchanges +from freqtrade.misc import render_template + +logger = logging.getLogger(__name__) + + +def ask_user_config() -> Dict[str, Any]: + """ + Ask user a few questions to build the configuration. + :returns: Dict with keys to put into template + """ + questions = [ + { + "type": "confirm", + "name": "dry_run", + "message": "Do you want to enable Dry-run (simulated trades)?", + "default": True, + }, + { + "type": "text", + "name": "stake_currency", + "message": "Please insert your stake currency:", + "default": 'BTC', + }, + { + "type": "text", + "name": "stake_amount", + "message": "Please insert your stake amount:", + "default": "0.01", + }, + { + "type": "text", + "name": "max_open_trades", + "message": "Please insert max_open_trades:", + "default": "3", + }, + { + "type": "text", + "name": "ticker_interval", + "message": "Please insert your ticker interval:", + "default": "5m", + }, + { + "type": "text", + "name": "fiat_display_currency", + "message": "Please insert your display Currency (for reporting):", + "default": 'USD', + }, + { + "type": "select", + "name": "exchange_name", + "message": "Select exchange", + "choices": [ + "bittrex", + "binance", + "binanceje", + "binanceus", + "kraken", + Separator(), + "other", + ], + }, + { + "type": "autocomplete", + "name": "exchange_name", + "message": "Type your exchange name (Must be supported by ccxt)", + "choices": available_exchanges(), + "when": lambda x: x["exchange_name"] == 'other' + }, + { + "type": "password", + "name": "exchange_key", + "message": "Insert Exchange Key", + "when": lambda x: not x['dry_run'] + }, + { + "type": "password", + "name": "exchange_secret", + "message": "Insert Exchange Secret", + "when": lambda x: not x['dry_run'] + }, + { + "type": "confirm", + "name": "telegram", + "message": "Do you want to enable Telegram?", + "default": False, + }, + { + "type": "password", + "name": "telegram_token", + "message": "Insert Telegram token", + "when": lambda x: x['telegram'] + }, + { + "type": "text", + "name": "telegram_chat_id", + "message": "Insert Telegram chat id", + "when": lambda x: x['telegram'] + }, + ] + answers = prompt(questions) + + print(answers) + + sample_selections = { + 'max_open_trades': 3, + 'stake_currency': 'USDT', + 'stake_amount': 100, + 'fiat_display_currency': 'EUR', + 'ticker_interval': '15m', + 'dry_run': True, + 'exchange_name': 'binance', + 'exchange_key': 'sampleKey', + 'exchange_secret': 'Samplesecret', + 'telegram': False, + 'telegram_token': 'asdf1244', + 'telegram_chat_id': '1144444', + } + return sample_selections + + +def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: + """ + Applies selections to the template and writes the result to config_path + :param config_path: Path object for new config file. Should not exist yet + :param selecions: Dict containing selections taken by the user. + """ + from jinja2.exceptions import TemplateNotFound + try: + selections['exchange'] = render_template( + templatefile=f"subtemplates/exchange_{selections['exchange_name']}.j2", + arguments=selections + ) + except TemplateNotFound: + selections['exchange'] = render_template( + templatefile=f"subtemplates/exchange_generic.j2", + arguments=selections + ) + + config_text = render_template(templatefile='base_config.json.j2', + arguments=selections) + + logger.info(f"Writing config to `{config_path}`.") + config_path.write_text(config_text) + + +def start_new_config(args: Dict[str, Any]) -> None: + """ + Create a new strategy from a template + Asking the user questions to fill out the templateaccordingly. + """ + selections = ask_user_config() + config_path = Path(args['config'][0]) + deploy_new_config(config_path, selections) diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 670f272ce..99ae63244 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -3,14 +3,11 @@ import sys from pathlib import Path from typing import Any, Dict -from questionary import Separator, prompt - from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY from freqtrade.exceptions import OperationalException -from freqtrade.exchange import available_exchanges from freqtrade.misc import render_template from freqtrade.state import RunMode @@ -113,153 +110,3 @@ def start_new_hyperopt(args: Dict[str, Any]) -> None: deploy_new_hyperopt(args['hyperopt'], new_path, args['template']) else: raise OperationalException("`new-hyperopt` requires --hyperopt to be set.") - - -def ask_user_config() -> Dict[str, Any]: - """ - Ask user a few questions to build the configuration. - :returns: Dict with keys to put into template - """ - questions = [ - { - "type": "confirm", - "name": "dry_run", - "message": "Do you want to enable Dry-run (simulated trades)?", - "default": True, - }, - { - "type": "text", - "name": "stake_currency", - "message": "Please insert your stake currency:", - "default": 'BTC', - }, - { - "type": "text", - "name": "stake_amount", - "message": "Please insert your stake amount:", - "default": "0.01", - }, - { - "type": "text", - "name": "max_open_trades", - "message": "Please insert max_open_trades:", - "default": "3", - }, - { - "type": "text", - "name": "ticker_interval", - "message": "Please insert your ticker interval:", - "default": "5m", - }, - { - "type": "text", - "name": "fiat_display_currency", - "message": "Please insert your display Currency (for reporting):", - "default": 'USD', - }, - { - "type": "select", - "name": "exchange_name", - "message": "Select exchange", - "choices": [ - "bittrex", - "binance", - "binanceje", - "binanceus", - "kraken", - Separator(), - "other", - ], - }, - { - "type": "autocomplete", - "name": "exchange_name", - "message": "Type your exchange name (Must be supported by ccxt)", - "choices": available_exchanges(), - "when": lambda x: x["exchange_name"] == 'other' - }, - { - "type": "password", - "name": "exchange_key", - "message": "Insert Exchange Key", - "when": lambda x: not x['dry_run'] - }, - { - "type": "password", - "name": "exchange_secret", - "message": "Insert Exchange Secret", - "when": lambda x: not x['dry_run'] - }, - { - "type": "confirm", - "name": "telegram", - "message": "Do you want to enable Telegram?", - "default": False, - }, - { - "type": "password", - "name": "telegram_token", - "message": "Insert Telegram token", - "when": lambda x: x['telegram'] - }, - { - "type": "text", - "name": "telegram_chat_id", - "message": "Insert Telegram chat id", - "when": lambda x: x['telegram'] - }, - ] - answers = prompt(questions) - - print(answers) - - sample_selections = { - 'max_open_trades': 3, - 'stake_currency': 'USDT', - 'stake_amount': 100, - 'fiat_display_currency': 'EUR', - 'ticker_interval': '15m', - 'dry_run': True, - 'exchange_name': 'binance', - 'exchange_key': 'sampleKey', - 'exchange_secret': 'Samplesecret', - 'telegram': False, - 'telegram_token': 'asdf1244', - 'telegram_chat_id': '1144444', - } - return sample_selections - - -def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: - """ - Applies selections to the template and writes the result to config_path - :param config_path: Path object for new config file. Should not exist yet - :param selecions: Dict containing selections taken by the user. - """ - from jinja2.exceptions import TemplateNotFound - try: - selections['exchange'] = render_template( - templatefile=f"subtemplates/exchange_{selections['exchange_name']}.j2", - arguments=selections - ) - except TemplateNotFound: - selections['exchange'] = render_template( - templatefile=f"subtemplates/exchange_generic.j2", - arguments=selections - ) - - config_text = render_template(templatefile='base_config.json.j2', - arguments=selections) - - logger.info(f"Writing config to `{config_path}`.") - config_path.write_text(config_text) - - -def start_new_config(args: Dict[str, Any]) -> None: - """ - Create a new strategy from a template - Asking the user questions to fill out the templateaccordingly. - """ - selections = ask_user_config() - config_path = Path(args['config'][0]) - deploy_new_config(config_path, selections) diff --git a/freqtrade/templates/subtemplates/exchange_generic.j2 b/freqtrade/templates/subtemplates/exchange_generic.j2 index 5d5bee2b2..33309de3b 100644 --- a/freqtrade/templates/subtemplates/exchange_generic.j2 +++ b/freqtrade/templates/subtemplates/exchange_generic.j2 @@ -3,7 +3,7 @@ "secret": "{{ exchange_secret }}", "ccxt_config": {"enableRateLimit": true}, "ccxt_async_config": { - "enableRateLimit": true, + "enableRateLimit": true }, "pair_whitelist": [ diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 19999f319..51b69449d 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -557,7 +557,7 @@ def test_start_new_config(mocker, caplog, exchange): 'telegram_token': 'asdf1244', 'telegram_chat_id': '1144444', } - mocker.patch('freqtrade.commands.deploy_commands.ask_user_config', + mocker.patch('freqtrade.commands.build_config_commands.ask_user_config', return_value=sample_selections) args = [ "new-config", From 2f0775fa1b6381b163ecd55ba1a0b684a9bbfea8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 21:30:29 +0100 Subject: [PATCH 0354/1106] Extract build-config tests to new file --- tests/commands/test_build_config.py | 42 +++++++++++++++++++++++++++++ tests/commands/test_commands.py | 40 ++------------------------- 2 files changed, 44 insertions(+), 38 deletions(-) create mode 100644 tests/commands/test_build_config.py diff --git a/tests/commands/test_build_config.py b/tests/commands/test_build_config.py new file mode 100644 index 000000000..4114ff489 --- /dev/null +++ b/tests/commands/test_build_config.py @@ -0,0 +1,42 @@ +import json +from pathlib import Path +from unittest.mock import MagicMock + +import pytest + +from freqtrade.commands import start_new_config +from tests.conftest import get_args, log_has_re + + +@pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken', 'ftx']) +def test_start_new_config(mocker, caplog, exchange): + wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) + mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + sample_selections = { + 'max_open_trades': 3, + 'stake_currency': 'USDT', + 'stake_amount': 100, + 'fiat_display_currency': 'EUR', + 'ticker_interval': '15m', + 'dry_run': True, + 'exchange_name': exchange, + 'exchange_key': 'sampleKey', + 'exchange_secret': 'Samplesecret', + 'telegram': False, + 'telegram_token': 'asdf1244', + 'telegram_chat_id': '1144444', + } + mocker.patch('freqtrade.commands.build_config_commands.ask_user_config', + return_value=sample_selections) + args = [ + "new-config", + "--config", + "coolconfig.json" + ] + start_new_config(get_args(args)) + + assert log_has_re("Writing config to .*", caplog) + assert wt_mock.call_count == 1 + result = json.loads(wt_mock.call_args_list[0][0][0]) + assert result['exchange']['name'] == exchange + assert result['ticker_interval'] == '15m' diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 51b69449d..65d7f6eaf 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1,4 +1,3 @@ -import json import re from pathlib import Path from unittest.mock import MagicMock, PropertyMock @@ -9,9 +8,8 @@ from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, start_list_strategies, start_list_timeframes, - start_new_config, start_new_hyperopt, - start_new_strategy, start_test_pairlist, - start_trading) + start_new_hyperopt, start_new_strategy, + start_test_pairlist, start_trading) from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode @@ -539,40 +537,6 @@ def test_start_new_hyperopt_no_arg(mocker, caplog): start_new_hyperopt(get_args(args)) -@pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken', 'ftx']) -def test_start_new_config(mocker, caplog, exchange): - wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) - mocker.patch.object(Path, "exists", MagicMock(return_value=False)) - sample_selections = { - 'max_open_trades': 3, - 'stake_currency': 'USDT', - 'stake_amount': 100, - 'fiat_display_currency': 'EUR', - 'ticker_interval': '15m', - 'dry_run': True, - 'exchange_name': exchange, - 'exchange_key': 'sampleKey', - 'exchange_secret': 'Samplesecret', - 'telegram': False, - 'telegram_token': 'asdf1244', - 'telegram_chat_id': '1144444', - } - mocker.patch('freqtrade.commands.build_config_commands.ask_user_config', - return_value=sample_selections) - args = [ - "new-config", - "--config", - "coolconfig.json" - ] - start_new_config(get_args(args)) - - assert log_has_re("Writing config to .*", caplog) - assert wt_mock.call_count == 1 - result = json.loads(wt_mock.call_args_list[0][0][0]) - assert result['exchange']['name'] == exchange - assert result['ticker_interval'] == '15m' - - def test_download_data_keyboardInterrupt(mocker, caplog, markets): dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) From acbf13e648425987d19654123d7e9d2ae83e8da7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 21:47:05 +0100 Subject: [PATCH 0355/1106] Fail gracefully if user interrupted question session --- freqtrade/commands/build_config_commands.py | 24 ++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 393416f53..a6623c3cd 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -6,13 +6,14 @@ from questionary import Separator, prompt from freqtrade.exchange import available_exchanges from freqtrade.misc import render_template - +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) def ask_user_config() -> Dict[str, Any]: """ Ask user a few questions to build the configuration. + Interactive questions built using https://github.com/tmbo/questionary :returns: Dict with keys to put into template """ questions = [ @@ -106,23 +107,11 @@ def ask_user_config() -> Dict[str, Any]: ] answers = prompt(questions) - print(answers) + if not answers: + # Interrupted questionary sessions return an empty dict. + raise OperationalException("User interrupted interactive questions.") - sample_selections = { - 'max_open_trades': 3, - 'stake_currency': 'USDT', - 'stake_amount': 100, - 'fiat_display_currency': 'EUR', - 'ticker_interval': '15m', - 'dry_run': True, - 'exchange_name': 'binance', - 'exchange_key': 'sampleKey', - 'exchange_secret': 'Samplesecret', - 'telegram': False, - 'telegram_token': 'asdf1244', - 'telegram_chat_id': '1144444', - } - return sample_selections + return answers def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: @@ -156,5 +145,6 @@ def start_new_config(args: Dict[str, Any]) -> None: Asking the user questions to fill out the templateaccordingly. """ selections = ask_user_config() + config_path = Path(args['config'][0]) deploy_new_config(config_path, selections) From cebf99b5d890cd2979d5e68816b43d4c999bda7e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 21:59:24 +0100 Subject: [PATCH 0356/1106] Implement validation --- freqtrade/commands/build_config_commands.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index a6623c3cd..6abacd826 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -4,12 +4,29 @@ from typing import Any, Dict from questionary import Separator, prompt +from freqtrade.constants import UNLIMITED_STAKE_AMOUNT from freqtrade.exchange import available_exchanges from freqtrade.misc import render_template from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) +def validate_is_int(val): + try: + _ = int(val) + return True + except Exception: + return False + + +def validate_is_float(val): + try: + _ = float(val) + return True + except Exception: + return False + + def ask_user_config() -> Dict[str, Any]: """ Ask user a few questions to build the configuration. @@ -34,12 +51,14 @@ def ask_user_config() -> Dict[str, Any]: "name": "stake_amount", "message": "Please insert your stake amount:", "default": "0.01", + "validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_float(val), }, { "type": "text", "name": "max_open_trades", - "message": "Please insert max_open_trades:", + "message": f"Please insert max_open_trades (Integer or '{UNLIMITED_STAKE_AMOUNT}'):", "default": "3", + "validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_int(val) }, { "type": "text", From 83baa6ee2e2c59a4b97ecf76d091cca2c7389154 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Jan 2020 22:47:15 +0100 Subject: [PATCH 0357/1106] Add test stub --- tests/commands/test_build_config.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_build_config.py b/tests/commands/test_build_config.py index 4114ff489..46e79b357 100644 --- a/tests/commands/test_build_config.py +++ b/tests/commands/test_build_config.py @@ -4,7 +4,8 @@ from unittest.mock import MagicMock import pytest -from freqtrade.commands import start_new_config +from freqtrade.commands.build_config_commands import (ask_user_config, + start_new_config) from tests.conftest import get_args, log_has_re @@ -40,3 +41,9 @@ def test_start_new_config(mocker, caplog, exchange): result = json.loads(wt_mock.call_args_list[0][0][0]) assert result['exchange']['name'] == exchange assert result['ticker_interval'] == '15m' + + +def test_ask_user_config(): + # TODO: Implement me + pass + # assert ask_user_config() From 4be3f053ca38fc5534a445ac08ff0766708f17df Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Jan 2020 21:42:48 +0100 Subject: [PATCH 0358/1106] Exclude trading against BNB bases on binance --- .../templates/subtemplates/exchange_binance.j2 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/freqtrade/templates/subtemplates/exchange_binance.j2 b/freqtrade/templates/subtemplates/exchange_binance.j2 index 082af45c4..c527d296b 100644 --- a/freqtrade/templates/subtemplates/exchange_binance.j2 +++ b/freqtrade/templates/subtemplates/exchange_binance.j2 @@ -24,5 +24,16 @@ "XTZ/BTC" ], "pair_blacklist": [ - "BNB/BTC" + "BNB/BTC", + "BNB/BUSD", + "BNB/ETH", + "BNB/EUR", + "BNB/NGN", + "BNB/PAX", + "BNB/RUB", + "BNB/TRY", + "BNB/TUSD", + "BNB/USDC", + "BNB/USDS", + "BNB/USDT", ] From e2b3907df58737dd0a28854b8ce3d51452e032b0 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 31 Jan 2020 04:39:18 +0100 Subject: [PATCH 0359/1106] more consistent backtesting tables and labels --- freqtrade/optimize/backtesting.py | 17 ++++++---- freqtrade/optimize/optimize_reports.py | 45 +++++++++++++++++++++---- tests/optimize/test_optimize_reports.py | 32 +++++++++++------- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index cdf74f65f..e2ad0f090 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -404,12 +404,12 @@ class Backtesting: ) # Execute backtest and print results all_results[self.strategy.get_strategy_name()] = self.backtest( - processed=preprocessed, - stake_amount=self.config['stake_amount'], - start_date=min_date, - end_date=max_date, - max_open_trades=max_open_trades, - position_stacking=position_stacking, + processed=preprocessed, + stake_amount=self.config['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=max_open_trades, + position_stacking=position_stacking, ) for strategy, results in all_results.items(): @@ -426,7 +426,10 @@ class Backtesting: results=results)) print(' SELL REASON STATS '.center(133, '=')) - print(generate_text_table_sell_reason(data, results)) + print(generate_text_table_sell_reason(data, + stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results)) print(' LEFT OPEN TRADES REPORT '.center(133, '=')) print(generate_text_table(data, diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 67056eaa9..6af04d4f2 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -19,9 +19,17 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') tabular_data = [] - headers = ['pair', 'buy count', 'avg profit %', 'cum profit %', - f'tot profit {stake_currency}', 'tot profit %', 'avg duration', - 'profit', 'loss'] + headers = [ + 'Pair', + 'Buy Count', + 'Avg Profit %', + 'Cum Profit %', + f'Tot Profit {stake_currency}', + 'Tot Profit %', + 'Avg Duration', + 'Wins', + 'Losses' + ] for pair in data: result = results[results.pair == pair] if skip_nan and result.profit_abs.isnull().all(): @@ -58,7 +66,9 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra floatfmt=floatfmt, tablefmt="pipe") # type: ignore -def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) -> str: +def generate_text_table_sell_reason( + data: Dict[str, Dict], stake_currency: str, max_open_trades: int, results: DataFrame +) -> str: """ Generate small table outlining Backtest results :param data: Dict of containing data that was used during backtesting. @@ -66,13 +76,36 @@ def generate_text_table_sell_reason(data: Dict[str, Dict], results: DataFrame) - :return: pretty printed table with tabulate as string """ tabular_data = [] - headers = ['Sell Reason', 'Count', 'Profit', 'Loss', 'Profit %'] + headers = [ + "Sell Reason", + "Sell Count", + "Wins", + "Losses", + "Avg Profit %", + "Cum Profit %", + f"Tot Profit {stake_currency}", + "Tot Profit %", + ] for reason, count in results['sell_reason'].value_counts().iteritems(): result = results.loc[results['sell_reason'] == reason] profit = len(result[result['profit_abs'] >= 0]) loss = len(result[result['profit_abs'] < 0]) profit_mean = round(result['profit_percent'].mean() * 100.0, 2) - tabular_data.append([reason.value, count, profit, loss, profit_mean]) + profit_sum = round(result["profit_percent"].sum() * 100.0, 2) + profit_tot = result["profit_abs"].sum() + profit_percent_tot = result["profit_percent"].sum() * 100.0 / max_open_trades + tabular_data.append( + [ + reason.value, + count, + profit, + loss, + profit_mean, + profit_sum, + profit_tot, + profit_percent_tot, + ] + ) return tabulate(tabular_data, headers=headers, tablefmt="pipe") diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 518b50d0f..8c1a3619d 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -21,14 +21,14 @@ def test_generate_text_table(default_conf, mocker): ) result_str = ( - '| pair | buy count | avg profit % | cum profit % | ' - 'tot profit BTC | tot profit % | avg duration | profit | loss |\n' - '|:--------|------------:|---------------:|---------------:|' - '-----------------:|---------------:|:---------------|---------:|-------:|\n' - '| ETH/BTC | 2 | 15.00 | 30.00 | ' - '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |\n' - '| TOTAL | 2 | 15.00 | 30.00 | ' - '0.60000000 | 15.00 | 0:20:00 | 2 | 0 |' + '| Pair | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC ' + '| Tot Profit % | Avg Duration | Wins | Losses |\n' + '|:--------|------------:|---------------:|---------------:|-----------------:' + '|---------------:|:---------------|-------:|---------:|\n' + '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 ' + '| 15.00 | 0:20:00 | 2 | 0 |\n' + '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 ' + '| 15.00 | 0:20:00 | 2 | 0 |' ) assert generate_text_table(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, @@ -50,13 +50,19 @@ def test_generate_text_table_sell_reason(default_conf, mocker): ) result_str = ( - '| Sell Reason | Count | Profit | Loss | Profit % |\n' - '|:--------------|--------:|---------:|-------:|-----------:|\n' - '| roi | 2 | 2 | 0 | 15 |\n' - '| stop_loss | 1 | 0 | 1 | -10 |' + '| Sell Reason | Sell Count | Wins | Losses | Avg Profit % |' + ' Cum Profit % | Tot Profit BTC | Tot Profit % |\n' + '|:--------------|-------------:|-------:|---------:|---------------:|' + '---------------:|-----------------:|---------------:|\n' + '| roi | 2 | 2 | 0 | 15 |' + ' 30 | 0.6 | 15 |\n' + '| stop_loss | 1 | 0 | 1 | -10 |' + ' -10 | -0.2 | -5 |' ) assert generate_text_table_sell_reason( - data={'ETH/BTC': {}}, results=results) == result_str + data={'ETH/BTC': {}}, + stake_currency='BTC', max_open_trades=2, + results=results) == result_str def test_generate_text_table_strategy(default_conf, mocker): From 907a61152c7be4c1c25c250a7c70bd19e7dae286 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 31 Jan 2020 04:53:37 +0100 Subject: [PATCH 0360/1106] added rounding to Tot Profit % on Sell Reasosn table to be consistent with other percentiles on table. --- freqtrade/optimize/optimize_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 6af04d4f2..1c558a77c 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -93,7 +93,7 @@ def generate_text_table_sell_reason( profit_mean = round(result['profit_percent'].mean() * 100.0, 2) profit_sum = round(result["profit_percent"].sum() * 100.0, 2) profit_tot = result["profit_abs"].sum() - profit_percent_tot = result["profit_percent"].sum() * 100.0 / max_open_trades + profit_percent_tot = round(result["profit_percent"].sum() * 100.0 / max_open_trades, 2) tabular_data.append( [ reason.value, From c396ad4daa5c582141a3088a3d472e083ec9d094 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 31 Jan 2020 20:41:51 +0100 Subject: [PATCH 0361/1106] Align quotes in same area --- freqtrade/optimize/optimize_reports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 1c558a77c..c5cd944a1 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -92,8 +92,8 @@ def generate_text_table_sell_reason( loss = len(result[result['profit_abs'] < 0]) profit_mean = round(result['profit_percent'].mean() * 100.0, 2) profit_sum = round(result["profit_percent"].sum() * 100.0, 2) - profit_tot = result["profit_abs"].sum() - profit_percent_tot = round(result["profit_percent"].sum() * 100.0 / max_open_trades, 2) + profit_tot = result['profit_abs'].sum() + profit_percent_tot = round(result['profit_percent'].sum() * 100.0 / max_open_trades, 2) tabular_data.append( [ reason.value, From d038bcedb0bd8dee7ae84936a9ff6993d86b4b5b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 31 Jan 2020 22:37:05 +0100 Subject: [PATCH 0362/1106] fixed some more line alignments --- freqtrade/optimize/backtesting.py | 12 ++++++------ freqtrade/optimize/hyperopt.py | 29 +++++++++++++++-------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index cdf74f65f..7684c5c90 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -404,12 +404,12 @@ class Backtesting: ) # Execute backtest and print results all_results[self.strategy.get_strategy_name()] = self.backtest( - processed=preprocessed, - stake_amount=self.config['stake_amount'], - start_date=min_date, - end_date=max_date, - max_open_trades=max_open_trades, - position_stacking=position_stacking, + processed=preprocessed, + stake_amount=self.config['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=max_open_trades, + position_stacking=position_stacking, ) for strategy, results in all_results.items(): diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 525f491f3..ad8b4f2c8 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -59,6 +59,7 @@ class Hyperopt: hyperopt = Hyperopt(config) hyperopt.start() """ + def __init__(self, config: Dict[str, Any]) -> None: self.config = config @@ -90,13 +91,13 @@ class Hyperopt: # Populate functions here (hasattr is slow so should not be run during "regular" operations) if hasattr(self.custom_hyperopt, 'populate_indicators'): self.backtesting.strategy.advise_indicators = \ - self.custom_hyperopt.populate_indicators # type: ignore + self.custom_hyperopt.populate_indicators # type: ignore if hasattr(self.custom_hyperopt, 'populate_buy_trend'): self.backtesting.strategy.advise_buy = \ - self.custom_hyperopt.populate_buy_trend # type: ignore + self.custom_hyperopt.populate_buy_trend # type: ignore if hasattr(self.custom_hyperopt, 'populate_sell_trend'): self.backtesting.strategy.advise_sell = \ - self.custom_hyperopt.populate_sell_trend # type: ignore + self.custom_hyperopt.populate_sell_trend # type: ignore # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set if self.config.get('use_max_market_positions', True): @@ -345,15 +346,15 @@ class Hyperopt: if self.has_space('roi'): self.backtesting.strategy.minimal_roi = \ - self.custom_hyperopt.generate_roi_table(params_dict) + self.custom_hyperopt.generate_roi_table(params_dict) if self.has_space('buy'): self.backtesting.strategy.advise_buy = \ - self.custom_hyperopt.buy_strategy_generator(params_dict) + self.custom_hyperopt.buy_strategy_generator(params_dict) if self.has_space('sell'): self.backtesting.strategy.advise_sell = \ - self.custom_hyperopt.sell_strategy_generator(params_dict) + self.custom_hyperopt.sell_strategy_generator(params_dict) if self.has_space('stoploss'): self.backtesting.strategy.stoploss = params_dict['stoploss'] @@ -372,12 +373,12 @@ class Hyperopt: min_date, max_date = get_timerange(processed) backtesting_results = self.backtesting.backtest( - processed=processed, - stake_amount=self.config['stake_amount'], - start_date=min_date, - end_date=max_date, - max_open_trades=self.max_open_trades, - position_stacking=self.position_stacking, + processed=processed, + stake_amount=self.config['stake_amount'], + start_date=min_date, + end_date=max_date, + max_open_trades=self.max_open_trades, + position_stacking=self.position_stacking, ) return self._get_results_dict(backtesting_results, min_date, max_date, params_dict, params_details) @@ -469,8 +470,8 @@ class Hyperopt: trials = Hyperopt._read_trials(trials_file) if trials[0].get('is_best') is None: raise OperationalException( - "The file with Hyperopt results is incompatible with this version " - "of Freqtrade and cannot be loaded.") + "The file with Hyperopt results is incompatible with this version " + "of Freqtrade and cannot be loaded.") logger.info(f"Loaded {len(trials)} previous evaluations from disk.") return trials From d69ef4380b273468b20c652fb5e6f3d489fc4dd6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 13:44:04 +0100 Subject: [PATCH 0363/1106] Add basic documentation for new-config option --- docs/utils.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/utils.md b/docs/utils.md index 18deeac54..df2a1c3c3 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -36,6 +36,24 @@ optional arguments: └── sample_strategy.py ``` +## Create new config + +Creates a new configuration file, asking some questions which are important selections for a configuration. + + +``` +usage: freqtrade new-config [-h] [-c PATH] + +optional arguments: + -h, --help show this help message and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. +``` + +!!! Warning + Only vital questions are asked. Freqtrade offers a lot more configuration possibilities, which are listed in the [Configuration documentation](configuration.md#configuration-parameters) + ## Create new strategy Creates a new strategy from a template similar to SampleStrategy. From c40a4d77f8972c80be8be311a9dfd183a1222a64 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 13:46:58 +0100 Subject: [PATCH 0364/1106] Use exchange_mapping to determine correct exchange-template --- freqtrade/commands/build_config_commands.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 6abacd826..e0910e5b7 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -5,7 +5,7 @@ from typing import Any, Dict from questionary import Separator, prompt from freqtrade.constants import UNLIMITED_STAKE_AMOUNT -from freqtrade.exchange import available_exchanges +from freqtrade.exchange import available_exchanges, MAP_EXCHANGE_CHILDCLASS from freqtrade.misc import render_template from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) @@ -141,8 +141,11 @@ def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: """ from jinja2.exceptions import TemplateNotFound try: + exchange_template = MAP_EXCHANGE_CHILDCLASS.get( + selections['exchange_name'], selections['exchange_name']) + selections['exchange'] = render_template( - templatefile=f"subtemplates/exchange_{selections['exchange_name']}.j2", + templatefile=f"subtemplates/exchange_{exchange_template}.j2", arguments=selections ) except TemplateNotFound: From 54512a66ef187aedcddc048968f822b515fa510d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 13:52:25 +0100 Subject: [PATCH 0365/1106] Update help-strings for list-utils --- docs/utils.md | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index df2a1c3c3..44cbc35d6 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -197,20 +197,31 @@ All exchanges supported by the ccxt library: _1btcxe, acx, adara, allcoin, anxpr Use the `list-timeframes` subcommand to see the list of ticker intervals (timeframes) available for the exchange. ``` -usage: freqtrade list-timeframes [-h] [--exchange EXCHANGE] [-1] +usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1] optional arguments: - -h, --help show this help message and exit - --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no - config is provided. - -1, --one-column Print output in one column. + -h, --help show this help message and exit + --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided. + -1, --one-column Print output in one column. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. ``` * Example: see the timeframes for the 'binance' exchange, set in the configuration file: ``` -$ freqtrade -c config_binance.json list-timeframes +$ freqtrade list-timeframes -c config_binance.json ... Timeframes available for the exchange `binance`: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M ``` @@ -234,14 +245,16 @@ You can print info about any pair/market with these subcommands - and you can fi These subcommands have same usage and same set of available options: ``` -usage: freqtrade list-markets [-h] [--exchange EXCHANGE] [--print-list] - [--print-json] [-1] [--print-csv] +usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--exchange EXCHANGE] + [--print-list] [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] -usage: freqtrade list-pairs [-h] [--exchange EXCHANGE] [--print-list] - [--print-json] [-1] [--print-csv] +usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--exchange EXCHANGE] + [--print-list] [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] @@ -260,6 +273,22 @@ optional arguments: Specify quote currency(-ies). Space-separated list. -a, --all Print all pairs or market symbols. By default only active ones are shown. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. + ``` By default, only active pairs/markets are shown. Active pairs/markets are those that can currently be traded @@ -281,7 +310,7 @@ $ freqtrade list-pairs --quote USD --print-json human-readable list with summary: ``` -$ freqtrade -c config_binance.json list-pairs --all --base BTC ETH --quote USDT USD --print-list +$ freqtrade list-pairs -c config_binance.json --all --base BTC ETH --quote USDT USD --print-list ``` * Print all markets on exchange "Kraken", in the tabular format: From 8796ecb2a9565e04c336c6e84ac606413c9c8c4c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 13:54:17 +0100 Subject: [PATCH 0366/1106] Ad example for new-config with answered questions --- docs/installation.md | 3 ++- docs/utils.md | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index cbe000da4..8d3d2c464 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -31,7 +31,7 @@ Freqtrade provides the Linux/MacOS Easy Installation script to install all depen !!! Note Windows installation is explained [here](#windows). -The easiest way to install and run Freqtrade is to clone the bot GitHub repository and then run the Easy Installation script, if it's available for your platform. +The easiest way to install and run Freqtrade is to clone the bot Github repository and then run the Easy Installation script, if it's available for your platform. !!! Note "Version considerations" When cloning the repository the default working branch has the name `develop`. This branch contains all last features (can be considered as relatively stable, thanks to automated tests). The `master` branch contains the code of the last release (done usually once per month on an approximately one week old snapshot of the `develop` branch to prevent packaging bugs, so potentially it's more stable). @@ -47,6 +47,7 @@ cd freqtrade git checkout master # Optional, see (1) ./setup.sh --install ``` + (1) This command switches the cloned repository to the use of the `master` branch. It's not needed if you wish to stay on the `develop` branch. You may later switch between branches at any time with the `git checkout master`/`git checkout develop` commands. ## Easy Installation Script (Linux/MacOS) diff --git a/docs/utils.md b/docs/utils.md index 44cbc35d6..f77d2c428 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -54,6 +54,21 @@ optional arguments: !!! Warning Only vital questions are asked. Freqtrade offers a lot more configuration possibilities, which are listed in the [Configuration documentation](configuration.md#configuration-parameters) +### Create config examples + +``` +$ freqtrade new-config --config config_binance.json + +? Do you want to enable Dry-run (simulated trades)? Yes +? Please insert your stake currency: BTC +? Please insert your stake amount: 0.05 +? Please insert max_open_trades (Integer or 'unlimited'): 5 +? Please insert your ticker interval: 15m +? Please insert your display Currency (for reporting): USD +? Select exchange binance +? Do you want to enable Telegram? No +``` + ## Create new strategy Creates a new strategy from a template similar to SampleStrategy. From 929bbe3058e5682793126781956095207d04e3c0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:01:19 +0100 Subject: [PATCH 0367/1106] Link to docker installation from index.md --- docs/index.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index c88c73619..f0ee831e3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,12 +51,15 @@ To run this bot we recommend you a cloud instance with a minimum of: ### Software requirements +- Docker (Recommended) + +Alternatively + - Python 3.6.x - pip (pip3) - git - TA-Lib - virtualenv (Recommended) -- Docker (Recommended) ## Support @@ -67,4 +70,4 @@ Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODc ## Ready to try? -Begin by reading our installation guide [here](installation). +Begin by reading our installation guide [for docker](docker.md), or for [installation without docker](installation.md). From c224c669784cdf0383fab61380e3b65d8189f95a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:06:31 +0100 Subject: [PATCH 0368/1106] Small edits to install.md --- docs/installation.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 8d3d2c464..054cafe9b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -130,6 +130,17 @@ bash setup.sh -i #### 1. Install TA-Lib +Use the provided ta-lib installation script + +```bash +sudo ./build_helpers/install_ta-lib.sh +``` + +!!! Note + This will use the ta-lib tar.gz included in this repository. + +##### TA-Lib manual installation + Official webpage: https://mrjbq7.github.io/ta-lib/install.html ```bash @@ -185,7 +196,8 @@ python3 -m pip install -e . # Initialize the user_directory freqtrade create-userdir --userdir user_data/ -cp config.json.example config.json +# Create a new configuration file +freqtrade new-config --config config.json ``` > *To edit the config please refer to [Bot Configuration](configuration.md).* From cfa6a3e3d32d5575299bb346367ec394ff8a1a7c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:12:21 +0100 Subject: [PATCH 0369/1106] Don't overwrite files --- freqtrade/commands/build_config_commands.py | 6 +++++- tests/commands/test_build_config.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index e0910e5b7..6ba9cf0ac 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -166,7 +166,11 @@ def start_new_config(args: Dict[str, Any]) -> None: Create a new strategy from a template Asking the user questions to fill out the templateaccordingly. """ - selections = ask_user_config() config_path = Path(args['config'][0]) + if config_path.exists(): + raise OperationalException( + f"Configuration `{config_path}` already exists. " + "Please use another configuration name or delete the existing configuration.") + selections = ask_user_config() deploy_new_config(config_path, selections) diff --git a/tests/commands/test_build_config.py b/tests/commands/test_build_config.py index 46e79b357..b0a048c15 100644 --- a/tests/commands/test_build_config.py +++ b/tests/commands/test_build_config.py @@ -6,6 +6,7 @@ import pytest from freqtrade.commands.build_config_commands import (ask_user_config, start_new_config) +from freqtrade.exceptions import OperationalException from tests.conftest import get_args, log_has_re @@ -43,6 +44,17 @@ def test_start_new_config(mocker, caplog, exchange): assert result['ticker_interval'] == '15m' +def test_start_new_config_exists(mocker, caplog): + mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + args = [ + "new-config", + "--config", + "coolconfig.json" + ] + with pytest.raises(OperationalException, match=r"Configuration .* already exists\."): + start_new_config(get_args(args)) + + def test_ask_user_config(): # TODO: Implement me pass From d1a3a2d000f1a2e5600265cc4fcf84287fd0122a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:22:40 +0100 Subject: [PATCH 0370/1106] Add tests for build_config --- freqtrade/commands/build_config_commands.py | 23 ++++++++++++++++++--- tests/commands/test_build_config.py | 12 ++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 6ba9cf0ac..838fd510a 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -27,6 +27,19 @@ def validate_is_float(val): return False +def ask_user_overwrite(config_path: Path) -> bool: + questions = [ + { + "type": "confirm", + "name": "overwrite", + "message": f"File {config_path} already exists. Overwrite?", + "default": False, + }, + ] + answers = prompt(questions) + return answers['overwrite'] + + def ask_user_config() -> Dict[str, Any]: """ Ask user a few questions to build the configuration. @@ -169,8 +182,12 @@ def start_new_config(args: Dict[str, Any]) -> None: config_path = Path(args['config'][0]) if config_path.exists(): - raise OperationalException( - f"Configuration `{config_path}` already exists. " - "Please use another configuration name or delete the existing configuration.") + overwrite = ask_user_overwrite(config_path) + if overwrite: + config_path.unlink() + else: + raise OperationalException( + f"Configuration `{config_path}` already exists. " + "Please use another configuration name or delete the existing configuration.") selections = ask_user_config() deploy_new_config(config_path, selections) diff --git a/tests/commands/test_build_config.py b/tests/commands/test_build_config.py index b0a048c15..8f71c2098 100644 --- a/tests/commands/test_build_config.py +++ b/tests/commands/test_build_config.py @@ -1,8 +1,8 @@ -import json from pathlib import Path from unittest.mock import MagicMock import pytest +import rapidjson from freqtrade.commands.build_config_commands import (ask_user_config, start_new_config) @@ -13,7 +13,10 @@ from tests.conftest import get_args, log_has_re @pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken', 'ftx']) def test_start_new_config(mocker, caplog, exchange): wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) - mocker.patch.object(Path, "exists", MagicMock(return_value=False)) + mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + unlink_mock = mocker.patch.object(Path, "unlink", MagicMock()) + mocker.patch('freqtrade.commands.build_config_commands.ask_user_overwrite', return_value=True) + sample_selections = { 'max_open_trades': 3, 'stake_currency': 'USDT', @@ -39,13 +42,16 @@ def test_start_new_config(mocker, caplog, exchange): assert log_has_re("Writing config to .*", caplog) assert wt_mock.call_count == 1 - result = json.loads(wt_mock.call_args_list[0][0][0]) + assert unlink_mock.call_count == 1 + result = rapidjson.loads(wt_mock.call_args_list[0][0][0], + parse_mode=rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS) assert result['exchange']['name'] == exchange assert result['ticker_interval'] == '15m' def test_start_new_config_exists(mocker, caplog): mocker.patch.object(Path, "exists", MagicMock(return_value=True)) + mocker.patch('freqtrade.commands.build_config_commands.ask_user_overwrite', return_value=False) args = [ "new-config", "--config", From 12317b1c535a4ca6b82441896000527c4f69d8cb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:46:43 +0100 Subject: [PATCH 0371/1106] Add some rudimentary tests for questions --- tests/commands/test_build_config.py | 59 ++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/tests/commands/test_build_config.py b/tests/commands/test_build_config.py index 8f71c2098..d4ebe1de2 100644 --- a/tests/commands/test_build_config.py +++ b/tests/commands/test_build_config.py @@ -5,11 +5,33 @@ import pytest import rapidjson from freqtrade.commands.build_config_commands import (ask_user_config, - start_new_config) + ask_user_overwrite, + start_new_config, + validate_is_float, + validate_is_int) from freqtrade.exceptions import OperationalException from tests.conftest import get_args, log_has_re +def test_validate_is_float(): + assert validate_is_float('2.0') + assert validate_is_float('2.1') + assert validate_is_float('0.1') + assert validate_is_float('-0.5') + assert not validate_is_float('-0.5e') + + +def test_validate_is_int(): + assert validate_is_int('2') + assert validate_is_int('6') + assert validate_is_int('-1') + assert validate_is_int('500') + assert not validate_is_int('2.0') + assert not validate_is_int('2.1') + assert not validate_is_int('-2.1') + assert not validate_is_int('-ee') + + @pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken', 'ftx']) def test_start_new_config(mocker, caplog, exchange): wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) @@ -61,7 +83,34 @@ def test_start_new_config_exists(mocker, caplog): start_new_config(get_args(args)) -def test_ask_user_config(): - # TODO: Implement me - pass - # assert ask_user_config() +def test_ask_user_overwrite(mocker): + """ + Once https://github.com/tmbo/questionary/issues/35 is implemented, improve this test. + """ + prompt_mock = mocker.patch('freqtrade.commands.build_config_commands.prompt', + return_value={'overwrite': False}) + assert not ask_user_overwrite(Path('test.json')) + assert prompt_mock.call_count == 1 + + prompt_mock.reset_mock() + prompt_mock = mocker.patch('freqtrade.commands.build_config_commands.prompt', + return_value={'overwrite': True}) + assert ask_user_overwrite(Path('test.json')) + assert prompt_mock.call_count == 1 + + +def test_ask_user_config(mocker): + """ + Once https://github.com/tmbo/questionary/issues/35 is implemented, improve this test. + """ + prompt_mock = mocker.patch('freqtrade.commands.build_config_commands.prompt', + return_value={'overwrite': False}) + answers = ask_user_config() + assert isinstance(answers, dict) + assert prompt_mock.call_count == 1 + + prompt_mock = mocker.patch('freqtrade.commands.build_config_commands.prompt', + return_value={}) + + with pytest.raises(OperationalException, match=r"User interrupted interactive questions\."): + ask_user_config() From 628b06927c08b043338faa11254305bbce948287 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 14:59:14 +0100 Subject: [PATCH 0372/1106] Support python3.8 virtualenvs and remove config generation via SED --- setup.sh | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/setup.sh b/setup.sh index fb5102e12..bce2e56cf 100755 --- a/setup.sh +++ b/setup.sh @@ -17,6 +17,14 @@ function check_installed_python() { exit 2 fi + which python3.8 + if [ $? -eq 0 ]; then + echo "using Python 3.8" + PYTHON=python3.8 + check_installed_pip + return + fi + which python3.7 if [ $? -eq 0 ]; then echo "using Python 3.7" @@ -215,27 +223,8 @@ function config_generator() { function config() { echo "-------------------------" - echo "Generating config file" + echo "Please use freqtrade new-config -c config.json to generate a new configuration file." echo "-------------------------" - if [ -f config.json ] - then - read -p "A config file already exist, do you want to override it [y/N]? " - if [[ $REPLY =~ ^[Yy]$ ]] - then - config_generator - else - echo "Configuration of config.json ignored." - fi - else - config_generator - fi - - echo - echo "-------------------------" - echo "Config file generated" - echo "-------------------------" - echo "Edit ./config.json to modify Pair and other configurations." - echo } function install() { From 4459679c6404ac1d6aa58c4543eda7e6f4819a19 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 15:14:44 +0100 Subject: [PATCH 0373/1106] Update dockerfile to 3.8.1 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f631d891d..923285f39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.6-slim-stretch +FROM python:3.8.1-slim-buster RUN apt-get update \ && apt-get -y install curl build-essential libssl-dev \ From 321bc336ea7b63064c41a2f3807fe8838331f56f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 15:14:55 +0100 Subject: [PATCH 0374/1106] Run tests against 3.8 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53b2e5440..c838baced 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: os: [ ubuntu-18.04, macos-latest ] - python-version: [3.7] + python-version: [3.7, 3.8] steps: - uses: actions/checkout@v1 From cbd2b265bbb2eea78ad6ffc6b727e1b733729ce5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Feb 2020 15:16:44 +0100 Subject: [PATCH 0375/1106] Fix small error --- freqtrade/commands/arguments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 504c6b0b5..c8a038328 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -182,7 +182,7 @@ class Arguments: # add new-config subcommand build_config_cmd = subparsers.add_parser('new-config', - help="Create new config") + help="Create new config") build_config_cmd.set_defaults(func=start_new_config) self._build_args(optionlist=ARGS_BUILD_CONFIG, parser=build_config_cmd) From f3d500085c0fec96a8ae59bc164e06a55a0beacb Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 07:00:40 +0300 Subject: [PATCH 0376/1106] Add some type hints --- freqtrade/commands/data_commands.py | 10 +++-- freqtrade/commands/deploy_commands.py | 4 +- freqtrade/commands/plot_commands.py | 2 +- freqtrade/configuration/check_exchange.py | 2 +- .../configuration/deprecated_settings.py | 4 +- .../configuration/directory_operations.py | 2 +- freqtrade/configuration/timerange.py | 5 ++- freqtrade/data/btanalysis.py | 7 +-- freqtrade/data/history.py | 12 ++--- freqtrade/edge/edge_positioning.py | 4 +- freqtrade/exchange/exchange.py | 45 +++++++++++-------- freqtrade/freqtradebot.py | 16 +++---- freqtrade/misc.py | 9 ++-- freqtrade/optimize/backtesting.py | 10 +++-- freqtrade/optimize/hyperopt.py | 18 ++++---- freqtrade/pairlist/IPairList.py | 5 ++- freqtrade/pairlist/PrecisionFilter.py | 6 +-- freqtrade/pairlist/PriceFilter.py | 5 ++- freqtrade/pairlist/VolumePairList.py | 7 +-- freqtrade/persistence.py | 9 ++-- freqtrade/plot/plotting.py | 2 +- freqtrade/resolvers/iresolver.py | 2 +- freqtrade/resolvers/strategy_resolver.py | 7 +-- freqtrade/rpc/rpc.py | 5 ++- freqtrade/rpc/rpc_manager.py | 2 +- freqtrade/strategy/interface.py | 2 +- freqtrade/wallets.py | 10 ++--- freqtrade/worker.py | 2 +- 28 files changed, 114 insertions(+), 100 deletions(-) diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index c01772023..aeb598009 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -1,6 +1,6 @@ import logging import sys -from typing import Any, Dict, List +from typing import Any, Dict, List, cast import arrow @@ -43,16 +43,18 @@ def start_download_data(args: Dict[str, Any]) -> None: if config.get('download_trades'): pairs_not_available = refresh_backtest_trades_data( exchange, pairs=config["pairs"], datadir=config['datadir'], - timerange=timerange, erase=config.get("erase")) + timerange=timerange, erase=cast(bool, config.get("erase"))) # Convert downloaded trade data to different timeframes convert_trades_to_ohlcv( pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, + erase=cast(bool, config.get("erase"))) else: pairs_not_available = refresh_backtest_ohlcv_data( exchange, pairs=config["pairs"], timeframes=config["timeframes"], - datadir=config['datadir'], timerange=timerange, erase=config.get("erase")) + datadir=config['datadir'], timerange=timerange, + erase=cast(bool, config.get("erase"))) except KeyboardInterrupt: sys.exit("SIGINT received, aborting ...") diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 99ae63244..809740661 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -28,7 +28,7 @@ def start_create_userdir(args: Dict[str, Any]) -> None: sys.exit(1) -def deploy_new_strategy(strategy_name, strategy_path: Path, subtemplate: str): +def deploy_new_strategy(strategy_name: str, strategy_path: Path, subtemplate: str) -> None: """ Deploy new strategy from template to strategy_path """ @@ -69,7 +69,7 @@ def start_new_strategy(args: Dict[str, Any]) -> None: raise OperationalException("`new-strategy` requires --strategy to be set.") -def deploy_new_hyperopt(hyperopt_name, hyperopt_path: Path, subtemplate: str): +def deploy_new_hyperopt(hyperopt_name: str, hyperopt_path: Path, subtemplate: str) -> None: """ Deploys a new hyperopt template to hyperopt_path """ diff --git a/freqtrade/commands/plot_commands.py b/freqtrade/commands/plot_commands.py index 028933ba7..5e547acb0 100644 --- a/freqtrade/commands/plot_commands.py +++ b/freqtrade/commands/plot_commands.py @@ -5,7 +5,7 @@ from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -def validate_plot_args(args: Dict[str, Any]): +def validate_plot_args(args: Dict[str, Any]) -> None: if not args.get('datadir') and not args.get('config'): raise OperationalException( "You need to specify either `--datadir` or `--config` " diff --git a/freqtrade/configuration/check_exchange.py b/freqtrade/configuration/check_exchange.py index 0076b1c5d..92daaf251 100644 --- a/freqtrade/configuration/check_exchange.py +++ b/freqtrade/configuration/check_exchange.py @@ -10,7 +10,7 @@ from freqtrade.state import RunMode logger = logging.getLogger(__name__) -def remove_credentials(config: Dict[str, Any]): +def remove_credentials(config: Dict[str, Any]) -> None: """ Removes exchange keys from the configuration and specifies dry-run Used for backtesting / hyperopt / edge and utils. diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index 78d8218d4..55497d4f5 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -13,7 +13,7 @@ logger = logging.getLogger(__name__) def check_conflicting_settings(config: Dict[str, Any], section1: str, name1: str, - section2: str, name2: str): + section2: str, name2: str) -> None: section1_config = config.get(section1, {}) section2_config = config.get(section2, {}) if name1 in section1_config and name2 in section2_config: @@ -28,7 +28,7 @@ def check_conflicting_settings(config: Dict[str, Any], def process_deprecated_setting(config: Dict[str, Any], section1: str, name1: str, - section2: str, name2: str): + section2: str, name2: str) -> None: section2_config = config.get(section2, {}) if name2 in section2_config: diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index 43a209483..5f8eb76b0 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -23,7 +23,7 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> Pat return folder -def create_userdata_dir(directory: str, create_dir=False) -> Path: +def create_userdata_dir(directory: str, create_dir: bool = False) -> Path: """ Create userdata directory structure. if create_dir is True, then the parent-directory will be created if it does not exist. diff --git a/freqtrade/configuration/timerange.py b/freqtrade/configuration/timerange.py index a8be873df..3db5f6217 100644 --- a/freqtrade/configuration/timerange.py +++ b/freqtrade/configuration/timerange.py @@ -7,6 +7,7 @@ from typing import Optional import arrow + logger = logging.getLogger(__name__) @@ -30,7 +31,7 @@ class TimeRange: return (self.starttype == other.starttype and self.stoptype == other.stoptype and self.startts == other.startts and self.stopts == other.stopts) - def subtract_start(self, seconds) -> None: + def subtract_start(self, seconds: int) -> None: """ Subtracts from startts if startts is set. :param seconds: Seconds to subtract from starttime @@ -59,7 +60,7 @@ class TimeRange: self.starttype = 'date' @staticmethod - def parse_timerange(text: Optional[str]): + def parse_timerange(text: Optional[str]) -> 'TimeRange': """ Parse the value of the argument --timerange to determine what is the range desired :param text: value from --timerange diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 04b2ca980..c28e462ba 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -3,7 +3,7 @@ Helpers when analyzing backtest data """ import logging from pathlib import Path -from typing import Dict +from typing import Dict, Union import numpy as np import pandas as pd @@ -20,7 +20,7 @@ BT_DATA_COLUMNS = ["pair", "profitperc", "open_time", "close_time", "index", "du "open_rate", "close_rate", "open_at_end", "sell_reason"] -def load_backtest_data(filename) -> pd.DataFrame: +def load_backtest_data(filename: Union[Path, str]) -> pd.DataFrame: """ Load backtest data file. :param filename: pathlib.Path object, or string pointing to the file. @@ -151,7 +151,8 @@ def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> p return trades -def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = "close"): +def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], + column: str = "close") -> pd.DataFrame: """ Combine multiple dataframes "column" :param tickers: Dict of Dataframes, dict key should be pair. diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index 30d168f78..d891aa5b0 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -86,7 +86,7 @@ def load_tickerdata_file(datadir: Path, pair: str, timeframe: str, def store_tickerdata_file(datadir: Path, pair: str, - timeframe: str, data: list, is_zip: bool = False): + timeframe: str, data: list, is_zip: bool = False) -> None: """ Stores tickerdata to file """ @@ -109,7 +109,7 @@ def load_trades_file(datadir: Path, pair: str, def store_trades_file(datadir: Path, pair: str, - data: list, is_zip: bool = True): + data: list, is_zip: bool = True) -> None: """ Stores tickerdata to file """ @@ -117,7 +117,7 @@ def store_trades_file(datadir: Path, pair: str, misc.file_dump_json(filename, data, is_zip=is_zip) -def _validate_pairdata(pair, pairdata, timerange: TimeRange): +def _validate_pairdata(pair: str, pairdata: List[Dict], timerange: TimeRange) -> None: if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000: logger.warning('Missing data at start for pair %s, data starts at %s', pair, arrow.get(pairdata[0][0] // 1000).strftime('%Y-%m-%d %H:%M:%S')) @@ -331,7 +331,7 @@ def _download_pair_history(datadir: Path, def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str], datadir: Path, timerange: Optional[TimeRange] = None, - erase=False) -> List[str]: + erase: bool = False) -> List[str]: """ Refresh stored ohlcv data for backtesting and hyperopt operations. Used by freqtrade download-data subcommand. @@ -401,7 +401,7 @@ def _download_trades_history(datadir: Path, def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: Path, - timerange: TimeRange, erase=False) -> List[str]: + timerange: TimeRange, erase: bool = False) -> List[str]: """ Refresh stored trades data for backtesting and hyperopt operations. Used by freqtrade download-data subcommand. @@ -428,7 +428,7 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], - datadir: Path, timerange: TimeRange, erase=False) -> None: + datadir: Path, timerange: TimeRange, erase: bool = False) -> None: """ Convert stored trades data to ohlcv data """ diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index 15883357b..1506b4ed5 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -1,7 +1,7 @@ # pragma pylint: disable=W0603 """ Edge positioning package """ import logging -from typing import Any, Dict, NamedTuple +from typing import Any, Dict, List, NamedTuple import arrow import numpy as np @@ -181,7 +181,7 @@ class Edge: 'strategy stoploss is returned instead.') return self.strategy.stoploss - def adjust(self, pairs) -> list: + def adjust(self, pairs: List[str]) -> list: """ Filters out and sorts "pairs" according to Edge calculated pairs """ diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 87c189457..f7bfb0ee1 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -24,6 +24,12 @@ from freqtrade.exceptions import (DependencyException, InvalidOrderException, from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async from freqtrade.misc import deep_merge_dicts + +# Should probably use typing.Literal when we switch to python 3.8+ +# CcxtModuleType = Literal[ccxt, ccxt_async] +CcxtModuleType = Any + + logger = logging.getLogger(__name__) @@ -51,7 +57,7 @@ class Exchange: } _ft_has: Dict = {} - def __init__(self, config: dict, validate: bool = True) -> None: + def __init__(self, config: Dict[str, Any], validate: bool = True) -> None: """ Initializes this module with the given config, it does basic validation whether the specified exchange and pairs are valid. @@ -135,7 +141,7 @@ class Exchange: if self._api_async and inspect.iscoroutinefunction(self._api_async.close): asyncio.get_event_loop().run_until_complete(self._api_async.close()) - def _init_ccxt(self, exchange_config: dict, ccxt_module=ccxt, + def _init_ccxt(self, exchange_config: Dict[str, Any], ccxt_module: CcxtModuleType = ccxt, ccxt_kwargs: dict = None) -> ccxt.Exchange: """ Initialize ccxt with given config and return valid @@ -224,13 +230,13 @@ class Exchange: markets = self.markets return sorted(set([x['quote'] for _, x in markets.items()])) - def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame: + def klines(self, pair_interval: Tuple[str, str], copy: bool = True) -> DataFrame: if pair_interval in self._klines: return self._klines[pair_interval].copy() if copy else self._klines[pair_interval] else: return DataFrame() - def set_sandbox(self, api, exchange_config: dict, name: str): + def set_sandbox(self, api: ccxt.Exchange, exchange_config: dict, name: str) -> None: if exchange_config.get('sandbox'): if api.urls.get('test'): api.urls['api'] = api.urls['test'] @@ -240,7 +246,7 @@ class Exchange: "Please check your config.json") raise OperationalException(f'Exchange {name} does not provide a sandbox api') - def _load_async_markets(self, reload=False) -> None: + def _load_async_markets(self, reload: bool = False) -> None: try: if self._api_async: asyncio.get_event_loop().run_until_complete( @@ -273,7 +279,7 @@ class Exchange: except ccxt.BaseError: logger.exception("Could not reload markets.") - def validate_stakecurrency(self, stake_currency) -> None: + def validate_stakecurrency(self, stake_currency: str) -> None: """ Checks stake-currency against available currencies on the exchange. :param stake_currency: Stake-currency to validate @@ -319,7 +325,7 @@ class Exchange: f"Please check if you are impacted by this restriction " f"on the exchange and eventually remove {pair} from your whitelist.") - def get_valid_pair_combination(self, curr_1, curr_2) -> str: + def get_valid_pair_combination(self, curr_1: str, curr_2: str) -> str: """ Get valid pair combination of curr_1 and curr_2 by trying both combinations. """ @@ -373,7 +379,7 @@ class Exchange: raise OperationalException( f'Time in force policies are not supported for {self.name} yet.') - def validate_required_startup_candles(self, startup_candles) -> None: + def validate_required_startup_candles(self, startup_candles: int) -> None: """ Checks if required startup_candles is more than ohlcv_candle_limit. Requires a grace-period of 5 candles - so a startup-period up to 494 is allowed by default. @@ -392,7 +398,7 @@ class Exchange: """ return endpoint in self._api.has and self._api.has[endpoint] - def amount_to_precision(self, pair, amount: float) -> float: + def amount_to_precision(self, pair: str, amount: float) -> float: ''' Returns the amount to buy or sell to a precision the Exchange accepts Reimplementation of ccxt internal methods - ensuring we can test the result is correct @@ -406,7 +412,7 @@ class Exchange: return amount - def price_to_precision(self, pair, price: float) -> float: + def price_to_precision(self, pair: str, price: float) -> float: ''' Returns the price rounded up to the precision the Exchange accepts. Partial Reimplementation of ccxt internal method decimal_to_precision(), @@ -494,7 +500,7 @@ class Exchange: raise OperationalException(e) from e def buy(self, pair: str, ordertype: str, amount: float, - rate: float, time_in_force) -> Dict: + rate: float, time_in_force: str) -> Dict: if self._config['dry_run']: dry_order = self.dry_run_order(pair, ordertype, "buy", amount, rate) @@ -507,7 +513,7 @@ class Exchange: return self.create_order(pair, ordertype, 'buy', amount, rate, params) def sell(self, pair: str, ordertype: str, amount: float, - rate: float, time_in_force='gtc') -> Dict: + rate: float, time_in_force: str = 'gtc') -> Dict: if self._config['dry_run']: dry_order = self.dry_run_order(pair, ordertype, "sell", amount, rate) @@ -976,8 +982,8 @@ class Exchange: raise OperationalException(e) from e @retrier - def get_fee(self, symbol, type='', side='', amount=1, - price=1, taker_or_maker='maker') -> float: + def get_fee(self, symbol: str, type: str = '', side: str = '', amount: float = 1, + price: float = 1, taker_or_maker: str = 'maker') -> float: try: # validate that markets are loaded before trying to get fee if self._api.markets is None or len(self._api.markets) == 0: @@ -1000,7 +1006,7 @@ def get_exchange_bad_reason(exchange_name: str) -> str: return BAD_EXCHANGES.get(exchange_name, "") -def is_exchange_known_ccxt(exchange_name: str, ccxt_module=None) -> bool: +def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: return exchange_name in ccxt_exchanges(ccxt_module) @@ -1008,14 +1014,14 @@ def is_exchange_officially_supported(exchange_name: str) -> bool: return exchange_name in ['bittrex', 'binance'] -def ccxt_exchanges(ccxt_module=None) -> List[str]: +def ccxt_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: """ Return the list of all exchanges known to ccxt """ return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges -def available_exchanges(ccxt_module=None) -> List[str]: +def available_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: """ Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list """ @@ -1075,7 +1081,8 @@ def timeframe_to_next_date(timeframe: str, date: datetime = None) -> datetime: return datetime.fromtimestamp(new_timestamp, tz=timezone.utc) -def symbol_is_pair(market_symbol: str, base_currency: str = None, quote_currency: str = None): +def symbol_is_pair(market_symbol: str, base_currency: str = None, + quote_currency: str = None) -> bool: """ Check if the market symbol is a pair, i.e. that its symbol consists of the base currency and the quote currency separated by '/' character. If base_currency and/or quote_currency is passed, @@ -1088,7 +1095,7 @@ def symbol_is_pair(market_symbol: str, base_currency: str = None, quote_currency (symbol_parts[1] == quote_currency if quote_currency else len(symbol_parts[1]) > 0)) -def market_is_active(market): +def market_is_active(market: Dict) -> bool: """ Return True if the market is active. """ diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aac501054..34dbca38e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -265,7 +265,7 @@ class FreqtradeBot: return used_rate - def get_trade_stake_amount(self, pair) -> float: + def get_trade_stake_amount(self, pair: str) -> float: """ Calculate stake amount for the trade :return: float: Stake amount @@ -539,7 +539,7 @@ class FreqtradeBot: return True - def _notify_buy(self, trade: Trade, order_type: str): + def _notify_buy(self, trade: Trade, order_type: str) -> None: """ Sends rpc notification when a buy occured. """ @@ -735,7 +735,7 @@ class FreqtradeBot: return False - def handle_trailing_stoploss_on_exchange(self, trade: Trade, order): + def handle_trailing_stoploss_on_exchange(self, trade: Trade, order: dict) -> None: """ Check to see if stoploss on exchange should be updated in case of trailing stoploss on exchange @@ -758,10 +758,8 @@ class FreqtradeBot: f"for pair {trade.pair}") # Create new stoploss order - if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss, - rate=trade.stop_loss): - return False - else: + if not self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss, + rate=trade.stop_loss): logger.warning(f"Could not create trailing stoploss order " f"for pair {trade.pair}.") @@ -990,7 +988,7 @@ class FreqtradeBot: self._notify_sell(trade, order_type) - def _notify_sell(self, trade: Trade, order_type: str): + def _notify_sell(self, trade: Trade, order_type: str) -> None: """ Sends rpc notification when a sell occured. """ @@ -1031,7 +1029,7 @@ class FreqtradeBot: # Common update trade state methods # - def update_trade_state(self, trade, action_order: dict = None): + def update_trade_state(self, trade: Trade, action_order: dict = None) -> None: """ Checks trades with open orders and updates the amount if necessary """ diff --git a/freqtrade/misc.py b/freqtrade/misc.py index bcba78cf0..2a981c249 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -6,6 +6,7 @@ import logging import re from datetime import datetime from pathlib import Path +from typing import Any from typing.io import IO import numpy as np @@ -40,7 +41,7 @@ def datesarray_to_datetimearray(dates: np.ndarray) -> np.ndarray: return dates.dt.to_pydatetime() -def file_dump_json(filename: Path, data, is_zip=False) -> None: +def file_dump_json(filename: Path, data: Any, is_zip: bool = False) -> None: """ Dump JSON data into a file :param filename: file to create @@ -61,7 +62,7 @@ def file_dump_json(filename: Path, data, is_zip=False) -> None: logger.debug(f'done json to "{filename}"') -def json_load(datafile: IO): +def json_load(datafile: IO) -> Any: """ load data with rapidjson Use this to have a consistent experience, @@ -125,11 +126,11 @@ def round_dict(d, n): return {k: (round(v, n) if isinstance(v, float) else v) for k, v in d.items()} -def plural(num, singular: str, plural: str = None) -> str: +def plural(num: float, singular: str, plural: str = None) -> str: return singular if (num == 1 or num == -1) else plural or singular + 's' -def render_template(templatefile: str, arguments: dict = {}): +def render_template(templatefile: str, arguments: dict = {}) -> str: from jinja2 import Environment, PackageLoader, select_autoescape diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index cdf74f65f..ef493e240 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -9,6 +9,7 @@ from datetime import datetime, timedelta from pathlib import Path from typing import Any, Dict, List, NamedTuple, Optional +import arrow from pandas import DataFrame from freqtrade.configuration import (TimeRange, remove_credentials, @@ -24,7 +25,7 @@ from freqtrade.optimize.optimize_reports import ( from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode -from freqtrade.strategy.interface import IStrategy, SellType +from freqtrade.strategy.interface import IStrategy, SellCheckTuple, SellType logger = logging.getLogger(__name__) @@ -148,7 +149,7 @@ class Backtesting: logger.info(f'Dumping backtest results to {recordfilename}') file_dump_json(recordfilename, records) - def _get_ticker_list(self, processed) -> Dict[str, DataFrame]: + def _get_ticker_list(self, processed: Dict) -> Dict[str, DataFrame]: """ Helper function to convert a processed tickerlist into a list for performance reasons. @@ -175,7 +176,8 @@ class Backtesting: ticker[pair] = [x for x in ticker_data.itertuples()] return ticker - def _get_close_rate(self, sell_row, trade: Trade, sell, trade_dur) -> float: + def _get_close_rate(self, sell_row, trade: Trade, sell: SellCheckTuple, + trade_dur: int) -> float: """ Get close rate for backtesting result """ @@ -280,7 +282,7 @@ class Backtesting: return None def backtest(self, processed: Dict, stake_amount: float, - start_date, end_date, + start_date: arrow.Arrow, end_date: arrow.Arrow, max_open_trades: int = 0, position_stacking: bool = False) -> DataFrame: """ Implement backtesting functionality diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 525f491f3..841f8b6db 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -117,11 +117,11 @@ class Hyperopt: self.print_json = self.config.get('print_json', False) @staticmethod - def get_lock_filename(config) -> str: + def get_lock_filename(config: Dict[str, Any]) -> str: return str(config['user_data_dir'] / 'hyperopt.lock') - def clean_hyperopt(self): + def clean_hyperopt(self) -> None: """ Remove hyperopt pickle files to restart hyperopt. """ @@ -158,7 +158,7 @@ class Hyperopt: f"saved to '{self.trials_file}'.") @staticmethod - def _read_trials(trials_file) -> List: + def _read_trials(trials_file: Path) -> List: """ Read hyperopt trials file """ @@ -189,7 +189,7 @@ class Hyperopt: return result @staticmethod - def print_epoch_details(results, total_epochs, print_json: bool, + def print_epoch_details(results, total_epochs: int, print_json: bool, no_header: bool = False, header_str: str = None) -> None: """ Display details of the hyperopt result @@ -218,7 +218,7 @@ class Hyperopt: Hyperopt._params_pretty_print(params, 'trailing', "Trailing stop:") @staticmethod - def _params_update_for_json(result_dict, params, space: str): + def _params_update_for_json(result_dict, params, space: str) -> None: if space in params: space_params = Hyperopt._space_params(params, space) if space in ['buy', 'sell']: @@ -235,7 +235,7 @@ class Hyperopt: result_dict.update(space_params) @staticmethod - def _params_pretty_print(params, space: str, header: str): + def _params_pretty_print(params, space: str, header: str) -> None: if space in params: space_params = Hyperopt._space_params(params, space, 5) if space == 'stoploss': @@ -251,7 +251,7 @@ class Hyperopt: return round_dict(d, r) if r else d @staticmethod - def is_best_loss(results, current_best_loss) -> bool: + def is_best_loss(results, current_best_loss: float) -> bool: return results['loss'] < current_best_loss def print_results(self, results) -> None: @@ -438,7 +438,7 @@ class Hyperopt: random_state=self.random_state, ) - def fix_optimizer_models_list(self): + def fix_optimizer_models_list(self) -> None: """ WORKAROUND: Since skopt is not actively supported, this resolves problems with skopt memory usage, see also: https://github.com/scikit-optimize/scikit-optimize/pull/746 @@ -460,7 +460,7 @@ class Hyperopt: wrap_non_picklable_objects(self.generate_optimizer))(v, i) for v in asked) @staticmethod - def load_previous_results(trials_file) -> List: + def load_previous_results(trials_file: Path) -> List: """ Load data for epochs from the file if we have one """ diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index d722e70f5..1ad4da523 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -7,7 +7,7 @@ Provides lists as configured in config.json import logging from abc import ABC, abstractmethod, abstractproperty from copy import deepcopy -from typing import Dict, List +from typing import Any, Dict, List from freqtrade.exchange import market_is_active @@ -16,7 +16,8 @@ logger = logging.getLogger(__name__) class IPairList(ABC): - def __init__(self, exchange, pairlistmanager, config, pairlistconfig: dict, + def __init__(self, exchange, pairlistmanager, + config: Dict[str, Any], pairlistconfig: Dict[str, Any], pairlist_pos: int) -> None: """ :param exchange: Exchange instance diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 5d364795d..f16458ca5 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -48,10 +48,10 @@ class PrecisionFilter(IPairList): """ Filters and sorts pairlists and assigns and returns them again. """ - stoploss = None - if self._config.get('stoploss') is not None: + stoploss = self._config.get('stoploss') + if stoploss is not None: # Precalculate sanitized stoploss value to avoid recalculation for every pair - stoploss = 1 - abs(self._config.get('stoploss')) + stoploss = 1 - abs(stoploss) # Copy list since we're modifying this list for p in deepcopy(pairlist): ticker = tickers.get(p) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index b3546ebd9..dc02ae251 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -1,6 +1,6 @@ import logging from copy import deepcopy -from typing import Dict, List +from typing import Any, Dict, List from freqtrade.pairlist.IPairList import IPairList @@ -9,7 +9,8 @@ logger = logging.getLogger(__name__) class PriceFilter(IPairList): - def __init__(self, exchange, pairlistmanager, config, pairlistconfig: dict, + def __init__(self, exchange, pairlistmanager, + config: Dict[str, Any], pairlistconfig: Dict[str, Any], pairlist_pos: int) -> None: super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 4ac9935ba..3b28cb7d1 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -6,7 +6,7 @@ Provides lists as configured in config.json """ import logging from datetime import datetime -from typing import Dict, List +from typing import Any, Dict, List from freqtrade.exceptions import OperationalException from freqtrade.pairlist.IPairList import IPairList @@ -18,7 +18,7 @@ SORT_VALUES = ['askVolume', 'bidVolume', 'quoteVolume'] class VolumePairList(IPairList): - def __init__(self, exchange, pairlistmanager, config, pairlistconfig: dict, + def __init__(self, exchange, pairlistmanager, config: Dict[str, Any], pairlistconfig: dict, pairlist_pos: int) -> None: super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) @@ -77,7 +77,8 @@ class VolumePairList(IPairList): else: return pairlist - def _gen_pair_whitelist(self, pairlist, tickers, base_currency: str, key: str) -> List[str]: + def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict, + base_currency: str, key: str) -> List[str]: """ Updates the whitelist with with a dynamically generated list :param base_currency: base currency as str diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 75116f1e3..5b0046091 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -64,11 +64,11 @@ def init(db_url: str, clean_open_orders: bool = False) -> None: clean_dry_run_db() -def has_column(columns, searchname: str) -> bool: +def has_column(columns: List, searchname: str) -> bool: return len(list(filter(lambda x: x["name"] == searchname, columns))) == 1 -def get_column_def(columns, column: str, default: str) -> str: +def get_column_def(columns: List, column: str, default: str) -> str: return default if not has_column(columns, column) else column @@ -246,14 +246,15 @@ class Trade(_DECL_BASE): if self.initial_stop_loss_pct else None), } - def adjust_min_max_rates(self, current_price: float): + def adjust_min_max_rates(self, current_price: float) -> None: """ Adjust the max_rate and min_rate. """ self.max_rate = max(current_price, self.max_rate or self.open_rate) self.min_rate = min(current_price, self.min_rate or self.open_rate) - def adjust_stop_loss(self, current_price: float, stoploss: float, initial: bool = False): + def adjust_stop_loss(self, current_price: float, stoploss: float, + initial: bool = False) -> None: """ This adjusts the stop loss to it's most recently observed setting :param current_price: Current rate the asset is traded diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 5301d762d..943133ed0 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -370,7 +370,7 @@ def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame], return fig -def generate_plot_filename(pair, timeframe) -> str: +def generate_plot_filename(pair: str, timeframe: str) -> str: """ Generate filenames per pair/timeframe to be used for storing plots """ diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 5a844097c..3aec5f9e9 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -25,7 +25,7 @@ class IResolver: initial_search_path: Path @classmethod - def build_search_paths(cls, config, user_subdir: Optional[str] = None, + def build_search_paths(cls, config: Dict[str, Any], user_subdir: Optional[str] = None, extra_dir: Optional[str] = None) -> List[Path]: abs_paths: List[Path] = [cls.initial_search_path] diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 9e64f38df..015ba24d9 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -9,7 +9,7 @@ from base64 import urlsafe_b64decode from collections import OrderedDict from inspect import getfullargspec from pathlib import Path -from typing import Dict, Optional +from typing import Any, Dict, Optional from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, USERPATH_STRATEGY) @@ -30,7 +30,7 @@ class StrategyResolver(IResolver): initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve() @staticmethod - def load_strategy(config: Optional[Dict] = None) -> IStrategy: + def load_strategy(config: Dict[str, Any] = None) -> IStrategy: """ Load the custom class from config parameter :param config: configuration dictionary or None @@ -96,7 +96,8 @@ class StrategyResolver(IResolver): return strategy @staticmethod - def _override_attribute_helper(strategy, config, attribute: str, default): + def _override_attribute_helper(strategy, config: Dict[str, Any], + attribute: str, default: Any): """ Override attributes in the strategy. Prevalence: diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 41097c211..7f5cfc101 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -139,7 +139,8 @@ class RPC: results.append(trade_dict) return results - def _rpc_status_table(self, stake_currency, fiat_display_currency: str) -> Tuple[List, List]: + def _rpc_status_table(self, stake_currency: str, + fiat_display_currency: str) -> Tuple[List, List]: trades = Trade.get_open_trades() if not trades: raise RPCException('no active trade') @@ -385,7 +386,7 @@ class RPC: return {'status': 'No more buy will occur from now. Run /reload_conf to reset.'} - def _rpc_forcesell(self, trade_id) -> Dict[str, str]: + def _rpc_forcesell(self, trade_id: str) -> Dict[str, str]: """ Handler for forcesell . Sells the given trade at current price diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index f687fe4d1..670275991 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -61,7 +61,7 @@ class RPCManager: except NotImplementedError: logger.error(f"Message type {msg['type']} not implemented by handler {mod.name}.") - def startup_messages(self, config, pairlist) -> None: + def startup_messages(self, config: Dict[str, Any], pairlist) -> None: if config['dry_run']: self.send_msg({ 'type': RPCMessageType.WARNING_NOTIFICATION, diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 27bc8280e..6e15c5183 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -180,7 +180,7 @@ class IStrategy(ABC): if pair not in self._pair_locked_until or self._pair_locked_until[pair] < until: self._pair_locked_until[pair] = until - def unlock_pair(self, pair) -> None: + def unlock_pair(self, pair: str) -> None: """ Unlocks a pair previously locked using lock_pair. Not used by freqtrade itself, but intended to be used if users lock pairs diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index c52767162..dd5e34fe6 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -30,24 +30,21 @@ class Wallets: self._last_wallet_refresh = 0 self.update() - def get_free(self, currency) -> float: - + def get_free(self, currency: str) -> float: balance = self._wallets.get(currency) if balance and balance.free: return balance.free else: return 0 - def get_used(self, currency) -> float: - + def get_used(self, currency: str) -> float: balance = self._wallets.get(currency) if balance and balance.used: return balance.used else: return 0 - def get_total(self, currency) -> float: - + def get_total(self, currency: str) -> float: balance = self._wallets.get(currency) if balance and balance.total: return balance.total @@ -87,7 +84,6 @@ class Wallets: self._wallets = _wallets def _update_live(self) -> None: - balances = self._exchange.get_balances() for currency in balances: diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 6da04b4a2..64cc97026 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -22,7 +22,7 @@ class Worker: Freqtradebot worker class """ - def __init__(self, args: Dict[str, Any], config=None) -> None: + def __init__(self, args: Dict[str, Any], config: Dict[str, Any] = None) -> None: """ Init all variables and objects the bot needs to work """ From 3499f1b85c883a4ff0298d8d83de158a43d158ec Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sun, 2 Feb 2020 08:47:33 +0100 Subject: [PATCH 0377/1106] better readability and more consistent with daily sharpe loss method --- freqtrade/optimize/hyperopt_loss_sharpe.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sharpe.py b/freqtrade/optimize/hyperopt_loss_sharpe.py index 5631a75de..a4ec6f90a 100644 --- a/freqtrade/optimize/hyperopt_loss_sharpe.py +++ b/freqtrade/optimize/hyperopt_loss_sharpe.py @@ -28,18 +28,19 @@ class SharpeHyperOptLoss(IHyperOptLoss): Uses Sharpe Ratio calculation. """ - total_profit = results.profit_percent + total_profit = results["profit_percent"] days_period = (max_date - min_date).days # adding slippage of 0.1% per trade total_profit = total_profit - 0.0005 - expected_yearly_return = total_profit.sum() / days_period + expected_returns_mean = total_profit.sum() / days_period + up_stdev = np.std(total_profit) if (np.std(total_profit) != 0.): - sharp_ratio = expected_yearly_return / np.std(total_profit) * np.sqrt(365) + sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365) else: # Define high (negative) sharpe ratio to be clear that this is NOT optimal. sharp_ratio = -20. - # print(expected_yearly_return, np.std(total_profit), sharp_ratio) + # print(expected_returns_mean, up_stdev, sharp_ratio) return -sharp_ratio From d64751687b50e97d3b31d1262f7aeef49fc7aab7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 2 Feb 2020 10:47:44 +0100 Subject: [PATCH 0378/1106] Fix link and lowercase variable --- docs/exchanges.md | 2 +- freqtrade/exchange/binance.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index 18a9f1cba..3c861ce44 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -23,7 +23,7 @@ Binance has been split into 3, and users must use the correct ccxt exchange ID f ## Kraken !!! Tip "Stoploss on Exchange" - Kraken supports `stoploss_on_exchange` and uses stop-loss-market orders. It provides great advantages, so we recommend to benefit from it, however since the resulting order is a stoploss-market order, sell-rates are not guaranteed, which makes this feature less secure than on other exchanges. This limitation is based on kraken's policy [source](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) and [source2](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) - which has stoploss-limit orders disabled. + Kraken supports `stoploss_on_exchange` and uses stop-loss-market orders. It provides great advantages, so we recommend to benefit from it, however since the resulting order is a stoploss-market order, sell-rates are not guaranteed, which makes this feature less secure than on other exchanges. This limitation is based on kraken's policy [source](https://blog.kraken.com/post/1234/announcement-delisting-pairs-and-temporary-suspension-of-advanced-order-types/) and [source2](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) - which has stoploss-limit orders disabled. ### Historic Kraken data diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 45102359d..875628af9 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -46,8 +46,8 @@ class Binance(Exchange): It may work with a limited number of other exchanges, but this has not been tested yet. """ # Limit price threshold: As limit price should always be below stop-price - LIMIT_PRICE_PCT = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) - rate = stop_price * LIMIT_PRICE_PCT + limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) + rate = stop_price * limit_price_pct ordertype = "stop_loss_limit" From aeabe1800bd2dbe924f454a0a5121bfb81987b9b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sun, 2 Feb 2020 10:49:00 +0100 Subject: [PATCH 0379/1106] modified two lines from logger.info to logger.debug cause they're too spammy --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aac501054..7d13eacd6 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -627,7 +627,7 @@ class FreqtradeBot: self.dataprovider.ohlcv(trade.pair, self.strategy.ticker_interval)) if config_ask_strategy.get('use_order_book', False): - logger.info('Using order book for selling...') + logger.debug(f'Using order book for selling {trade.pair}...') # logger.debug('Order book %s',orderBook) order_book_min = config_ask_strategy.get('order_book_min', 1) order_book_max = config_ask_strategy.get('order_book_max', 1) @@ -636,7 +636,7 @@ class FreqtradeBot: for i in range(order_book_min, order_book_max + 1): order_book_rate = order_book['asks'][i - 1][0] - logger.info(' order book asks top %s: %0.8f', i, order_book_rate) + logger.debug(' order book asks top %s: %0.8f', i, order_book_rate) sell_rate = order_book_rate if self._check_and_execute_sell(trade, sell_rate, buy, sell): From a5e670b4023c2ae50a3441714d607f84ce8b0010 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 18:07:21 +0300 Subject: [PATCH 0380/1106] Add USERPATH_NOTEBOOKS --- freqtrade/constants.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 53bc4af53..23a60ed0e 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -23,6 +23,7 @@ MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons USERPATH_HYPEROPTS = 'hyperopts' USERPATH_STRATEGY = 'strategies' +USERPATH_NOTEBOOKS = 'notebooks' # Soure files with destination directories within user-directory USER_DATA_FILES = { @@ -30,7 +31,7 @@ USER_DATA_FILES = { 'sample_hyperopt_advanced.py': USERPATH_HYPEROPTS, 'sample_hyperopt_loss.py': USERPATH_HYPEROPTS, 'sample_hyperopt.py': USERPATH_HYPEROPTS, - 'strategy_analysis_example.ipynb': 'notebooks', + 'strategy_analysis_example.ipynb': USERPATH_NOTEBOOKS, } SUPPORTED_FIAT = [ From 3fe39a3e1b3e494cd8ebaff1718e809845a324de Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 18:12:23 +0300 Subject: [PATCH 0381/1106] Rename constant --- freqtrade/commands/deploy_commands.py | 4 ++-- freqtrade/commands/list_commands.py | 4 ++-- freqtrade/constants.py | 4 ++-- freqtrade/resolvers/strategy_resolver.py | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index 99ae63244..e0935f0e5 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -6,7 +6,7 @@ from typing import Any, Dict from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) -from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY +from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES from freqtrade.exceptions import OperationalException from freqtrade.misc import render_template from freqtrade.state import RunMode @@ -57,7 +57,7 @@ def start_new_strategy(args: Dict[str, Any]) -> None: if args["strategy"] == "DefaultStrategy": raise OperationalException("DefaultStrategy is not allowed as name.") - new_path = config['user_data_dir'] / USERPATH_STRATEGY / (args["strategy"] + ".py") + new_path = config['user_data_dir'] / USERPATH_STRATEGIES / (args["strategy"] + ".py") if new_path.exists(): raise OperationalException(f"`{new_path}` already exists. " diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 022822782..9fe66783d 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -9,7 +9,7 @@ import rapidjson from tabulate import tabulate from freqtrade.configuration import setup_utils_configuration -from freqtrade.constants import USERPATH_STRATEGY +from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES from freqtrade.exceptions import OperationalException from freqtrade.exchange import (available_exchanges, ccxt_exchanges, market_is_active, symbol_is_pair) @@ -42,7 +42,7 @@ def start_list_strategies(args: Dict[str, Any]) -> None: """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGY)) + directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES)) strategies = StrategyResolver.search_all_objects(directory) # Sort alphabetically strategies = sorted(strategies, key=lambda x: x['name']) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 23a60ed0e..efdd6cc0e 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -22,12 +22,12 @@ DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons USERPATH_HYPEROPTS = 'hyperopts' -USERPATH_STRATEGY = 'strategies' +USERPATH_STRATEGIES = 'strategies' USERPATH_NOTEBOOKS = 'notebooks' # Soure files with destination directories within user-directory USER_DATA_FILES = { - 'sample_strategy.py': USERPATH_STRATEGY, + 'sample_strategy.py': USERPATH_STRATEGIES, 'sample_hyperopt_advanced.py': USERPATH_HYPEROPTS, 'sample_hyperopt_loss.py': USERPATH_HYPEROPTS, 'sample_hyperopt.py': USERPATH_HYPEROPTS, diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 9e64f38df..7f28bd2e6 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -12,7 +12,7 @@ from pathlib import Path from typing import Dict, Optional from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, - USERPATH_STRATEGY) + USERPATH_STRATEGIES) from freqtrade.exceptions import OperationalException from freqtrade.resolvers import IResolver from freqtrade.strategy.interface import IStrategy @@ -26,7 +26,7 @@ class StrategyResolver(IResolver): """ object_type = IStrategy object_type_str = "Strategy" - user_subdir = USERPATH_STRATEGY + user_subdir = USERPATH_STRATEGIES initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve() @staticmethod @@ -140,7 +140,7 @@ class StrategyResolver(IResolver): """ abs_paths = StrategyResolver.build_search_paths(config, - user_subdir=USERPATH_STRATEGY, + user_subdir=USERPATH_STRATEGIES, extra_dir=extra_dir) if ":" in strategy_name: From 857eb5ff6994cd3a5c8765cf6d43b5b01be1dc3c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 18:48:29 +0300 Subject: [PATCH 0382/1106] Add list-hyperopts command --- freqtrade/commands/__init__.py | 1 + freqtrade/commands/arguments.py | 18 +++++++++++++++--- freqtrade/commands/list_commands.py | 22 +++++++++++++++++++++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index 990c1107a..17723715e 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -14,6 +14,7 @@ from freqtrade.commands.deploy_commands import (start_create_userdir, from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, start_hyperopt_show) from freqtrade.commands.list_commands import (start_list_exchanges, + start_list_hyperopts, start_list_markets, start_list_strategies, start_list_timeframes) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 724814554..0995c89c4 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -32,6 +32,8 @@ ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column"] +ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column"] + ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"] @@ -132,9 +134,10 @@ class Arguments: from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, - start_list_exchanges, start_list_markets, - start_list_strategies, start_new_hyperopt, - start_new_strategy, start_list_timeframes, + start_list_exchanges, start_list_hyperopts, + start_list_markets, start_list_strategies, + start_list_timeframes, + start_new_hyperopt, start_new_strategy, start_plot_dataframe, start_plot_profit, start_backtesting, start_hyperopt, start_edge, start_test_pairlist, start_trading) @@ -198,6 +201,15 @@ class Arguments: list_strategies_cmd.set_defaults(func=start_list_strategies) self._build_args(optionlist=ARGS_LIST_STRATEGIES, parser=list_strategies_cmd) + # Add list-hyperopts subcommand + list_hyperopts_cmd = subparsers.add_parser( + 'list-hyperopts', + help='Print available hyperopt classes.', + parents=[_common_parser], + ) + list_hyperopts_cmd.set_defaults(func=start_list_hyperopts) + self._build_args(optionlist=ARGS_LIST_HYPEROPTS, parser=list_hyperopts_cmd) + # Add list-exchanges subcommand list_exchanges_cmd = subparsers.add_parser( 'list-exchanges', diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 9fe66783d..f2b6bf995 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -38,7 +38,7 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: def start_list_strategies(args: Dict[str, Any]) -> None: """ - Print Strategies available in a directory + Print files with Strategy custom classes available in the directory """ config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) @@ -54,6 +54,26 @@ def start_list_strategies(args: Dict[str, Any]) -> None: print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) +def start_list_hyperopts(args: Dict[str, Any]) -> None: + """ + Print files with HyperOpt custom classes available in the directory + """ + from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver + + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + directory = Path(config.get('hyperopt_path', config['user_data_dir'] / USERPATH_HYPEROPTS)) + hyperopts = HyperOptResolver.search_all_objects(directory) + # Sort alphabetically + hyperopts = sorted(hyperopts, key=lambda x: x['name']) + hyperopts_to_print = [{'name': s['name'], 'location': s['location'].name} for s in hyperopts] + + if args['print_one_column']: + print('\n'.join([s['name'] for s in hyperopts])) + else: + print(tabulate(hyperopts_to_print, headers='keys', tablefmt='pipe')) + + def start_list_timeframes(args: Dict[str, Any]) -> None: """ Print ticker intervals (timeframes) available on Exchange From 505648fb661ea792d555ece1355e241079e9af82 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 18:56:54 +0300 Subject: [PATCH 0383/1106] Adjust docs --- docs/utils.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 18deeac54..b0559f9cc 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -108,9 +108,9 @@ With custom user directory freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt ``` -## List Strategies +## List Strategies and List Hyperopts -Use the `list-strategies` subcommand to see all strategies in one particular directory. +Use the `list-strategies` subcommand to see all strategies in one particular directory and the `list-hyperopts` subcommand to list custom Hyperopts. ``` freqtrade list-strategies --help @@ -133,22 +133,63 @@ Common arguments: --userdir PATH, --user-data-dir PATH Path to userdata directory. ``` +``` +freqtrade list-hyperopts --help +usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] + [--hyperopt-path PATH] [-1] + +optional arguments: + -h, --help show this help message and exit + --hyperopt-path PATH Specify additional lookup path for Hyperopt and + Hyperopt Loss functions. + -1, --one-column Print output in one column. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. +``` !!! Warning - Using this command will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed. + Using these commands will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed. -Example: search default strategy directory within userdir +Example: Search default strategies and hyperopts directories (within the default userdir). + +``` bash +freqtrade list-strategies +freqtrade list-hyperopts +``` + +Example: Search strategies and hyperopts directory within the userdir. ``` bash freqtrade list-strategies --userdir ~/.freqtrade/ +freqtrade list-hyperopts --userdir ~/.freqtrade/ ``` -Example: search dedicated strategy path +Example: Search dedicated strategy path. ``` bash freqtrade list-strategies --strategy-path ~/.freqtrade/strategies/ ``` +Example: Search dedicated hyperopt path. + +``` bash +freqtrade list-hyperopt --hyperopt-path ~/.freqtrade/hyperopts/ +``` + ## List Exchanges Use the `list-exchanges` subcommand to see the exchanges available for the bot. From cd0534efcc1a0fa7d748508d22fff7972b643be2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 19:13:17 +0300 Subject: [PATCH 0384/1106] Add test --- tests/commands/test_commands.py | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 65d7f6eaf..c59799190 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -7,7 +7,8 @@ import pytest from freqtrade.commands import (start_create_userdir, start_download_data, start_hyperopt_list, start_hyperopt_show, start_list_exchanges, start_list_markets, - start_list_strategies, start_list_timeframes, + start_list_hyperopts, start_list_strategies, + start_list_timeframes, start_new_hyperopt, start_new_strategy, start_test_pairlist, start_trading) from freqtrade.configuration import setup_utils_configuration @@ -665,6 +666,39 @@ def test_start_list_strategies(mocker, caplog, capsys): assert "DefaultStrategy" in captured.out +def test_start_list_hyperopts(mocker, caplog, capsys): + + args = [ + "list-hyperopts", + "--hyperopt-path", + str(Path(__file__).parent.parent / "optimize"), + "-1" + ] + pargs = get_args(args) + # pargs['config'] = None + start_list_hyperopts(pargs) + captured = capsys.readouterr() + assert "TestHyperoptLegacy" not in captured.out + assert "legacy_hyperopt.py" not in captured.out + assert "DefaultHyperOpt" in captured.out + assert "test_hyperopt.py" not in captured.out + + # Test regular output + args = [ + "list-hyperopts", + "--hyperopt-path", + str(Path(__file__).parent.parent / "optimize"), + ] + pargs = get_args(args) + # pargs['config'] = None + start_list_hyperopts(pargs) + captured = capsys.readouterr() + assert "TestHyperoptLegacy" not in captured.out + assert "legacy_hyperopt.py" not in captured.out + assert "DefaultHyperOpt" in captured.out + assert "test_hyperopt.py" in captured.out + + def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): patch_exchange(mocker, mock_markets=True) mocker.patch.multiple('freqtrade.exchange.Exchange', From d12e03e50d30c13f57e5fa661ebf78d388051310 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 20:01:25 +0300 Subject: [PATCH 0385/1106] Fix test inconsistency in test_freqtradebot.py --- tests/test_freqtradebot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5f16894ab..f334e4eb0 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1145,11 +1145,11 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # Should not create new order trade.stoploss_order_id = None trade.is_open = False - stoploss_limit.reset_mock() + stoploss.reset_mock() mocker.patch('freqtrade.exchange.Exchange.get_order') - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss) assert freqtrade.handle_stoploss_on_exchange(trade) is False - assert stoploss_limit.call_count == 0 + assert stoploss.call_count == 0 def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, From 84156879f6e96e18e6e60589bc2f45d2bb989261 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 2 Feb 2020 20:11:42 +0300 Subject: [PATCH 0386/1106] Fix NO_CONF_REQUIRED for list-hyperopts --- freqtrade/commands/arguments.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 0995c89c4..1931a51be 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -66,8 +66,8 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop "print_json", "hyperopt_show_no_header"] NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs", - "list-strategies", "hyperopt-list", "hyperopt-show", "plot-dataframe", - "plot-profit"] + "list-strategies", "list-hyperopts", "hyperopt-list", "hyperopt-show", + "plot-dataframe", "plot-profit"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] From 2b69e7830d89d9b8ae164511c5b14923ce99080a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 2 Feb 2020 20:02:38 +0100 Subject: [PATCH 0387/1106] Fix failing CI test --- tests/test_freqtradebot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5f16894ab..f334e4eb0 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1145,11 +1145,11 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, # Should not create new order trade.stoploss_order_id = None trade.is_open = False - stoploss_limit.reset_mock() + stoploss.reset_mock() mocker.patch('freqtrade.exchange.Exchange.get_order') - mocker.patch('freqtrade.exchange.Exchange.stoploss_limit', stoploss_limit) + mocker.patch('freqtrade.exchange.Exchange.stoploss', stoploss) assert freqtrade.handle_stoploss_on_exchange(trade) is False - assert stoploss_limit.call_count == 0 + assert stoploss.call_count == 0 def test_handle_sle_cancel_cant_recreate(mocker, default_conf, fee, caplog, From 537596001e5c4ff030855327095992c48d205724 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 3 Feb 2020 06:20:01 +0300 Subject: [PATCH 0388/1106] Allow derived strategies --- freqtrade/resolvers/iresolver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 5a844097c..53d08d387 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -61,7 +61,8 @@ class IResolver: valid_objects_gen = ( obj for name, obj in inspect.getmembers(module, inspect.isclass) - if (object_name is None or object_name == name) and cls.object_type in obj.__bases__ + 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 From c8960ab62893dfcbc15ab6d5cab82ac179908c3d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 3 Feb 2020 06:50:07 +0100 Subject: [PATCH 0389/1106] Only run coveralls once --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c838baced..8dd61a602 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,7 @@ jobs: pytest --random-order --cov=freqtrade --cov-config=.coveragerc - name: Coveralls - if: startsWith(matrix.os, 'ubuntu') + if: (startsWith(matrix.os, 'ubuntu') && matrix.os == '3.8') env: # Coveralls token. Not used as secret due to github not providing secrets to forked repositories COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu From d0506a643571e74a99a309028403c27bfdf426a3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 3 Feb 2020 07:01:07 +0100 Subject: [PATCH 0390/1106] Use correct matrix variable --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8dd61a602..05d151a88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,7 @@ jobs: pytest --random-order --cov=freqtrade --cov-config=.coveragerc - name: Coveralls - if: (startsWith(matrix.os, 'ubuntu') && matrix.os == '3.8') + if: (startsWith(matrix.os, 'ubuntu') && matrix.python-version == '3.8') env: # Coveralls token. Not used as secret due to github not providing secrets to forked repositories COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu From df249c7c03051ff499e8688e6044990d1100d11c Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 3 Feb 2020 09:37:50 +0300 Subject: [PATCH 0391/1106] Remove unclear comment --- freqtrade/exchange/exchange.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f7bfb0ee1..ede7156a1 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -25,8 +25,6 @@ from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async from freqtrade.misc import deep_merge_dicts -# Should probably use typing.Literal when we switch to python 3.8+ -# CcxtModuleType = Literal[ccxt, ccxt_async] CcxtModuleType = Any From 7b8e6653235d7607bef3e5fb71f08a57bded9571 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:01:28 +0000 Subject: [PATCH 0392/1106] Bump jinja2 from 2.10.3 to 2.11.1 Bumps [jinja2](https://github.com/pallets/jinja) from 2.10.3 to 2.11.1. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/2.10.3...2.11.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e4fe54721..48ba794cb 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -12,7 +12,7 @@ jsonschema==3.2.0 TA-Lib==0.4.17 tabulate==0.8.6 coinmarketcap==5.0.3 -jinja2==2.10.3 +jinja2==2.11.1 # find first, C search in arrays py_find_1st==1.1.4 From bc2ae3e88de22634a3c66b9d9f41349d1ef826c0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:02:21 +0000 Subject: [PATCH 0393/1106] Bump pytest from 5.3.4 to 5.3.5 Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.4 to 5.3.5. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.3.4...5.3.5) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 6330d93e5..268c5f777 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 mypy==0.761 -pytest==5.3.4 +pytest==5.3.5 pytest-asyncio==0.10.0 pytest-cov==2.8.1 pytest-mock==2.0.0 From 401748e9a73757bdf6c04c382b656d901474dfc5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:02:54 +0000 Subject: [PATCH 0394/1106] Bump ccxt from 1.21.91 to 1.22.30 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.91 to 1.22.30. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.21.91...1.22.30) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e4fe54721..5f6557161 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.21.91 +ccxt==1.22.30 SQLAlchemy==1.3.13 python-telegram-bot==12.3.0 arrow==0.15.5 From 3938418ad51a7c8dd794b5467a4c61b2e8086c99 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:03:21 +0000 Subject: [PATCH 0395/1106] Bump scikit-optimize from 0.5.2 to 0.7.1 Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.5.2 to 0.7.1. - [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases) - [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md) - [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.5.2...v0.7.1) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 43cad1a0e..202806cef 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -4,6 +4,6 @@ # Required for hyperopt scipy==1.4.1 scikit-learn==0.22.1 -scikit-optimize==0.5.2 +scikit-optimize==0.7.1 filelock==3.0.12 joblib==0.14.1 From d5f704009ffd7fd428201f6432110c344014fd4e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:03:45 +0000 Subject: [PATCH 0396/1106] Bump pandas from 0.25.3 to 1.0.0 Bumps [pandas](https://github.com/pandas-dev/pandas) from 0.25.3 to 1.0.0. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md) - [Commits](https://github.com/pandas-dev/pandas/compare/v0.25.3...v1.0.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c7dd07ee4..21be02a87 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ -r requirements-common.txt numpy==1.18.1 -pandas==0.25.3 +pandas==1.0.0 From f6c09160ab1afda16e0c22acbac7c8b7b608744f Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 3 Feb 2020 15:17:36 +0100 Subject: [PATCH 0397/1106] make sure asyncio_loop is not initialized within ccxt code --- tests/exchange/test_exchange.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 7064d76e1..1121bb035 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -76,9 +76,11 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') caplog.set_level(logging.INFO) conf = copy.deepcopy(default_conf) - conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True} + conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True, 'asyncio_loop': True} ex = Exchange(conf) - assert log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog) + assert log_has( + "Applying additional ccxt config: {'aiohttp_trust_env': True, 'asyncio_loop': True}", + caplog) assert ex._api_async.aiohttp_trust_env assert not ex._api.aiohttp_trust_env @@ -86,6 +88,8 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog): caplog.clear() conf = copy.deepcopy(default_conf) conf['exchange']['ccxt_config'] = {'TestKWARG': 11} + conf['exchange']['ccxt_async_config'] = {'asyncio_loop': True} + ex = Exchange(conf) assert not log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog) assert not ex._api_async.aiohttp_trust_env From 684cb54992777d9c7e105033ee1d4d5d918590ee Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 3 Feb 2020 17:17:46 +0300 Subject: [PATCH 0398/1106] Add pair to exception msg --- freqtrade/exchange/exchange.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a8df4c1bb..c1999b6fa 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -736,10 +736,11 @@ class Exchange: f'Exchange {self._api.name} does not support fetching historical candlestick data.' f'Message: {e}') from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: - raise TemporaryError(f'Could not load ticker history due to {e.__class__.__name__}. ' - f'Message: {e}') from e + raise TemporaryError(f'Could not load ticker history for pair {pair} due to ' + f'{e.__class__.__name__}. Message: {e}') from e except ccxt.BaseError as e: - raise OperationalException(f'Could not fetch ticker data. Msg: {e}') from e + raise OperationalException(f'Could not fetch ticker data for pair {pair}. ' + f'Msg: {e}') from e @retrier_async async def _async_fetch_trades(self, pair: str, From cbabc295c7c82bb70f7544337f27e9041e982b8b Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 3 Feb 2020 20:25:43 +0100 Subject: [PATCH 0399/1106] Don't convert to datetime - but convert to datetime64 instead --- tests/edge/test_edge.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index ef1280fa4..6b86d9c1f 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -163,8 +163,8 @@ def test_edge_results(edge_conf, mocker, caplog, data) -> None: for c, trade in enumerate(data.trades): res = results.iloc[c] assert res.exit_type == trade.sell_reason - assert arrow.get(res.open_time) == _get_frame_time_from_offset(trade.open_tick) - assert arrow.get(res.close_time) == _get_frame_time_from_offset(trade.close_tick) + assert res.open_time == np.datetime64(_get_frame_time_from_offset(trade.open_tick)) + assert res.close_time == np.datetime64(_get_frame_time_from_offset(trade.close_tick)) def test_adjust(mocker, edge_conf): From ffb53a6df5201326fdc65b1b4d15b21ecea2b3ce Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 3 Feb 2020 23:08:35 +0300 Subject: [PATCH 0400/1106] get rid of typing.cast() --- freqtrade/commands/data_commands.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index aeb598009..ddc2ca25b 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -1,6 +1,6 @@ import logging import sys -from typing import Any, Dict, List, cast +from typing import Any, Dict, List import arrow @@ -43,18 +43,18 @@ def start_download_data(args: Dict[str, Any]) -> None: if config.get('download_trades'): pairs_not_available = refresh_backtest_trades_data( exchange, pairs=config["pairs"], datadir=config['datadir'], - timerange=timerange, erase=cast(bool, config.get("erase"))) + timerange=timerange, erase=bool(config.get("erase"))) # Convert downloaded trade data to different timeframes convert_trades_to_ohlcv( pairs=config["pairs"], timeframes=config["timeframes"], datadir=config['datadir'], timerange=timerange, - erase=cast(bool, config.get("erase"))) + erase=bool(config.get("erase"))) else: pairs_not_available = refresh_backtest_ohlcv_data( exchange, pairs=config["pairs"], timeframes=config["timeframes"], datadir=config['datadir'], timerange=timerange, - erase=cast(bool, config.get("erase"))) + erase=bool(config.get("erase"))) except KeyboardInterrupt: sys.exit("SIGINT received, aborting ...") From 91b4c9668cb019892c79bf47b30d9850a2a32f73 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 4 Feb 2020 01:57:24 +0100 Subject: [PATCH 0401/1106] More consistency changes... --- freqtrade/freqtradebot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 1a9cbfa64..e51b3d550 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -427,23 +427,23 @@ class FreqtradeBot: Checks depth of market before executing a buy """ conf_bids_to_ask_delta = conf.get('bids_to_ask_delta', 0) - logger.info('checking depth of market for %s', pair) + logger.info(f"Checking depth of market for {pair} ...") order_book = self.exchange.get_order_book(pair, 1000) order_book_data_frame = order_book_to_dataframe(order_book['bids'], order_book['asks']) order_book_bids = order_book_data_frame['b_size'].sum() order_book_asks = order_book_data_frame['a_size'].sum() bids_ask_delta = order_book_bids / order_book_asks logger.info( - f"bids: {order_book_bids}, asks: {order_book_asks}, delta: {bids_ask_delta}, " - f"askprice: {order_book['asks'][0][0]}, bidprice: {order_book['bids'][0][0]}, " - f"immediate ask quantity: {order_book['asks'][0][1]}, " - f"immediate bid quantity: {order_book['bids'][0][1]}", + f"Bids: {order_book_bids}, Asks: {order_book_asks}, Delta: {bids_ask_delta}, " + f"Bid Price: {order_book['bids'][0][0]}, Ask Price: {order_book['asks'][0][0]}, " + f"Immediate Bid Quantity: {order_book['bids'][0][1]}, " + f"Immediate Ask Quantity: {order_book['asks'][0][1]}." ) if bids_ask_delta >= conf_bids_to_ask_delta: - logger.info('bids to ask delta DOES satisfy condition.') + logger.info(f"Bids to asks delta for {pair} DOES satisfy condition.") return True else: - logger.info(f"bids to ask delta for {pair} does not satisfy condition.") + logger.info(f"Bids to asks delta for {pair} does not satisfy condition.") return False def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = None) -> bool: From a707aeb3d01b223340ff8ebce02716bfe6777b3d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 4 Feb 2020 07:00:53 +0100 Subject: [PATCH 0402/1106] Fix implementation of rolling_max --- freqtrade/vendor/qtpylib/indicators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/vendor/qtpylib/indicators.py b/freqtrade/vendor/qtpylib/indicators.py index b3b2ac533..bef140396 100644 --- a/freqtrade/vendor/qtpylib/indicators.py +++ b/freqtrade/vendor/qtpylib/indicators.py @@ -288,9 +288,9 @@ def rolling_min(series, window=14, min_periods=None): def rolling_max(series, window=14, min_periods=None): min_periods = window if min_periods is None else min_periods try: - return series.rolling(window=window, min_periods=min_periods).min() + return series.rolling(window=window, min_periods=min_periods).max() except Exception as e: # noqa: F841 - return pd.Series(series).rolling(window=window, min_periods=min_periods).min() + return pd.Series(series).rolling(window=window, min_periods=min_periods).max() # --------------------------------------------- From aa54fd2251f6144a6c76df33585fa59b4b4886c4 Mon Sep 17 00:00:00 2001 From: untoreh Date: Mon, 3 Feb 2020 07:44:17 +0100 Subject: [PATCH 0403/1106] - added spread filter - minimum value to volume pairlist --- config_full.json.example | 4 +- docs/configuration.md | 6 +++ freqtrade/constants.py | 3 +- freqtrade/pairlist/SpreadFilter.py | 59 ++++++++++++++++++++++++++++ freqtrade/pairlist/VolumePairList.py | 8 +++- tests/conftest.py | 47 ++++++++++++++++++++++ tests/pairlist/test_pairlist.py | 10 ++++- 7 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 freqtrade/pairlist/SpreadFilter.py diff --git a/config_full.json.example b/config_full.json.example index 82d8bd04a..9f09d2247 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -62,8 +62,8 @@ "refresh_period": 1800 }, {"method": "PrecisionFilter"}, - {"method": "PriceFilter", "low_price_ratio": 0.01 - } + {"method": "PriceFilter", "low_price_ratio": 0.01}, + {"method": "SpreadFilter", "max_spread_ratio": 0.005} ], "exchange": { "name": "bittrex", diff --git a/docs/configuration.md b/docs/configuration.md index fe692eacb..17b9a82c5 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -503,6 +503,7 @@ Inactive markets and blacklisted pairs are always removed from the resulting `pa * [`VolumePairList`](#volume-pair-list) * [`PrecisionFilter`](#precision-filter) * [`PriceFilter`](#price-pair-filter) +* [`SpreadFilter`](#spread-filter) !!! Tip "Testing pairlists" Pairlist configurations can be quite tricky to get right. Best use the [`test-pairlist`](utils.md#test-pairlist) subcommand to test your configuration quickly. @@ -551,6 +552,11 @@ Min price precision is 8 decimals. If price is 0.00000011 - one step would be 0. These pairs are dangerous since it may be impossible to place the desired stoploss - and often result in high losses. +#### Spread Filter +Removes pairs that have a difference between asks and bids above the specified ratio (default `0.005`). +Example: +If `DOGE/BTC` maximum bid is 0.00000026 and minimum ask is 0.00000027 the ratio is calculated as: `1 - bid/ask ~= 0.037` which is `> 0.005` + ### Full Pairlist example The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets, sorting by `quoteVolume` and applies both [`PrecisionFilter`](#precision-filter) and [`PriceFilter`](#price-pair-filter), filtering all assets where 1 priceunit is > 1%. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 53bc4af53..56876e2c9 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -17,7 +17,8 @@ REQUIRED_ORDERTIF = ['buy', 'sell'] REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange'] ORDERTYPE_POSSIBILITIES = ['limit', 'market'] ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] -AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', 'PrecisionFilter', 'PriceFilter'] +AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', + 'PrecisionFilter', 'PriceFilter', 'SpreadFilter'] DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons diff --git a/freqtrade/pairlist/SpreadFilter.py b/freqtrade/pairlist/SpreadFilter.py new file mode 100644 index 000000000..9361837cc --- /dev/null +++ b/freqtrade/pairlist/SpreadFilter.py @@ -0,0 +1,59 @@ +import logging +from copy import deepcopy +from typing import Dict, List + +from freqtrade.pairlist.IPairList import IPairList + +logger = logging.getLogger(__name__) + + +class SpreadFilter(IPairList): + + def __init__(self, exchange, pairlistmanager, config, pairlistconfig: dict, + pairlist_pos: int) -> None: + super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) + + self._max_spread_ratio = pairlistconfig.get('max_spread_ratio', 0.005) + + @property + def needstickers(self) -> bool: + """ + Boolean property defining if tickers are necessary. + If no Pairlist requries tickers, an empty List is passed + as tickers argument to filter_pairlist + """ + return True + + def short_desc(self) -> str: + """ + Short whitelist method description - used for startup-messages + """ + return (f"{self.name} - Filtering pairs with ask/bid diff above " + f"{self._max_spread_ratio * 100}%.") + + def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: + + """ + Filters and sorts pairlist and returns the whitelist again. + Called on each bot iteration - please use internal caching if necessary + :param pairlist: pairlist to filter or sort + :param tickers: Tickers (from exchange.get_tickers()). May be cached. + :return: new whitelist + """ + # Copy list since we're modifying this list + + spread = None + for p in deepcopy(pairlist): + ticker = tickers.get(p) + assert ticker is not None + if 'bid' in ticker and 'ask' in ticker: + spread = 1 - ticker['bid'] / ticker['ask'] + if not ticker or spread > self._max_spread_ratio: + logger.info(f"Removed {ticker['symbol']} from whitelist, " + f"because spread {spread * 100:.3f}% >" + f"{self._max_spread_ratio * 100}%") + pairlist.remove(p) + else: + pairlist.remove(p) + + return pairlist diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 4ac9935ba..3f31f5523 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -28,6 +28,7 @@ class VolumePairList(IPairList): 'for "pairlist.config.number_assets"') self._number_pairs = self._pairlistconfig['number_assets'] self._sort_key = self._pairlistconfig.get('sort_key', 'quoteVolume') + self._min_value = self._pairlistconfig.get('min_value', 0) self.refresh_period = self._pairlistconfig.get('refresh_period', 1800) if not self._exchange.exchange_has('fetchTickers'): @@ -73,11 +74,13 @@ class VolumePairList(IPairList): tickers, self._config['stake_currency'], self._sort_key, + self._min_value ) else: return pairlist - def _gen_pair_whitelist(self, pairlist, tickers, base_currency: str, key: str) -> List[str]: + def _gen_pair_whitelist(self, pairlist, tickers, base_currency: str, + key: str, min_val: int) -> List[str]: """ Updates the whitelist with with a dynamically generated list :param base_currency: base currency as str @@ -96,6 +99,9 @@ class VolumePairList(IPairList): # If other pairlist is in front, use the incomming pairlist. filtered_tickers = [v for k, v in tickers.items() if k in pairlist] + if min_val > 0: + filtered_tickers = list(filter(lambda t: t[key] > min_val, filtered_tickers)) + sorted_tickers = sorted(filtered_tickers, reverse=True, key=lambda t: t[key]) # Validate whitelist to only have active market pairs diff --git a/tests/conftest.py b/tests/conftest.py index 395388f73..e897dbccd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -640,6 +640,31 @@ def shitcoinmarkets(markets): }, 'info': {}, }, + 'NANO/USDT': { + "percentage": True, + "tierBased": False, + "taker": 0.001, + "maker": 0.001, + "precision": { + "base": 8, + "quote": 8, + "amount": 2, + "price": 4 + }, + "limits": { + }, + "id": "NANOUSDT", + "symbol": "NANO/USDT", + "base": "NANO", + "quote": "USDT", + "baseId": "NANO", + "quoteId": "USDT", + "info": {}, + "type": "spot", + "spot": True, + "future": False, + "active": True + }, }) return shitmarkets @@ -1114,6 +1139,28 @@ def tickers(): 'quoteVolume': 1154.19266394, 'info': {} }, + "NANO/USDT": { + "symbol": "NANO/USDT", + "timestamp": 1580469388244, + "datetime": "2020-01-31T11:16:28.244Z", + "high": 0.7519, + "low": 0.7154, + "bid": 0.7305, + "bidVolume": 300.3, + "ask": 0.7342, + "askVolume": 15.14, + "vwap": 0.73645591, + "open": 0.7154, + "close": 0.7342, + "last": 0.7342, + "previousClose": 0.7189, + "change": 0.0188, + "percentage": 2.628, + "average": None, + "baseVolume": 439472.44, + "quoteVolume": 323652.075405, + "info": {} + }, }) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index ac4cbc813..b8a4be037 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -141,7 +141,7 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}], "BTC", ['HOT/BTC', 'FUEL/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']), ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}], - "USDT", ['ETH/USDT']), + "USDT", ['ETH/USDT', 'NANO/USDT']), # No pair for ETH ... ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}], "ETH", []), @@ -160,6 +160,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): {"method": "PrecisionFilter"}, {"method": "PriceFilter", "low_price_ratio": 0.02} ], "BTC", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC']), + # HOT and XRP are removed because below 1250 quoteVolume + ([{"method": "VolumePairList", "number_assets": 5, + "sort_key": "quoteVolume", "min_value": 1250}], + "BTC", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC']), # StaticPairlist Only ([{"method": "StaticPairList"}, ], "BTC", ['ETH/BTC', 'TKN/BTC']), @@ -167,6 +171,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): ([{"method": "StaticPairList"}, {"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}, ], "BTC", ['TKN/BTC', 'ETH/BTC']), + # SpreadFilter + ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}, + {"method": "SpreadFilter", "max_spread": 0.005} + ], "USDT", ['ETH/USDT']), ]) def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, tickers, pairlists, base_currency, whitelist_result, From 6866f6389d45bccf7a261a0f4b3e6362cadb7a0a Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 4 Feb 2020 20:41:13 +0100 Subject: [PATCH 0404/1106] Fix merge-error --- freqtrade/pairlist/VolumePairList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index af6760197..e50dafb63 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -80,7 +80,7 @@ class VolumePairList(IPairList): return pairlist def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict, - base_currency: str, key: str) -> List[str]: + base_currency: str, key: str, min_val: int) -> List[str]: """ Updates the whitelist with with a dynamically generated list :param base_currency: base currency as str From 586cbc750c711ccf8b9bcaa6836be5f8b89d91f3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 6 Feb 2020 06:45:11 +0100 Subject: [PATCH 0405/1106] Add considerations for dry-run --- docs/configuration.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 4ed8bbd0c..72e12f066 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -608,6 +608,14 @@ Once you will be happy with your bot performance running in the Dry-run mode, yo !!! Note A simulated wallet is available during dry-run mode, and will assume a starting capital of `dry_run_wallet` (defaults to 1000). +### Considerations for dry-run + +* API-Keys may or may not be provided. Only Read-Only operations on the exchange are performed in dry-run mode. +* Wallets (`/balance`) will be simulated. +* Orders will be simulated, and will not be posted to the exchange +* In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled. +* Open orders (not Trades!) are reset on bot restart. + ## Switch to production mode In production mode, the bot will engage your money. Be careful, since a wrong From 9639ffb14052f72dd3dc37820c79a8fdf6212bb1 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Thu, 6 Feb 2020 06:49:08 +0100 Subject: [PATCH 0406/1106] added daily sharpe ratio hyperopt loss method, ty @djacky (#2826) * more consistent backtesting tables and labels * added rounding to Tot Profit % on Sell Reasosn table to be consistent with other percentiles on table. * added daily sharpe ratio hyperopt loss method, ty @djacky * removed commented code * removed unused profit_abs * added proper slippage to each trade * replaced use of old value total_profit * Align quotes in same area * added daily sharpe ratio test and modified hyperopt_loss_sharpe_daily * fixed some more line alignments * updated docs to include SharpeHyperOptLossDaily * Update dockerfile to 3.8.1 * Run tests against 3.8 * added daily sharpe ratio hyperopt loss method, ty @djacky * removed commented code * removed unused profit_abs * added proper slippage to each trade * replaced use of old value total_profit * added daily sharpe ratio test and modified hyperopt_loss_sharpe_daily * updated docs to include SharpeHyperOptLossDaily * docs fixes * missed one fix * fixed standard deviation line * fixed to bracket notation * fixed to bracket notation * fixed syntax error * better readability, kept np.sqrt(365) which results in annualized sharpe ratio * fixed method arguments indentation * updated commented out debug print line * renamed after slippage profit_percent so it wont affect _calculate_results_metrics() * Reworked to fill leading and trailing days * No need for np; make flake happy * Fix risk free rate Co-authored-by: Matthias Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/bot-usage.md | 4 +- docs/hyperopt.md | 38 ++++++------ freqtrade/commands/cli_options.py | 2 +- .../optimize/hyperopt_loss_sharpe_daily.py | 61 +++++++++++++++++++ tests/optimize/test_hyperopt.py | 26 +++++++- 5 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 freqtrade/optimize/hyperopt_loss_sharpe_daily.py diff --git a/docs/bot-usage.md b/docs/bot-usage.md index e856755d2..56e6008a1 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -337,8 +337,8 @@ optional arguments: generate completely different results, since the target for optimization is different. Built-in Hyperopt-loss-functions are: DefaultHyperOptLoss, - OnlyProfitHyperOptLoss, SharpeHyperOptLoss (default: - `DefaultHyperOptLoss`). + OnlyProfitHyperOptLoss, SharpeHyperOptLoss, + SharpeHyperOptLossDaily (default: `DefaultHyperOptLoss`). Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/docs/hyperopt.md b/docs/hyperopt.md index f399fe816..3e10f66da 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -57,12 +57,12 @@ Rarely you may also need to override: !!! Tip "Quickly optimize ROI, stoploss and trailing stoploss" You can quickly optimize the spaces `roi`, `stoploss` and `trailing` without changing anything (i.e. without creation of a "complete" Hyperopt class with dimensions, parameters, triggers and guards, as described in this document) from the default hyperopt template by relying on your strategy to do most of the calculations. - ``` python + ```python # Have a working strategy at hand. freqtrade new-hyperopt --hyperopt EmptyHyperopt freqtrade hyperopt --hyperopt EmptyHyperopt --spaces roi stoploss trailing --strategy MyWorkingStrategy --config config.json -e 100 - ``` + ``` ### 1. Install a Custom Hyperopt File @@ -75,8 +75,8 @@ Copy the file `user_data/hyperopts/sample_hyperopt.py` into `user_data/hyperopts There are two places you need to change in your hyperopt file to add a new buy hyperopt for testing: -- Inside `indicator_space()` - the parameters hyperopt shall be optimizing. -- Inside `populate_buy_trend()` - applying the parameters. +* Inside `indicator_space()` - the parameters hyperopt shall be optimizing. +* Inside `populate_buy_trend()` - applying the parameters. There you have two different types of indicators: 1. `guards` and 2. `triggers`. @@ -141,7 +141,7 @@ one we call `trigger` and use it to decide which buy trigger we want to use. So let's write the buy strategy using these values: -``` python +```python def populate_buy_trend(dataframe: DataFrame) -> DataFrame: conditions = [] # GUARDS AND TRENDS @@ -192,6 +192,7 @@ Currently, the following loss functions are builtin: * `DefaultHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function) * `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration) * `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on the trade returns) +* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on daily trade returns) Creation of a custom loss function is covered in the [Advanced Hyperopt](advanced-hyperopt.md) part of the documentation. @@ -206,7 +207,7 @@ We strongly recommend to use `screen` or `tmux` to prevent any connection loss. freqtrade hyperopt --config config.json --hyperopt -e 5000 --spaces all ``` -Use `` as the name of the custom hyperopt used. +Use `` as the name of the custom hyperopt used. The `-e` option will set how many evaluations hyperopt will do. We recommend running at least several thousand evaluations. @@ -265,23 +266,23 @@ The default Hyperopt Search Space, used when no `--space` command line option is ### Position stacking and disabling max market positions -In some situations, you may need to run Hyperopt (and Backtesting) with the +In some situations, you may need to run Hyperopt (and Backtesting) with the `--eps`/`--enable-position-staking` and `--dmmp`/`--disable-max-market-positions` arguments. By default, hyperopt emulates the behavior of the Freqtrade Live Run/Dry Run, where only one -open trade is allowed for every traded pair. The total number of trades open for all pairs +open trade is allowed for every traded pair. The total number of trades open for all pairs is also limited by the `max_open_trades` setting. During Hyperopt/Backtesting this may lead to some potential trades to be hidden (or masked) by previosly open trades. The `--eps`/`--enable-position-stacking` argument allows emulation of buying the same pair multiple times, -while `--dmmp`/`--disable-max-market-positions` disables applying `max_open_trades` +while `--dmmp`/`--disable-max-market-positions` disables applying `max_open_trades` during Hyperopt/Backtesting (which is equal to setting `max_open_trades` to a very high number). !!! Note Dry/live runs will **NOT** use position stacking - therefore it does make sense to also validate the strategy without this as it's closer to reality. -You can also enable position stacking in the configuration file by explicitly setting +You can also enable position stacking in the configuration file by explicitly setting `"position_stacking"=true`. ### Reproducible results @@ -323,7 +324,7 @@ method, what those values match to. So for example you had `rsi-value: 29.0` so we would look at `rsi`-block, that translates to the following code block: -``` python +```python (dataframe['rsi'] < 29.0) ``` @@ -372,18 +373,19 @@ In order to use this best ROI table found by Hyperopt in backtesting and for liv 118: 0 } ``` + As stated in the comment, you can also use it as the value of the `minimal_roi` setting in the configuration file. #### Default ROI Search Space If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps). Hyperopt implements adaptive ranges for ROI tables with ranges for values in the ROI steps that depend on the ticker_interval used. By default the values vary in the following ranges (for some of the most used ticker intervals, values are rounded to 5 digits after the decimal point): -| # step | 1m | | 5m | | 1h | | 1d | | -|---|---|---|---|---|---|---|---|---| -| 1 | 0 | 0.01161...0.11992 | 0 | 0.03...0.31 | 0 | 0.06883...0.71124 | 0 | 0.12178...1.25835 | -| 2 | 2...8 | 0.00774...0.04255 | 10...40 | 0.02...0.11 | 120...480 | 0.04589...0.25238 | 2880...11520 | 0.08118...0.44651 | -| 3 | 4...20 | 0.00387...0.01547 | 20...100 | 0.01...0.04 | 240...1200 | 0.02294...0.09177 | 5760...28800 | 0.04059...0.16237 | -| 4 | 6...44 | 0.0 | 30...220 | 0.0 | 360...2640 | 0.0 | 8640...63360 | 0.0 | +| # step | 1m | | 5m | | 1h | | 1d | | +| ------ | ------ | ----------------- | -------- | ----------- | ---------- | ----------------- | ------------ | ----------------- | +| 1 | 0 | 0.01161...0.11992 | 0 | 0.03...0.31 | 0 | 0.06883...0.71124 | 0 | 0.12178...1.25835 | +| 2 | 2...8 | 0.00774...0.04255 | 10...40 | 0.02...0.11 | 120...480 | 0.04589...0.25238 | 2880...11520 | 0.08118...0.44651 | +| 3 | 4...20 | 0.00387...0.01547 | 20...100 | 0.01...0.04 | 240...1200 | 0.02294...0.09177 | 5760...28800 | 0.04059...0.16237 | +| 4 | 6...44 | 0.0 | 30...220 | 0.0 | 360...2640 | 0.0 | 8640...63360 | 0.0 | These ranges should be sufficient in most cases. The minutes in the steps (ROI dict keys) are scaled linearly depending on the ticker interval used. The ROI values in the steps (ROI dict values) are scaled logarithmically depending on the ticker interval used. @@ -416,6 +418,7 @@ In order to use this best stoploss value found by Hyperopt in backtesting and fo # This attribute will be overridden if the config file contains "stoploss" stoploss = -0.27996 ``` + As stated in the comment, you can also use it as the value of the `stoploss` setting in the configuration file. #### Default Stoploss Search Space @@ -452,6 +455,7 @@ In order to use these best trailing stop parameters found by Hyperopt in backtes trailing_stop_positive_offset = 0.06038 trailing_only_offset_is_reached = True ``` + As stated in the comment, you can also use it as the values of the corresponding settings in the configuration file. #### Default Trailing Stop Search Space diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 490f26cfa..6d8d13129 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -256,7 +256,7 @@ AVAILABLE_CLI_OPTIONS = { help='Specify the class name of the hyperopt loss function class (IHyperOptLoss). ' 'Different functions can generate completely different results, ' 'since the target for optimization is different. Built-in Hyperopt-loss-functions are: ' - 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss.' + 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily.' '(default: `%(default)s`).', metavar='NAME', default=constants.DEFAULT_HYPEROPT_LOSS, diff --git a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py new file mode 100644 index 000000000..d8ea3c5fe --- /dev/null +++ b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py @@ -0,0 +1,61 @@ +""" +SharpeHyperOptLossDaily + +This module defines the alternative HyperOptLoss class which can be used for +Hyperoptimization. +""" +import math +from datetime import datetime + +from pandas import DataFrame, date_range + +from freqtrade.optimize.hyperopt import IHyperOptLoss + + +class SharpeHyperOptLossDaily(IHyperOptLoss): + """ + Defines the loss function for hyperopt. + + This implementation uses the Sharpe Ratio calculation. + """ + + @staticmethod + def hyperopt_loss_function(results: DataFrame, trade_count: int, + min_date: datetime, max_date: datetime, + *args, **kwargs) -> float: + """ + Objective function, returns smaller number for more optimal results. + + Uses Sharpe Ratio calculation. + """ + resample_freq = '1D' + slippage_per_trade_ratio = 0.0005 + days_in_year = 365 + annual_risk_free_rate = 0.0 + risk_free_rate = annual_risk_free_rate / days_in_year + + # apply slippage per trade to profit_percent + results.loc[:, 'profit_percent_after_slippage'] = \ + results['profit_percent'] - slippage_per_trade_ratio + + # create the index within the min_date and end max_date + t_index = date_range(start=min_date, end=max_date, freq=resample_freq) + + sum_daily = ( + results.resample(resample_freq, on='close_time').agg( + {"profit_percent_after_slippage": sum}).reindex(t_index).fillna(0) + ) + + total_profit = sum_daily["profit_percent_after_slippage"] - risk_free_rate + expected_returns_mean = total_profit.mean() + up_stdev = total_profit.std() + + if (up_stdev != 0.): + sharp_ratio = expected_returns_mean / up_stdev * math.sqrt(days_in_year) + else: + # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + sharp_ratio = -20. + + # print(t_index, sum_daily, total_profit) + # print(risk_free_rate, expected_returns_mean, up_stdev, sharp_ratio) + return -sharp_ratio diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 69d110649..b3356bd6d 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -42,7 +42,13 @@ def hyperopt_results(): 'profit_percent': [-0.1, 0.2, 0.3], 'profit_abs': [-0.2, 0.4, 0.6], 'trade_duration': [10, 30, 10], - 'sell_reason': [SellType.STOP_LOSS, SellType.ROI, SellType.ROI] + 'sell_reason': [SellType.STOP_LOSS, SellType.ROI, SellType.ROI], + 'close_time': + [ + datetime(2019, 1, 1, 9, 26, 3, 478039), + datetime(2019, 2, 1, 9, 26, 3, 478039), + datetime(2019, 3, 1, 9, 26, 3, 478039) + ] } ) @@ -336,6 +342,24 @@ def test_sharpe_loss_prefers_higher_profits(default_conf, hyperopt_results) -> N assert under > correct +def test_sharpe_loss_daily_prefers_higher_profits(default_conf, hyperopt_results) -> None: + results_over = hyperopt_results.copy() + results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 + results_under = hyperopt_results.copy() + results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 + + default_conf.update({'hyperopt_loss': 'SharpeHyperOptLossDaily'}) + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) + correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + under = hl.hyperopt_loss_function(results_under, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + assert over < correct + assert under > correct + + def test_onlyprofit_loss_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 From 5b00eaa42df93ccd583699b98f7d44e43596423c Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Thu, 6 Feb 2020 06:58:58 +0100 Subject: [PATCH 0407/1106] Updated Strategy Summary table to match other backtesting tables (#2864) --- docs/backtesting.md | 4 ++-- freqtrade/optimize/backtesting.py | 2 +- freqtrade/optimize/optimize_reports.py | 6 +++--- tests/optimize/test_optimize_reports.py | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 41428085d..2abb32ca0 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -237,8 +237,8 @@ There will be an additional table comparing win/losses of the different strategi Detailed output for all strategies one after the other will be available, so make sure to scroll up to see the details per strategy. ``` -=========================================================== Strategy Summary =========================================================== -| Strategy | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss | +=========================================================== STRATEGY SUMMARY =========================================================== +| Strategy | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Losses | |:------------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:| | Strategy1 | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 | | Strategy2 | 1487 | -0.13 | -197.58 | -0.00988917 | -98.79 | 4:43:00 | 662 | 825 | diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 96978d407..13c8990a5 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -441,7 +441,7 @@ class Backtesting: print() if len(all_results) > 1: # Print Strategy summary table - print(' Strategy Summary '.center(133, '=')) + print(' STRATEGY SUMMARY '.center(133, '=')) print(generate_text_table_strategy(self.config['stake_currency'], self.config['max_open_trades'], all_results=all_results)) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index c5cd944a1..8ad063056 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -121,9 +121,9 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') tabular_data = [] - headers = ['Strategy', 'buy count', 'avg profit %', 'cum profit %', - f'tot profit {stake_currency}', 'tot profit %', 'avg duration', - 'profit', 'loss'] + headers = ['Strategy', 'Buy Count', 'Avg Profit %', 'Cum Profit %', + f'Tot Profit {stake_currency}', 'Tot Profit %', 'Avg Duration', + 'Wins', 'Losses'] for strategy, results in all_results.items(): tabular_data.append([ strategy, diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 8c1a3619d..3ea13be47 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -91,14 +91,14 @@ def test_generate_text_table_strategy(default_conf, mocker): ) result_str = ( - '| Strategy | buy count | avg profit % | cum profit % ' - '| tot profit BTC | tot profit % | avg duration | profit | loss |\n' - '|:-----------|------------:|---------------:|---------------:' - '|-----------------:|---------------:|:---------------|---------:|-------:|\n' + '| Strategy | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC ' + '| Tot Profit % | Avg Duration | Wins | Losses |\n' + '|:-----------|------------:|---------------:|---------------:|-----------------:' + '|---------------:|:---------------|-------:|---------:|\n' '| ETH/BTC | 3 | 20.00 | 60.00 ' - '| 1.10000000 | 30.00 | 0:17:00 | 3 | 0 |\n' + '| 1.10000000 | 30.00 | 0:17:00 | 3 | 0 |\n' '| LTC/BTC | 3 | 30.00 | 90.00 ' - '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' + '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str From 739acaa47502d63dbe24cd89b7dfd7b1babdcbd9 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 13:54:51 +0300 Subject: [PATCH 0408/1106] Wordings improved --- docs/configuration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 72e12f066..c0404d647 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -610,11 +610,11 @@ Once you will be happy with your bot performance running in the Dry-run mode, yo ### Considerations for dry-run -* API-Keys may or may not be provided. Only Read-Only operations on the exchange are performed in dry-run mode. -* Wallets (`/balance`) will be simulated. -* Orders will be simulated, and will not be posted to the exchange +* API-keys may or may not be provided. Only Read-Only operations (i.e. operations that do not alter account state) on the exchange are performed in the dry-run mode. +* Wallets (`/balance`) are simulated. +* Orders are simulated, and will not be posted to the exchange. * In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled. -* Open orders (not Trades!) are reset on bot restart. +* Open orders (not trades, which are stored in the database) are reset on bot restart. ## Switch to production mode From 2846f9454fdf48cf90493f91d19f790ddf51cb61 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 17:02:11 +0300 Subject: [PATCH 0409/1106] Add description in the docs --- docs/strategy-customization.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index d59b097d7..cc3f8ee33 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -532,6 +532,27 @@ If you want to use a strategy from a different directory you can pass `--strateg freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory ``` +### Derived strategies + +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: + +``` +class MyAwesomeStrategy(IStrategy): + ... + stoploss = 0.13 + trailing_stop = False + # All other attributes and methods are here as they + # should be in any custom strategy... + ... + +class MyAwesomeStrategy2(MyAwesomeStrategy): + # Override something + stoploss = 0.08 + trailing_stop = True +``` + +Both attributes and methods may be overriden, altering behavior of the original strategy in a way you need. The strategy classes may be located in the same module (python file with the source code of your strategy) or in different modules (different python files). In the latter case you need to properly import the strategy class you derive the new one from. + ### Common mistakes when developing strategies Backtesting analyzes the whole time-range at once for performance reasons. Because of this, strategy authors need to make sure that strategies do not look-ahead into the future. From 412f5d68de2eeefa9b306e5b2604cb695dfc317a Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 17:42:26 +0300 Subject: [PATCH 0410/1106] Add description to hyperopt advanced doc chapter --- docs/advanced-hyperopt.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md index 20af0aaab..f47c33880 100644 --- a/docs/advanced-hyperopt.md +++ b/docs/advanced-hyperopt.md @@ -4,6 +4,34 @@ This page explains some advanced Hyperopt topics that may require higher coding skills and Python knowledge than creation of an ordinal hyperoptimization class. +## Derived hyperopt classes + +Custom hyperop classes can be derived in the same way [it can be done for strategies](strategy-customization.md#derived-strategies). + +Applying to hyperoptimization, as an example, you may override how dimensions are defined in your optimization hyperspace: + +``` +class MyAwesomeHyperOpt(IHyperOpt): + ... + # Uses default stoploss dimension + +class MyAwesomeHyperOpt2(MyAwesomeHyperOpt): + @staticmethod + def stoploss_space() -> List[Dimension]: + # Override boundaries for stoploss + return [ + Real(-0.33, -0.01, name='stoploss'), + ] +``` + +and then quickly switch between hyperopt classes, running optimization process with hyperopt class you need in each particular case: + +``` +$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt ... +or +$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 ... +``` + ## Creating and using a custom loss function To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class. From 2034527faa4c96d518f9a0506799fac89f1f0f56 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 17:45:15 +0300 Subject: [PATCH 0411/1106] Update docs/strategy-customization.md Co-Authored-By: Matthias --- docs/strategy-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index cc3f8ee33..717baf4db 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -536,7 +536,7 @@ freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory 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 class MyAwesomeStrategy(IStrategy): ... stoploss = 0.13 From 418e7adac159d30e48a21cb09c4547c432fbf67e Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 17:49:10 +0300 Subject: [PATCH 0412/1106] Highlight syntax in advanced-hyperopt as well --- docs/advanced-hyperopt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md index f47c33880..25b4bd900 100644 --- a/docs/advanced-hyperopt.md +++ b/docs/advanced-hyperopt.md @@ -10,7 +10,7 @@ Custom hyperop classes can be derived in the same way [it can be done for strate Applying to hyperoptimization, as an example, you may override how dimensions are defined in your optimization hyperspace: -``` +```python class MyAwesomeHyperOpt(IHyperOpt): ... # Uses default stoploss dimension From f57bd6b616872904c68dee27fcd3c5814e67d486 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 6 Feb 2020 21:53:03 +0300 Subject: [PATCH 0413/1106] Keep the docs clean for unexperienced users --- docs/strategy-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 717baf4db..688647c2b 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -551,7 +551,7 @@ class MyAwesomeStrategy2(MyAwesomeStrategy): trailing_stop = True ``` -Both attributes and methods may be overriden, altering behavior of the original strategy in a way you need. The strategy classes may be located in the same module (python file with the source code of your strategy) or in different modules (different python files). In the latter case you need to properly import the strategy class you derive the new one from. +Both attributes and methods may be overriden, altering behavior of the original strategy in a way you need. ### Common mistakes when developing strategies From 2816b96650b46c2a18859b95527cda0edb5de1d6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 6 Feb 2020 20:26:04 +0100 Subject: [PATCH 0414/1106] Create strategy_wrapper to call user-defined code with --- freqtrade/exceptions.py | 7 +++++++ freqtrade/strategy/interface.py | 25 ++++++++-------------- freqtrade/strategy/strategy_wrapper.py | 29 ++++++++++++++++++++++++++ tests/strategy/test_interface.py | 4 ++-- 4 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 freqtrade/strategy/strategy_wrapper.py diff --git a/freqtrade/exceptions.py b/freqtrade/exceptions.py index 2f05ddb57..553a691ef 100644 --- a/freqtrade/exceptions.py +++ b/freqtrade/exceptions.py @@ -35,3 +35,10 @@ class TemporaryError(FreqtradeException): This could happen when an exchange is congested, unavailable, or the user has networking problems. Usually resolves itself after a time. """ + + +class StrategyError(FreqtradeException): + """ + Errors with custom user-code deteced. + Usually caused by errors in the strategy. + """ diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 6e15c5183..c20bf0218 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -3,21 +3,22 @@ IStrategy interface This module defines the interface to apply for strategies """ import logging +import warnings from abc import ABC, abstractmethod from datetime import datetime, timezone from enum import Enum from typing import Dict, List, NamedTuple, Optional, Tuple -import warnings import arrow from pandas import DataFrame from freqtrade.data.dataprovider import DataProvider +from freqtrade.exceptions import StrategyError from freqtrade.exchange import timeframe_to_minutes from freqtrade.persistence import Trade +from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.wallets import Wallets - logger = logging.getLogger(__name__) @@ -255,20 +256,12 @@ class IStrategy(ABC): return False, False try: - dataframe = self._analyze_ticker_internal(dataframe, {'pair': pair}) - except ValueError as error: - logger.warning( - 'Unable to analyze ticker for pair %s: %s', - pair, - str(error) - ) - return False, False - except Exception as error: - logger.exception( - 'Unexpected error when analyzing ticker for pair %s: %s', - pair, - str(error) - ) + dataframe = strategy_safe_wrapper( + self._analyze_ticker_internal, message="" + )(dataframe, {'pair': pair}) + except StrategyError as error: + logger.warning(f"Unable to analyze ticker for pair {pair}: {error}") + return False, False if dataframe.empty: diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py new file mode 100644 index 000000000..61c986732 --- /dev/null +++ b/freqtrade/strategy/strategy_wrapper.py @@ -0,0 +1,29 @@ +import logging + +from freqtrade.exceptions import StrategyError + +logger = logging.getLogger(__name__) + + +def strategy_safe_wrapper(f, message: str, default_retval=None): + def wrapper(*args, **kwargs): + try: + return f(*args, **kwargs) + except ValueError as error: + logger.warning( + f"{message}" + f"Strategy caused the following exception: {error}" + f"{f}" + ) + if not default_retval: + raise StrategyError(str(error)) from error + return default_retval + except Exception as error: + logger.exception( + f"Unexpected error {error} calling {f}" + ) + if not default_retval: + raise StrategyError(str(error)) from error + return default_retval + + return wrapper diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 89c38bda1..2959fe62c 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -10,8 +10,8 @@ from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.persistence import Trade -from tests.conftest import get_patched_exchange, log_has from freqtrade.strategy.default_strategy import DefaultStrategy +from tests.conftest import get_patched_exchange, log_has, log_has_re # Avoid to reinit the same object again and again _STRATEGY = DefaultStrategy(config={}) @@ -65,7 +65,7 @@ def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_hi ) assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'], ticker_history) - assert log_has('Unable to analyze ticker for pair foo: xyz', caplog) + assert log_has_re(r'Strategy caused the following exception: xyz.*', caplog) def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history): From 49dcc561b77461ce22f8f875c49814008592b078 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 6 Feb 2020 20:30:17 +0100 Subject: [PATCH 0415/1106] POC for check_buy_timeout --- freqtrade/freqtradebot.py | 7 ++++++- freqtrade/strategy/interface.py | 18 ++++++++++++++++++ freqtrade/strategy/strategy_wrapper.py | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e51b3d550..f458f91d6 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -26,6 +26,7 @@ from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.rpc import RPCManager, RPCMessageType from freqtrade.state import State from freqtrade.strategy.interface import IStrategy, SellType +from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.wallets import Wallets logger = logging.getLogger(__name__) @@ -819,7 +820,11 @@ class FreqtradeBot: continue if ((order['side'] == 'buy' and order['status'] == 'canceled') - or (self._check_timed_out('buy', order))): + or self._check_timed_out('buy', order) + or strategy_safe_wrapper(self.strategy.check_buy_timeout, + default_retval=False)(pair=trade.pair, + trade=trade, + order=order)): self.handle_timedout_limit_buy(trade, order) self.wallets.update() diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index c20bf0218..de08b7cda 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -149,6 +149,24 @@ class IStrategy(ABC): :return: DataFrame with sell column """ + def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + """ + Check buy timeout function callback. + This method can be used to override the buy-timeout. + It is called whenever a limit buy order has been created, + and is not yet fully filled. + Configuration options in `unfilledtimeout` will be verified before this, + so ensure to set these timeouts high enough. + + When not implemented by a strategy, this simply returns False. + :param pair: Pair the trade is for + :param trade: trade object. + :param order: Order dictionary as returned from CCXT. + :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. + :return bool: When True is returned, then the buy-order is cancelled. + """ + return False + def informative_pairs(self) -> List[Tuple[str, str]]: """ Define additional, informative pair/interval combinations to be cached from the exchange. diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py index 61c986732..4f35bfbab 100644 --- a/freqtrade/strategy/strategy_wrapper.py +++ b/freqtrade/strategy/strategy_wrapper.py @@ -5,7 +5,7 @@ from freqtrade.exceptions import StrategyError logger = logging.getLogger(__name__) -def strategy_safe_wrapper(f, message: str, default_retval=None): +def strategy_safe_wrapper(f, message: str = "", default_retval=None): def wrapper(*args, **kwargs): try: return f(*args, **kwargs) From ff819386e1ce2f03f63acb9601486fcf0280053e Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 03:51:50 +0100 Subject: [PATCH 0416/1106] added draws to backtesting tables, reduced len of some labels to help fit this without increasing total width --- docs/backtesting.md | 72 ++++++++++++------------- freqtrade/optimize/optimize_reports.py | 25 +++++---- tests/optimize/test_optimize_reports.py | 62 ++++++++++----------- 3 files changed, 79 insertions(+), 80 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 2abb32ca0..79bfa2350 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -119,40 +119,40 @@ A backtesting result will look like that: ``` ========================================================= BACKTESTING REPORT ======================================================== -| pair | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss | -|:---------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:| -| ADA/BTC | 35 | -0.11 | -3.88 | -0.00019428 | -1.94 | 4:35:00 | 14 | 21 | -| ARK/BTC | 11 | -0.41 | -4.52 | -0.00022647 | -2.26 | 2:03:00 | 3 | 8 | -| BTS/BTC | 32 | 0.31 | 9.78 | 0.00048938 | 4.89 | 5:05:00 | 18 | 14 | -| DASH/BTC | 13 | -0.08 | -1.07 | -0.00005343 | -0.53 | 4:39:00 | 6 | 7 | -| ENG/BTC | 18 | 1.36 | 24.54 | 0.00122807 | 12.27 | 2:50:00 | 8 | 10 | -| EOS/BTC | 36 | 0.08 | 3.06 | 0.00015304 | 1.53 | 3:34:00 | 16 | 20 | -| ETC/BTC | 26 | 0.37 | 9.51 | 0.00047576 | 4.75 | 6:14:00 | 11 | 15 | -| ETH/BTC | 33 | 0.30 | 9.96 | 0.00049856 | 4.98 | 7:31:00 | 16 | 17 | -| IOTA/BTC | 32 | 0.03 | 1.09 | 0.00005444 | 0.54 | 3:12:00 | 14 | 18 | -| LSK/BTC | 15 | 1.75 | 26.26 | 0.00131413 | 13.13 | 2:58:00 | 6 | 9 | -| LTC/BTC | 32 | -0.04 | -1.38 | -0.00006886 | -0.69 | 4:49:00 | 11 | 21 | -| NANO/BTC | 17 | 1.26 | 21.39 | 0.00107058 | 10.70 | 1:55:00 | 10 | 7 | -| NEO/BTC | 23 | 0.82 | 18.97 | 0.00094936 | 9.48 | 2:59:00 | 10 | 13 | -| REQ/BTC | 9 | 1.17 | 10.54 | 0.00052734 | 5.27 | 3:47:00 | 4 | 5 | -| XLM/BTC | 16 | 1.22 | 19.54 | 0.00097800 | 9.77 | 3:15:00 | 7 | 9 | -| XMR/BTC | 23 | -0.18 | -4.13 | -0.00020696 | -2.07 | 5:30:00 | 12 | 11 | -| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 | 23 | -| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 | 15 | -| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 | +| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses | +|:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|--------:| +| ADA/BTC | 35 | -0.11 | -3.88 | -0.00019428 | -1.94 | 4:35:00 | 14 | 0 | 21 | +| ARK/BTC | 11 | -0.41 | -4.52 | -0.00022647 | -2.26 | 2:03:00 | 3 | 0 | 8 | +| BTS/BTC | 32 | 0.31 | 9.78 | 0.00048938 | 4.89 | 5:05:00 | 18 | 0 | 14 | +| DASH/BTC | 13 | -0.08 | -1.07 | -0.00005343 | -0.53 | 4:39:00 | 6 | 0 | 7 | +| ENG/BTC | 18 | 1.36 | 24.54 | 0.00122807 | 12.27 | 2:50:00 | 8 | 0 | 10 | +| EOS/BTC | 36 | 0.08 | 3.06 | 0.00015304 | 1.53 | 3:34:00 | 16 | 0 | 20 | +| ETC/BTC | 26 | 0.37 | 9.51 | 0.00047576 | 4.75 | 6:14:00 | 11 | 0 | 15 | +| ETH/BTC | 33 | 0.30 | 9.96 | 0.00049856 | 4.98 | 7:31:00 | 16 | 0 | 17 | +| IOTA/BTC | 32 | 0.03 | 1.09 | 0.00005444 | 0.54 | 3:12:00 | 14 | 0 | 18 | +| LSK/BTC | 15 | 1.75 | 26.26 | 0.00131413 | 13.13 | 2:58:00 | 6 | 0 | 9 | +| LTC/BTC | 32 | -0.04 | -1.38 | -0.00006886 | -0.69 | 4:49:00 | 11 | 0 | 21 | +| NANO/BTC | 17 | 1.26 | 21.39 | 0.00107058 | 10.70 | 1:55:00 | 10 | 0 | 7 | +| NEO/BTC | 23 | 0.82 | 18.97 | 0.00094936 | 9.48 | 2:59:00 | 10 | 0 | 13 | +| REQ/BTC | 9 | 1.17 | 10.54 | 0.00052734 | 5.27 | 3:47:00 | 4 | 0 | 5 | +| XLM/BTC | 16 | 1.22 | 19.54 | 0.00097800 | 9.77 | 3:15:00 | 7 | 0 | 9 | +| XMR/BTC | 23 | -0.18 | -4.13 | -0.00020696 | -2.07 | 5:30:00 | 12 | 0 | 11 | +| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 | 0 | 23 | +| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 | 0 | 15 | +| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 0 | 243 | ========================================================= SELL REASON STATS ========================================================= -| Sell Reason | Count | Profit | Loss | -|:-------------------|--------:|---------:|-------:| -| trailing_stop_loss | 205 | 150 | 55 | -| stop_loss | 166 | 0 | 166 | -| sell_signal | 56 | 36 | 20 | -| force_sell | 2 | 0 | 2 | +| Sell Reason | Sells | Wins | Draws | Losses | +|:-------------------|--------:|------:|-------:|--------:| +| trailing_stop_loss | 205 | 150 | 0 | 55 | +| stop_loss | 166 | 0 | 0 | 166 | +| sell_signal | 56 | 36 | 0 | 20 | +| force_sell | 2 | 0 | 0 | 2 | ====================================================== LEFT OPEN TRADES REPORT ====================================================== -| pair | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss | -|:---------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:| -| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 | 0 | -| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 | 0 | -| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 | 0 | +| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses | +|:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|--------:| +| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 | 0 | 0 | +| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 | 0 | 0 | +| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 | 0 | 0 | ``` The 1st table contains all trades the bot made, including "left open trades". @@ -238,10 +238,10 @@ Detailed output for all strategies one after the other will be available, so mak ``` =========================================================== STRATEGY SUMMARY =========================================================== -| Strategy | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Losses | -|:------------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:| -| Strategy1 | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 | -| Strategy2 | 1487 | -0.13 | -197.58 | -0.00988917 | -98.79 | 4:43:00 | 662 | 825 | +| Strategy | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses | +|:------------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|-------:| +| Strategy1 | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 0 | 243 | +| Strategy2 | 1487 | -0.13 | -197.58 | -0.00988917 | -98.79 | 4:43:00 | 662 | 0 | 825 | ``` ## Next step diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 8ad063056..b00adbd48 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -21,13 +21,14 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra tabular_data = [] headers = [ 'Pair', - 'Buy Count', + 'Buys', 'Avg Profit %', 'Cum Profit %', f'Tot Profit {stake_currency}', 'Tot Profit %', 'Avg Duration', 'Wins', + 'Draws', 'Losses' ] for pair in data: @@ -45,6 +46,7 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra str(timedelta( minutes=round(result.trade_duration.mean()))) if not result.empty else '0:00', len(result[result.profit_abs > 0]), + len(result[result.profit_abs == 0]), len(result[result.profit_abs < 0]) ]) @@ -59,6 +61,7 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra str(timedelta( minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', len(results[results.profit_abs > 0]), + len(results[results.profit_abs == 0]), len(results[results.profit_abs < 0]) ]) # Ignore type as floatfmt does allow tuples but mypy does not know that @@ -78,8 +81,9 @@ def generate_text_table_sell_reason( tabular_data = [] headers = [ "Sell Reason", - "Sell Count", + "Sells", "Wins", + "Draws", "Losses", "Avg Profit %", "Cum Profit %", @@ -88,7 +92,8 @@ def generate_text_table_sell_reason( ] for reason, count in results['sell_reason'].value_counts().iteritems(): result = results.loc[results['sell_reason'] == reason] - profit = len(result[result['profit_abs'] >= 0]) + wins = len(result[result['profit_abs'] > 0]) + draws = len(result[result['profit_abs'] == 0]) loss = len(result[result['profit_abs'] < 0]) profit_mean = round(result['profit_percent'].mean() * 100.0, 2) profit_sum = round(result["profit_percent"].sum() * 100.0, 2) @@ -98,7 +103,8 @@ def generate_text_table_sell_reason( [ reason.value, count, - profit, + wins, + draws, loss, profit_mean, profit_sum, @@ -121,9 +127,9 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, floatfmt = ('s', 'd', '.2f', '.2f', '.8f', '.2f', 'd', '.1f', '.1f') tabular_data = [] - headers = ['Strategy', 'Buy Count', 'Avg Profit %', 'Cum Profit %', + headers = ['Strategy', 'Buys', 'Avg Profit %', 'Cum Profit %', f'Tot Profit {stake_currency}', 'Tot Profit %', 'Avg Duration', - 'Wins', 'Losses'] + 'Wins', 'Draws', 'Losses'] for strategy, results in all_results.items(): tabular_data.append([ strategy, @@ -135,6 +141,7 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, str(timedelta( minutes=round(results.trade_duration.mean()))) if not results.empty else '0:00', len(results[results.profit_abs > 0]), + len(results[results.profit_abs == 0]), len(results[results.profit_abs < 0]) ]) # Ignore type as floatfmt does allow tuples but mypy does not know that @@ -146,9 +153,9 @@ def generate_edge_table(results: dict) -> str: floatfmt = ('s', '.10g', '.2f', '.2f', '.2f', '.2f', 'd', '.d') tabular_data = [] - headers = ['pair', 'stoploss', 'win rate', 'risk reward ratio', - 'required risk reward', 'expectancy', 'total number of trades', - 'average duration (min)'] + headers = ['Pair', 'Stoploss', 'Win Rate', 'Risk Reward Ratio', + 'Required Risk Reward', 'Expectancy', 'Total Number of Trades', + 'Average Duration (min)'] for result in results.items(): if result[1].nb_trades > 0: diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 3ea13be47..c31b10290 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -15,20 +15,17 @@ def test_generate_text_table(default_conf, mocker): 'profit_percent': [0.1, 0.2], 'profit_abs': [0.2, 0.4], 'trade_duration': [10, 30], - 'profit': [2, 0], - 'loss': [0, 0] + 'wins': [2, 0], + 'draws': [0, 0], + 'losses': [0, 0] } ) result_str = ( - '| Pair | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC ' - '| Tot Profit % | Avg Duration | Wins | Losses |\n' - '|:--------|------------:|---------------:|---------------:|-----------------:' - '|---------------:|:---------------|-------:|---------:|\n' - '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 ' - '| 15.00 | 0:20:00 | 2 | 0 |\n' - '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 ' - '| 15.00 | 0:20:00 | 2 | 0 |' + '| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|:--------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|-------:|--------:|---------:|\n' + '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 | 15.00 | 0:20:00 | 2 | 0 | 0 |\n' + '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 | 15.00 | 0:20:00 | 2 | 0 | 0 |' ) assert generate_text_table(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, @@ -43,21 +40,18 @@ def test_generate_text_table_sell_reason(default_conf, mocker): 'profit_percent': [0.1, 0.2, -0.1], 'profit_abs': [0.2, 0.4, -0.2], 'trade_duration': [10, 30, 10], - 'profit': [2, 0, 0], - 'loss': [0, 0, 1], + 'wins': [2, 0, 0], + 'draws': [0, 0, 0], + 'losses': [0, 0, 1], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] } ) result_str = ( - '| Sell Reason | Sell Count | Wins | Losses | Avg Profit % |' - ' Cum Profit % | Tot Profit BTC | Tot Profit % |\n' - '|:--------------|-------------:|-------:|---------:|---------------:|' - '---------------:|-----------------:|---------------:|\n' - '| roi | 2 | 2 | 0 | 15 |' - ' 30 | 0.6 | 15 |\n' - '| stop_loss | 1 | 0 | 1 | -10 |' - ' -10 | -0.2 | -5 |' + '| Sell Reason | Sells | Wins | Draws | Losses | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % |\n' + '|:--------------|--------:|-------:|--------:|---------:|---------------:|---------------:|-----------------:|---------------:|\n' + '| roi | 2 | 2 | 0 | 0 | 15 | 30 | 0.6 | 15 |\n' + '| stop_loss | 1 | 0 | 0 | 1 | -10 | -10 | -0.2 | -5 |' ) assert generate_text_table_sell_reason( data={'ETH/BTC': {}}, @@ -67,38 +61,36 @@ def test_generate_text_table_sell_reason(default_conf, mocker): def test_generate_text_table_strategy(default_conf, mocker): results = {} - results['ETH/BTC'] = pd.DataFrame( + results['TestStrategy1'] = pd.DataFrame( { 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], 'profit_percent': [0.1, 0.2, 0.3], 'profit_abs': [0.2, 0.4, 0.5], 'trade_duration': [10, 30, 10], - 'profit': [2, 0, 0], - 'loss': [0, 0, 1], + 'wins': [2, 0, 0], + 'draws': [0, 0, 0], + 'losses': [0, 0, 1], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] } ) - results['LTC/BTC'] = pd.DataFrame( + results['TestStrategy2'] = pd.DataFrame( { 'pair': ['LTC/BTC', 'LTC/BTC', 'LTC/BTC'], 'profit_percent': [0.4, 0.2, 0.3], 'profit_abs': [0.4, 0.4, 0.5], 'trade_duration': [15, 30, 15], - 'profit': [4, 1, 0], - 'loss': [0, 0, 1], + 'wins': [4, 1, 0], + 'draws': [0, 0, 0], + 'losses': [0, 0, 1], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] } ) result_str = ( - '| Strategy | Buy Count | Avg Profit % | Cum Profit % | Tot Profit BTC ' - '| Tot Profit % | Avg Duration | Wins | Losses |\n' - '|:-----------|------------:|---------------:|---------------:|-----------------:' - '|---------------:|:---------------|-------:|---------:|\n' - '| ETH/BTC | 3 | 20.00 | 60.00 ' - '| 1.10000000 | 30.00 | 0:17:00 | 3 | 0 |\n' - '| LTC/BTC | 3 | 30.00 | 90.00 ' - '| 1.30000000 | 45.00 | 0:20:00 | 3 | 0 |' + '| Strategy | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|:--------------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|-------:|--------:|---------:|\n' + '| TestStrategy1 | 3 | 20.00 | 60.00 | 1.10000000 | 30.00 | 0:17:00 | 3 | 0 | 0 |\n' + '| TestStrategy2 | 3 | 30.00 | 90.00 | 1.30000000 | 45.00 | 0:20:00 | 3 | 0 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str @@ -111,4 +103,4 @@ def test_generate_edge_table(edge_conf, mocker): assert generate_edge_table(results).count(':|') == 7 assert generate_edge_table(results).count('| ETH/BTC |') == 1 assert generate_edge_table(results).count( - '| risk reward ratio | required risk reward | expectancy |') == 1 + '| Risk Reward Ratio | Required Risk Reward | Expectancy |') == 1 From aa2cb937b145f7a87b8044fe17e4d945c617ba2c Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 03:54:47 +0100 Subject: [PATCH 0417/1106] flake8 :) --- tests/optimize/test_optimize_reports.py | 36 ++++++++++++++++--------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index c31b10290..57e928cca 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -22,10 +22,14 @@ def test_generate_text_table(default_conf, mocker): ) result_str = ( - '| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' - '|:--------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|-------:|--------:|---------:|\n' - '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 | 15.00 | 0:20:00 | 2 | 0 | 0 |\n' - '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 | 15.00 | 0:20:00 | 2 | 0 | 0 |' + '| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC |' + ' Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|:--------|-------:|---------------:|---------------:|-----------------:|' + '---------------:|:---------------|-------:|--------:|---------:|\n' + '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 |' + ' 15.00 | 0:20:00 | 2 | 0 | 0 |\n' + '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 |' + ' 15.00 | 0:20:00 | 2 | 0 | 0 |' ) assert generate_text_table(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, @@ -48,10 +52,14 @@ def test_generate_text_table_sell_reason(default_conf, mocker): ) result_str = ( - '| Sell Reason | Sells | Wins | Draws | Losses | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % |\n' - '|:--------------|--------:|-------:|--------:|---------:|---------------:|---------------:|-----------------:|---------------:|\n' - '| roi | 2 | 2 | 0 | 0 | 15 | 30 | 0.6 | 15 |\n' - '| stop_loss | 1 | 0 | 0 | 1 | -10 | -10 | -0.2 | -5 |' + '| Sell Reason | Sells | Wins | Draws | Losses |' + ' Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % |\n' + '|:--------------|--------:|-------:|--------:|---------:|' + '---------------:|---------------:|-----------------:|---------------:|\n' + '| roi | 2 | 2 | 0 | 0 |' + ' 15 | 30 | 0.6 | 15 |\n' + '| stop_loss | 1 | 0 | 0 | 1 |' + ' -10 | -10 | -0.2 | -5 |' ) assert generate_text_table_sell_reason( data={'ETH/BTC': {}}, @@ -87,10 +95,14 @@ def test_generate_text_table_strategy(default_conf, mocker): ) result_str = ( - '| Strategy | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' - '|:--------------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|-------:|--------:|---------:|\n' - '| TestStrategy1 | 3 | 20.00 | 60.00 | 1.10000000 | 30.00 | 0:17:00 | 3 | 0 | 0 |\n' - '| TestStrategy2 | 3 | 30.00 | 90.00 | 1.30000000 | 45.00 | 0:20:00 | 3 | 0 | 0 |' + '| Strategy | Buys | Avg Profit % | Cum Profit % | Tot' + ' Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|:--------------|-------:|---------------:|---------------:|------' + '-----------:|---------------:|:---------------|-------:|--------:|---------:|\n' + '| TestStrategy1 | 3 | 20.00 | 60.00 | ' + ' 1.10000000 | 30.00 | 0:17:00 | 3 | 0 | 0 |\n' + '| TestStrategy2 | 3 | 30.00 | 90.00 | ' + ' 1.30000000 | 45.00 | 0:20:00 | 3 | 0 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str From 44d67389d2b88133c8ca745c4574b6c9fb4c3e10 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 4 Feb 2020 02:02:57 +0100 Subject: [PATCH 0418/1106] initial push of sortino, work not done, still need own tests --- freqtrade/optimize/hyperopt_loss_sortino.py | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 freqtrade/optimize/hyperopt_loss_sortino.py diff --git a/freqtrade/optimize/hyperopt_loss_sortino.py b/freqtrade/optimize/hyperopt_loss_sortino.py new file mode 100644 index 000000000..e84ecb402 --- /dev/null +++ b/freqtrade/optimize/hyperopt_loss_sortino.py @@ -0,0 +1,49 @@ +""" +SortinoHyperOptLoss + +This module defines the alternative HyperOptLoss class which can be used for +Hyperoptimization. +""" +from datetime import datetime + +from pandas import DataFrame +import numpy as np + +from freqtrade.optimize.hyperopt import IHyperOptLoss + + +class SortinoHyperOptLoss(IHyperOptLoss): + """ + Defines the loss function for hyperopt. + + This implementation uses the Sharpe Ratio calculation. + """ + + @staticmethod + def hyperopt_loss_function(results: DataFrame, trade_count: int, + min_date: datetime, max_date: datetime, + *args, **kwargs) -> float: + """ + Objective function, returns smaller number for more optimal results. + + Uses Sharpe Ratio calculation. + """ + total_profit = results["profit_percent"] + days_period = (max_date - min_date).days + + # adding slippage of 0.1% per trade + total_profit = total_profit - 0.0005 + expected_returns_mean = total_profit.sum() / days_period + + results['downside_returns'] = 0 + results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent'] + down_stdev = np.std(results['downside_returns']) + + if np.std(total_profit) != 0.0: + sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) + else: + # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + sortino_ratio = -20. + + # print(expected_returns_mean, down_stdev, sortino_ratio) + return -sortino_ratio From deb0b7ad675b16cdbbde41d289fbe45840689c9b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 01:18:15 +0100 Subject: [PATCH 0419/1106] Added both SortinoHyperOptLoss and SortinoHyperOptLossDaily --- freqtrade/optimize/hyperopt_loss_sortino.py | 6 +- .../optimize/hyperopt_loss_sortino_daily.py | 64 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 freqtrade/optimize/hyperopt_loss_sortino_daily.py diff --git a/freqtrade/optimize/hyperopt_loss_sortino.py b/freqtrade/optimize/hyperopt_loss_sortino.py index e84ecb402..83f644a43 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino.py +++ b/freqtrade/optimize/hyperopt_loss_sortino.py @@ -16,7 +16,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Defines the loss function for hyperopt. - This implementation uses the Sharpe Ratio calculation. + This implementation uses the Sortino Ratio calculation. """ @staticmethod @@ -26,7 +26,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Objective function, returns smaller number for more optimal results. - Uses Sharpe Ratio calculation. + Uses Sortino Ratio calculation. """ total_profit = results["profit_percent"] days_period = (max_date - min_date).days @@ -42,7 +42,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): if np.std(total_profit) != 0.0: sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) else: - # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + # Define high (negative) sortino ratio to be clear that this is NOT optimal. sortino_ratio = -20. # print(expected_returns_mean, down_stdev, sortino_ratio) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py new file mode 100644 index 000000000..b59baabcb --- /dev/null +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -0,0 +1,64 @@ +""" +SortinoHyperOptLossDaily + +This module defines the alternative HyperOptLoss class which can be used for +Hyperoptimization. +""" +import math +from datetime import datetime + +from pandas import DataFrame, date_range + +from freqtrade.optimize.hyperopt import IHyperOptLoss + + +class SortinoHyperOptLossDaily(IHyperOptLoss): + """ + Defines the loss function for hyperopt. + + This implementation uses the Sortino Ratio calculation. + """ + + @staticmethod + def hyperopt_loss_function(results: DataFrame, trade_count: int, + min_date: datetime, max_date: datetime, + *args, **kwargs) -> float: + """ + Objective function, returns smaller number for more optimal results. + + Uses Sortino Ratio calculation. + """ + resample_freq = '1D' + slippage_per_trade_ratio = 0.0005 + days_in_year = 365 + annual_risk_free_rate = 0.0 + risk_free_rate = annual_risk_free_rate / days_in_year + + # apply slippage per trade to profit_percent + results.loc[:, 'profit_percent_after_slippage'] = \ + results['profit_percent'] - slippage_per_trade_ratio + + # create the index within the min_date and end max_date + t_index = date_range(start=min_date, end=max_date, freq=resample_freq) + + sum_daily = ( + results.resample(resample_freq, on='close_time').agg( + {"profit_percent_after_slippage": sum}).reindex(t_index).fillna(0) + ) + + total_profit = sum_daily["profit_percent_after_slippage"] - risk_free_rate + expected_returns_mean = total_profit.mean() + + results['downside_returns'] = 0 + results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent'] + down_stdev = results['downside_returns'].std() + + if (down_stdev != 0.): + sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year) + else: + # Define high (negative) sortino ratio to be clear that this is NOT optimal. + sortino_ratio = -20. + + # print(t_index, sum_daily, total_profit) + # print(risk_free_rate, expected_returns_mean, down_stdev, sortino_ratio) + return -sortino_ratio From b56a1f060318c22fa414aa0060eeb9c7c0754ac9 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 4 Feb 2020 02:02:57 +0100 Subject: [PATCH 0420/1106] initial push of sortino, work not done, still need own tests --- freqtrade/optimize/hyperopt_loss_sortino.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino.py b/freqtrade/optimize/hyperopt_loss_sortino.py index 83f644a43..e84ecb402 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino.py +++ b/freqtrade/optimize/hyperopt_loss_sortino.py @@ -16,7 +16,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Defines the loss function for hyperopt. - This implementation uses the Sortino Ratio calculation. + This implementation uses the Sharpe Ratio calculation. """ @staticmethod @@ -26,7 +26,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Objective function, returns smaller number for more optimal results. - Uses Sortino Ratio calculation. + Uses Sharpe Ratio calculation. """ total_profit = results["profit_percent"] days_period = (max_date - min_date).days @@ -42,7 +42,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): if np.std(total_profit) != 0.0: sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) else: - # Define high (negative) sortino ratio to be clear that this is NOT optimal. + # Define high (negative) sharpe ratio to be clear that this is NOT optimal. sortino_ratio = -20. # print(expected_returns_mean, down_stdev, sortino_ratio) From 728ab0ff2115dac6affd80c5b6b5f6bfb4e85a71 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 01:18:15 +0100 Subject: [PATCH 0421/1106] Added both SortinoHyperOptLoss and SortinoHyperOptLossDaily --- freqtrade/optimize/hyperopt_loss_sortino.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino.py b/freqtrade/optimize/hyperopt_loss_sortino.py index e84ecb402..83f644a43 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino.py +++ b/freqtrade/optimize/hyperopt_loss_sortino.py @@ -16,7 +16,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Defines the loss function for hyperopt. - This implementation uses the Sharpe Ratio calculation. + This implementation uses the Sortino Ratio calculation. """ @staticmethod @@ -26,7 +26,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): """ Objective function, returns smaller number for more optimal results. - Uses Sharpe Ratio calculation. + Uses Sortino Ratio calculation. """ total_profit = results["profit_percent"] days_period = (max_date - min_date).days @@ -42,7 +42,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): if np.std(total_profit) != 0.0: sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) else: - # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + # Define high (negative) sortino ratio to be clear that this is NOT optimal. sortino_ratio = -20. # print(expected_returns_mean, down_stdev, sortino_ratio) From 9bcc5d2eedb07417a0a468b3b6fa6514bc3fe2fd Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 01:24:03 +0100 Subject: [PATCH 0422/1106] fixed downside_returns to read from profit_percent_after_slippage --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index b59baabcb..0739379f6 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -50,7 +50,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): expected_returns_mean = total_profit.mean() results['downside_returns'] = 0 - results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent'] + results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent_after_slippage'] down_stdev = results['downside_returns'].std() if (down_stdev != 0.): From be34dc463b31e4698638d72dc2c295f2c3ec91f5 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 01:30:03 +0100 Subject: [PATCH 0423/1106] fixed bad commit From 951a19fb00f7e7203a430a254b583eca654cfd08 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 01:50:51 +0100 Subject: [PATCH 0424/1106] added tests for both sortino methods --- tests/optimize/test_hyperopt.py | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index b3356bd6d..5cdbe7b5a 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -360,6 +360,42 @@ def test_sharpe_loss_daily_prefers_higher_profits(default_conf, hyperopt_results assert under > correct +def test_sortino_loss_prefers_higher_profits(default_conf, hyperopt_results) -> None: + results_over = hyperopt_results.copy() + results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 + results_under = hyperopt_results.copy() + results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 + + default_conf.update({'hyperopt_loss': 'SortinoHyperOptLoss'}) + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) + correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + under = hl.hyperopt_loss_function(results_under, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + assert over < correct + assert under > correct + + +def test_sortino_loss_daily_prefers_higher_profits(default_conf, hyperopt_results) -> None: + results_over = hyperopt_results.copy() + results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 + results_under = hyperopt_results.copy() + results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 + + default_conf.update({'hyperopt_loss': 'SortinoHyperOptLossDaily'}) + hl = HyperOptLossResolver.load_hyperoptloss(default_conf) + correct = hl.hyperopt_loss_function(hyperopt_results, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + over = hl.hyperopt_loss_function(results_over, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + under = hl.hyperopt_loss_function(results_under, len(hyperopt_results), + datetime(2019, 1, 1), datetime(2019, 5, 1)) + assert over < correct + assert under > correct + + def test_onlyprofit_loss_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 From a46b7bcd6d7705bb4d2c6adc4c85ddbf8d2ad18e Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 02:12:24 +0100 Subject: [PATCH 0425/1106] more fixes... --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 8 +++++--- tests/optimize/test_hyperopt.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 0739379f6..31482b981 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -47,11 +47,13 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): ) total_profit = sum_daily["profit_percent_after_slippage"] - risk_free_rate + total_downside = sum_daily['downside_returns'] - risk_free_rate expected_returns_mean = total_profit.mean() - results['downside_returns'] = 0 - results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent_after_slippage'] - down_stdev = results['downside_returns'].std() + sum_daily['downside_returns'] = 0 + sum_daily.loc[total_profit < 0, + 'downside_returns'] = sum_daily['profit_percent_after_slippage'] + down_stdev = total_downside.std() if (down_stdev != 0.): sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 5cdbe7b5a..a2a98b0fb 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -380,9 +380,9 @@ def test_sortino_loss_prefers_higher_profits(default_conf, hyperopt_results) -> def test_sortino_loss_daily_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() - results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 + results_over['profit_percent_after_slippage'] = hyperopt_results['profit_percent_after_slippage'] * 2 results_under = hyperopt_results.copy() - results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 + results_under['profit_percent_after_slippage'] = hyperopt_results['profit_percent_after_slippage'] / 2 default_conf.update({'hyperopt_loss': 'SortinoHyperOptLossDaily'}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) From e8b9d88eb68cdda26b666dd42b8be39dccfc9940 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 02:14:12 +0100 Subject: [PATCH 0426/1106] moved line for total_downside --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 31482b981..891e2bf1c 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -47,12 +47,12 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): ) total_profit = sum_daily["profit_percent_after_slippage"] - risk_free_rate - total_downside = sum_daily['downside_returns'] - risk_free_rate expected_returns_mean = total_profit.mean() sum_daily['downside_returns'] = 0 sum_daily.loc[total_profit < 0, 'downside_returns'] = sum_daily['profit_percent_after_slippage'] + total_downside = sum_daily['downside_returns'] - risk_free_rate down_stdev = total_downside.std() if (down_stdev != 0.): From 6b279f297c1eb0e8f75957f7562fc2b6784677fe Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 7 Feb 2020 02:22:05 +0100 Subject: [PATCH 0427/1106] fixed test --- tests/optimize/test_hyperopt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index a2a98b0fb..5cdbe7b5a 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -380,9 +380,9 @@ def test_sortino_loss_prefers_higher_profits(default_conf, hyperopt_results) -> def test_sortino_loss_daily_prefers_higher_profits(default_conf, hyperopt_results) -> None: results_over = hyperopt_results.copy() - results_over['profit_percent_after_slippage'] = hyperopt_results['profit_percent_after_slippage'] * 2 + results_over['profit_percent'] = hyperopt_results['profit_percent'] * 2 results_under = hyperopt_results.copy() - results_under['profit_percent_after_slippage'] = hyperopt_results['profit_percent_after_slippage'] / 2 + results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 default_conf.update({'hyperopt_loss': 'SortinoHyperOptLossDaily'}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) From a893f70e49188ad7711d0b9db4b24780baeb20c9 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 8 Feb 2020 02:21:39 +0300 Subject: [PATCH 0428/1106] Replace NXT with XRP in config.json.example --- config.json.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json.example b/config.json.example index 8b85e71eb..c62b8240c 100644 --- a/config.json.example +++ b/config.json.example @@ -44,7 +44,7 @@ "DASH/BTC", "ZEC/BTC", "XLM/BTC", - "NXT/BTC", + "XRP/BTC", "TRX/BTC", "ADA/BTC", "XMR/BTC" From 28184201e471385d29a48629ce6a6bac7bbb39ec Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 8 Feb 2020 02:47:50 +0300 Subject: [PATCH 0429/1106] Align sample_hyperopt_advanced.py to hyperopt_interface.py --- freqtrade/templates/sample_hyperopt_advanced.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/freqtrade/templates/sample_hyperopt_advanced.py b/freqtrade/templates/sample_hyperopt_advanced.py index b4bbee3fb..e66ef948b 100644 --- a/freqtrade/templates/sample_hyperopt_advanced.py +++ b/freqtrade/templates/sample_hyperopt_advanced.py @@ -230,7 +230,7 @@ class AdvancedSampleHyperOpt(IHyperOpt): 'stoploss' optimization hyperspace. """ return [ - Real(-0.5, -0.02, name='stoploss'), + Real(-0.35, -0.02, name='stoploss'), ] @staticmethod @@ -249,8 +249,15 @@ class AdvancedSampleHyperOpt(IHyperOpt): # other 'trailing' hyperspace parameters. Categorical([True], name='trailing_stop'), - Real(0.02, 0.35, name='trailing_stop_positive'), - Real(0.01, 0.1, name='trailing_stop_positive_offset'), + Real(0.01, 0.35, name='trailing_stop_positive'), + + # 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive', + # so this intermediate parameter is used as the value of the difference between + # them. The value of the 'trailing_stop_positive_offset' is constructed in the + # generate_trailing_params() method. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. + Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), + Categorical([True, False], name='trailing_only_offset_is_reached'), ] From 61ced5e926db56740550192db1cba34883a81374 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 8 Feb 2020 02:49:06 +0300 Subject: [PATCH 0430/1106] Fix typo --- freqtrade/optimize/hyperopt_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_interface.py b/freqtrade/optimize/hyperopt_interface.py index d7d917c19..b3cedef2c 100644 --- a/freqtrade/optimize/hyperopt_interface.py +++ b/freqtrade/optimize/hyperopt_interface.py @@ -207,7 +207,7 @@ class IHyperOpt(ABC): # so this intermediate parameter is used as the value of the difference between # them. The value of the 'trailing_stop_positive_offset' is constructed in the # generate_trailing_params() method. - # # This is similar to the hyperspace dimensions used for constructing the ROI tables. + # This is similar to the hyperspace dimensions used for constructing the ROI tables. Real(0.001, 0.1, name='trailing_stop_positive_offset_p1'), Categorical([True, False], name='trailing_only_offset_is_reached'), From a1fe3850e29d6cd04bbb4e2df182885dcca601c7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 13:34:04 +0100 Subject: [PATCH 0431/1106] Improve docker-compose file to be ready to use --- docker-compose.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index cae98c3ee..3a4c4c2db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,18 @@ version: '3' services: freqtrade: image: freqtradeorg/freqtrade:master + # Build step - only needed when additional dependencies are needed + # build: + # context: . + # dockerfile: "./Dockerfile.technical" + restart: unless-stopped + container_name: freqtrade volumes: - "./user_data:/freqtrade/user_data" - - "./config.json:/freqtrade/config.json" + # Default command used when running `docker compose up` + command: > + trade + --logfile /freqtrade/user_data/freqtrade.log + --db-url sqlite:////freqtrade/user_data/tradesv3.sqlite + --config /freqtrade/user_data/config.json + --strategy SampleStrategy From f508324fc82641f5ccddc46940bff9baeda4f8ac Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 13:38:45 +0100 Subject: [PATCH 0432/1106] Update docker documentation to be easier to use --- docs/docker.md | 127 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 3 deletions(-) diff --git a/docs/docker.md b/docs/docker.md index d1684abc5..b1eb0b298 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -1,4 +1,4 @@ -# Using FreqTrade with Docker +# Using Freqtrade with Docker ## Install Docker @@ -8,13 +8,134 @@ Start by downloading and installing Docker CE for your platform: * [Windows](https://docs.docker.com/docker-for-windows/install/) * [Linux](https://docs.docker.com/install/) +Optionally, [docker-compose](https://docs.docker.com/compose/install/) should be installed and available to follow the docker quick start guide. + Once you have Docker installed, simply prepare the config file (e.g. `config.json`) and run the image for `freqtrade` as explained below. -## Download the official FreqTrade docker image +## Freqtrade with docker-compose + +Freqtrade provides an official Docker image on [Dockerhub](https://hub.docker.com/r/freqtradeorg/freqtrade/), as well as a [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) ready for usage. + +!!! Note + The following section assumes that docker and docker-compose is installed and available to the logged in user. + +!!! Note + All below comands use relative directories and will have to be executed from the directory containing the `docker-compose.yml` file. + +### Docker quick start + +Create a new directory and place the [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) in this directory. + +``` bash +mkdir freqtrade +cd freqtrade/ +# Download the docker-compose file from the repository +curl https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docker-compose.yml -o docker-compose.yml + +# Pull the freqtrade image +docker-compose pull + +# Create user directory structure +docker-compose run --rm freqtrade create-userdir --userdir user_data + +# Create configuration - Requires answering interactive questions +docker-compose run --rm freqtrade new-config --config user_data/config.json +``` + +The above snippet will create a directory called "freqtrade" - download the latest compose file and pull the freqtrade image. +The last 2 steps will create the user-directory, as well as a default configuration based on your selections. + +#### Adding your strategy + +The configuration is now available as `user_data/config.json`. +You should now copy your strategy to `user_data/strategies/` - and add the Strategy class name to the `docker-compose.yml` file, replacing `SampleStrategy`. + +Once this is done, you're ready to launch the bot in trading mode. + +``` bash +docker-compose up -d +``` + +#### Docker-compose logs + +Logs will be written to `user_data/freqtrade.log`. +Alternatively, you can check the latest logs using `docker-compose logs -f`. + +#### Database + +The database will be in the user_data directory as well, and will be called `user_data/tradesv3.sqlite`. + +#### Updating freqtrade with docker-compose + +To update freqtrade when using docker-compose is as simple as running the following 2 commands: + +``` bash +# Download the latest image +docker-compose pull +# Restart the image +docker-compose up -d +``` + +This will first pull the latest image, and will then restart the container with the just pulled version. + +!!! Note + You should always check the changelog for breaking changes / manual interventions required and make sure the bot starts correctly after the update. + +#### Going from here + +Advanced users may edit the docker-compose file further to include all possible options or arguments. + +All possible freqtrade arguments will be available by running `docker-compose run --rm freqtrade `. + +!!! Note "`docker-compose run --rm`" + Inluding `--rm` will clean up the container after completion, and is highly recommended for all modes except trading mode (`freqtrade trade`). + +##### Example: Download data with docker-compose + +Downloading backtest data for one pair from binance. The data will be stored in the host directory `user_data/data/`. + +``` bash +docker-compose run --rm freqtrade download-data --pairs ETH/BTC --exchange binance --days 5 -t 1h +``` + +Head over to the [Data Downloading Documentation](data-download.md) for more details on downloading data. + +##### Example: Backtest with docker-compose + +Backtesting in docker-containers: + +``` bash +docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy SampleStrategy --timerange 20190801-20191001 -i 5m +``` + +Head over to the [Backtesting Documentation](backtesting.md) to learn more. + +#### Additional dependencies with docker-compose + +If your strategy requires dependencies not included in the default image (like [technical](https://github.com/freqtrade/technical)) - it will be necessary to build the image on your host. +For this, please create a Dockerfile containing installation steps for the additional dependencies (have a look at [Dockerfile.technical](https://github.com/freqtrade/freqtrade/blob/develop/Dockerfile.technical) for an example). + +You'll then also need to modify the `docker-compose.yml` file and uncomment the build step, as well as rename the image to avoid naming collisions. + +``` yaml + image: freqtrade_custom + build: + context: . + dockerfile: "./Dockerfile." +``` + +You can then run `docker-compose build` to build the docker image, and run it using the commands described above. + +## Docker - without docker compose + +!!! Warning + The below documentation is provided for completeness and assumes that you are somewhat familiar with running docker containers. If you're just starting out with docker, we recommend to follow the [Freqtrade with docker-compose](#freqtrade-with-docker-compose) instructions. + +### Download the official Freqtrade docker image Pull the image from docker hub. -Branches / tags available can be checked out on [Dockerhub](https://hub.docker.com/r/freqtradeorg/freqtrade/tags/). +Branches / tags available can be checked out on [Dockerhub tags page](https://hub.docker.com/r/freqtradeorg/freqtrade/tags/). ```bash docker pull freqtradeorg/freqtrade:develop From 52f4187129566deeed3121752d34e5131410a87e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 13:51:55 +0100 Subject: [PATCH 0433/1106] Allow exchange templates to configure outside-options too --- freqtrade/commands/build_config_commands.py | 2 +- freqtrade/templates/base_config.json.j2 | 4 +- .../subtemplates/exchange_binance.j2 | 80 ++++++++++--------- .../subtemplates/exchange_generic.j2 | 24 +++--- .../templates/subtemplates/exchange_kraken.j2 | 67 ++++++++-------- 5 files changed, 91 insertions(+), 86 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 838fd510a..7dd1be607 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -90,10 +90,10 @@ def ask_user_config() -> Dict[str, Any]: "name": "exchange_name", "message": "Select exchange", "choices": [ - "bittrex", "binance", "binanceje", "binanceus", + "bittrex", "kraken", Separator(), "other", diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index 1370bfa80..0a4f92c4b 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -27,9 +27,7 @@ "sell_profit_only": false, "ignore_roi_if_buy_signal": false }, - "exchange": { - {{ exchange | indent(8) }} - }, + {{ exchange | indent(4) }}, "pairlists": [ {"method": "StaticPairList"} ], diff --git a/freqtrade/templates/subtemplates/exchange_binance.j2 b/freqtrade/templates/subtemplates/exchange_binance.j2 index c527d296b..03aa0560c 100644 --- a/freqtrade/templates/subtemplates/exchange_binance.j2 +++ b/freqtrade/templates/subtemplates/exchange_binance.j2 @@ -1,39 +1,41 @@ -"name": "{{ exchange_name | lower }}", -"key": "{{ exchange_key }}", -"secret": "{{ exchange_secret }}", -"ccxt_config": {"enableRateLimit": true}, -"ccxt_async_config": { - "enableRateLimit": true, - "rateLimit": 200 -}, -"pair_whitelist": [ - "ALGO/BTC", - "ATOM/BTC", - "BAT/BTC", - "BCH/BTC", - "BRD/BTC", - "EOS/BTC", - "ETH/BTC", - "IOTA/BTC", - "LINK/BTC", - "LTC/BTC", - "NEO/BTC", - "NXS/BTC", - "XMR/BTC", - "XRP/BTC", - "XTZ/BTC" -], -"pair_blacklist": [ - "BNB/BTC", - "BNB/BUSD", - "BNB/ETH", - "BNB/EUR", - "BNB/NGN", - "BNB/PAX", - "BNB/RUB", - "BNB/TRY", - "BNB/TUSD", - "BNB/USDC", - "BNB/USDS", - "BNB/USDT", -] +"exchange": { + "name": "{{ exchange_name | lower }}", + "key": "{{ exchange_key }}", + "secret": "{{ exchange_secret }}", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 200 + }, + "pair_whitelist": [ + "ALGO/BTC", + "ATOM/BTC", + "BAT/BTC", + "BCH/BTC", + "BRD/BTC", + "EOS/BTC", + "ETH/BTC", + "IOTA/BTC", + "LINK/BTC", + "LTC/BTC", + "NEO/BTC", + "NXS/BTC", + "XMR/BTC", + "XRP/BTC", + "XTZ/BTC" + ], + "pair_blacklist": [ + "BNB/BTC", + "BNB/BUSD", + "BNB/ETH", + "BNB/EUR", + "BNB/NGN", + "BNB/PAX", + "BNB/RUB", + "BNB/TRY", + "BNB/TUSD", + "BNB/USDC", + "BNB/USDS", + "BNB/USDT", + ] +} diff --git a/freqtrade/templates/subtemplates/exchange_generic.j2 b/freqtrade/templates/subtemplates/exchange_generic.j2 index 33309de3b..ade9c2f28 100644 --- a/freqtrade/templates/subtemplates/exchange_generic.j2 +++ b/freqtrade/templates/subtemplates/exchange_generic.j2 @@ -1,13 +1,15 @@ -"name": "{{ exchange_name | lower }}", -"key": "{{ exchange_key }}", -"secret": "{{ exchange_secret }}", -"ccxt_config": {"enableRateLimit": true}, -"ccxt_async_config": { - "enableRateLimit": true -}, -"pair_whitelist": [ +"exchange": { + "name": "{{ exchange_name | lower }}", + "key": "{{ exchange_key }}", + "secret": "{{ exchange_secret }}", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true + }, + "pair_whitelist": [ -], -"pair_blacklist": [ + ], + "pair_blacklist": [ -] + ] +} diff --git a/freqtrade/templates/subtemplates/exchange_kraken.j2 b/freqtrade/templates/subtemplates/exchange_kraken.j2 index 690828887..7139a0830 100644 --- a/freqtrade/templates/subtemplates/exchange_kraken.j2 +++ b/freqtrade/templates/subtemplates/exchange_kraken.j2 @@ -1,33 +1,36 @@ -"name": "kraken", -"key": "{{ exchange_key }}", -"secret": "{{ exchange_secret }}", -"ccxt_config": {"enableRateLimit": true}, -"ccxt_async_config": { - "enableRateLimit": true, - "rateLimit": 1000 -}, -"pair_whitelist": [ - "ADA/EUR", - "ATOM/EUR", - "BAT/EUR", - "BCH/EUR", - "BTC/EUR", - "DAI/EUR", - "DASH/EUR", - "EOS/EUR", - "ETC/EUR", - "ETH/EUR", - "LINK/EUR", - "LTC/EUR", - "QTUM/EUR", - "REP/EUR", - "WAVES/EUR", - "XLM/EUR", - "XMR/EUR", - "XRP/EUR", - "XTZ/EUR", - "ZEC/EUR" -], -"pair_blacklist": [ +"download_trades": true, +"exchange": { + "name": "kraken", + "key": "{{ exchange_key }}", + "secret": "{{ exchange_secret }}", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 1000 + }, + "pair_whitelist": [ + "ADA/EUR", + "ATOM/EUR", + "BAT/EUR", + "BCH/EUR", + "BTC/EUR", + "DAI/EUR", + "DASH/EUR", + "EOS/EUR", + "ETC/EUR", + "ETH/EUR", + "LINK/EUR", + "LTC/EUR", + "QTUM/EUR", + "REP/EUR", + "WAVES/EUR", + "XLM/EUR", + "XMR/EUR", + "XRP/EUR", + "XTZ/EUR", + "ZEC/EUR" + ], + "pair_blacklist": [ -] + ] +} From 34f04668c19f719f712b34bd556f13c5fb3af1bc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 14:02:51 +0100 Subject: [PATCH 0434/1106] Add template for bittrex --- docs/utils.md | 1 - .../subtemplates/exchange_bittrex.j2 | 24 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 freqtrade/templates/subtemplates/exchange_bittrex.j2 diff --git a/docs/utils.md b/docs/utils.md index 66101d9bc..a986f040b 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -40,7 +40,6 @@ optional arguments: Creates a new configuration file, asking some questions which are important selections for a configuration. - ``` usage: freqtrade new-config [-h] [-c PATH] diff --git a/freqtrade/templates/subtemplates/exchange_bittrex.j2 b/freqtrade/templates/subtemplates/exchange_bittrex.j2 new file mode 100644 index 000000000..7a7e8e291 --- /dev/null +++ b/freqtrade/templates/subtemplates/exchange_bittrex.j2 @@ -0,0 +1,24 @@ +"exchange": { + "name": "{{ exchange_name | lower }}", + "key": "{{ exchange_key }}", + "secret": "{{ exchange_secret }}", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": true, + "rateLimit": 500 + }, + "pair_whitelist": [ + "ETH/BTC", + "LTC/BTC", + "ETC/BTC", + "DASH/BTC", + "ZEC/BTC", + "XLM/BTC", + "XRP/BTC", + "TRX/BTC", + "ADA/BTC", + "XMR/BTC" + ], + "pair_blacklist": [ + ] +} From c4031761fec25cb1193557cc09733451fa028612 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 09:53:20 +0100 Subject: [PATCH 0435/1106] Don't validate exchange for data-download subcommand --- freqtrade/commands/data_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index ddc2ca25b..aee144505 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -37,7 +37,7 @@ def start_download_data(args: Dict[str, Any]) -> None: pairs_not_available: List[str] = [] # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) + exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) try: if config.get('download_trades'): From f3b1161640507d91e7694f03e80095304bfdaf0a Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 8 Feb 2020 21:02:52 +0100 Subject: [PATCH 0436/1106] wide notifications fixes --- docs/configuration.md | 2 + docs/telegram-usage.md | 2 +- docs/webhook-config.md | 51 ++++++++++++ freqtrade/constants.py | 4 +- freqtrade/freqtradebot.py | 137 ++++++++++++++++++++++++--------- freqtrade/rpc/rpc.py | 14 ++-- freqtrade/rpc/telegram.py | 20 +++-- freqtrade/rpc/webhook.py | 4 + tests/rpc/test_rpc.py | 6 +- tests/rpc/test_rpc_telegram.py | 81 ++++++++++++++++--- tests/rpc/test_rpc_webhook.py | 46 ++++++----- tests/test_freqtradebot.py | 6 +- 12 files changed, 288 insertions(+), 85 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index c0404d647..53e554709 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -92,7 +92,9 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `webhook.enabled` | Enable usage of Webhook notifications
***Datatype:*** *Boolean* | `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* +| `webhook.webhookbuycancel` | Payload to send on buy order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* +| `webhook.webhooksellcancel` | Payload to send on sell order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* | `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Boolean* | `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *IPv4* diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index ed0c21a6e..ac9cea3d6 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -55,7 +55,7 @@ official commands. You can ask at any moment for help with `/help`. | `/reload_conf` | | Reloads the configuration file | `/show_config` | | Shows part of the current configuration with relevant settings to operation | `/status` | | Lists all open trades -| `/status table` | | List all open trades in a table format +| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk(*) | `/count` | | Displays number of trades used and available | `/profit` | | Display a summary of your profit/loss from close trades and some stats about your performance | `/forcesell ` | | Instantly sells the given trade (Ignoring `minimum_roi`). diff --git a/docs/webhook-config.md b/docs/webhook-config.md index 9e0a34eae..878b18e8a 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -15,11 +15,21 @@ Sample configuration (tested using IFTTT). "value2": "limit {limit:8f}", "value3": "{stake_amount:8f} {stake_currency}" }, + "webhookbuycancel": { + "value1": "Cancelling Buy {pair}", + "value2": "limit {limit:8f}", + "value3": "{stake_amount:8f} {stake_currency}" + }, "webhooksell": { "value1": "Selling {pair}", "value2": "limit {limit:8f}", "value3": "profit: {profit_amount:8f} {stake_currency}" }, + "webhooksellcancel": { + "value1": "Cancelling Sell {pair}", + "value2": "limit {limit:8f}", + "value3": "profit: {profit_amount:8f} {stake_currency}" + }, "webhookstatus": { "value1": "Status: {status}", "value2": "", @@ -40,10 +50,29 @@ Possible parameters are: * `exchange` * `pair` * `limit` +* `amount` * `stake_amount` * `stake_currency` * `fiat_currency` * `order_type` +* `open_rate` +* `current_rate` + +### Webhookbuycancel + +The fields in `webhook.webhookbuycancel` are filled when the bot cancels a buy order. Parameters are filled using string.format. +Possible parameters are: + +* `exchange` +* `pair` +* `limit` +* `amount` +* `stake_amount` +* `stake_currency` +* `fiat_currency` +* `order_type` +* `open_rate` +* `current_rate` ### Webhooksell @@ -57,6 +86,7 @@ Possible parameters are: * `amount` * `open_rate` * `current_rate` +* `close_rate` * `profit_amount` * `profit_percent` * `stake_currency` @@ -66,6 +96,27 @@ Possible parameters are: * `open_date` * `close_date` +### Webhooksellcancel + +The fields in `webhook.webhooksellcancel` are filled when the bot cancels a sell order. Parameters are filled using string.format. +Possible parameters are: + +* `exchange` +* `pair` +* `gain` +* `limit` +* `amount` +* `open_rate` +* `current_rate` +* `close_rate` +* `profit_amount` +* `profit_percent` +* `stake_currency` +* `fiat_currency` +* `sell_reason` +* `order_type` +* `open_date` + ### Webhookstatus The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index e68e741af..b34805e94 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -78,7 +78,7 @@ CONF_SCHEMA = { 'amend_last_stake_amount': {'type': 'boolean', 'default': False}, 'last_stake_amount_min_ratio': { 'type': 'number', 'minimum': 0.0, 'maximum': 1.0, 'default': 0.5 - }, + }, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, @@ -191,7 +191,9 @@ CONF_SCHEMA = { 'properties': { 'enabled': {'type': 'boolean'}, 'webhookbuy': {'type': 'object'}, + 'webhookbuycancel': {'type': 'object'}, 'webhooksell': {'type': 'object'}, + 'webhooksellcancel': {'type': 'object'}, 'webhookstatus': {'type': 'object'}, }, }, diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e51b3d550..2f57ca41b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -234,7 +234,7 @@ class FreqtradeBot: return trades_created - def get_buy_rate(self, pair: str, tick: Dict = None) -> float: + def get_buy_rate(self, pair: str, refresh: bool = False, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price :return: float: Price @@ -253,7 +253,7 @@ class FreqtradeBot: else: if not tick: logger.info('Using Last Ask / Last Price') - ticker = self.exchange.fetch_ticker(pair) + ticker = self.exchange.fetch_ticker(pair, refresh) else: ticker = tick if ticker['ask'] < ticker['last']: @@ -404,7 +404,7 @@ class FreqtradeBot: stake_amount = self.get_trade_stake_amount(pair) if not stake_amount: - logger.debug("Stake amount is 0, ignoring possible trade for {pair}.") + logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.") return False logger.info(f"Buy signal found: about create a new trade with stake_amount: " @@ -414,10 +414,12 @@ class FreqtradeBot: if ((bid_check_dom.get('enabled', False)) and (bid_check_dom.get('bids_to_ask_delta', 0) > 0)): if self._check_depth_of_market_buy(pair, bid_check_dom): + logger.info(f'Executed Buy for {pair}.') return self.execute_buy(pair, stake_amount) else: return False + logger.info(f'Executed Buy for {pair}') return self.execute_buy(pair, stake_amount) else: return False @@ -450,7 +452,7 @@ class FreqtradeBot: """ Executes a limit buy for the given pair :param pair: pair for which we want to create a LIMIT_BUY - :return: None + :return: bool """ time_in_force = self.strategy.order_time_in_force['buy'] @@ -458,7 +460,7 @@ class FreqtradeBot: buy_limit_requested = price else: # Calculate price - buy_limit_requested = self.get_buy_rate(pair) + buy_limit_requested = self.get_buy_rate(pair, True) min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested) if min_stake_amount is not None and min_stake_amount > stake_amount: @@ -547,11 +549,37 @@ class FreqtradeBot: 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, - 'limit': trade.open_rate, + 'limit': trade.open_rate_requested, 'order_type': order_type, 'stake_amount': trade.stake_amount, 'stake_currency': self.config['stake_currency'], 'fiat_currency': self.config.get('fiat_display_currency', None), + 'amount': trade.amount, + 'open_date': trade.open_date or datetime.utcnow(), + 'current_rate': trade.open_rate_requested, + } + + # Send the message + self.rpc.send_msg(msg) + + def _notify_buy_cancel(self, trade: Trade, order_type: str) -> None: + """ + Sends rpc notification when a buy cancel occured. + """ + current_rate = self.get_buy_rate(trade.pair, False) + + msg = { + 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, + 'exchange': self.exchange.name.capitalize(), + 'pair': trade.pair, + 'limit': trade.open_rate_requested, + 'order_type': order_type, + 'stake_amount': trade.stake_amount, + 'stake_currency': self.config['stake_currency'], + 'fiat_currency': self.config.get('fiat_display_currency', None), + 'amount': trade.amount, + 'open_date': trade.open_date, + 'current_rate': current_rate, } # Send the message @@ -587,7 +615,7 @@ class FreqtradeBot: return trades_closed - def get_sell_rate(self, pair: str, refresh: bool) -> float: + def get_sell_rate(self, pair: str, refresh: bool = False) -> float: """ Get sell rate - either using get-ticker bid or first bid based on orderbook The orderbook portion is only used for rpc messaging, which would otherwise fail @@ -751,7 +779,7 @@ class FreqtradeBot: update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60) if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() >= update_beat: # cancelling the current stoploss on exchange first - logger.info('Trailing stoploss: cancelling current stoploss on exchange (id:{%s})' + logger.info('Trailing stoploss: cancelling current stoploss on exchange (id:{%s}) ' 'in order to add another one ...', order['id']) try: self.exchange.cancel_order(order['id'], trade.pair) @@ -777,7 +805,7 @@ class FreqtradeBot: if should_sell.sell_flag: self.execute_sell(trade, sell_rate, should_sell.sell_type) - logger.info('executed sell, reason: %s', should_sell.sell_type) + logger.info(f'Executed Sell for {trade.pair}. Reason: {should_sell.sell_type}') return True return False @@ -820,41 +848,41 @@ class FreqtradeBot: if ((order['side'] == 'buy' and order['status'] == 'canceled') or (self._check_timed_out('buy', order))): - self.handle_timedout_limit_buy(trade, order) self.wallets.update() + order_type = self.strategy.order_types['buy'] + self._notify_buy_cancel(trade, order_type) elif ((order['side'] == 'sell' and order['status'] == 'canceled') or (self._check_timed_out('sell', order))): self.handle_timedout_limit_sell(trade, order) self.wallets.update() + order_type = self.strategy.order_types['sell'] + self._notify_sell_cancel(trade, order_type) - def handle_buy_order_full_cancel(self, trade: Trade, reason: str) -> None: - """Close trade in database and send message""" + def delete_trade(self, trade: Trade) -> None: + """Delete trade in database""" Trade.session.delete(trade) Trade.session.flush() - logger.info('Buy order %s for %s.', reason, trade) - self.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'Unfilled buy order for {trade.pair} {reason}' - }) def handle_timedout_limit_buy(self, trade: Trade, order: Dict) -> bool: """ Buy timeout - cancel order :return: True if order was fully cancelled """ - reason = "cancelled due to timeout" if order['status'] != 'canceled': + reason = "cancelled due to timeout" corder = self.exchange.cancel_order(trade.open_order_id, trade.pair) + logger.info('Buy order %s for %s.', reason, trade) else: # Order was cancelled already, so we can reuse the existing dict corder = order - reason = "canceled on Exchange" + reason = "cancelled on exchange" + logger.info('Buy order %s for %s.', reason, trade) if corder.get('remaining', order['remaining']) == order['amount']: # if trade is not partially completed, just delete the trade - self.handle_buy_order_full_cancel(trade, reason) + self.delete_trade(trade) return True # if trade is partially complete, edit the stake details for the trade @@ -878,10 +906,6 @@ class FreqtradeBot: trade.open_order_id = None logger.info('Partial buy order timeout for %s.', trade) - self.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'Remaining buy order for {trade.pair} cancelled due to timeout' - }) return False def handle_timedout_limit_sell(self, trade: Trade, order: Dict) -> bool: @@ -889,24 +913,22 @@ class FreqtradeBot: Sell timeout - cancel order and update trade :return: True if order was fully cancelled """ + # if trade is not partially completed, just cancel the trade if order['remaining'] == order['amount']: - # if trade is not partially completed, just cancel the trade if order["status"] != "canceled": - reason = "due to timeout" + reason = "cancelled due to timeout" + # if trade is not partially completed, just delete the trade self.exchange.cancel_order(trade.open_order_id, trade.pair) - logger.info('Sell order timeout for %s.', trade) + logger.info('Sell order %s for %s.', reason, trade) else: - reason = "on exchange" - logger.info('Sell order canceled on exchange for %s.', trade) + reason = "cancelled on exchange" + logger.info('Sell order %s for %s.', reason, trade) + trade.close_rate = None trade.close_profit = None trade.close_date = None trade.is_open = True trade.open_order_id = None - self.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'Unfilled sell order for {trade.pair} cancelled {reason}' - }) return True @@ -938,13 +960,13 @@ class FreqtradeBot: raise DependencyException( f"Not enough amount to sell. Trade-amount: {amount}, Wallet: {wallet_amount}") - def execute_sell(self, trade: Trade, limit: float, sell_reason: SellType) -> None: + def execute_sell(self, trade: Trade, limit: float, sell_reason: SellType) -> bool: """ Executes a limit sell for the given trade and limit :param trade: Trade instance :param limit: limit rate for the sell order :param sellreason: Reason the sell was triggered - :return: None + :return: bool """ sell_type = 'sell' if sell_reason in (SellType.STOP_LOSS, SellType.TRAILING_STOP_LOSS): @@ -965,7 +987,7 @@ class FreqtradeBot: order_type = self.strategy.order_types[sell_type] if sell_reason == SellType.EMERGENCY_SELL: - # Emergencysells (default to market!) + # Emergency sells (default to market!) order_type = self.strategy.order_types.get("emergencysell", "market") amount = self._safe_sell_amount(trade.pair, trade.amount) @@ -990,6 +1012,8 @@ class FreqtradeBot: self._notify_sell(trade, order_type) + return True + def _notify_sell(self, trade: Trade, order_type: str) -> None: """ Sends rpc notification when a sell occured. @@ -1006,7 +1030,7 @@ class FreqtradeBot: 'exchange': trade.exchange.capitalize(), 'pair': trade.pair, 'gain': gain, - 'limit': trade.close_rate_requested, + 'limit': profit_rate, 'order_type': order_type, 'amount': trade.amount, 'open_rate': trade.open_rate, @@ -1017,6 +1041,45 @@ class FreqtradeBot: 'open_date': trade.open_date, 'close_date': trade.close_date or datetime.utcnow(), 'stake_currency': self.config['stake_currency'], + 'fiat_currency': self.config.get('fiat_display_currency', None), + } + + if 'fiat_display_currency' in self.config: + msg.update({ + 'fiat_currency': self.config['fiat_display_currency'], + }) + + # Send the message + self.rpc.send_msg(msg) + + def _notify_sell_cancel(self, trade: Trade, order_type: str) -> None: + """ + Sends rpc notification when a sell cancel occured. + """ + profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested + profit_trade = trade.calc_profit(rate=profit_rate) + # Use cached ticker here - it was updated seconds ago. + current_rate = self.get_sell_rate(trade.pair, False) + profit_percent = trade.calc_profit_ratio(profit_rate) + gain = "profit" if profit_percent > 0 else "loss" + + msg = { + 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, + 'exchange': trade.exchange.capitalize(), + 'pair': trade.pair, + 'gain': gain, + 'limit': profit_rate, + 'order_type': order_type, + 'amount': trade.amount, + 'open_rate': trade.open_rate, + 'current_rate': current_rate, + 'profit_amount': profit_trade, + 'profit_percent': profit_percent, + 'sell_reason': trade.sell_reason, + 'open_date': trade.open_date, + 'close_date': trade.close_date, + 'stake_currency': self.config['stake_currency'], + 'fiat_currency': self.config.get('fiat_display_currency', None), } if 'fiat_display_currency' in self.config: diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 7f5cfc101..c1efea79e 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -26,7 +26,9 @@ class RPCMessageType(Enum): WARNING_NOTIFICATION = 'warning' CUSTOM_NOTIFICATION = 'custom' BUY_NOTIFICATION = 'buy' + BUY_CANCEL_NOTIFICATION = 'buy_cancel' SELL_NOTIFICATION = 'sell' + SELL_CANCEL_NOTIFICATION = 'sell_cancel' def __repr__(self): return self.value @@ -39,6 +41,7 @@ class RPCException(Exception): raise RPCException('*Status:* `no active trade`') """ + def __init__(self, message: str) -> None: super().__init__(self) self.message = message @@ -157,15 +160,16 @@ class RPC: profit_str = f'{trade_perc:.2f}%' if self._fiat_converter: fiat_profit = self._fiat_converter.convert_amount( - trade_profit, - stake_currency, - fiat_display_currency - ) + trade_profit, + stake_currency, + fiat_display_currency + ) if fiat_profit and not isnan(fiat_profit): profit_str += f" ({fiat_profit:.2f})" trades_list.append([ trade.id, - trade.pair, + trade.pair + ['', '*'][trade.open_order_id is not None + and trade.close_rate_requested is None], shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ]) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index e9ecdcff6..0dd7a8ffd 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -134,13 +134,18 @@ class Telegram(RPC): msg['stake_amount_fiat'] = 0 message = ("*{exchange}:* Buying {pair}\n" - "at rate `{limit:.8f}\n" - "({stake_amount:.6f} {stake_currency}").format(**msg) + "*Amount:* `{amount:.8f}`\n" + "*Open Rate:* `{limit:.8f}`\n" + "*Current Rate:* `{current_rate:.8f}`\n" + "*Total:* `({stake_amount:.6f} {stake_currency}").format(**msg) if msg.get('fiat_currency', None): - message += ",{stake_amount_fiat:.3f} {fiat_currency}".format(**msg) + message += ", {stake_amount_fiat:.3f} {fiat_currency}".format(**msg) message += ")`" + elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION: + message = "*{exchange}:* Cancelling Buy {pair}".format(**msg) + elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: msg['amount'] = round(msg['amount'], 8) msg['profit_percent'] = round(msg['profit_percent'] * 100, 2) @@ -149,10 +154,10 @@ class Telegram(RPC): msg['duration_min'] = msg['duration'].total_seconds() / 60 message = ("*{exchange}:* Selling {pair}\n" - "*Rate:* `{limit:.8f}`\n" "*Amount:* `{amount:.8f}`\n" "*Open Rate:* `{open_rate:.8f}`\n" "*Current Rate:* `{current_rate:.8f}`\n" + "*Close Rate:* `{limit:.8f}`\n" "*Sell Reason:* `{sell_reason}`\n" "*Duration:* `{duration} ({duration_min:.1f} min)`\n" "*Profit:* `{profit_percent:.2f}%`").format(**msg) @@ -163,8 +168,11 @@ class Telegram(RPC): and self._fiat_converter): msg['profit_fiat'] = self._fiat_converter.convert_amount( msg['profit_amount'], msg['stake_currency'], msg['fiat_currency']) - message += ('` ({gain}: {profit_amount:.8f} {stake_currency}`' - '` / {profit_fiat:.3f} {fiat_currency})`').format(**msg) + message += (' `({gain}: {profit_amount:.8f} {stake_currency}' + ' / {profit_fiat:.3f} {fiat_currency})`').format(**msg) + + elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: + message = "*{exchange}:* Cancelling Sell {pair}".format(**msg) elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION: message = '*Status:* `{status}`'.format(**msg) diff --git a/freqtrade/rpc/webhook.py b/freqtrade/rpc/webhook.py index 37ca466de..1309663d4 100644 --- a/freqtrade/rpc/webhook.py +++ b/freqtrade/rpc/webhook.py @@ -41,8 +41,12 @@ class Webhook(RPC): if msg['type'] == RPCMessageType.BUY_NOTIFICATION: valuedict = self._config['webhook'].get('webhookbuy', None) + elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION: + valuedict = self._config['webhook'].get('webhookbuycancel', None) elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: valuedict = self._config['webhook'].get('webhooksell', None) + elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: + valuedict = self._config['webhook'].get('webhooksellcancel', None) elif msg['type'] in(RPCMessageType.STATUS_NOTIFICATION, RPCMessageType.CUSTOM_NOTIFICATION, RPCMessageType.WARNING_NOTIFICATION): diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 36fce1797..a35bfa0d6 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -122,7 +122,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert "Since" in headers assert "Pair" in headers assert 'instantly' == result[0][2] - assert 'ETH/BTC' == result[0][1] + assert 'ETH/BTC' in result[0][1] assert '-0.59%' == result[0][3] # Test with fiatconvert @@ -131,7 +131,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert "Since" in headers assert "Pair" in headers assert 'instantly' == result[0][2] - assert 'ETH/BTC' == result[0][1] + assert 'ETH/BTC' in result[0][1] assert '-0.59% (-0.09)' == result[0][3] mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', @@ -140,7 +140,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: rpc._freqtrade.exchange._cached_ticker = {} result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert 'instantly' == result[0][2] - assert 'ETH/BTC' == result[0][1] + assert 'ETH/BTC' in result[0][1] assert 'nan%' == result[0][3] diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index ffc29ee12..ae9c0c4dc 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -284,7 +284,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: fields = re.sub('[ ]+', ' ', line[2].strip()).split(' ') assert int(fields[0]) == 1 - assert fields[1] == 'ETH/BTC' + assert 'ETH/BTC' in fields[1] assert msg_mock.call_count == 1 @@ -1200,12 +1200,35 @@ def test_send_msg_buy_notification(default_conf, mocker) -> None: 'stake_amount': 0.001, 'stake_amount_fiat': 0.0, 'stake_currency': 'BTC', - 'fiat_currency': 'USD' + 'fiat_currency': 'USD', + 'current_rate': 1.099e-05, + 'amount': 1333.3333333333335, + 'open_date': arrow.utcnow().shift(hours=-1) }) assert msg_mock.call_args[0][0] \ == '*Bittrex:* Buying ETH/BTC\n' \ - 'at rate `0.00001099\n' \ - '(0.001000 BTC,0.000 USD)`' + '*Amount:* `1333.33333333`\n' \ + '*Open Rate:* `0.00001099`\n' \ + '*Current Rate:* `0.00001099`\n' \ + '*Total:* `(0.001000 BTC, 0.000 USD)`' + + +def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None: + msg_mock = MagicMock() + mocker.patch.multiple( + 'freqtrade.rpc.telegram.Telegram', + _init=MagicMock(), + _send_msg=msg_mock + ) + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + telegram = Telegram(freqtradebot) + telegram.send_msg({ + 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, + 'exchange': 'Bittrex', + 'pair': 'ETH/BTC', + }) + assert msg_mock.call_args[0][0] \ + == ('*Bittrex:* Cancelling Buy ETH/BTC') def test_send_msg_sell_notification(default_conf, mocker) -> None: @@ -1239,13 +1262,13 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: }) assert msg_mock.call_args[0][0] \ == ('*Binance:* Selling KEY/ETH\n' - '*Rate:* `0.00003201`\n' '*Amount:* `1333.33333333`\n' '*Open Rate:* `0.00007500`\n' '*Current Rate:* `0.00003201`\n' + '*Close Rate:* `0.00003201`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `1:00:00 (60.0 min)`\n' - '*Profit:* `-57.41%`` (loss: -0.05746268 ETH`` / -24.812 USD)`') + '*Profit:* `-57.41%` `(loss: -0.05746268 ETH / -24.812 USD)`') msg_mock.reset_mock() telegram.send_msg({ @@ -1267,10 +1290,10 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: }) assert msg_mock.call_args[0][0] \ == ('*Binance:* Selling KEY/ETH\n' - '*Rate:* `0.00003201`\n' '*Amount:* `1333.33333333`\n' '*Open Rate:* `0.00007500`\n' '*Current Rate:* `0.00003201`\n' + '*Close Rate:* `0.00003201`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `1 day, 2:30:00 (1590.0 min)`\n' '*Profit:* `-57.41%`') @@ -1278,6 +1301,37 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: telegram._fiat_converter.convert_amount = old_convamount +def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None: + msg_mock = MagicMock() + mocker.patch.multiple( + 'freqtrade.rpc.telegram.Telegram', + _init=MagicMock(), + _send_msg=msg_mock + ) + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + telegram = Telegram(freqtradebot) + old_convamount = telegram._fiat_converter.convert_amount + telegram._fiat_converter.convert_amount = lambda a, b, c: -24.812 + telegram.send_msg({ + 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, + 'exchange': 'Binance', + 'pair': 'KEY/ETH', + }) + assert msg_mock.call_args[0][0] \ + == ('*Binance:* Cancelling Sell KEY/ETH') + + msg_mock.reset_mock() + telegram.send_msg({ + 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, + 'exchange': 'Binance', + 'pair': 'KEY/ETH', + }) + assert msg_mock.call_args[0][0] \ + == ('*Binance:* Cancelling Sell KEY/ETH') + # Reset singleton function to avoid random breaks + telegram._fiat_converter.convert_amount = old_convamount + + def test_send_msg_status_notification(default_conf, mocker) -> None: msg_mock = MagicMock() mocker.patch.multiple( @@ -1360,12 +1414,17 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None: 'stake_amount': 0.001, 'stake_amount_fiat': 0.0, 'stake_currency': 'BTC', - 'fiat_currency': None + 'fiat_currency': None, + 'current_rate': 1.099e-05, + 'amount': 1333.3333333333335, + 'open_date': arrow.utcnow().shift(hours=-1) }) assert msg_mock.call_args[0][0] \ == '*Bittrex:* Buying ETH/BTC\n' \ - 'at rate `0.00001099\n' \ - '(0.001000 BTC)`' + '*Amount:* `1333.33333333`\n' \ + '*Open Rate:* `0.00001099`\n' \ + '*Current Rate:* `0.00001099`\n' \ + '*Total:* `(0.001000 BTC)`' def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None: @@ -1398,10 +1457,10 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None: }) assert msg_mock.call_args[0][0] \ == '*Binance:* Selling KEY/ETH\n' \ - '*Rate:* `0.00003201`\n' \ '*Amount:* `1333.33333333`\n' \ '*Open Rate:* `0.00007500`\n' \ '*Current Rate:* `0.00003201`\n' \ + '*Close Rate:* `0.00003201`\n' \ '*Sell Reason:* `stop_loss`\n' \ '*Duration:* `2:35:03 (155.1 min)`\n' \ '*Profit:* `-57.41%`' diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index c066aa8e7..3b9ce3f0d 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -13,24 +13,34 @@ from tests.conftest import get_patched_freqtradebot, log_has def get_webhook_dict() -> dict: return { - "enabled": True, - "url": "https://maker.ifttt.com/trigger/freqtrade_test/with/key/c764udvJ5jfSlswVRukZZ2/", - "webhookbuy": { - "value1": "Buying {pair}", - "value2": "limit {limit:8f}", - "value3": "{stake_amount:8f} {stake_currency}" - }, - "webhooksell": { - "value1": "Selling {pair}", - "value2": "limit {limit:8f}", - "value3": "profit: {profit_amount:8f} {stake_currency}" - }, - "webhookstatus": { - "value1": "Status: {status}", - "value2": "", - "value3": "" - } - } + "enabled": True, + "url": "https://maker.ifttt.com/trigger/freqtrade_test/with/key/c764udvJ5jfSlswVRukZZ2/", + "webhookbuy": { + "value1": "Buying {pair}", + "value2": "limit {limit:8f}", + "value3": "{stake_amount:8f} {stake_currency}" + }, + "webhookbuycancel": { + "value1": "Cancelling Buy {pair}", + "value2": "limit {limit:8f}", + "value3": "{stake_amount:8f} {stake_currency}" + }, + "webhooksell": { + "value1": "Selling {pair}", + "value2": "limit {limit:8f}", + "value3": "profit: {profit_amount:8f} {stake_currency}" + }, + "webhooksellcancel": { + "value1": "Cancelling Sell {pair}", + "value2": "limit {limit:8f}", + "value3": "profit: {profit_amount:8f} {stake_currency}" + }, + "webhookstatus": { + "value1": "Status: {status}", + "value2": "", + "value3": "" + } + } def test__init__(mocker, default_conf): diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index f334e4eb0..429d3599d 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -300,7 +300,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf # stoploss shoud be hit assert freqtrade.handle_trade(trade) is True - assert log_has('executed sell, reason: SellType.STOP_LOSS', caplog) + assert log_has('Executed Sell for NEO/BTC. Reason: SellType.STOP_LOSS', caplog) assert trade.sell_reason == SellType.STOP_LOSS.value @@ -1964,7 +1964,7 @@ def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old, o trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() nb_trades = len(trades) assert nb_trades == 0 - assert log_has_re("Buy order canceled on Exchange for Trade.*", caplog) + assert log_has_re("Buy order cancelled on exchange for Trade.*", caplog) def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_order_old, open_trade, @@ -2045,7 +2045,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old, assert cancel_order_mock.call_count == 0 assert rpc_mock.call_count == 1 assert open_trade.is_open is True - assert log_has_re("Sell order canceled on exchange for Trade.*", caplog) + assert log_has_re("Sell order cancelled on exchange for Trade.*", caplog) def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old_partial, From 4fad7a462cc067c6c91aaa5b970de881025a9f07 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 8 Feb 2020 21:19:07 +0100 Subject: [PATCH 0437/1106] fixes in webhook-config docs --- docs/webhook-config.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/webhook-config.md b/docs/webhook-config.md index 878b18e8a..b287fa71e 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -51,11 +51,11 @@ Possible parameters are: * `pair` * `limit` * `amount` +* `open_date` * `stake_amount` * `stake_currency` * `fiat_currency` * `order_type` -* `open_rate` * `current_rate` ### Webhookbuycancel @@ -67,11 +67,11 @@ Possible parameters are: * `pair` * `limit` * `amount` +* `open_date` * `stake_amount` * `stake_currency` * `fiat_currency` * `order_type` -* `open_rate` * `current_rate` ### Webhooksell @@ -86,7 +86,6 @@ Possible parameters are: * `amount` * `open_rate` * `current_rate` -* `close_rate` * `profit_amount` * `profit_percent` * `stake_currency` @@ -108,7 +107,6 @@ Possible parameters are: * `amount` * `open_rate` * `current_rate` -* `close_rate` * `profit_amount` * `profit_percent` * `stake_currency` @@ -116,6 +114,7 @@ Possible parameters are: * `sell_reason` * `order_type` * `open_date` +* `close_date` ### Webhookstatus From 879b5138228cc2052ab6bff3fd913080686828e6 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 8 Feb 2020 21:31:36 +0100 Subject: [PATCH 0438/1106] enhanced method description --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 2f57ca41b..5f1024f8c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -452,7 +452,7 @@ class FreqtradeBot: """ Executes a limit buy for the given pair :param pair: pair for which we want to create a LIMIT_BUY - :return: bool + :return: True if a buy order is created, false if it fails. """ time_in_force = self.strategy.order_time_in_force['buy'] @@ -966,7 +966,7 @@ class FreqtradeBot: :param trade: Trade instance :param limit: limit rate for the sell order :param sellreason: Reason the sell was triggered - :return: bool + :return: True if it succeeds (supported) False (not supported) """ sell_type = 'sell' if sell_reason in (SellType.STOP_LOSS, SellType.TRAILING_STOP_LOSS): From 1a9787ac76d6df1f337c1889ccf3135ae8cdaa13 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 8 Feb 2020 21:53:34 +0100 Subject: [PATCH 0439/1106] Add validation for data-download relevant settings --- freqtrade/commands/data_commands.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index aee144505..e8e0f06d2 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -38,6 +38,11 @@ def start_download_data(args: Dict[str, Any]) -> None: # Init exchange exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + # Manual validations of relevant settings + exchange.validate_pairs(config['pairs']) + for timeframe in config['timeframes']: + exchange.validate_timeframes(timeframe) + try: if config.get('download_trades'): From 636bd5acb5e8b66dab60879c50343a26dc8e15c6 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Sat, 8 Feb 2020 23:21:42 +0100 Subject: [PATCH 0440/1106] Added filter options to "hyperopt-list" in order to easier find epochs. --profitable Select only profitable epochs. --min-avg-time INT Select epochs on above average time. --max-avg-time INT Select epochs on under average time. --min-avg-profit FLOAT Select epochs on above average profit. --min-total-profit FLOAT Select epochs on above total profit. --- docs/utils.md | 24 +++++++++--- freqtrade/commands/arguments.py | 3 +- freqtrade/commands/cli_options.py | 24 ++++++++++++ freqtrade/commands/hyperopt_commands.py | 47 ++++++++++++++++++------ freqtrade/configuration/configuration.py | 12 ++++++ 5 files changed, 91 insertions(+), 19 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index b0559f9cc..71039f174 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -135,15 +135,27 @@ Common arguments: ``` ``` freqtrade list-hyperopts --help -usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] - [--hyperopt-path PATH] [-1] +usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--best] + [--profitable] [--min-avg-time INT] + [--max-avg-time INT] [--min-avg-profit FLOAT] + [--min-total-profit FLOAT] [--no-color] + [--print-json] [--no-details] optional arguments: -h, --help show this help message and exit - --hyperopt-path PATH Specify additional lookup path for Hyperopt and - Hyperopt Loss functions. - -1, --one-column Print output in one column. + --best Select only best epochs. + --profitable Select only profitable epochs. + --min-avg-time INT Select epochs on above average time. + --max-avg-time INT Select epochs on under average time. + --min-avg-profit FLOAT + Select epochs on above average profit. + --min-total-profit FLOAT + Select epochs on above total profit. + --no-color Disable colorization of hyperopt results. May be + useful if you are redirecting output to a file. + --print-json Print best result detailization in JSON format. + --no-details Do not print best epoch details. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 1931a51be..2d02058f1 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -59,7 +59,8 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] -ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "print_colorized", +ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", + "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 6d8d13129..0c6d64691 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -398,6 +398,30 @@ AVAILABLE_CLI_OPTIONS = { help='Select only best epochs.', action='store_true', ), + "hyperopt_list_min_avg_time": Arg( + '--min-avg-time', + help='Select epochs on above average time.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_max_avg_time": Arg( + '--max-avg-time', + help='Select epochs on under average time.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_min_avg_profit": Arg( + '--min-avg-profit', + help='Select epochs on above average profit.', + type=float, + metavar='FLOAT', + ), + "hyperopt_list_min_total_profit": Arg( + '--min-total-profit', + help='Select epochs on above total profit.', + type=float, + metavar='FLOAT', + ), "hyperopt_list_no_details": Arg( '--no-details', help='Do not print best epoch details.', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 5c6f25848..8472fcfe1 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -19,13 +19,20 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False + filteroptions = { + 'only_best': config.get('hyperopt_list_best', False), + 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0.0), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0.0) + } + trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') @@ -33,7 +40,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + trials = _hyperopt_filter_trials(trials, filteroptions) # TODO: fetch the interval for epochs to print from the cli option epoch_start, epoch_stop = 0, None @@ -44,7 +51,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: try: # Human-friendly indexes used here (starting from 1) for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, not only_best, print_colorized) + Hyperopt.print_results_explanation(val, total_epochs, not filteroptions['only_best'], print_colorized) except KeyboardInterrupt: print('User interrupted..') @@ -63,8 +70,14 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) + filteroptions = { + 'only_best': config.get('hyperopt_list_best', False), + 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0) + } no_header = config.get('hyperopt_show_no_header', False) trials_file = (config['user_data_dir'] / @@ -74,7 +87,7 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + trials = _hyperopt_filter_trials(trials, filteroptions) trials_epochs = len(trials) n = config.get('hyperopt_show_index', -1) @@ -97,18 +110,28 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: header_str="Epoch details") -def _hyperopt_filter_trials(trials: List, only_best: bool, only_profitable: bool) -> List: +def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: """ Filter our items from the list of hyperopt results """ - if only_best: + if filteroptions['only_best']: trials = [x for x in trials if x['is_best']] - if only_profitable: + if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] + if not filteroptions['only_best']: + if filteroptions['filter_min_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time']] + if filteroptions['filter_max_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time']] + if filteroptions['filter_min_avg_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit']] + if filteroptions['filter_min_total_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit']] + logger.info(f"{len(trials)} " + - ("best " if only_best else "") + - ("profitable " if only_profitable else "") + + ("best " if filteroptions['only_best'] else "") + + ("profitable " if filteroptions['only_profitable'] else "") + "epochs found.") return trials diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index a8b7638c8..f7e87f3a1 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -310,6 +310,18 @@ class Configuration: self._args_to_config(config, argname='hyperopt_list_profitable', logstring='Parameter --profitable detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_avg_time', + logstring='Parameter --min-avg-time detected: {}') + + self._args_to_config(config, argname='hyperopt_list_max_avg_time', + logstring='Parameter --max-avg-time detected: {}') + + self._args_to_config(config, argname='hyperopt_list_min_avg_profit', + logstring='Parameter --min-avg-profit detected: {}') + + self._args_to_config(config, argname='hyperopt_list_min_total_profit', + logstring='Parameter --min-total-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_no_details', logstring='Parameter --no-details detected: {}') From 2796d3d8a0c1af2c297170f030cc5cfbb4b9c924 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sun, 9 Feb 2020 00:11:58 +0100 Subject: [PATCH 0441/1106] added missing tests to increase coverage --- tests/rpc/test_rpc_webhook.py | 53 +++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index 3b9ce3f0d..ab40047c0 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -54,6 +54,9 @@ def test_send_msg(default_conf, mocker): msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) + # Test buy + msg_mock = MagicMock() + mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': 'Bittrex', @@ -64,8 +67,6 @@ def test_send_msg(default_conf, mocker): 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } - msg_mock = MagicMock() - mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == @@ -74,6 +75,27 @@ def test_send_msg(default_conf, mocker): default_conf["webhook"]["webhookbuy"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookbuy"]["value3"].format(**msg)) + # Test buy cancel + msg_mock = MagicMock() + mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) + msg = { + 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, + 'exchange': 'Bittrex', + 'pair': 'ETH/BTC', + 'limit': 0.005, + 'stake_amount': 0.8, + 'stake_amount_fiat': 500, + 'stake_currency': 'BTC', + 'fiat_currency': 'EUR' + } + webhook.send_msg(msg=msg) + assert msg_mock.call_count == 1 + assert (msg_mock.call_args[0][0]["value1"] == + default_conf["webhook"]["webhookbuycancel"]["value1"].format(**msg)) + assert (msg_mock.call_args[0][0]["value2"] == + default_conf["webhook"]["webhookbuycancel"]["value2"].format(**msg)) + assert (msg_mock.call_args[0][0]["value3"] == + default_conf["webhook"]["webhookbuycancel"]["value3"].format(**msg)) # Test sell msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) @@ -100,7 +122,32 @@ def test_send_msg(default_conf, mocker): default_conf["webhook"]["webhooksell"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhooksell"]["value3"].format(**msg)) - + # Test sell cancel + msg_mock = MagicMock() + mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) + msg = { + 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, + 'exchange': 'Bittrex', + 'pair': 'ETH/BTC', + 'gain': "profit", + 'limit': 0.005, + 'amount': 0.8, + 'order_type': 'limit', + 'open_rate': 0.004, + 'current_rate': 0.005, + 'profit_amount': 0.001, + 'profit_percent': 0.20, + 'stake_currency': 'BTC', + 'sell_reason': SellType.STOP_LOSS.value + } + webhook.send_msg(msg=msg) + assert msg_mock.call_count == 1 + assert (msg_mock.call_args[0][0]["value1"] == + default_conf["webhook"]["webhooksellcancel"]["value1"].format(**msg)) + assert (msg_mock.call_args[0][0]["value2"] == + default_conf["webhook"]["webhooksellcancel"]["value2"].format(**msg)) + assert (msg_mock.call_args[0][0]["value3"] == + default_conf["webhook"]["webhooksellcancel"]["value3"].format(**msg)) for msgtype in [RPCMessageType.STATUS_NOTIFICATION, RPCMessageType.WARNING_NOTIFICATION, RPCMessageType.CUSTOM_NOTIFICATION]: From c96acd6ca02b6e0dc5cd1e28c78ad0b3be648fe1 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Sun, 9 Feb 2020 00:16:11 +0100 Subject: [PATCH 0442/1106] Fixed to pass PEP8 --- freqtrade/commands/arguments.py | 7 ++++--- freqtrade/commands/hyperopt_commands.py | 28 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 2d02058f1..6d0c16d88 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -59,9 +59,10 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] -ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", - "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", "print_colorized", - "print_json", "hyperopt_list_no_details"] +ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", + "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", + "hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", + "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 8472fcfe1..f5fcc971f 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -32,7 +32,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0.0), 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0.0) } - + trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') @@ -51,7 +51,8 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: try: # Human-friendly indexes used here (starting from 1) for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, not filteroptions['only_best'], print_colorized) + Hyperopt.print_results_explanation(val, total_epochs, + not filteroptions['only_best'], print_colorized) except KeyboardInterrupt: print('User interrupted..') @@ -121,14 +122,27 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: if not filteroptions['only_best']: if filteroptions['filter_min_avg_time'] > 0: - trials = [x for x in trials if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time']] + trials = [ + x for x in trials + if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] + ] if filteroptions['filter_max_avg_time'] > 0: - trials = [x for x in trials if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time']] + trials = [ + x for x in trials + if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] + ] if filteroptions['filter_min_avg_profit'] > 0: - trials = [x for x in trials if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit']] + trials = [ + x for x in trials + if x['results_metrics']['avg_profit'] + > filteroptions['filter_min_avg_profit'] + ] if filteroptions['filter_min_total_profit'] > 0: - trials = [x for x in trials if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit']] - + trials = [ + x for x in trials + if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] + ] + logger.info(f"{len(trials)} " + ("best " if filteroptions['only_best'] else "") + ("profitable " if filteroptions['only_profitable'] else "") + From b536d501945c502ecc6003f7fea8ffc781f45f02 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 9 Feb 2020 11:41:29 +0100 Subject: [PATCH 0443/1106] Address PR Review --- freqtrade/commands/build_config_commands.py | 4 ++-- freqtrade/templates/base_config.json.j2 | 2 +- setup.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 7dd1be607..1598fa2ae 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -187,7 +187,7 @@ def start_new_config(args: Dict[str, Any]) -> None: config_path.unlink() else: raise OperationalException( - f"Configuration `{config_path}` already exists. " - "Please use another configuration name or delete the existing configuration.") + f"Configuration file `{config_path}` already exists. " + "Please delete it or use a different configuration file name.") selections = ask_user_config() deploy_new_config(config_path, selections) diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index 0a4f92c4b..88edeb1e8 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -19,7 +19,7 @@ "bids_to_ask_delta": 1 } }, - "ask_strategy":{ + "ask_strategy": { "use_order_book": false, "order_book_min": 1, "order_book_max": 9, diff --git a/setup.sh b/setup.sh index bce2e56cf..e120190ce 100755 --- a/setup.sh +++ b/setup.sh @@ -223,7 +223,7 @@ function config_generator() { function config() { echo "-------------------------" - echo "Please use freqtrade new-config -c config.json to generate a new configuration file." + echo "Please use 'freqtrade new-config -c config.json' to generate a new configuration file." echo "-------------------------" } From c7ba85c2e6c244f861a9e914782d5d5d14f30837 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 14:19:13 +0300 Subject: [PATCH 0444/1106] Add tip on running order types for Bittrex --- docs/faq.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 2416beae4..390b35b9b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -45,12 +45,24 @@ the tutorial [here|Testing-new-strategies-with-Hyperopt](bot-usage.md#hyperopt-c You can use the `/forcesell all` command from Telegram. -### I get the message "RESTRICTED_MARKET" +### I'm getting the "RESTRICTED_MARKET" message in the log Currently known to happen for US Bittrex users. Read [the Bittrex section about restricted markets](exchanges.md#restricted-markets) for more information. +### I'm getting the "Exchange Bittrex does not support market orders." message and cannot run my strategy + +As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written for another exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of other exchanges. + +To fix it for Bittrex, redefine order types in the configuration file (do this for all order types that are defined as "market" in your strategy): + +``` +"order_types": { + "stoploss": "limit", +} +``` + ### How do I search the bot logs for something? By default, the bot writes its log into stderr stream. This is implemented this way so that you can easily separate the bot's diagnostics messages from Backtesting, Edge and Hyperopt results, output from other various Freqtrade utility subcommands, as well as from the output of your custom `print()`'s you may have inserted into your strategy. So if you need to search the log messages with the grep utility, you need to redirect stderr to stdout and disregard stdout. From c648ec7c0c76e09d57bee0e52bf820bb0d9adf01 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Sun, 9 Feb 2020 14:18:56 +0100 Subject: [PATCH 0445/1106] Added test cases and fixed a minor bug --- freqtrade/commands/hyperopt_commands.py | 6 +++ tests/commands/test_commands.py | 59 ++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index f5fcc971f..38e1fa429 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -120,24 +120,30 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] + print(trials[0]) + if not filteroptions['only_best']: if filteroptions['filter_min_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ x for x in trials if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] ] if filteroptions['filter_max_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ x for x in trials if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] ] if filteroptions['filter_min_avg_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ x for x in trials if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit'] ] if filteroptions['filter_min_total_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ x for x in trials if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index c59799190..fb15c3d7f 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -778,7 +778,64 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) - + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--min-avg-profit", "0.11" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 10/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--no-details", + "--min-total-profit", "0.4" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 10/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", + " 9/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--min-avg-time", "2000" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 10/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", + " 8/12", " 9/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--no-details", + "--max-avg-time", "1500" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 6/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" + " 9/12", " 10/12", " 11/12", " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): mocker.patch( From eb3783dc0095740ccf973cbec351a67951cfcda5 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Sun, 9 Feb 2020 14:30:29 +0100 Subject: [PATCH 0446/1106] Fixed a blank line issue :-( --- tests/commands/test_commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index fb15c3d7f..db8a9289a 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -837,6 +837,7 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) + def test_hyperopt_show(mocker, capsys, hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.load_previous_results', From c89a32224c2f77fa14aa2244dfcd23ab9f7ea56d Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 18:40:19 +0300 Subject: [PATCH 0447/1106] Fix SharpeHyperOptLossDaily --- freqtrade/optimize/hyperopt_loss_sharpe_daily.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py index d8ea3c5fe..5a8ebaa11 100644 --- a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py @@ -39,7 +39,8 @@ class SharpeHyperOptLossDaily(IHyperOptLoss): results['profit_percent'] - slippage_per_trade_ratio # create the index within the min_date and end max_date - t_index = date_range(start=min_date, end=max_date, freq=resample_freq) + t_index = date_range(start=min_date, end=max_date, freq=resample_freq, + normalize=True) sum_daily = ( results.resample(resample_freq, on='close_time').agg( From 40abdd26083f20e6fb05a1facae694b91724ba85 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 18:54:04 +0300 Subject: [PATCH 0448/1106] Suggest changing strategy --- docs/faq.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 390b35b9b..81fd47561 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -55,14 +55,18 @@ Read [the Bittrex section about restricted markets](exchanges.md#restricted-mark As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written for another exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of other exchanges. -To fix it for Bittrex, redefine order types in the configuration file (do this for all order types that are defined as "market" in your strategy): +To fix it for Bittrex, redefine order types in the strategy to use "limit" instead of "market": ``` -"order_types": { - "stoploss": "limit", -} + order_types = { + ... + 'stoploss': 'limit', + ... + } ``` +Same fix should be done in the configuration file, if order types are defined in your custom config rather than in the strategy. + ### How do I search the bot logs for something? By default, the bot writes its log into stderr stream. This is implemented this way so that you can easily separate the bot's diagnostics messages from Backtesting, Edge and Hyperopt results, output from other various Freqtrade utility subcommands, as well as from the output of your custom `print()`'s you may have inserted into your strategy. So if you need to search the log messages with the grep utility, you need to redirect stderr to stdout and disregard stdout. From c83da7cadb4db3c0c7d59d4e787d80e7c876e79c Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 19:11:06 +0300 Subject: [PATCH 0449/1106] Add section about order types into Bittrex Exchange-specific chapter --- docs/exchanges.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/exchanges.md b/docs/exchanges.md index 3c861ce44..06d33d562 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -32,6 +32,10 @@ To download data for the Kraken exchange, using `--dl-trades` is mandatory, othe ## Bittrex +### Order types + +Bittrex does not support market orders. If you have a message at the bot startup about this, you should change order type values set in your configuration and/or in the strategy from `"market"` to `"limit"`. See some more details on this [here in the FAQ](faw.md#im-getting-the-exchange-bittrex-does-not-support-market-orders-message-and-cannot-run-my-strategy). + ### Restricted markets Bittrex split its exchange into US and International versions. From cc3f65d069ddaa08ffa81e76a155f471adc37f9b Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 19:45:04 +0300 Subject: [PATCH 0450/1106] Fix typo --- docs/exchanges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index 06d33d562..f615bc61a 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -34,7 +34,7 @@ To download data for the Kraken exchange, using `--dl-trades` is mandatory, othe ### Order types -Bittrex does not support market orders. If you have a message at the bot startup about this, you should change order type values set in your configuration and/or in the strategy from `"market"` to `"limit"`. See some more details on this [here in the FAQ](faw.md#im-getting-the-exchange-bittrex-does-not-support-market-orders-message-and-cannot-run-my-strategy). +Bittrex does not support market orders. If you have a message at the bot startup about this, you should change order type values set in your configuration and/or in the strategy from `"market"` to `"limit"`. See some more details on this [here in the FAQ](faq.md#im-getting-the-exchange-bittrex-does-not-support-market-orders-message-and-cannot-run-my-strategy). ### Restricted markets From 9ec9a7b124a05c4f25905e8b391d06b2ec17cc26 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 21:20:15 +0300 Subject: [PATCH 0451/1106] Fix t_index to be normalized --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 891e2bf1c..c02f88434 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -39,7 +39,8 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): results['profit_percent'] - slippage_per_trade_ratio # create the index within the min_date and end max_date - t_index = date_range(start=min_date, end=max_date, freq=resample_freq) + t_index = date_range(start=min_date, end=max_date, freq=resample_freq, + normalize=True) sum_daily = ( results.resample(resample_freq, on='close_time').agg( From 5bf4c5869b81c39176efc7fe6705cebb02a7f489 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 9 Feb 2020 19:32:09 +0100 Subject: [PATCH 0452/1106] Update hyperopt_commands.py Missed a debug print --- freqtrade/commands/hyperopt_commands.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 38e1fa429..cdfdb5ca6 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -120,8 +120,6 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] - print(trials[0]) - if not filteroptions['only_best']: if filteroptions['filter_min_avg_time'] > 0: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] From f7c74e551fa4ff0674576de73a7892fdd32d1bfb Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 9 Feb 2020 21:56:59 +0300 Subject: [PATCH 0453/1106] Fix wording --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 81fd47561..94818964b 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -53,7 +53,7 @@ Read [the Bittrex section about restricted markets](exchanges.md#restricted-mark ### I'm getting the "Exchange Bittrex does not support market orders." message and cannot run my strategy -As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written for another exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of other exchanges. +As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Bittrex). To fix it for Bittrex, redefine order types in the strategy to use "limit" instead of "market": From 4af25ec315c95a9335285d9375b544f0f23b1a46 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 10 Feb 2020 05:52:07 +0300 Subject: [PATCH 0454/1106] Adjust mypy and flake commands --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a087103c6..a4a1a29f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ pytest tests/test_.py::test_ #### Run Flake8 ```bash -flake8 freqtrade +flake8 freqtrade tests ``` We receive a lot of code that fails the `flake8` checks. @@ -61,7 +61,7 @@ Guide for installing them is [here](http://flake8.pycqa.org/en/latest/user/using #### Run mypy ``` bash -mypy freqtrade +mypy freqtrade tests ``` ## (Core)-Committer Guide From 90ee82ac437cbe1711d70d3663e986a8acce2fe8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:01:42 +0000 Subject: [PATCH 0455/1106] Bump ccxt from 1.22.30 to 1.22.39 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.30 to 1.22.39. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.22.30...1.22.39) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 466880950..e1ae4a5bd 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.22.30 +ccxt==1.22.39 SQLAlchemy==1.3.13 python-telegram-bot==12.3.0 arrow==0.15.5 From 88f2ad1eae978f9e95e4b20c5c262dc5f97fb298 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:02:07 +0000 Subject: [PATCH 0456/1106] Bump pandas from 1.0.0 to 1.0.1 Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md) - [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.0...v1.0.1) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 21be02a87..68024f587 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ -r requirements-common.txt numpy==1.18.1 -pandas==1.0.0 +pandas==1.0.1 From 6b4094fd92866065ca0717f330e64dc29c5305b1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:02:45 +0000 Subject: [PATCH 0457/1106] Bump mkdocs-material from 4.6.0 to 4.6.2 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.0 to 4.6.2. - [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/4.6.0...4.6.2) Signed-off-by: dependabot-preview[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 3e53c15e3..3980ecd64 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==4.6.0 +mkdocs-material==4.6.2 mdx_truly_sane_lists==1.2 From 550f9fc8915841eef544bb51302d4c10553e2794 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:45:27 +0000 Subject: [PATCH 0458/1106] Bump python-telegram-bot from 12.3.0 to 12.4.1 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.3.0 to 12.4.1. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.3.0...v12.4.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e1ae4a5bd..f641dd2ad 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.22.39 SQLAlchemy==1.3.13 -python-telegram-bot==12.3.0 +python-telegram-bot==12.4.1 arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 From 83644ce5d8502ddc99c5d24a46a33750cf7745bf Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 10 Feb 2020 10:35:48 +0100 Subject: [PATCH 0459/1106] Fix mypy type errors in tests --- tests/data/test_history.py | 6 +++--- tests/optimize/__init__.py | 2 +- tests/optimize/test_backtesting.py | 4 ++-- tests/optimize/test_edge_cli.py | 4 ++-- tests/optimize/test_hyperopt.py | 22 ++++++++++++---------- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 7b3143db9..da4c90191 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -370,7 +370,7 @@ def test_load_partial_missing(testdatadir, caplog) -> None: def test_init(default_conf, mocker) -> None: assert {} == load_data( - datadir='', + datadir=Path(''), pairs=[], timeframe=default_conf['ticker_interval'] ) @@ -379,13 +379,13 @@ def test_init(default_conf, mocker) -> None: def test_init_with_refresh(default_conf, mocker) -> None: exchange = get_patched_exchange(mocker, default_conf) refresh_data( - datadir='', + datadir=Path(''), pairs=[], timeframe=default_conf['ticker_interval'], exchange=exchange ) assert {} == load_data( - datadir='', + datadir=Path(''), pairs=[], timeframe=default_conf['ticker_interval'] ) diff --git a/tests/optimize/__init__.py b/tests/optimize/__init__.py index 8756143a0..524db093e 100644 --- a/tests/optimize/__init__.py +++ b/tests/optimize/__init__.py @@ -23,7 +23,7 @@ class BTContainer(NamedTuple): """ Minimal BacktestContainer defining Backtest inputs and results. """ - data: List[float] + data: List[List[float]] stop_loss: float roi: Dict[str, float] trades: List[BTrade] diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 07872da57..ec85c8030 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -287,8 +287,8 @@ def test_start(mocker, fee, default_conf, caplog) -> None: '--config', 'config.json', '--strategy', 'DefaultStrategy', ] - args = get_args(args) - start_backtesting(args) + pargs = get_args(args) + start_backtesting(pargs) assert log_has('Starting freqtrade in Backtesting mode', caplog) assert start_mock.call_count == 1 diff --git a/tests/optimize/test_edge_cli.py b/tests/optimize/test_edge_cli.py index 96dd0899d..a5e468542 100644 --- a/tests/optimize/test_edge_cli.py +++ b/tests/optimize/test_edge_cli.py @@ -82,8 +82,8 @@ def test_start(mocker, fee, edge_conf, caplog) -> None: '--config', 'config.json', '--strategy', 'DefaultStrategy', ] - args = get_args(args) - start_edge(args) + pargs = get_args(args) + start_edge(pargs) assert log_has('Starting freqtrade in Edge mode', caplog) assert start_mock.call_count == 1 diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index b3356bd6d..1780b5155 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -2,6 +2,7 @@ import locale from datetime import datetime from pathlib import Path +from typing import Dict, List from unittest.mock import MagicMock, PropertyMock import pandas as pd @@ -9,7 +10,8 @@ import pytest from arrow import Arrow from filelock import Timeout -from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_hyperopt +from freqtrade.commands.optimize_commands import (setup_optimize_configuration, + start_hyperopt) from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.exceptions import OperationalException @@ -54,7 +56,7 @@ def hyperopt_results(): # Functions for recurrent object patching -def create_trials(mocker, hyperopt, testdatadir) -> None: +def create_trials(mocker, hyperopt, testdatadir) -> List[Dict]: """ When creating trials, mock the hyperopt Trials so that *by default* - we don't create any pickle'd files in the filesystem @@ -228,10 +230,10 @@ def test_start_not_installed(mocker, default_conf, caplog, import_fails) -> None '--hyperopt', 'DefaultHyperOpt', '--epochs', '5' ] - args = get_args(args) + pargs = get_args(args) with pytest.raises(OperationalException, match=r"Please ensure that the hyperopt dependencies"): - start_hyperopt(args) + start_hyperopt(pargs) def test_start(mocker, default_conf, caplog) -> None: @@ -246,8 +248,8 @@ def test_start(mocker, default_conf, caplog) -> None: '--hyperopt', 'DefaultHyperOpt', '--epochs', '5' ] - args = get_args(args) - start_hyperopt(args) + pargs = get_args(args) + start_hyperopt(pargs) assert log_has('Starting freqtrade in Hyperopt mode', caplog) assert start_mock.call_count == 1 @@ -269,9 +271,9 @@ def test_start_no_data(mocker, default_conf, caplog) -> None: '--hyperopt', 'DefaultHyperOpt', '--epochs', '5' ] - args = get_args(args) + pargs = get_args(args) with pytest.raises(OperationalException, match='No data found. Terminating.'): - start_hyperopt(args) + start_hyperopt(pargs) def test_start_filelock(mocker, default_conf, caplog) -> None: @@ -286,8 +288,8 @@ def test_start_filelock(mocker, default_conf, caplog) -> None: '--hyperopt', 'DefaultHyperOpt', '--epochs', '5' ] - args = get_args(args) - start_hyperopt(args) + pargs = get_args(args) + start_hyperopt(pargs) assert log_has("Another running instance of freqtrade Hyperopt detected.", caplog) From 7bb02d0cc60074fd668a8e498c81f167fa74198e Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 10 Feb 2020 11:01:33 +0100 Subject: [PATCH 0460/1106] Update docker-docs wording --- docs/docker.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/docker.md b/docs/docker.md index b1eb0b298..6267c0cf2 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -27,8 +27,8 @@ Freqtrade provides an official Docker image on [Dockerhub](https://hub.docker.co Create a new directory and place the [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) in this directory. ``` bash -mkdir freqtrade -cd freqtrade/ +mkdir ft_userdata +cd ft_userdata/ # Download the docker-compose file from the repository curl https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docker-compose.yml -o docker-compose.yml @@ -42,15 +42,22 @@ docker-compose run --rm freqtrade create-userdir --userdir user_data docker-compose run --rm freqtrade new-config --config user_data/config.json ``` -The above snippet will create a directory called "freqtrade" - download the latest compose file and pull the freqtrade image. -The last 2 steps will create the user-directory, as well as a default configuration based on your selections. +The above snippet creates a new directory called "ft_userdata", downloads the latest compose file and pulls the freqtrade image. +The last 2 steps in the snippet create the directory with user-data, as well as (interactively) the default configuration based on your selections. + +!!! Note + You can edit the configuration at any time, which is available as `user_data/config.json` (within the directory `ft_userdata`) when using the above configuration. #### Adding your strategy The configuration is now available as `user_data/config.json`. -You should now copy your strategy to `user_data/strategies/` - and add the Strategy class name to the `docker-compose.yml` file, replacing `SampleStrategy`. +You should now copy your strategy to `user_data/strategies/` - and add the Strategy class name to the `docker-compose.yml` file, replacing `SampleStrategy`. If you wish to run the bot with the SampleStrategy, just leave it as it is. -Once this is done, you're ready to launch the bot in trading mode. +!!! Warning + The `SampleStrategy` is there for your reference and give you ideas for your own strategy. + Please always backtest the strategy and use dry-run for some time before risking real money! + +Once this is done, you're ready to launch the bot in trading mode (Dry-run or Live-trading, depending on your answer to the corresponding question you made above). ``` bash docker-compose up -d @@ -88,11 +95,11 @@ Advanced users may edit the docker-compose file further to include all possible All possible freqtrade arguments will be available by running `docker-compose run --rm freqtrade `. !!! Note "`docker-compose run --rm`" - Inluding `--rm` will clean up the container after completion, and is highly recommended for all modes except trading mode (`freqtrade trade`). + Including `--rm` will clean up the container after completion, and is highly recommended for all modes except trading mode (running with `freqtrade trade` command). ##### Example: Download data with docker-compose -Downloading backtest data for one pair from binance. The data will be stored in the host directory `user_data/data/`. +Download backtesting data for 5 days for the pair ETH/BTC and 1h timeframe from Binance. The data will be stored in the directory `user_data/data/` on the host. ``` bash docker-compose run --rm freqtrade download-data --pairs ETH/BTC --exchange binance --days 5 -t 1h @@ -102,7 +109,7 @@ Head over to the [Data Downloading Documentation](data-download.md) for more det ##### Example: Backtest with docker-compose -Backtesting in docker-containers: +Run backtesting in docker-containers for SampleStrategy and specified timerange of historical data, on 5m timeframe: ``` bash docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy SampleStrategy --timerange 20190801-20191001 -i 5m @@ -126,7 +133,7 @@ You'll then also need to modify the `docker-compose.yml` file and uncomment the You can then run `docker-compose build` to build the docker image, and run it using the commands described above. -## Docker - without docker compose +## Freqtrade with docker without docker-compose !!! Warning The below documentation is provided for completeness and assumes that you are somewhat familiar with running docker containers. If you're just starting out with docker, we recommend to follow the [Freqtrade with docker-compose](#freqtrade-with-docker-compose) instructions. From d69ddd2ac37b18251b55f6f6e40995b1fac04402 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Mon, 10 Feb 2020 11:54:12 +0100 Subject: [PATCH 0461/1106] Apply suggestions from code review Committed 1 code suggestion in code review. Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/telegram-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index ac9cea3d6..c8ded4af5 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -55,7 +55,7 @@ official commands. You can ask at any moment for help with `/help`. | `/reload_conf` | | Reloads the configuration file | `/show_config` | | Shows part of the current configuration with relevant settings to operation | `/status` | | Lists all open trades -| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk(*) +| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) | `/count` | | Displays number of trades used and available | `/profit` | | Display a summary of your profit/loss from close trades and some stats about your performance | `/forcesell ` | | Instantly sells the given trade (Ignoring `minimum_roi`). From 0ac0ca74b5fe5db2e23d35bef0ad39174aaaabfd Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 10 Feb 2020 15:41:09 +0300 Subject: [PATCH 0462/1106] return back hint for running mypy --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a4a1a29f8..d84c743c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,7 +61,7 @@ Guide for installing them is [here](http://flake8.pycqa.org/en/latest/user/using #### Run mypy ``` bash -mypy freqtrade tests +mypy freqtrade ``` ## (Core)-Committer Guide From d07c69809da128471d664f2e19cc7cb28504ca5b Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 10 Feb 2020 18:32:41 +0300 Subject: [PATCH 0463/1106] Fix tests for hyperopt_loss --- tests/optimize/test_hyperopt.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 1780b5155..a4704b793 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -295,9 +295,12 @@ def test_start_filelock(mocker, default_conf, caplog) -> None: def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None: hl = HyperOptLossResolver.load_hyperoptloss(default_conf) - correct = hl.hyperopt_loss_function(hyperopt_results, 600) - over = hl.hyperopt_loss_function(hyperopt_results, 600 + 100) - under = hl.hyperopt_loss_function(hyperopt_results, 600 - 100) + correct = hl.hyperopt_loss_function(hyperopt_results, 600, + datetime(2019, 1, 1), datetime(2019, 5, 1)) + over = hl.hyperopt_loss_function(hyperopt_results, 600 + 100, + datetime(2019, 1, 1), datetime(2019, 5, 1)) + under = hl.hyperopt_loss_function(hyperopt_results, 600 - 100, + datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over > correct assert under > correct @@ -307,8 +310,10 @@ def test_loss_calculation_prefer_shorter_trades(default_conf, hyperopt_results) resultsb.loc[1, 'trade_duration'] = 20 hl = HyperOptLossResolver.load_hyperoptloss(default_conf) - longer = hl.hyperopt_loss_function(hyperopt_results, 100) - shorter = hl.hyperopt_loss_function(resultsb, 100) + longer = hl.hyperopt_loss_function(hyperopt_results, 100, + datetime(2019, 1, 1), datetime(2019, 5, 1)) + shorter = hl.hyperopt_loss_function(resultsb, 100, + datetime(2019, 1, 1), datetime(2019, 5, 1)) assert shorter < longer @@ -319,9 +324,12 @@ def test_loss_calculation_has_limited_profit(default_conf, hyperopt_results) -> results_under['profit_percent'] = hyperopt_results['profit_percent'] / 2 hl = HyperOptLossResolver.load_hyperoptloss(default_conf) - correct = hl.hyperopt_loss_function(hyperopt_results, 600) - over = hl.hyperopt_loss_function(results_over, 600) - under = hl.hyperopt_loss_function(results_under, 600) + correct = hl.hyperopt_loss_function(hyperopt_results, 600, + datetime(2019, 1, 1), datetime(2019, 5, 1)) + over = hl.hyperopt_loss_function(results_over, 600, + datetime(2019, 1, 1), datetime(2019, 5, 1)) + under = hl.hyperopt_loss_function(results_under, 600, + datetime(2019, 1, 1), datetime(2019, 5, 1)) assert over < correct assert under > correct From faf19eda86e3728905cf94644d47275af5cabbc5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 10 Feb 2020 17:27:47 +0100 Subject: [PATCH 0464/1106] Break the old binary file so users are forced to reinstall Note: This should not be relevant anymore - this binary has been deprecated and is not being used by new installations since July 2019. --- bin/freqtrade | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/freqtrade b/bin/freqtrade index 25c94fe98..eee7cbef4 100755 --- a/bin/freqtrade +++ b/bin/freqtrade @@ -1,11 +1,11 @@ #!/usr/bin/env python3 import sys -import warnings +import logging -from freqtrade.main import main +logger = logging.getLogger(__name__) -warnings.warn( - "Deprecated - To continue to run the bot like this, please run `pip install -e .` again.", - DeprecationWarning) -main(sys.argv[1:]) + +logger.error("DEPRECATED installation detected, please run `pip install -e .` again.") + +sys.exit(2) From 05128d21a8be65a71d1a8a30e973b3bb26bf3884 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Mon, 10 Feb 2020 20:48:49 +0300 Subject: [PATCH 0465/1106] Suggest to run flake for scripts --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d84c743c9..1c83437f6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ pytest tests/test_.py::test_ #### Run Flake8 ```bash -flake8 freqtrade tests +flake8 freqtrade tests scripts ``` We receive a lot of code that fails the `flake8` checks. From c924e4d519253a400218d95b7f17a64da27e5da6 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Mon, 10 Feb 2020 20:54:31 +0100 Subject: [PATCH 0466/1106] Updated based on feedback: - Profit commands now use float - Compatible with --best - Corrected wrong information in docs --- docs/utils.md | 134 ++++++++++++++++++------ freqtrade/commands/cli_options.py | 8 +- freqtrade/commands/hyperopt_commands.py | 68 ++++++------ 3 files changed, 140 insertions(+), 70 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 71039f174..5bb3a0e53 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -36,6 +36,38 @@ optional arguments: └── sample_strategy.py ``` +## Create new config + +Creates a new configuration file, asking some questions which are important selections for a configuration. + +``` +usage: freqtrade new-config [-h] [-c PATH] + +optional arguments: + -h, --help show this help message and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. +``` + +!!! Warning + Only vital questions are asked. Freqtrade offers a lot more configuration possibilities, which are listed in the [Configuration documentation](configuration.md#configuration-parameters) + +### Create config examples + +``` +$ freqtrade new-config --config config_binance.json + +? Do you want to enable Dry-run (simulated trades)? Yes +? Please insert your stake currency: BTC +? Please insert your stake amount: 0.05 +? Please insert max_open_trades (Integer or 'unlimited'): 5 +? Please insert your ticker interval: 15m +? Please insert your display Currency (for reporting): USD +? Select exchange binance +? Do you want to enable Telegram? No +``` + ## Create new strategy Creates a new strategy from a template similar to SampleStrategy. @@ -135,27 +167,15 @@ Common arguments: ``` ``` freqtrade list-hyperopts --help -usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] [--best] - [--profitable] [--min-avg-time INT] - [--max-avg-time INT] [--min-avg-profit FLOAT] - [--min-total-profit FLOAT] [--no-color] - [--print-json] [--no-details] +usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] + [--hyperopt-path PATH] [-1] optional arguments: -h, --help show this help message and exit - --best Select only best epochs. - --profitable Select only profitable epochs. - --min-avg-time INT Select epochs on above average time. - --max-avg-time INT Select epochs on under average time. - --min-avg-profit FLOAT - Select epochs on above average profit. - --min-total-profit FLOAT - Select epochs on above total profit. - --no-color Disable colorization of hyperopt results. May be - useful if you are redirecting output to a file. - --print-json Print best result detailization in JSON format. - --no-details Do not print best epoch details. + --hyperopt-path PATH Specify additional lookup path for Hyperopt and + Hyperopt Loss functions. + -1, --one-column Print output in one column. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). @@ -232,20 +252,31 @@ All exchanges supported by the ccxt library: _1btcxe, acx, adara, allcoin, anxpr Use the `list-timeframes` subcommand to see the list of ticker intervals (timeframes) available for the exchange. ``` -usage: freqtrade list-timeframes [-h] [--exchange EXCHANGE] [-1] +usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1] optional arguments: - -h, --help show this help message and exit - --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no - config is provided. - -1, --one-column Print output in one column. + -h, --help show this help message and exit + --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided. + -1, --one-column Print output in one column. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` + to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. ``` * Example: see the timeframes for the 'binance' exchange, set in the configuration file: ``` -$ freqtrade -c config_binance.json list-timeframes +$ freqtrade list-timeframes -c config_binance.json ... Timeframes available for the exchange `binance`: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M ``` @@ -269,14 +300,16 @@ You can print info about any pair/market with these subcommands - and you can fi These subcommands have same usage and same set of available options: ``` -usage: freqtrade list-markets [-h] [--exchange EXCHANGE] [--print-list] - [--print-json] [-1] [--print-csv] +usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--exchange EXCHANGE] + [--print-list] [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] -usage: freqtrade list-pairs [-h] [--exchange EXCHANGE] [--print-list] - [--print-json] [-1] [--print-csv] +usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--exchange EXCHANGE] + [--print-list] [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] @@ -295,6 +328,22 @@ optional arguments: Specify quote currency(-ies). Space-separated list. -a, --all Print all pairs or market symbols. By default only active ones are shown. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. + ``` By default, only active pairs/markets are shown. Active pairs/markets are those that can currently be traded @@ -316,7 +365,7 @@ $ freqtrade list-pairs --quote USD --print-json human-readable list with summary: ``` -$ freqtrade -c config_binance.json list-pairs --all --base BTC ETH --quote USDT USD --print-list +$ freqtrade list-pairs -c config_binance.json --all --base BTC ETH --quote USDT USD --print-list ``` * Print all markets on exchange "Kraken", in the tabular format: @@ -364,17 +413,40 @@ You can list the hyperoptimization epochs the Hyperopt module evaluated previous ``` usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--best] - [--profitable] [--no-color] [--print-json] - [--no-details] + [--profitable] [--min-avg-time FLOAT] + [--max-avg-time FLOAT] [--min-avg-profit FLOAT] + [--min-total-profit FLOAT] [--no-color] + [--print-json] [--no-details] optional arguments: -h, --help show this help message and exit --best Select only best epochs. --profitable Select only profitable epochs. + --min-avg-time FLOAT Select epochs on above average time. + --max-avg-time FLOAT Select epochs on under average time. + --min-avg-profit FLOAT + Select epochs on above average profit. + --min-total-profit FLOAT + Select epochs on above total profit. --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. --no-details Do not print best epoch details. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. ``` ### Examples diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 0c6d64691..154404821 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -401,14 +401,14 @@ AVAILABLE_CLI_OPTIONS = { "hyperopt_list_min_avg_time": Arg( '--min-avg-time', help='Select epochs on above average time.', - type=check_int_nonzero, - metavar='INT', + type=float, + metavar='FLOAT', ), "hyperopt_list_max_avg_time": Arg( '--max-avg-time', help='Select epochs on under average time.', - type=check_int_nonzero, - metavar='INT', + type=float, + metavar='FLOAT', ), "hyperopt_list_min_avg_profit": Arg( '--min-avg-profit', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index cdfdb5ca6..ed0728bf6 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -27,10 +27,10 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), - 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), - 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), - 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0.0), - 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0.0) + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) } trials_file = (config['user_data_dir'] / @@ -74,10 +74,10 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), - 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), - 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), - 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0), - 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0) + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) } no_header = config.get('hyperopt_show_no_header', False) @@ -119,33 +119,31 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: trials = [x for x in trials if x['is_best']] if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] - - if not filteroptions['only_best']: - if filteroptions['filter_min_avg_time'] > 0: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] - ] - if filteroptions['filter_max_avg_time'] > 0: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] - ] - if filteroptions['filter_min_avg_profit'] > 0: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['avg_profit'] - > filteroptions['filter_min_avg_profit'] - ] - if filteroptions['filter_min_total_profit'] > 0: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] - ] + if filteroptions['filter_min_avg_time'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] + ] + if filteroptions['filter_max_avg_time'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] + ] + if filteroptions['filter_min_avg_profit'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['avg_profit'] + > filteroptions['filter_min_avg_profit'] + ] + if filteroptions['filter_min_total_profit'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] + ] logger.info(f"{len(trials)} " + ("best " if filteroptions['only_best'] else "") + From f2520c11e70c3f0717bdd842f7b7cdeb5482ab0a Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Mon, 10 Feb 2020 21:19:25 +0100 Subject: [PATCH 0467/1106] Used wrong utils.md as base --- docs/utils.md | 83 +++++++-------------------------------------------- 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 5bb3a0e53..4bb2fdafb 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -36,38 +36,6 @@ optional arguments: └── sample_strategy.py ``` -## Create new config - -Creates a new configuration file, asking some questions which are important selections for a configuration. - -``` -usage: freqtrade new-config [-h] [-c PATH] - -optional arguments: - -h, --help show this help message and exit - -c PATH, --config PATH - Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` - to read config from stdin. -``` - -!!! Warning - Only vital questions are asked. Freqtrade offers a lot more configuration possibilities, which are listed in the [Configuration documentation](configuration.md#configuration-parameters) - -### Create config examples - -``` -$ freqtrade new-config --config config_binance.json - -? Do you want to enable Dry-run (simulated trades)? Yes -? Please insert your stake currency: BTC -? Please insert your stake amount: 0.05 -? Please insert max_open_trades (Integer or 'unlimited'): 5 -? Please insert your ticker interval: 15m -? Please insert your display Currency (for reporting): USD -? Select exchange binance -? Do you want to enable Telegram? No -``` - ## Create new strategy Creates a new strategy from a template similar to SampleStrategy. @@ -252,31 +220,20 @@ All exchanges supported by the ccxt library: _1btcxe, acx, adara, allcoin, anxpr Use the `list-timeframes` subcommand to see the list of ticker intervals (timeframes) available for the exchange. ``` -usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1] +usage: freqtrade list-timeframes [-h] [--exchange EXCHANGE] [-1] optional arguments: - -h, --help show this help message and exit - --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided. - -1, --one-column Print output in one column. - -Common arguments: - -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. - -V, --version show program's version number and exit - -c PATH, --config PATH - Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` - to read config from stdin. - -d PATH, --datadir PATH - Path to directory with historical backtesting data. - --userdir PATH, --user-data-dir PATH - Path to userdata directory. + -h, --help show this help message and exit + --exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no + config is provided. + -1, --one-column Print output in one column. ``` * Example: see the timeframes for the 'binance' exchange, set in the configuration file: ``` -$ freqtrade list-timeframes -c config_binance.json +$ freqtrade -c config_binance.json list-timeframes ... Timeframes available for the exchange `binance`: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M ``` @@ -300,16 +257,14 @@ You can print info about any pair/market with these subcommands - and you can fi These subcommands have same usage and same set of available options: ``` -usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] [--exchange EXCHANGE] - [--print-list] [--print-json] [-1] [--print-csv] +usage: freqtrade list-markets [-h] [--exchange EXCHANGE] [--print-list] + [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] -usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] [--exchange EXCHANGE] - [--print-list] [--print-json] [-1] [--print-csv] +usage: freqtrade list-pairs [-h] [--exchange EXCHANGE] [--print-list] + [--print-json] [-1] [--print-csv] [--base BASE_CURRENCY [BASE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] @@ -328,22 +283,6 @@ optional arguments: Specify quote currency(-ies). Space-separated list. -a, --all Print all pairs or market symbols. By default only active ones are shown. - -Common arguments: - -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. Special values are: - 'syslog', 'journald'. See the documentation for more - details. - -V, --version show program's version number and exit - -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. - -d PATH, --datadir PATH - Path to directory with historical backtesting data. - --userdir PATH, --user-data-dir PATH - Path to userdata directory. - ``` By default, only active pairs/markets are shown. Active pairs/markets are those that can currently be traded @@ -365,7 +304,7 @@ $ freqtrade list-pairs --quote USD --print-json human-readable list with summary: ``` -$ freqtrade list-pairs -c config_binance.json --all --base BTC ETH --quote USDT USD --print-list +$ freqtrade -c config_binance.json list-pairs --all --base BTC ETH --quote USDT USD --print-list ``` * Print all markets on exchange "Kraken", in the tabular format: From 62bcb3d7660ad60f0b9c3f7374878df16117c253 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 11 Feb 2020 03:43:20 +0300 Subject: [PATCH 0468/1106] Fix tests in test_history.py --- tests/data/test_history.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index da4c90191..15f507b90 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -420,7 +420,7 @@ def test_trim_tickerlist(testdatadir) -> None: # Test the pattern ^(\d{8})-$ # This pattern extracts elements from the date to now - timerange = TimeRange('date', None, ticker_list[10][0] / 1000 - 1, None) + timerange = TimeRange('date', None, ticker_list[10][0] / 1000 - 1, 0) ticker = trim_tickerlist(ticker_list, timerange) ticker_len = len(ticker) @@ -430,14 +430,14 @@ def test_trim_tickerlist(testdatadir) -> None: # Test a wrong pattern # This pattern must return the list unchanged - timerange = TimeRange(None, None, None, 5) + timerange = TimeRange(None, None, 0, 5) ticker = trim_tickerlist(ticker_list, timerange) ticker_len = len(ticker) assert ticker_list_len == ticker_len # passing empty list - timerange = TimeRange(None, None, None, 5) + timerange = TimeRange(None, None, 0, 5) ticker = trim_tickerlist([], timerange) assert 0 == len(ticker) assert not ticker From 29f7c5071b2c99536f1499ba420f7c09a7eadcf2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 11 Feb 2020 04:17:10 +0300 Subject: [PATCH 0469/1106] Fix usage of an item from BTContainer in tests --- tests/optimize/__init__.py | 4 ++-- tests/optimize/test_backtest_detail.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/optimize/__init__.py b/tests/optimize/__init__.py index 524db093e..13605a38c 100644 --- a/tests/optimize/__init__.py +++ b/tests/optimize/__init__.py @@ -1,4 +1,4 @@ -from typing import Dict, List, NamedTuple +from typing import Dict, List, NamedTuple, Optional import arrow from pandas import DataFrame @@ -30,7 +30,7 @@ class BTContainer(NamedTuple): profit_perc: float trailing_stop: bool = False trailing_only_offset_is_reached: bool = False - trailing_stop_positive: float = None + trailing_stop_positive: Optional[float] = None trailing_stop_positive_offset: float = 0.0 use_sell_signal: bool = False diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index bd2765430..e7bc76c1d 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -364,7 +364,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None: default_conf["trailing_stop"] = data.trailing_stop default_conf["trailing_only_offset_is_reached"] = data.trailing_only_offset_is_reached # Only add this to configuration If it's necessary - if data.trailing_stop_positive: + if data.trailing_stop_positive is not None: default_conf["trailing_stop_positive"] = data.trailing_stop_positive default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset default_conf["ask_strategy"] = {"use_sell_signal": data.use_sell_signal} From f99d1c38298b717a3e1d1299477338e41746c756 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 15:44:47 +0100 Subject: [PATCH 0470/1106] fixed open_rate instead of open_rate_requested --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5f1024f8c..aa617a386 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -549,7 +549,7 @@ class FreqtradeBot: 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, - 'limit': trade.open_rate_requested, + 'limit': trade.open_rate, 'order_type': order_type, 'stake_amount': trade.stake_amount, 'stake_currency': self.config['stake_currency'], From 7f4b90c68f9fd1a116ba3179b335add64c66c3cd Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 15:45:35 +0100 Subject: [PATCH 0471/1106] fixed actual open_rate in notify_buy_cancel --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aa617a386..6d1122aa1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -572,7 +572,7 @@ class FreqtradeBot: 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, - 'limit': trade.open_rate_requested, + 'limit': trade.open_rate, 'order_type': order_type, 'stake_amount': trade.stake_amount, 'stake_currency': self.config['stake_currency'], From 867b736b8477507f933ce8b9768a433de5721615 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 15:49:57 +0100 Subject: [PATCH 0472/1106] Fixed to Executing Buys & Sells --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6d1122aa1..85ddb0da1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -414,7 +414,7 @@ class FreqtradeBot: if ((bid_check_dom.get('enabled', False)) and (bid_check_dom.get('bids_to_ask_delta', 0) > 0)): if self._check_depth_of_market_buy(pair, bid_check_dom): - logger.info(f'Executed Buy for {pair}.') + logger.info(f'Executing Buy for {pair}.') return self.execute_buy(pair, stake_amount) else: return False @@ -804,8 +804,8 @@ class FreqtradeBot: ) if should_sell.sell_flag: + logger.info(f'Executing Sell for {trade.pair}. Reason: {should_sell.sell_type}') self.execute_sell(trade, sell_rate, should_sell.sell_type) - logger.info(f'Executed Sell for {trade.pair}. Reason: {should_sell.sell_type}') return True return False From fc29564974d77e54599bf759dd1d1ed4d2df884a Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 15:58:40 +0100 Subject: [PATCH 0473/1106] Fixed messages and readability --- docs/webhook-config.md | 4 ++-- freqtrade/rpc/rpc.py | 4 ++-- freqtrade/rpc/telegram.py | 4 ++-- tests/rpc/test_rpc_telegram.py | 6 +++--- tests/rpc/test_rpc_webhook.py | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/webhook-config.md b/docs/webhook-config.md index b287fa71e..e53aa8af5 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -16,7 +16,7 @@ Sample configuration (tested using IFTTT). "value3": "{stake_amount:8f} {stake_currency}" }, "webhookbuycancel": { - "value1": "Cancelling Buy {pair}", + "value1": "Cancelling Open Buy Order for {pair}", "value2": "limit {limit:8f}", "value3": "{stake_amount:8f} {stake_currency}" }, @@ -26,7 +26,7 @@ Sample configuration (tested using IFTTT). "value3": "profit: {profit_amount:8f} {stake_currency}" }, "webhooksellcancel": { - "value1": "Cancelling Sell {pair}", + "value1": "Cancelling Open Sell Order for {pair}", "value2": "limit {limit:8f}", "value3": "profit: {profit_amount:8f} {stake_currency}" }, diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index c1efea79e..07631f258 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -168,8 +168,8 @@ class RPC: profit_str += f" ({fiat_profit:.2f})" trades_list.append([ trade.id, - trade.pair + ['', '*'][trade.open_order_id is not None - and trade.close_rate_requested is None], + trade.pair + '*' if (trade.open_order_id is not None + and trade.close_rate_requested is None) else '', shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ]) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 0dd7a8ffd..e3d4f54e7 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -144,7 +144,7 @@ class Telegram(RPC): message += ")`" elif msg['type'] == RPCMessageType.BUY_CANCEL_NOTIFICATION: - message = "*{exchange}:* Cancelling Buy {pair}".format(**msg) + message = "*{exchange}:* Cancelling Open Buy Order for {pair}".format(**msg) elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: msg['amount'] = round(msg['amount'], 8) @@ -172,7 +172,7 @@ class Telegram(RPC): ' / {profit_fiat:.3f} {fiat_currency})`').format(**msg) elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: - message = "*{exchange}:* Cancelling Sell {pair}".format(**msg) + message = "*{exchange}:* Cancelling Open Sell Order for {pair}".format(**msg) elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION: message = '*Status:* `{status}`'.format(**msg) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index ae9c0c4dc..a8b8e0c5a 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -1228,7 +1228,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None: 'pair': 'ETH/BTC', }) assert msg_mock.call_args[0][0] \ - == ('*Bittrex:* Cancelling Buy ETH/BTC') + == ('*Bittrex:* Cancelling Open Buy Order for ETH/BTC') def test_send_msg_sell_notification(default_conf, mocker) -> None: @@ -1318,7 +1318,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None: 'pair': 'KEY/ETH', }) assert msg_mock.call_args[0][0] \ - == ('*Binance:* Cancelling Sell KEY/ETH') + == ('*Binance:* Cancelling Open Sell Order for KEY/ETH') msg_mock.reset_mock() telegram.send_msg({ @@ -1327,7 +1327,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None: 'pair': 'KEY/ETH', }) assert msg_mock.call_args[0][0] \ - == ('*Binance:* Cancelling Sell KEY/ETH') + == ('*Binance:* Cancelling Open Sell Order for KEY/ETH') # Reset singleton function to avoid random breaks telegram._fiat_converter.convert_amount = old_convamount diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index ab40047c0..3f3f36766 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -21,7 +21,7 @@ def get_webhook_dict() -> dict: "value3": "{stake_amount:8f} {stake_currency}" }, "webhookbuycancel": { - "value1": "Cancelling Buy {pair}", + "value1": "Cancelling Open Buy Order for {pair}", "value2": "limit {limit:8f}", "value3": "{stake_amount:8f} {stake_currency}" }, @@ -31,7 +31,7 @@ def get_webhook_dict() -> dict: "value3": "profit: {profit_amount:8f} {stake_currency}" }, "webhooksellcancel": { - "value1": "Cancelling Sell {pair}", + "value1": "Cancelling Open Sell Order for {pair}", "value2": "limit {limit:8f}", "value3": "profit: {profit_amount:8f} {stake_currency}" }, From 5b4d8d69ef567ca074351186eebe97e3c9e2fe52 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Tue, 11 Feb 2020 16:02:08 +0100 Subject: [PATCH 0474/1106] Adding --min-trades and --max-trades for hyperopt-list --- docs/utils.md | 5 +++- freqtrade/commands/arguments.py | 1 + freqtrade/commands/cli_options.py | 12 ++++++++++ freqtrade/commands/hyperopt_commands.py | 14 ++++++++++++ freqtrade/configuration/configuration.py | 6 +++++ tests/commands/test_commands.py | 29 ++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 1 deletion(-) mode change 100644 => 100755 freqtrade/commands/hyperopt_commands.py diff --git a/docs/utils.md b/docs/utils.md index 5bb3a0e53..91dd6eae0 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -413,7 +413,8 @@ You can list the hyperoptimization epochs the Hyperopt module evaluated previous ``` usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--best] - [--profitable] [--min-avg-time FLOAT] + [--profitable] [--min-trades INT] + [--max-trades INT] [--min-avg-time FLOAT] [--max-avg-time FLOAT] [--min-avg-profit FLOAT] [--min-total-profit FLOAT] [--no-color] [--print-json] [--no-details] @@ -422,6 +423,8 @@ optional arguments: -h, --help show this help message and exit --best Select only best epochs. --profitable Select only profitable epochs. + --min-trades INT Select epochs with more than INT trades. + --max-trades INT Select epochs with less than INT trades. --min-avg-time FLOAT Select epochs on above average time. --max-avg-time FLOAT Select epochs on under average time. --min-avg-profit FLOAT diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index e5a68389b..1b2c4482e 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -62,6 +62,7 @@ ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", + "hyperopt_list_min_trades", "hyperopt_list_max_trades", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", "print_colorized", "print_json", "hyperopt_list_no_details"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 154404821..f9351c207 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -398,6 +398,18 @@ AVAILABLE_CLI_OPTIONS = { help='Select only best epochs.', action='store_true', ), + "hyperopt_list_min_trades": Arg( + '--min-trades', + help='Select epochs with more than INT trades.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_max_trades": Arg( + '--max-trades', + help='Select epochs with less than INT trades.', + type=check_int_nonzero, + metavar='INT', + ), "hyperopt_list_min_avg_time": Arg( '--min-avg-time', help='Select epochs on above average time.', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py old mode 100644 new mode 100755 index ed0728bf6..c3baf2406 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -27,6 +27,8 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), + 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), @@ -74,6 +76,8 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), + 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), @@ -119,6 +123,16 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: trials = [x for x in trials if x['is_best']] if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] + if filteroptions['filter_min_trades'] > 0: + trials = [ + x for x in trials + if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades'] + ] + if filteroptions['filter_max_trades'] > 0: + trials = [ + x for x in trials + if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades'] + ] if filteroptions['filter_min_avg_time'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index f7e87f3a1..41f24e55c 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -310,6 +310,12 @@ class Configuration: self._args_to_config(config, argname='hyperopt_list_profitable', logstring='Parameter --profitable detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_trades', + logstring='Parameter --min-trades detected: {}') + + self._args_to_config(config, argname='hyperopt_list_max_trades', + logstring='Parameter --max-trades detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_avg_time', logstring='Parameter --min-avg-time detected: {}') diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index db8a9289a..e02a721a4 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -773,6 +773,35 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 10/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--no-details", + "--no-color", + "--min-trades", "20" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 3/12", " 6/12", " 7/12", " 9/12", " 11/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 8/12", " 10/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--max-trades", "20" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out From 4fedf1e564212b43b359a1bc533f0d571b9ce926 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 16:05:44 +0100 Subject: [PATCH 0475/1106] default refresh TRUE on get_buy_rate and get_sell_Rate --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 85ddb0da1..c04e3077e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -234,7 +234,7 @@ class FreqtradeBot: return trades_created - def get_buy_rate(self, pair: str, refresh: bool = False, tick: Dict = None) -> float: + def get_buy_rate(self, pair: str, refresh: bool = True, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price :return: float: Price @@ -615,7 +615,7 @@ class FreqtradeBot: return trades_closed - def get_sell_rate(self, pair: str, refresh: bool = False) -> float: + def get_sell_rate(self, pair: str, refresh: bool = True) -> float: """ Get sell rate - either using get-ticker bid or first bid based on orderbook The orderbook portion is only used for rpc messaging, which would otherwise fail From 5f4c209fca844f6ea66f7302c22a64d7375812db Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 16:14:49 +0100 Subject: [PATCH 0476/1106] fixed one more occurence of executed buy, and test --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c04e3077e..0d1105b2f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -419,7 +419,7 @@ class FreqtradeBot: else: return False - logger.info(f'Executed Buy for {pair}') + logger.info(f'Executing Buy for {pair}') return self.execute_buy(pair, stake_amount) else: return False diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 429d3599d..18cd81aed 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -300,7 +300,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, caplog, mocker, edge_conf # stoploss shoud be hit assert freqtrade.handle_trade(trade) is True - assert log_has('Executed Sell for NEO/BTC. Reason: SellType.STOP_LOSS', caplog) + assert log_has('Executing Sell for NEO/BTC. Reason: SellType.STOP_LOSS', caplog) assert trade.sell_reason == SellType.STOP_LOSS.value From cde1b2b56c7fa6285af72ec3d1758968f4d9b88d Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 16:28:48 +0100 Subject: [PATCH 0477/1106] readded rpc status message for partial buys --- freqtrade/freqtradebot.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 0d1105b2f..ffd951ee2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -906,6 +906,10 @@ class FreqtradeBot: trade.open_order_id = None logger.info('Partial buy order timeout for %s.', trade) + self.rpc.send_msg({ + 'type': RPCMessageType.STATUS_NOTIFICATION, + 'status': f'Remaining buy order for {trade.pair} cancelled due to timeout' + }) return False def handle_timedout_limit_sell(self, trade: Trade, order: Dict) -> bool: From 899de8b27c3f35273f090534b0bb2a9d131270f6 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Tue, 11 Feb 2020 16:50:18 +0100 Subject: [PATCH 0478/1106] modified tests for double partial call --- tests/test_freqtradebot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 18cd81aed..c0af1f015 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2067,7 +2067,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old # note this is for a partially-complete buy order freqtrade.check_handle_timedout() assert cancel_order_mock.call_count == 1 - assert rpc_mock.call_count == 1 + assert rpc_mock.call_count == 2 trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() assert len(trades) == 1 assert trades[0].amount == 23.0 @@ -2101,7 +2101,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap assert log_has_re(r"Applying fee on amount for Trade.* Order", caplog) assert cancel_order_mock.call_count == 1 - assert rpc_mock.call_count == 1 + assert rpc_mock.call_count == 2 trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() assert len(trades) == 1 # Verify that tradehas been updated @@ -2140,7 +2140,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, assert log_has_re(r"Could not update trade amount: .*", caplog) assert cancel_order_mock.call_count == 1 - assert rpc_mock.call_count == 1 + assert rpc_mock.call_count == 2 trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() assert len(trades) == 1 # Verify that tradehas been updated From d1c3eabb870fe5a5f2357086459b1a2ca06faaa9 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Tue, 11 Feb 2020 18:08:30 +0100 Subject: [PATCH 0479/1106] Changed commands to use "check_int_positive" --- freqtrade/commands/cli_options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index f9351c207..c3b79ae3a 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -401,13 +401,13 @@ AVAILABLE_CLI_OPTIONS = { "hyperopt_list_min_trades": Arg( '--min-trades', help='Select epochs with more than INT trades.', - type=check_int_nonzero, + type=check_int_positive, metavar='INT', ), "hyperopt_list_max_trades": Arg( '--max-trades', help='Select epochs with less than INT trades.', - type=check_int_nonzero, + type=check_int_positive, metavar='INT', ), "hyperopt_list_min_avg_time": Arg( From c35fe2c386ae84a128e817be79c901a5345538c9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 11 Feb 2020 19:29:43 +0100 Subject: [PATCH 0480/1106] Add link to quick-start-guide --- docs/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker.md b/docs/docker.md index 6267c0cf2..cd24994bc 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -8,7 +8,7 @@ Start by downloading and installing Docker CE for your platform: * [Windows](https://docs.docker.com/docker-for-windows/install/) * [Linux](https://docs.docker.com/install/) -Optionally, [docker-compose](https://docs.docker.com/compose/install/) should be installed and available to follow the docker quick start guide. +Optionally, [docker-compose](https://docs.docker.com/compose/install/) should be installed and available to follow the [docker quick start guide](#docker-quick-start). Once you have Docker installed, simply prepare the config file (e.g. `config.json`) and run the image for `freqtrade` as explained below. From 7be9f0067e63f7a889e10c096b1f3fd36cbedf81 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 11 Feb 2020 20:45:53 +0100 Subject: [PATCH 0481/1106] Update data-analysis documentation to properly initialize configuration --- docs/strategy_analysis_example.md | 27 +++++++++---------- .../templates/strategy_analysis_example.ipynb | 27 +++++++++---------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index cc6b9805f..2d77edaed 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -7,18 +7,19 @@ Debugging a strategy can be time-consuming. FreqTrade offers helper functions to ```python from pathlib import Path +from freqtrade.configuration import Configuration + # Customize these according to your needs. +# Initialize empty configuration object +config = Configuration.from_files([]) +# Optionally, Use existing configuration file +# config = Configuration.from_files(["config.json"]) + # Define some constants -timeframe = "5m" +config["ticker_interval"] = "5m" # Name of the strategy class -strategy_name = 'SampleStrategy' -# Path to user data -user_data_dir = Path('user_data') -# Location of the strategy -strategy_location = user_data_dir / 'strategies' -# Location of the data -data_location = Path(user_data_dir, 'data', 'binance') +config["strategy"] = "SampleStrategy" # Pair to analyze - Only use one pair here pair = "BTC_USDT" ``` @@ -28,8 +29,8 @@ pair = "BTC_USDT" # Load data using values set above from freqtrade.data.history import load_pair_history -candles = load_pair_history(datadir=data_location, - timeframe=timeframe, +candles = load_pair_history(datadir=config["data_dir"], + timeframe=config["ticker_interval"], pair=pair) # Confirm success @@ -44,9 +45,7 @@ candles.head() ```python # Load strategy using values set above from freqtrade.resolvers import StrategyResolver -strategy = StrategyResolver.load_strategy({'strategy': strategy_name, - 'user_data_dir': user_data_dir, - 'strategy_path': strategy_location}) +strategy = StrategyResolver.load_strategy(config) # Generate buy/sell signals using strategy df = strategy.analyze_ticker(candles, {'pair': pair}) @@ -86,7 +85,7 @@ Analyze a trades dataframe (also used below for plotting) from freqtrade.data.btanalysis import load_backtest_data # Load backtest results -trades = load_backtest_data(user_data_dir / "backtest_results/backtest-result.json") +trades = load_backtest_data(config["user_data_dir"] / "backtest_results/backtest-result.json") # Show value-counts per pair trades.groupby("pair")["sell_reason"].value_counts() diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index eea8fb85f..06fc3f557 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -23,18 +23,19 @@ "outputs": [], "source": [ "from pathlib import Path\n", + "from freqtrade.configuration import Configuration\n", + "\n", "# Customize these according to your needs.\n", "\n", + "# Initialize empty configuration object\n", + "config = Configuration.from_files([])\n", + "# Optionally, Use existing configuration file\n", + "# config = Configuration.from_files([\"config.json\"])\n", + "\n", "# Define some constants\n", - "timeframe = \"5m\"\n", + "config[\"ticker_interval\"] = \"5m\"\n", "# Name of the strategy class\n", - "strategy_name = 'SampleStrategy'\n", - "# Path to user data\n", - "user_data_dir = Path('user_data')\n", - "# Location of the strategy\n", - "strategy_location = user_data_dir / 'strategies'\n", - "# Location of the data\n", - "data_location = Path(user_data_dir, 'data', 'binance')\n", + "config[\"strategy\"] = \"SampleStrategy\"\n", "# Pair to analyze - Only use one pair here\n", "pair = \"BTC_USDT\"" ] @@ -48,8 +49,8 @@ "# Load data using values set above\n", "from freqtrade.data.history import load_pair_history\n", "\n", - "candles = load_pair_history(datadir=data_location,\n", - " timeframe=timeframe,\n", + "candles = load_pair_history(datadir=config[\"data_dir\"],\n", + " timeframe=config[\"ticker_interval\"],\n", " pair=pair)\n", "\n", "# Confirm success\n", @@ -73,9 +74,7 @@ "source": [ "# Load strategy using values set above\n", "from freqtrade.resolvers import StrategyResolver\n", - "strategy = StrategyResolver.load_strategy({'strategy': strategy_name,\n", - " 'user_data_dir': user_data_dir,\n", - " 'strategy_path': strategy_location})\n", + "strategy = StrategyResolver.load_strategy(config)\n", "\n", "# Generate buy/sell signals using strategy\n", "df = strategy.analyze_ticker(candles, {'pair': pair})\n", @@ -137,7 +136,7 @@ "from freqtrade.data.btanalysis import load_backtest_data\n", "\n", "# Load backtest results\n", - "trades = load_backtest_data(user_data_dir / \"backtest_results/backtest-result.json\")\n", + "trades = load_backtest_data(config[\"user_data_dir\"] / \"backtest_results/backtest-result.json\")\n", "\n", "# Show value-counts per pair\n", "trades.groupby(\"pair\")[\"sell_reason\"].value_counts()" From 539343b20d7304e3f746c3ac7868bb584f3e1539 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Tue, 11 Feb 2020 21:29:55 +0100 Subject: [PATCH 0482/1106] Adding 2 more filter options for completeness --- docs/utils.md | 8 ++++++- freqtrade/commands/arguments.py | 3 ++- freqtrade/commands/cli_options.py | 12 ++++++++++ freqtrade/commands/hyperopt_commands.py | 21 ++++++++++++++++-- freqtrade/configuration/configuration.py | 6 +++++ tests/commands/test_commands.py | 28 ++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 91dd6eae0..abb7fd0db 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -416,7 +416,9 @@ usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] [--profitable] [--min-trades INT] [--max-trades INT] [--min-avg-time FLOAT] [--max-avg-time FLOAT] [--min-avg-profit FLOAT] - [--min-total-profit FLOAT] [--no-color] + [--max-avg-profit FLOAT] + [--min-total-profit FLOAT] + [--max-total-profit FLOAT] [--no-color] [--print-json] [--no-details] optional arguments: @@ -429,8 +431,12 @@ optional arguments: --max-avg-time FLOAT Select epochs on under average time. --min-avg-profit FLOAT Select epochs on above average profit. + --max-avg-profit FLOAT + Select epochs on below average profit. --min-total-profit FLOAT Select epochs on above total profit. + --max-total-profit FLOAT + Select epochs on below total profit. --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 1b2c4482e..fe6f49039 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -64,7 +64,8 @@ ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_trades", "hyperopt_list_max_trades", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", - "hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", + "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", + "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index c3b79ae3a..1776955b1 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -428,12 +428,24 @@ AVAILABLE_CLI_OPTIONS = { type=float, metavar='FLOAT', ), + "hyperopt_list_max_avg_profit": Arg( + '--max-avg-profit', + help='Select epochs on below average profit.', + type=float, + metavar='FLOAT', + ), "hyperopt_list_min_total_profit": Arg( '--min-total-profit', help='Select epochs on above total profit.', type=float, metavar='FLOAT', ), + "hyperopt_list_max_total_profit": Arg( + '--max-total-profit', + help='Select epochs on below total profit.', + type=float, + metavar='FLOAT', + ), "hyperopt_list_no_details": Arg( '--no-details', help='Do not print best epoch details.', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index c3baf2406..8c1c80d98 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -32,7 +32,9 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), - 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) + 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), + 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } trials_file = (config['user_data_dir'] / @@ -81,7 +83,9 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), - 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) + 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), + 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } no_header = config.get('hyperopt_show_no_header', False) @@ -152,12 +156,25 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit'] ] + if filteroptions['filter_max_avg_profit'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['avg_profit'] + < filteroptions['filter_max_avg_profit'] + ] if filteroptions['filter_min_total_profit'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ x for x in trials if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] ] + if filteroptions['filter_max_total_profit'] is not None: + trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] + trials = [ + x for x in trials + if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit'] + ] logger.info(f"{len(trials)} " + ("best " if filteroptions['only_best'] else "") + diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 41f24e55c..c2613ba99 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -325,9 +325,15 @@ class Configuration: self._args_to_config(config, argname='hyperopt_list_min_avg_profit', logstring='Parameter --min-avg-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_max_avg_profit', + logstring='Parameter --max-avg-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_total_profit', logstring='Parameter --min-total-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_max_total_profit', + logstring='Parameter --max-total-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_no_details', logstring='Parameter --no-details detected: {}') diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index e02a721a4..ee1db5db5 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -822,6 +822,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--no-details", + "--max-avg-profit", "0.10" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 1/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12"]) + assert all(x not in captured.out + for x in [" 2/12", " 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", @@ -836,6 +850,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--no-details", + "--max-total-profit", "0.4" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", + " 9/12", " 11/12"]) + assert all(x not in captured.out + for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", From 4f3376e2a189618f649e8f5d91d3ae753b1ae730 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Wed, 12 Feb 2020 01:39:15 +0300 Subject: [PATCH 0483/1106] Do not instantiate directly DefaultStrategy in tests --- tests/data/test_history.py | 14 ++++++++++---- tests/optimize/test_backtesting.py | 6 ++++-- tests/strategy/test_interface.py | 18 ++++++++++++------ tests/test_plotting.py | 14 +++++++++----- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 15f507b90..cf0901587 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -24,7 +24,7 @@ from freqtrade.data.history import (_download_pair_history, validate_backtest_data) from freqtrade.exchange import timeframe_to_minutes from freqtrade.misc import file_dump_json -from freqtrade.strategy.default_strategy import DefaultStrategy +from freqtrade.resolvers import StrategyResolver from tests.conftest import (get_patched_exchange, log_has, log_has_re, patch_exchange) @@ -509,7 +509,9 @@ def test_file_dump_json_tofile(testdatadir) -> None: def test_get_timerange(default_conf, mocker, testdatadir) -> None: patch_exchange(mocker) - strategy = DefaultStrategy(default_conf) + + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) data = strategy.tickerdata_to_dataframe( load_data( @@ -525,7 +527,9 @@ def test_get_timerange(default_conf, mocker, testdatadir) -> None: def test_validate_backtest_data_warn(default_conf, mocker, caplog, testdatadir) -> None: patch_exchange(mocker) - strategy = DefaultStrategy(default_conf) + + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) data = strategy.tickerdata_to_dataframe( load_data( @@ -547,7 +551,9 @@ def test_validate_backtest_data_warn(default_conf, mocker, caplog, testdatadir) def test_validate_backtest_data(default_conf, mocker, caplog, testdatadir) -> None: patch_exchange(mocker) - strategy = DefaultStrategy(default_conf) + + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) timerange = TimeRange('index', 'index', 200, 250) data = strategy.tickerdata_to_dataframe( diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index ec85c8030..bba15c156 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -20,8 +20,8 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.data.history import get_timerange from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize.backtesting import Backtesting +from freqtrade.resolvers import StrategyResolver from freqtrade.state import RunMode -from freqtrade.strategy.default_strategy import DefaultStrategy from freqtrade.strategy.interface import SellType from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, patched_configuration_load_config_file) @@ -350,7 +350,9 @@ def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: assert len(data['UNITTEST/BTC']) == 102 # Load strategy to compare the result between Backtesting function and strategy are the same - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) + data2 = strategy.tickerdata_to_dataframe(tickerlist) assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC']) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 89c38bda1..a28519383 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -10,8 +10,9 @@ from freqtrade.configuration import TimeRange from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.persistence import Trade -from tests.conftest import get_patched_exchange, log_has +from freqtrade.resolvers import StrategyResolver from freqtrade.strategy.default_strategy import DefaultStrategy +from tests.conftest import get_patched_exchange, log_has # Avoid to reinit the same object again and again _STRATEGY = DefaultStrategy(config={}) @@ -104,7 +105,8 @@ def test_get_signal_handles_exceptions(mocker, default_conf): def test_tickerdata_to_dataframe(default_conf, testdatadir) -> None: - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) timerange = TimeRange.parse_timerange('1510694220-1510700340') tick = load_tickerdata_file(testdatadir, 'UNITTEST/BTC', '1m', timerange=timerange) @@ -120,7 +122,8 @@ def test_min_roi_reached(default_conf, fee) -> None: min_roi_list = [{20: 0.05, 55: 0.01, 0: 0.1}, {0: 0.1, 20: 0.05, 55: 0.01}] for roi in min_roi_list: - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) strategy.minimal_roi = roi trade = Trade( pair='ETH/BTC', @@ -158,7 +161,8 @@ def test_min_roi_reached2(default_conf, fee) -> None: }, ] for roi in min_roi_list: - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) strategy.minimal_roi = roi trade = Trade( pair='ETH/BTC', @@ -192,7 +196,8 @@ def test_min_roi_reached3(default_conf, fee) -> None: 30: 0.05, 55: 0.30, } - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) strategy.minimal_roi = min_roi trade = Trade( pair='ETH/BTC', @@ -292,7 +297,8 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) - def test_is_pair_locked(default_conf): - strategy = DefaultStrategy(default_conf) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) # dict should be empty assert not strategy._pair_locked_until diff --git a/tests/test_plotting.py b/tests/test_plotting.py index e7ec4ce46..34d1f2b0c 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -19,7 +19,7 @@ from freqtrade.plot.plotting import (add_indicators, add_profit, generate_profit_graph, init_plotscript, load_and_plot_trades, plot_profit, plot_trades, store_plot_file) -from freqtrade.strategy.default_strategy import DefaultStrategy +from freqtrade.resolvers import StrategyResolver from tests.conftest import get_args, log_has, log_has_re @@ -70,9 +70,11 @@ def test_add_indicators(default_conf, testdatadir, caplog): indicators1 = {"ema10": {}} indicators2 = {"macd": {"color": "red"}} + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) + # Generate buy/sell signals and indicators - strat = DefaultStrategy(default_conf) - data = strat.analyze_ticker(data, {'pair': pair}) + data = strategy.analyze_ticker(data, {'pair': pair}) fig = generate_empty_figure() # Row 1 @@ -181,9 +183,11 @@ def test_generate_candlestick_graph_no_trades(default_conf, mocker, testdatadir) data = history.load_pair_history(pair=pair, timeframe='1m', datadir=testdatadir, timerange=timerange) + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) + # Generate buy/sell signals and indicators - strat = DefaultStrategy(default_conf) - data = strat.analyze_ticker(data, {'pair': pair}) + data = strategy.analyze_ticker(data, {'pair': pair}) indicators1 = [] indicators2 = [] From d6b9397579c2d4542bf5742a9ac7aa7f68a56f08 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 12 Feb 2020 06:40:13 +0100 Subject: [PATCH 0484/1106] Fix typo in datadir key --- docs/strategy_analysis_example.md | 4 ++-- freqtrade/templates/strategy_analysis_example.ipynb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 2d77edaed..10ae73450 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -13,7 +13,7 @@ from freqtrade.configuration import Configuration # Initialize empty configuration object config = Configuration.from_files([]) -# Optionally, Use existing configuration file +# Optionally, use existing configuration file # config = Configuration.from_files(["config.json"]) # Define some constants @@ -29,7 +29,7 @@ pair = "BTC_USDT" # Load data using values set above from freqtrade.data.history import load_pair_history -candles = load_pair_history(datadir=config["data_dir"], +candles = load_pair_history(datadir=config["datadir"], timeframe=config["ticker_interval"], pair=pair) diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 06fc3f557..4541f5ed5 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -29,7 +29,7 @@ "\n", "# Initialize empty configuration object\n", "config = Configuration.from_files([])\n", - "# Optionally, Use existing configuration file\n", + "# Optionally, use existing configuration file\n", "# config = Configuration.from_files([\"config.json\"])\n", "\n", "# Define some constants\n", @@ -49,7 +49,7 @@ "# Load data using values set above\n", "from freqtrade.data.history import load_pair_history\n", "\n", - "candles = load_pair_history(datadir=config[\"data_dir\"],\n", + "candles = load_pair_history(datadir=config[\"datadir\"],\n", " timeframe=config[\"ticker_interval\"],\n", " pair=pair)\n", "\n", From 483cba453a3f9961ed6905b780de1a72881bdd20 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 12 Feb 2020 19:58:23 +0100 Subject: [PATCH 0485/1106] Fix last occurence of data_location --- docs/strategy_analysis_example.md | 2 +- freqtrade/templates/strategy_analysis_example.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 10ae73450..97a555e9e 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -34,7 +34,7 @@ candles = load_pair_history(datadir=config["datadir"], pair=pair) # Confirm success -print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}") +print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {config['datadir']}") candles.head() ``` diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 4541f5ed5..4b904e100 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -54,7 +54,7 @@ " pair=pair)\n", "\n", "# Confirm success\n", - "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {data_location}\")\n", + "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {config['datadir']}\")\n", "candles.head()" ] }, From 2efa1c164fa4c1b0f5bab1775fba7b0c496ef299 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 12 Feb 2020 21:43:43 +0100 Subject: [PATCH 0486/1106] Revert data-location section --- docs/strategy_analysis_example.md | 6 ++++-- freqtrade/templates/strategy_analysis_example.ipynb | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 97a555e9e..93e84122b 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -20,6 +20,8 @@ config = Configuration.from_files([]) config["ticker_interval"] = "5m" # Name of the strategy class config["strategy"] = "SampleStrategy" +# Location of the data +data_location = Path(config['user_data_dir'], 'data', 'binance') # Pair to analyze - Only use one pair here pair = "BTC_USDT" ``` @@ -29,12 +31,12 @@ pair = "BTC_USDT" # Load data using values set above from freqtrade.data.history import load_pair_history -candles = load_pair_history(datadir=config["datadir"], +candles = load_pair_history(datadir=data_location, timeframe=config["ticker_interval"], pair=pair) # Confirm success -print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {config['datadir']}") +print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}") candles.head() ``` diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 4b904e100..91e132380 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -36,6 +36,8 @@ "config[\"ticker_interval\"] = \"5m\"\n", "# Name of the strategy class\n", "config[\"strategy\"] = \"SampleStrategy\"\n", + "# Location of the data\n", + "data_location = Path(config['user_data_dir'], 'data', 'binance')\n", "# Pair to analyze - Only use one pair here\n", "pair = \"BTC_USDT\"" ] @@ -49,12 +51,12 @@ "# Load data using values set above\n", "from freqtrade.data.history import load_pair_history\n", "\n", - "candles = load_pair_history(datadir=config[\"datadir\"],\n", + "candles = load_pair_history(datadir=data_location,\n", " timeframe=config[\"ticker_interval\"],\n", " pair=pair)\n", "\n", "# Confirm success\n", - "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {config['datadir']}\")\n", + "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {data_location}\")\n", "candles.head()" ] }, From 47874a452787360b610ab0f3d038de6e53cc5d53 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 12 Feb 2020 21:45:55 +0100 Subject: [PATCH 0487/1106] added logic to differentiate sell orders with double asterisk --- docs/telegram-usage.md | 2 +- freqtrade/rpc/rpc.py | 3 ++- freqtrade/rpc/telegram.py | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index c8ded4af5..f683ae8da 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -55,7 +55,7 @@ official commands. You can ask at any moment for help with `/help`. | `/reload_conf` | | Reloads the configuration file | `/show_config` | | Shows part of the current configuration with relevant settings to operation | `/status` | | Lists all open trades -| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) +| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) Pending sell orders are marked with a double asterisk (**) | `/count` | | Displays number of trades used and available | `/profit` | | Display a summary of your profit/loss from close trades and some stats about your performance | `/forcesell ` | | Instantly sells the given trade (Ignoring `minimum_roi`). diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 07631f258..c182aad2b 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -169,7 +169,8 @@ class RPC: trades_list.append([ trade.id, trade.pair + '*' if (trade.open_order_id is not None - and trade.close_rate_requested is None) else '', + and trade.close_rate_requested is None) else '' + + '**' if (trade.close_rate_requested is not None) else '', shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ]) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index e3d4f54e7..d4ed5b189 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -561,6 +561,8 @@ class Telegram(RPC): "*/stop:* `Stops the trader`\n" \ "*/status [table]:* `Lists all open trades`\n" \ " *table :* `will display trades in a table`\n" \ + " pending buy orders are marked with an asterisk (*)\n" + " pending sell orders are marked with a double asterisk (**)\n" \ "*/profit:* `Lists cumulative profit from all finished trades`\n" \ "*/forcesell |all:* `Instantly sells the given trade or all trades, " \ "regardless of profit`\n" \ From f6db784a859b9a70a320e2c2da12dc47afce678e Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 12 Feb 2020 21:50:33 +0100 Subject: [PATCH 0488/1106] removed default to refresh argument in get_buy_rate and get_sell_rate --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ffd951ee2..455396352 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -234,7 +234,7 @@ class FreqtradeBot: return trades_created - def get_buy_rate(self, pair: str, refresh: bool = True, tick: Dict = None) -> float: + def get_buy_rate(self, pair: str, refresh: bool, tick: Dict = None) -> float: """ Calculates bid target between current ask price and last price :return: float: Price @@ -615,7 +615,7 @@ class FreqtradeBot: return trades_closed - def get_sell_rate(self, pair: str, refresh: bool = True) -> float: + def get_sell_rate(self, pair: str, refresh: bool) -> float: """ Get sell rate - either using get-ticker bid or first bid based on orderbook The orderbook portion is only used for rpc messaging, which would otherwise fail From 2e3b8cdba758a33abef2ce5f349335ff8194aa8a Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 12 Feb 2020 21:51:58 +0100 Subject: [PATCH 0489/1106] fixed flake8 issues on /help output --- freqtrade/rpc/telegram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index d4ed5b189..5603ab03c 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -561,8 +561,8 @@ class Telegram(RPC): "*/stop:* `Stops the trader`\n" \ "*/status [table]:* `Lists all open trades`\n" \ " *table :* `will display trades in a table`\n" \ - " pending buy orders are marked with an asterisk (*)\n" - " pending sell orders are marked with a double asterisk (**)\n" \ + " pending buy orders are marked with an asterisk (*)\n" \ + " pending sell orders are marked with a double asterisk (**)\n" \ "*/profit:* `Lists cumulative profit from all finished trades`\n" \ "*/forcesell |all:* `Instantly sells the given trade or all trades, " \ "regardless of profit`\n" \ From f09af888b153794ff135de9acedf493666124e9c Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 12 Feb 2020 21:55:38 +0100 Subject: [PATCH 0490/1106] modified get_buy/sell_rate refresh to true on notify_sell_cancel and notify_buy_cancel --- freqtrade/freqtradebot.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 455396352..158b631c1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -566,7 +566,7 @@ class FreqtradeBot: """ Sends rpc notification when a buy cancel occured. """ - current_rate = self.get_buy_rate(trade.pair, False) + current_rate = self.get_buy_rate(trade.pair, True) msg = { 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, @@ -1062,8 +1062,7 @@ class FreqtradeBot: """ profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) - # Use cached ticker here - it was updated seconds ago. - current_rate = self.get_sell_rate(trade.pair, False) + current_rate = self.get_sell_rate(trade.pair, True) profit_percent = trade.calc_profit_ratio(profit_rate) gain = "profit" if profit_percent > 0 else "loss" From 007cc94474c5f4bc0970f61b4716b00d8a8b8c92 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 12 Feb 2020 22:03:56 +0100 Subject: [PATCH 0491/1106] fixed tests to send refresh, since its no longer defaulted --- tests/test_freqtradebot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index c0af1f015..5ed4d296c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -921,7 +921,7 @@ def test_get_buy_rate(mocker, default_conf, ask, last, last_ab, expected) -> Non mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': ask, 'last': last})) - assert freqtrade.get_buy_rate('ETH/BTC') == expected + assert freqtrade.get_buy_rate('ETH/BTC', True) == expected def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: @@ -3524,7 +3524,7 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2) -> None: default_conf['telegram']['enabled'] = False freqtrade = FreqtradeBot(default_conf) - assert freqtrade.get_buy_rate('ETH/BTC') == 0.043935 + assert freqtrade.get_buy_rate('ETH/BTC', True) == 0.043935 assert ticker_mock.call_count == 0 @@ -3549,7 +3549,7 @@ def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2) -> None: freqtrade = FreqtradeBot(default_conf) # orderbook shall be used even if tickers would be lower. - assert freqtrade.get_buy_rate('ETH/BTC') != 0.042 + assert freqtrade.get_buy_rate('ETH/BTC', True) != 0.042 assert ticker_mock.call_count == 0 From 634bf2b15cf5078a1dba2fbd1ce0915346b30be5 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 13 Feb 2020 01:44:46 +0300 Subject: [PATCH 0492/1106] Docs: Fix checking of runmode --- docs/strategy-customization.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 688647c2b..07833da34 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -346,7 +346,7 @@ if self.dp: ``` python if self.dp: - if self.dp.runmode in ('live', 'dry_run'): + if self.dp.runmode.value in ('live', 'dry_run'): ob = self.dp.orderbook(metadata['pair'], 1) dataframe['best_bid'] = ob['bids'][0][0] dataframe['best_ask'] = ob['asks'][0][0] @@ -422,7 +422,7 @@ from freqtrade.persistence import Trade The following example queries for the current pair and trades from today, however other filters can easily be added. ``` python -if self.config['runmode'] in ('live', 'dry_run'): +if self.config['runmode'].value in ('live', 'dry_run'): trades = Trade.get_trades([Trade.pair == metadata['pair'], Trade.open_date > datetime.utcnow() - timedelta(days=1), Trade.is_open == False, @@ -434,7 +434,7 @@ if self.config['runmode'] in ('live', 'dry_run'): Get amount of stake_currency currently invested in Trades: ``` python -if self.config['runmode'] in ('live', 'dry_run'): +if self.config['runmode'].value in ('live', 'dry_run'): total_stakes = Trade.total_open_trades_stakes() ``` @@ -442,7 +442,7 @@ Retrieve performance per pair. Returns a List of dicts per pair. ``` python -if self.config['runmode'] in ('live', 'dry_run'): +if self.config['runmode'].value in ('live', 'dry_run'): performance = Trade.get_overall_performance() ``` @@ -487,7 +487,7 @@ from datetime import timedelta, datetime, timezone # -------- # Within populate indicators (or populate_buy): -if self.config['runmode'] in ('live', 'dry_run'): +if self.config['runmode'].value in ('live', 'dry_run'): # fetch closed trades for the last 2 days trades = Trade.get_trades([Trade.pair == metadata['pair'], Trade.open_date > datetime.utcnow() - timedelta(days=2), From b2328cdf4fdf45c1e2f3842ec08f855fa04f1552 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Thu, 13 Feb 2020 07:07:35 +0300 Subject: [PATCH 0493/1106] Do not subtract risk_free_ratio twice --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index c02f88434..d869a4e4e 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -53,7 +53,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): sum_daily['downside_returns'] = 0 sum_daily.loc[total_profit < 0, 'downside_returns'] = sum_daily['profit_percent_after_slippage'] - total_downside = sum_daily['downside_returns'] - risk_free_rate + total_downside = sum_daily['downside_returns'] down_stdev = total_downside.std() if (down_stdev != 0.): From 81f849811fdcf4a2273f56ba2d7851aec66990a6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Feb 2020 06:30:59 +0100 Subject: [PATCH 0494/1106] Initcap Freqtrade --- docs/strategy_analysis_example.md | 2 +- freqtrade/templates/strategy_analysis_example.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 93e84122b..f3f9b46c3 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -1,6 +1,6 @@ # Strategy analysis example -Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data. +Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data. ## Setup diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 91e132380..021056df2 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -6,7 +6,7 @@ "source": [ "# Strategy analysis example\n", "\n", - "Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data." + "Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data." ] }, { From 86592c3ba1c0f4b626d7d4edb471a320d120dd13 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Feb 2020 06:51:52 +0100 Subject: [PATCH 0495/1106] Fix /help from telegram --- freqtrade/rpc/telegram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 5603ab03c..abd322293 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -561,8 +561,8 @@ class Telegram(RPC): "*/stop:* `Stops the trader`\n" \ "*/status [table]:* `Lists all open trades`\n" \ " *table :* `will display trades in a table`\n" \ - " pending buy orders are marked with an asterisk (*)\n" \ - " pending sell orders are marked with a double asterisk (**)\n" \ + " `pending buy orders are marked with an asterisk (*)`\n" \ + " `pending sell orders are marked with a double asterisk (**)`\n" \ "*/profit:* `Lists cumulative profit from all finished trades`\n" \ "*/forcesell |all:* `Instantly sells the given trade or all trades, " \ "regardless of profit`\n" \ From ccc923975138e47440e5ce48fd6fb38c1f0691c1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Feb 2020 07:02:12 +0100 Subject: [PATCH 0496/1106] Reduce indentation of help --- freqtrade/rpc/telegram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index abd322293..e3958b31a 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -561,8 +561,8 @@ class Telegram(RPC): "*/stop:* `Stops the trader`\n" \ "*/status [table]:* `Lists all open trades`\n" \ " *table :* `will display trades in a table`\n" \ - " `pending buy orders are marked with an asterisk (*)`\n" \ - " `pending sell orders are marked with a double asterisk (**)`\n" \ + " `pending buy orders are marked with an asterisk (*)`\n" \ + " `pending sell orders are marked with a double asterisk (**)`\n" \ "*/profit:* `Lists cumulative profit from all finished trades`\n" \ "*/forcesell |all:* `Instantly sells the given trade or all trades, " \ "regardless of profit`\n" \ From a93bc74eff01cebaed7e1e9838a53b526178913d Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Feb 2020 07:04:37 +0100 Subject: [PATCH 0497/1106] Update documentation ... --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index c0404d647..98300c5fa 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,7 +40,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
***Datatype:*** *Positive integer or -1.* +| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* From 02148a1df203d8512dc6987ce7ac4ad5111211a2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 Feb 2020 15:09:09 +0100 Subject: [PATCH 0498/1106] Fix datatype styling issues --- docs/configuration.md | 132 +++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 98300c5fa..fd686834f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -41,74 +41,74 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. -| `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* -| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* -| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* -| `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* -| `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* -| `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* -| `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
*Defaults to `true`.*
***Datatype:*** *Boolean* -| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
*Defaults to `1000`.*
***Datatype:*** *Float* -| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Dict* -| `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Float (as ratio)* -| `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Boolean* -| `trailing_stop_positive` | Changes stoploss once profit has been reached. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Float* -| `trailing_stop_positive_offset` | Offset on when to apply `trailing_stop_positive`. Percentage value which should be positive. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `0.0` (no offset).*
***Datatype:*** *Float* -| `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Integer* -| `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Integer* +| `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String +| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Positive float or `"unlimited"`. +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
**Datatype:** Positive float between `0.1` and `1.0`. +| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
**Datatype:** Boolean +| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
**Datatype:** Float (as ratio) +| `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
**Datatype:** Positive Float as ratio. +| `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String +| `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
**Datatype:** String +| `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
*Defaults to `true`.*
**Datatype:** Boolean +| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
*Defaults to `1000`.*
**Datatype:** Float +| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Dict +| `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Float (as ratio) +| `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Boolean +| `trailing_stop_positive` | Changes stoploss once profit has been reached. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Float +| `trailing_stop_positive_offset` | Offset on when to apply `trailing_stop_positive`. Percentage value which should be positive. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `0.0` (no offset).*
**Datatype:** Float +| `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Integer +| `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Integer | `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#buy-price-without-orderbook). -| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled).
***Datatype:*** *Boolean* -| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled).
*Defaults to `1`.*
***Datatype:*** *Positive Integer* -| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market)
*Defaults to `0`.*
***Datatype:*** *Float (as ratio)* -| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled).
***Datatype:*** *Boolean* -| `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
***Datatype:*** *Positive Integer* -| `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
***Datatype:*** *Positive Integer* -| `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `true`.*
***Datatype:*** *Boolean* -| `ask_strategy.sell_profit_only` | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `ask_strategy.ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `order_types` | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Dict* -| `order_time_in_force` | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Dict* -| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
***Datatype:*** *String* -| `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
***Datatype:*** *Boolean* -| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#dynamic-pairlists)).
***Datatype:*** *List* -| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#dynamic-pairlists)).
***Datatype:*** *List* -| `exchange.ccxt_config` | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
***Datatype:*** *Dict* -| `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
***Datatype:*** *Dict* -| `exchange.markets_refresh_interval` | The interval in minutes in which markets are reloaded.
*Defaults to `60` minutes.*
***Datatype:*** *Positive Integer* +| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled).
**Datatype:** Boolean +| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled).
*Defaults to `1`.*
**Datatype:** Positive Integer +| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market).
*Defaults to `false`.*
**Datatype:** Boolean +| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market)
*Defaults to `0`.*
**Datatype:** Float (as ratio) +| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled).
**Datatype:** Boolean +| `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer +| `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer +| `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `true`.*
**Datatype:** Boolean +| `ask_strategy.sell_profit_only` | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `ask_strategy.ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean +| `order_types` | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Dict +| `order_time_in_force` | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Dict +| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
**Datatype:** String +| `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
**Datatype:** Boolean +| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#dynamic-pairlists)).
**Datatype:** List +| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#dynamic-pairlists)).
**Datatype:** List +| `exchange.ccxt_config` | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
**Datatype:** Dict +| `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
**Datatype:** Dict +| `exchange.markets_refresh_interval` | The interval in minutes in which markets are reloaded.
*Defaults to `60` minutes.*
**Datatype:** Positive Integer | `edge.*` | Please refer to [edge configuration document](edge.md) for detailed explanation. -| `experimental.block_bad_exchanges` | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
*Defaults to `true`.*
***Datatype:*** *Boolean* -| `pairlists` | Define one or more pairlists to be used. [More information below](#dynamic-pairlists).
*Defaults to `StaticPairList`.*
***Datatype:*** *List of Dicts* -| `telegram.enabled` | Enable the usage of Telegram.
***Datatype:*** *Boolean* -| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `webhook.enabled` | Enable usage of Webhook notifications
***Datatype:*** *Boolean* -| `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* -| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
***Datatype:*** *String* -| `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Boolean* -| `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *IPv4* -| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
***Datatype:*** *Integer between 1024 and 65535* -| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
***Datatype:*** *String* -| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances.
***Datatype:*** *String, SQLAlchemy connect string* -| `initial_state` | Defines the initial application state. More information below.
*Defaults to `stopped`.*
***Datatype:*** *Enum, either `stopped` or `running`* -| `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below.
***Datatype:*** *Boolean* -| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`.
***Datatype:*** *ClassName* -| `strategy_path` | Adds an additional strategy lookup path (must be a directory).
***Datatype:*** *String* -| `internals.process_throttle_secs` | Set the process throttle. Value in second.
*Defaults to `5` seconds.*
***Datatype:*** *Positive Integer* -| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages.
*Defaults to `60` seconds.*
***Datatype:*** *Positive Integer or 0* -| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
***Datatype:*** *Boolean* -| `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file.
***Datatype:*** *String* -| `user_data_dir` | Directory containing user data.
*Defaults to `./user_data/`*.
***Datatype:*** *String* +| `experimental.block_bad_exchanges` | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
*Defaults to `true`.*
**Datatype:** Boolean +| `pairlists` | Define one or more pairlists to be used. [More information below](#dynamic-pairlists).
*Defaults to `StaticPairList`.*
**Datatype:** List of Dicts +| `telegram.enabled` | Enable the usage of Telegram.
**Datatype:** Boolean +| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `webhook.enabled` | Enable usage of Webhook notifications
**Datatype:** Boolean +| `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String +| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String +| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String +| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
**Datatype:** String +| `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details.
**Datatype:** Boolean +| `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details.
**Datatype:** IPv4 +| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details.
**Datatype:** Integer between 1024 and 65535 +| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String +| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances.
**Datatype:** String, SQLAlchemy connect string +| `initial_state` | Defines the initial application state. More information below.
*Defaults to `stopped`.*
**Datatype:** Enum, either `stopped` or `running` +| `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below.
**Datatype:** Boolean +| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`.
**Datatype:** ClassName +| `strategy_path` | Adds an additional strategy lookup path (must be a directory).
**Datatype:** String +| `internals.process_throttle_secs` | Set the process throttle. Value in second.
*Defaults to `5` seconds.*
**Datatype:** Positive Intege +| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages.
*Defaults to `60` seconds.*
**Datatype:** Positive Integer or 0 +| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
**Datatype:** Boolean +| `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file.
**Datatype:** String +| `user_data_dir` | Directory containing user data.
*Defaults to `./user_data/`*.
**Datatype:** String ### Parameters in the strategy From a0a14a107820df972d1e02b42267093f58748f1e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 01:08:17 +0300 Subject: [PATCH 0499/1106] freqtrade/templates/subtemplates/exchange_bittrex.j2 --- freqtrade/templates/subtemplates/exchange_bittrex.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/freqtrade/templates/subtemplates/exchange_bittrex.j2 b/freqtrade/templates/subtemplates/exchange_bittrex.j2 index 7a7e8e291..7b27318ca 100644 --- a/freqtrade/templates/subtemplates/exchange_bittrex.j2 +++ b/freqtrade/templates/subtemplates/exchange_bittrex.j2 @@ -1,3 +1,10 @@ +"order_types": { + "buy": "limit", + "sell": "limit", + "emergencysell": "limit", + "stoploss": "limit", + "stoploss_on_exchange": false +}, "exchange": { "name": "{{ exchange_name | lower }}", "key": "{{ exchange_key }}", From 749463e4b7e9f9b1c475725a54b71d181b3a7a76 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 03:05:07 +0300 Subject: [PATCH 0500/1106] Adjust message in main.py --- freqtrade/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/main.py b/freqtrade/main.py index a75eeebed..08bdc5e32 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -38,8 +38,8 @@ def main(sysargv: List[str] = None) -> None: # No subcommand was issued. raise OperationalException( "Usage of Freqtrade requires a subcommand to be specified.\n" - "To have the previous behavior (bot executing trades in live/dry-run modes, " - "depending on the value of the `dry_run` setting in the config), run freqtrade " + "To have the bot executing trades in live/dry-run modes, " + "depending on the value of the `dry_run` setting in the config, run Freqtrade " "as `freqtrade trade [options...]`.\n" "To see the full list of options available, please use " "`freqtrade --help` or `freqtrade --help`." From 36ef5c6bdff2562e158bbd659db7bc6c67c00560 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 04:05:17 +0300 Subject: [PATCH 0501/1106] Get rid of delete_trades method in Freqtradebot --- freqtrade/freqtradebot.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 158b631c1..bf2697efa 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -860,11 +860,6 @@ class FreqtradeBot: order_type = self.strategy.order_types['sell'] self._notify_sell_cancel(trade, order_type) - def delete_trade(self, trade: Trade) -> None: - """Delete trade in database""" - Trade.session.delete(trade) - Trade.session.flush() - def handle_timedout_limit_buy(self, trade: Trade, order: Dict) -> bool: """ Buy timeout - cancel order @@ -882,7 +877,8 @@ class FreqtradeBot: if corder.get('remaining', order['remaining']) == order['amount']: # if trade is not partially completed, just delete the trade - self.delete_trade(trade) + Trade.session.delete(trade) + Trade.session.flush() return True # if trade is partially complete, edit the stake details for the trade From 20c21b42d50ce08fe4157c151c340a6be771b7f2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 06:23:03 +0300 Subject: [PATCH 0502/1106] Move rpc send to be after db session add/flash --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 158b631c1..1284b2e9b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -527,8 +527,6 @@ class FreqtradeBot: ticker_interval=timeframe_to_minutes(self.config['ticker_interval']) ) - self._notify_buy(trade, order_type) - # Update fees if order is closed if order_status == 'closed': self.update_trade_state(trade, order) @@ -539,6 +537,8 @@ class FreqtradeBot: # Updating wallets self.wallets.update() + self._notify_buy(trade, order_type) + return True def _notify_buy(self, trade: Trade, order_type: str) -> None: From 9cbf8c5f008520b99016a7a63fe299b4b0dcb821 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 21:15:36 +0300 Subject: [PATCH 0503/1106] Add status for listed strategies --- freqtrade/commands/list_commands.py | 11 +++++++++-- freqtrade/resolvers/iresolver.py | 20 +++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index f2b6bf995..b6ff682e6 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -43,10 +43,17 @@ def start_list_strategies(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES)) - strategies = StrategyResolver.search_all_objects(directory) + strategies = StrategyResolver.search_all_objects(directory, not args['print_one_column']) # Sort alphabetically strategies = sorted(strategies, key=lambda x: x['name']) - strats_to_print = [{'name': s['name'], 'location': s['location'].name} for s in strategies] + names = [s['name'] for s in strategies] + strats_to_print = [{ + 'name': s['name'] if s['name'] else "--", + 'location': s['location'].name, + 'status': ("LOAD FAILED" if s['class'] is None + else "OK" if names.count(s['name']) == 1 + else "DUPLICATED NAME") + } for s in strategies] if args['print_one_column']: print('\n'.join([s['name'] for s in strategies])) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index a75c45933..8b5aa1dff 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -41,11 +41,15 @@ class IResolver: @classmethod def _get_valid_object(cls, module_path: Path, - object_name: Optional[str]) -> Generator[Any, None, None]: + object_name: Optional[str], + enum_failed: bool = False) -> Union[Generator[Any, None, None], + Tuple[None]]: """ Generator returning objects with matching object_type and object_name in the path given. :param module_path: absolute path to the module :param object_name: Class name of the object + :param enum_failed: If True, will return None for modules which fail. + Otherwise, failing modules are skipped. :return: generator containing matching objects """ @@ -58,6 +62,8 @@ class IResolver: except (ModuleNotFoundError, SyntaxError) 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 (None, ) valid_objects_gen = ( obj for name, obj in inspect.getmembers(module, inspect.isclass) @@ -136,10 +142,13 @@ class IResolver: ) @classmethod - def search_all_objects(cls, directory: Path) -> List[Dict[str, Any]]: + def search_all_objects(cls, directory: Path, + enum_failed: bool) -> List[Dict[str, Any]]: """ Searches a directory for valid objects :param directory: Path to search + :param enum_failed: If True, will return None for modules which fail. + Otherwise, failing modules are skipped. :return: List of dicts containing 'name', 'class' and 'location' entires """ logger.debug(f"Searching for {cls.object_type.__name__} '{directory}'") @@ -151,10 +160,11 @@ class IResolver: continue module_path = entry.resolve() logger.debug(f"Path {module_path}") - for obj in cls._get_valid_object(module_path, object_name=None): + for obj in cls._get_valid_object(module_path, object_name=None, + enum_failed=enum_failed): objects.append( - {'name': obj.__name__, - 'class': obj, + {'name': obj.__name__ if obj is not None else '', + 'class': obj if obj is not None else None, 'location': entry, }) return objects From a2d7f8a70dc8e907c83ab4e958783708174ab07f Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 21:24:30 +0300 Subject: [PATCH 0504/1106] Split tabular printing into sep. helper function --- freqtrade/commands/list_commands.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index b6ff682e6..782cd074e 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -3,7 +3,7 @@ import logging import sys from collections import OrderedDict from pathlib import Path -from typing import Any, Dict +from typing import Any, Dict, List import rapidjson from tabulate import tabulate @@ -36,6 +36,19 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}") +def _print_objs_tabular(objs: List) -> None: + names = [s['name'] for s in objs] + strats_to_print = [{ + 'name': s['name'] if s['name'] else "--", + 'location': s['location'].name, + 'status': ("LOAD FAILED" if s['class'] is None + else "OK" if names.count(s['name']) == 1 + else "DUPLICATED NAME") + } for s in objs] + + print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) + + def start_list_strategies(args: Dict[str, Any]) -> None: """ Print files with Strategy custom classes available in the directory @@ -46,19 +59,11 @@ def start_list_strategies(args: Dict[str, Any]) -> None: strategies = StrategyResolver.search_all_objects(directory, not args['print_one_column']) # Sort alphabetically strategies = sorted(strategies, key=lambda x: x['name']) - names = [s['name'] for s in strategies] - strats_to_print = [{ - 'name': s['name'] if s['name'] else "--", - 'location': s['location'].name, - 'status': ("LOAD FAILED" if s['class'] is None - else "OK" if names.count(s['name']) == 1 - else "DUPLICATED NAME") - } for s in strategies] if args['print_one_column']: print('\n'.join([s['name'] for s in strategies])) else: - print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) + _print_objs_tabular(strategies) def start_list_hyperopts(args: Dict[str, Any]) -> None: From 9dafc2f3c84819cf95bda82ddb0cc8ec380ede3d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 11 Feb 2020 20:38:29 +0100 Subject: [PATCH 0505/1106] Load config.json from user_data first --- freqtrade/commands/arguments.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index fe6f49039..d37870ea0 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -6,8 +6,8 @@ from functools import partial from pathlib import Path from typing import Any, Dict, List, Optional -from freqtrade import constants from freqtrade.commands.cli_options import AVAILABLE_CLI_OPTIONS +from freqtrade.constants import DEFAULT_CONFIG ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"] @@ -107,10 +107,19 @@ class Arguments: # Workaround issue in argparse with action='append' and default value # (see https://bugs.python.org/issue16399) # Allow no-config for certain commands (like downloading / plotting) - if ('config' in parsed_arg and parsed_arg.config is None and - ((Path.cwd() / constants.DEFAULT_CONFIG).is_file() or - not ('command' in parsed_arg and parsed_arg.command in NO_CONF_REQURIED))): - parsed_arg.config = [constants.DEFAULT_CONFIG] + if ('config' in parsed_arg and parsed_arg.config is None): + conf_required = ('command' in parsed_arg and parsed_arg.command in NO_CONF_REQURIED) + + if 'user_data_dir' in parsed_arg and parsed_arg.user_data_dir is not None: + # Try loading from "user_data/config.json" + cfgfile = Path(parsed_arg.user_data_dir) / DEFAULT_CONFIG + if cfgfile.is_file() or not conf_required: + parsed_arg.config = [str(cfgfile)] + else: + # Else use "config.json". + cfgfile = Path.cwd() / DEFAULT_CONFIG + if cfgfile.is_file() or not conf_required: + parsed_arg.config = [DEFAULT_CONFIG] return parsed_arg From be4a9b5f4b0f9c4026ed043876bbcfb516a83a0d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 14 Feb 2020 19:37:20 +0100 Subject: [PATCH 0506/1106] Lowercase freqtrade --- CONTRIBUTING.md | 4 ++-- docs/configuration.md | 2 +- docs/developer.md | 4 ++-- docs/hyperopt.md | 2 +- docs/rest-api.md | 2 +- freqtrade/commands/cli_options.py | 3 ++- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c83437f6..90594866a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -109,11 +109,11 @@ Exceptions: Contributors may be given commit privileges. Preference will be given to those with: -1. Past contributions to FreqTrade and other related open-source projects. Contributions to FreqTrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Quantity and quality are considered. +1. Past contributions to Freqtrade and other related open-source projects. Contributions to Freqtrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Quantity and quality are considered. 1. A coding style that the other core committers find simple, minimal, and clean. 1. Access to resources for cross-platform development and testing. 1. Time to devote to the project regularly. -Being a Committer does not grant write permission on `develop` or `master` for security reasons (Users trust FreqTrade with their Exchange API keys). +Being a Committer does not grant write permission on `develop` or `master` for security reasons (Users trust Freqtrade with their Exchange API keys). After being Committer for some time, a Committer may be named Core Committer and given full repository access. diff --git a/docs/configuration.md b/docs/configuration.md index 211f7a04c..0f0279eb9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -672,7 +672,7 @@ freqtrade ## Embedding Strategies -FreqTrade provides you with with an easy way to embed the strategy into your configuration file. +Freqtrade provides you with with an easy way to embed the strategy into your configuration file. This is done by utilizing BASE64 encoding and providing this string at the strategy configuration field, in your chosen config file. diff --git a/docs/developer.md b/docs/developer.md index c679b8a49..b128ffd2b 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -1,6 +1,6 @@ # Development Help -This page is intended for developers of FreqTrade, people who want to contribute to the FreqTrade codebase or documentation, or people who want to understand the source code of the application they're running. +This page is intended for developers of Freqtrade, people who want to contribute to the Freqtrade codebase or documentation, or people who want to understand the source code of the application they're running. All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome. We [track issues](https://github.com/freqtrade/freqtrade/issues) on [GitHub](https://github.com) and also have a dev channel in [slack](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) where you can ask questions. @@ -153,7 +153,7 @@ In VolumePairList, this implements different methods of sorting, does early vali ## Implement a new Exchange (WIP) !!! Note - This section is a Work in Progress and is not a complete guide on how to test a new exchange with FreqTrade. + This section is a Work in Progress and is not a complete guide on how to test a new exchange with Freqtrade. Most exchanges supported by CCXT should work out of the box. diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 3e10f66da..401811a1b 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -182,7 +182,7 @@ add it to the `populate_indicators()` method in your custom hyperopt file. Each hyperparameter tuning requires a target. This is usually defined as a loss function (sometimes also called objective function), which should decrease for more desirable results, and increase for bad results. -By default, FreqTrade uses a loss function, which has been with freqtrade since the beginning and optimizes mostly for short trade duration and avoiding losses. +By default, Freqtrade uses a loss function, which has been with freqtrade since the beginning and optimizes mostly for short trade duration and avoiding losses. A different loss function can be specified by using the `--hyperopt-loss ` argument. This class should be in its own file within the `user_data/hyperopts/` directory. diff --git a/docs/rest-api.md b/docs/rest-api.md index 187a71c97..b68364f39 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -74,7 +74,7 @@ docker run -d \ ## Consuming the API You can consume the API by using the script `scripts/rest_client.py`. -The client script only requires the `requests` module, so FreqTrade does not need to be installed on the system. +The client script only requires the `requests` module, so Freqtrade does not need to be installed on the system. ``` bash python3 scripts/rest_client.py [optional parameters] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 1776955b1..cdc8cb8f1 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -59,7 +59,8 @@ AVAILABLE_CLI_OPTIONS = { ), "config": Arg( '-c', '--config', - help=f'Specify configuration file (default: `{constants.DEFAULT_CONFIG}`). ' + help=f'Specify configuration file (default: `userdir/{constants.DEFAULT_CONFIG}` ' + f'or `config.json` whichever exists). ' f'Multiple --config options may be used. ' f'Can be set to `-` to read config from stdin.', action='append', From 1bc26fd07a11bf064098e544e4a42063d3294b90 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 21:46:22 +0300 Subject: [PATCH 0507/1106] Add printing statuses for list-hyperopts --- freqtrade/commands/list_commands.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 782cd074e..a2ac388b0 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -38,7 +38,7 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: def _print_objs_tabular(objs: List) -> None: names = [s['name'] for s in objs] - strats_to_print = [{ + objss_to_print = [{ 'name': s['name'] if s['name'] else "--", 'location': s['location'].name, 'status': ("LOAD FAILED" if s['class'] is None @@ -46,7 +46,7 @@ def _print_objs_tabular(objs: List) -> None: else "DUPLICATED NAME") } for s in objs] - print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) + print(tabulate(objss_to_print, headers='keys', tablefmt='pipe')) def start_list_strategies(args: Dict[str, Any]) -> None: @@ -56,14 +56,14 @@ def start_list_strategies(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES)) - strategies = StrategyResolver.search_all_objects(directory, not args['print_one_column']) + strategy_objs = StrategyResolver.search_all_objects(directory, not args['print_one_column']) # Sort alphabetically - strategies = sorted(strategies, key=lambda x: x['name']) + strategy_objs = sorted(strategy_objs, key=lambda x: x['name']) if args['print_one_column']: - print('\n'.join([s['name'] for s in strategies])) + print('\n'.join([s['name'] for s in strategy_objs])) else: - _print_objs_tabular(strategies) + _print_objs_tabular(strategy_objs) def start_list_hyperopts(args: Dict[str, Any]) -> None: @@ -75,15 +75,14 @@ def start_list_hyperopts(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) directory = Path(config.get('hyperopt_path', config['user_data_dir'] / USERPATH_HYPEROPTS)) - hyperopts = HyperOptResolver.search_all_objects(directory) + hyperopt_objs = HyperOptResolver.search_all_objects(directory, not args['print_one_column']) # Sort alphabetically - hyperopts = sorted(hyperopts, key=lambda x: x['name']) - hyperopts_to_print = [{'name': s['name'], 'location': s['location'].name} for s in hyperopts] + hyperopt_objs = sorted(hyperopt_objs, key=lambda x: x['name']) if args['print_one_column']: - print('\n'.join([s['name'] for s in hyperopts])) + print('\n'.join([s['name'] for s in hyperopt_objs])) else: - print(tabulate(hyperopts_to_print, headers='keys', tablefmt='pipe')) + _print_objs_tabular(hyperopt_objs) def start_list_timeframes(args: Dict[str, Any]) -> None: From c92e1d97d65b796a061d19081f701cac6aa59ce3 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 21:52:02 +0300 Subject: [PATCH 0508/1106] Attempt to make mypy happy --- freqtrade/resolvers/iresolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 8b5aa1dff..d674daa9a 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -89,7 +89,7 @@ class IResolver: continue module_path = entry.resolve() - obj = next(cls._get_valid_object(module_path, object_name), None) + obj = next(cls._get_valid_object(module_path, object_name), None) # noqa if obj: return (obj, module_path) From 5efbdd25a7776c55eb8fbfb43a0e4b09213b4c41 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 14 Feb 2020 20:04:05 +0100 Subject: [PATCH 0509/1106] Properly default to user_data/config.json if it exists --- docs/bot-usage.md | 52 +++++++++++++++++++++------------ freqtrade/commands/arguments.py | 10 +++++-- tests/test_arguments.py | 24 +++++++++++++-- tests/test_main.py | 5 +++- 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 56e6008a1..dbc111d44 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -58,9 +58,10 @@ Common arguments: details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH @@ -71,6 +72,7 @@ Strategy arguments: Specify strategy class name which will be used by the bot. --strategy-path PATH Specify additional strategy lookup path. +. ``` @@ -242,12 +244,15 @@ optional arguments: Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH @@ -280,7 +285,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--hyperopt NAME] [--hyperopt-path PATH] [--eps] [-e INT] - [--spaces {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]] + [--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]] [--dmmp] [--print-all] [--no-color] [--print-json] [-j JOBS] [--random-state INT] [--min-trades INT] [--continue] [--hyperopt-loss NAME] @@ -308,9 +313,9 @@ optional arguments: Allow buying the same pair multiple times (position stacking). -e INT, --epochs INT Specify number of epochs (default: 100). - --spaces {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...] + --spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...] Specify which parameters to hyperopt. Space-separated - list. Default: `all`. + list. --dmmp, --disable-max-market-positions Disable applying `max_open_trades` during backtest (same as setting `max_open_trades` to a very high @@ -338,16 +343,20 @@ optional arguments: target for optimization is different. Built-in Hyperopt-loss-functions are: DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, - SharpeHyperOptLossDaily (default: `DefaultHyperOptLoss`). + SharpeHyperOptLossDaily.(default: + `DefaultHyperOptLoss`). Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH @@ -358,6 +367,7 @@ Strategy arguments: Specify strategy class name which will be used by the bot. --strategy-path PATH Specify additional strategy lookup path. + ``` ## Edge commands @@ -394,12 +404,15 @@ optional arguments: Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH @@ -410,6 +423,7 @@ Strategy arguments: Specify strategy class name which will be used by the bot. --strategy-path PATH Specify additional strategy lookup path. + ``` To understand edge and how to read the results, please read the [edge documentation](edge.md). diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index d37870ea0..580c9e298 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -111,10 +111,14 @@ class Arguments: conf_required = ('command' in parsed_arg and parsed_arg.command in NO_CONF_REQURIED) if 'user_data_dir' in parsed_arg and parsed_arg.user_data_dir is not None: + user_dir = parsed_arg.user_data_dir + else: + # Default case + user_dir = 'user_data' # Try loading from "user_data/config.json" - cfgfile = Path(parsed_arg.user_data_dir) / DEFAULT_CONFIG - if cfgfile.is_file() or not conf_required: - parsed_arg.config = [str(cfgfile)] + cfgfile = Path(user_dir) / DEFAULT_CONFIG + if cfgfile.is_file(): + parsed_arg.config = [str(cfgfile)] else: # Else use "config.json". cfgfile = Path.cwd() / DEFAULT_CONFIG diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 60da0082a..61bca04a4 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -18,7 +18,8 @@ def test_parse_args_none() -> None: assert isinstance(arguments.parser, argparse.ArgumentParser) -def test_parse_args_defaults() -> None: +def test_parse_args_defaults(mocker) -> None: + mocker.patch.object(Path, "is_file", MagicMock(side_effect=[False, True])) args = Arguments(['trade']).get_parsed_arg() assert args["config"] == ['config.json'] assert args["strategy_path"] is None @@ -26,6 +27,25 @@ def test_parse_args_defaults() -> None: assert args["verbosity"] == 0 +def test_parse_args_default_userdatadir(mocker) -> None: + mocker.patch.object(Path, "is_file", MagicMock(return_value=True)) + args = Arguments(['trade']).get_parsed_arg() + # configuration defaults to user_data if that is available. + assert args["config"] == ['user_data/config.json'] + assert args["strategy_path"] is None + assert args["datadir"] is None + assert args["verbosity"] == 0 + + +def test_parse_args_userdatadir(mocker) -> None: + mocker.patch.object(Path, "is_file", MagicMock(return_value=True)) + args = Arguments(['trade', '--user-data-dir', 'user_data']).get_parsed_arg() + # configuration defaults to user_data if that is available. + assert args["config"] == ['user_data/config.json'] + assert args["strategy_path"] is None + assert args["datadir"] is None + assert args["verbosity"] == 0 + def test_parse_args_config() -> None: args = Arguments(['trade', '-c', '/dev/null']).get_parsed_arg() assert args["config"] == ['/dev/null'] @@ -208,7 +228,7 @@ def test_config_notrequired(mocker) -> None: assert pargs["config"] is None # When file exists: - mocker.patch.object(Path, "is_file", MagicMock(return_value=True)) + mocker.patch.object(Path, "is_file", MagicMock(side_effect=[False, True])) args = [ 'download-data', ] diff --git a/tests/test_main.py b/tests/test_main.py index 1229f748a..70b784002 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -5,8 +5,9 @@ from unittest.mock import MagicMock, PropertyMock import pytest +from pathlib import Path from freqtrade.commands import Arguments -from freqtrade.exceptions import OperationalException, FreqtradeException +from freqtrade.exceptions import FreqtradeException, OperationalException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.main import main from freqtrade.state import State @@ -26,6 +27,7 @@ def test_parse_args_backtesting(mocker) -> None: Test that main() can start backtesting and also ensure we can pass some specific arguments further argument parsing is done in test_arguments.py """ + mocker.patch.object(Path, "is_file", MagicMock(side_effect=[False, True])) backtesting_mock = mocker.patch('freqtrade.commands.start_backtesting') backtesting_mock.__name__ = PropertyMock("start_backtesting") # it's sys.exit(0) at the end of backtesting @@ -42,6 +44,7 @@ def test_parse_args_backtesting(mocker) -> None: def test_main_start_hyperopt(mocker) -> None: + mocker.patch.object(Path, "is_file", MagicMock(side_effect=[False, True])) hyperopt_mock = mocker.patch('freqtrade.commands.start_hyperopt', MagicMock()) hyperopt_mock.__name__ = PropertyMock("start_hyperopt") # it's sys.exit(0) at the end of hyperopt From d5a298bbb7dd3db6be8f16c7ec1376fc7c677901 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 14 Feb 2020 20:12:26 +0100 Subject: [PATCH 0510/1106] Add sentence from suggestion --- docs/strategy_analysis_example.md | 1 + freqtrade/templates/strategy_analysis_example.ipynb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index f3f9b46c3..53b35ca09 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -1,6 +1,7 @@ # Strategy analysis example Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data. +The following assumes you work with SampleStrategy, data for 5m timeframe from Binance and have downloaded them into the data directory in the default location. ## Setup diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 021056df2..399235cfe 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -6,7 +6,8 @@ "source": [ "# Strategy analysis example\n", "\n", - "Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data." + "Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data.\n", + "The following assumes you work with SampleStrategy, data for 5m timeframe from Binance and have downloaded them into the data directory in the default location." ] }, { From ecca7164d91a41ee252c93c2533e6e7737d0db71 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 14 Feb 2020 20:13:36 +0100 Subject: [PATCH 0511/1106] Fix small issue --- tests/test_arguments.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 61bca04a4..22383661b 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -46,6 +46,7 @@ def test_parse_args_userdatadir(mocker) -> None: assert args["datadir"] is None assert args["verbosity"] == 0 + def test_parse_args_config() -> None: args = Arguments(['trade', '-c', '/dev/null']).get_parsed_arg() assert args["config"] == ['/dev/null'] From f024cc40d3808bfd75d55e75f8a8370b86cae57e Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 14 Feb 2020 20:21:09 +0100 Subject: [PATCH 0512/1106] Fix windows test failure --- tests/test_arguments.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 22383661b..0052a61d0 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -31,7 +31,7 @@ def test_parse_args_default_userdatadir(mocker) -> None: mocker.patch.object(Path, "is_file", MagicMock(return_value=True)) args = Arguments(['trade']).get_parsed_arg() # configuration defaults to user_data if that is available. - assert args["config"] == ['user_data/config.json'] + assert args["config"] == [str(Path('user_data/config.json'))] assert args["strategy_path"] is None assert args["datadir"] is None assert args["verbosity"] == 0 @@ -41,7 +41,7 @@ def test_parse_args_userdatadir(mocker) -> None: mocker.patch.object(Path, "is_file", MagicMock(return_value=True)) args = Arguments(['trade', '--user-data-dir', 'user_data']).get_parsed_arg() # configuration defaults to user_data if that is available. - assert args["config"] == ['user_data/config.json'] + assert args["config"] == [str(Path('user_data/config.json'))] assert args["strategy_path"] is None assert args["datadir"] is None assert args["verbosity"] == 0 From e598c769d448db0a03c7c7df5d470d3a389d8cee Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 22:28:49 +0300 Subject: [PATCH 0513/1106] Add colorization --- freqtrade/commands/arguments.py | 4 ++-- freqtrade/commands/list_commands.py | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index fe6f49039..063a152fe 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -30,9 +30,9 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] -ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column"] +ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column", "print_colorized"] -ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column"] +ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column", "print_colorized"] ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index a2ac388b0..6a2ccbfcf 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -5,6 +5,8 @@ from collections import OrderedDict from pathlib import Path from typing import Any, Dict, List +from colorama import init as colorama_init +from colorama import Fore, Style import rapidjson from tabulate import tabulate @@ -36,14 +38,23 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}") -def _print_objs_tabular(objs: List) -> None: +def _print_objs_tabular(objs: List, print_colorized: bool) -> None: + if print_colorized: + colorama_init(autoreset=True) + names = [s['name'] for s in objs] objss_to_print = [{ 'name': s['name'] if s['name'] else "--", 'location': s['location'].name, - 'status': ("LOAD FAILED" if s['class'] is None - else "OK" if names.count(s['name']) == 1 - else "DUPLICATED NAME") + 'status': (((Fore.RED if print_colorized else '') + + "LOAD FAILED" + (Style.RESET_ALL if print_colorized else '')) + if s['class'] is None + else ((Fore.GREEN if print_colorized else '') + + "OK" + (Style.RESET_ALL if print_colorized else '')) + if names.count(s['name']) == 1 + else ((Fore.YELLOW if print_colorized else '') + + "DUPLICATED NAME" + + (Style.RESET_ALL if print_colorized else ''))) } for s in objs] print(tabulate(objss_to_print, headers='keys', tablefmt='pipe')) @@ -63,7 +74,7 @@ def start_list_strategies(args: Dict[str, Any]) -> None: if args['print_one_column']: print('\n'.join([s['name'] for s in strategy_objs])) else: - _print_objs_tabular(strategy_objs) + _print_objs_tabular(strategy_objs, config.get('print_colorized', False)) def start_list_hyperopts(args: Dict[str, Any]) -> None: @@ -82,7 +93,7 @@ def start_list_hyperopts(args: Dict[str, Any]) -> None: if args['print_one_column']: print('\n'.join([s['name'] for s in hyperopt_objs])) else: - _print_objs_tabular(hyperopt_objs) + _print_objs_tabular(hyperopt_objs, config.get('print_colorized', False)) def start_list_timeframes(args: Dict[str, Any]) -> None: From 47a91c9d8ec0706add136b3b1713c586fadf4b5e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 22:32:46 +0300 Subject: [PATCH 0514/1106] Remove green color --- freqtrade/commands/list_commands.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 6a2ccbfcf..67ee59375 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -49,9 +49,7 @@ def _print_objs_tabular(objs: List, print_colorized: bool) -> None: 'status': (((Fore.RED if print_colorized else '') + "LOAD FAILED" + (Style.RESET_ALL if print_colorized else '')) if s['class'] is None - else ((Fore.GREEN if print_colorized else '') + - "OK" + (Style.RESET_ALL if print_colorized else '')) - if names.count(s['name']) == 1 + else "OK" if names.count(s['name']) == 1 else ((Fore.YELLOW if print_colorized else '') + "DUPLICATED NAME" + (Style.RESET_ALL if print_colorized else ''))) From 06b84b4086d6807bb6ac861973028e799dcaea91 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 14 Feb 2020 23:13:49 +0300 Subject: [PATCH 0515/1106] Remove redundant code --- freqtrade/resolvers/iresolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index d674daa9a..84dee85cd 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -164,7 +164,7 @@ class IResolver: enum_failed=enum_failed): objects.append( {'name': obj.__name__ if obj is not None else '', - 'class': obj if obj is not None else None, + 'class': obj, 'location': entry, }) return objects From 93f9ff1b636724ad729a88b0dc4cb35fa6612e35 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 04:22:21 +0300 Subject: [PATCH 0516/1106] Fix existing test --- tests/strategy/test_strategy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index d3977ae44..1b4b64f89 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -32,7 +32,7 @@ def test_search_strategy(): def test_search_all_strategies(): directory = Path(__file__).parent - strategies = StrategyResolver.search_all_objects(directory) + strategies = StrategyResolver.search_all_objects(directory, enum_failed=False) assert isinstance(strategies, list) assert len(strategies) == 3 assert isinstance(strategies[0], dict) From 29d9b6a46a94ed222a97bb1e14081c1948f2cca1 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 04:32:10 +0300 Subject: [PATCH 0517/1106] Add test for enum failed --- tests/strategy/test_strategy.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 1b4b64f89..3d3f0f424 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -30,7 +30,7 @@ def test_search_strategy(): assert s is None -def test_search_all_strategies(): +def test_search_all_strategies_no_failed(): directory = Path(__file__).parent strategies = StrategyResolver.search_all_objects(directory, enum_failed=False) assert isinstance(strategies, list) @@ -38,6 +38,15 @@ def test_search_all_strategies(): assert isinstance(strategies[0], dict) +def test_search_all_strategies_with_failed(): + directory = Path(__file__).parent + strategies = StrategyResolver.search_all_objects(directory, enum_failed=True) + assert isinstance(strategies, list) + assert len(strategies) == 4 + assert isinstance(strategies[0], dict) + assert strategies[0]['class'] is None + + def test_load_strategy(default_conf, result): default_conf.update({'strategy': 'SampleStrategy', 'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates') From 1cf19133f47237fa42e693e96bbdc42f072740ca Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 05:17:34 +0300 Subject: [PATCH 0518/1106] Added missing failing strategy --- tests/strategy/failing_strategy.py | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/strategy/failing_strategy.py diff --git a/tests/strategy/failing_strategy.py b/tests/strategy/failing_strategy.py new file mode 100644 index 000000000..57a8cc1ae --- /dev/null +++ b/tests/strategy/failing_strategy.py @@ -0,0 +1,87 @@ + +# --- Do not remove these libs --- +from freqtrade.strategy.interface import IStrategy +from pandas import DataFrame +# -------------------------------- + +# Add your lib to import here +import talib.abstract as ta + +import nonexiting_module # noqa + + +# This class is a sample. Feel free to customize it. +class TestStrategyLegacy(IStrategy): + """ + This is a test strategy using the legacy function headers, which will be + removed in a future update. + Please do not use this as a template, but refer to user_data/strategy/sample_strategy.py + for a uptodate version of this template. + """ + + # Minimal ROI designed for the strategy. + # This attribute will be overridden if the config file contains "minimal_roi" + minimal_roi = { + "40": 0.0, + "30": 0.01, + "20": 0.02, + "0": 0.04 + } + + # Optimal stoploss designed for the strategy + # This attribute will be overridden if the config file contains "stoploss" + stoploss = -0.10 + + # Optimal ticker interval for the strategy + ticker_interval = '5m' + + def populate_indicators(self, dataframe: DataFrame) -> 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. + """ + + # Momentum Indicator + # ------------------------------------ + + # ADX + dataframe['adx'] = ta.ADX(dataframe) + + # TEMA - Triple Exponential Moving Average + dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + + return dataframe + + def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (dataframe['adx'] > 30) & + (dataframe['tema'] > dataframe['tema'].shift(1)) & + (dataframe['volume'] > 0) + ), + 'buy'] = 1 + + return dataframe + + def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame + :return: DataFrame with buy column + """ + dataframe.loc[ + ( + (dataframe['adx'] > 70) & + (dataframe['tema'] < dataframe['tema'].shift(1)) & + (dataframe['volume'] > 0) + ), + 'sell'] = 1 + return dataframe From e8c0a0bcd3b242e49f02a620d489cf352b548aa3 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 06:18:00 +0300 Subject: [PATCH 0519/1106] Make mypy happy --- freqtrade/resolvers/iresolver.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 84dee85cd..34f3934b6 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -7,7 +7,7 @@ import importlib.util import inspect import logging from pathlib import Path -from typing import Any, Dict, Generator, List, Optional, Tuple, Type, Union +from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union from freqtrade.exceptions import OperationalException @@ -40,10 +40,8 @@ class IResolver: return abs_paths @classmethod - def _get_valid_object(cls, module_path: Path, - object_name: Optional[str], - enum_failed: bool = False) -> Union[Generator[Any, None, None], - Tuple[None]]: + def _get_valid_object(cls, module_path: Path, object_name: Optional[str], + enum_failed: bool = False) -> Iterator[Any]: """ Generator returning objects with matching object_type and object_name in the path given. :param module_path: absolute path to the module @@ -63,7 +61,7 @@ class IResolver: # 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 (None, ) + return iter([None]) valid_objects_gen = ( obj for name, obj in inspect.getmembers(module, inspect.isclass) From ddea4b9300f12fcd099f0e4f5724bf290ec17881 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 06:54:18 +0300 Subject: [PATCH 0520/1106] Fix test --- tests/strategy/test_strategy.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 3d3f0f424..379260599 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -43,8 +43,10 @@ def test_search_all_strategies_with_failed(): strategies = StrategyResolver.search_all_objects(directory, enum_failed=True) assert isinstance(strategies, list) assert len(strategies) == 4 - assert isinstance(strategies[0], dict) - assert strategies[0]['class'] is None + # with enum_failed=True search_all_objects() shall find 3 good strategies + # and 1 which fails to load + assert len([x for x in strategies if x['class'] is not None]) == 3 + assert len([x for x in strategies if x['class'] is None]) == 1 def test_load_strategy(default_conf, result): From 42a5d78e607f226e4e65cf5157f65bdf28ec54f5 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 07:19:24 +0300 Subject: [PATCH 0521/1106] Wording (duplicate, not duplicated) --- freqtrade/commands/list_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 67ee59375..0cfc78596 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -51,7 +51,7 @@ def _print_objs_tabular(objs: List, print_colorized: bool) -> None: if s['class'] is None else "OK" if names.count(s['name']) == 1 else ((Fore.YELLOW if print_colorized else '') + - "DUPLICATED NAME" + + "DUPLICATE NAME" + (Style.RESET_ALL if print_colorized else ''))) } for s in objs] From fdd362299f5c7018f500b626f884f7dd27c17e62 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 07:34:39 +0300 Subject: [PATCH 0522/1106] Docs adjusted --- docs/utils.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index abb7fd0db..cdf0c31af 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -144,38 +144,47 @@ freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt Use the `list-strategies` subcommand to see all strategies in one particular directory and the `list-hyperopts` subcommand to list custom Hyperopts. +These subcommands are useful for finding problems in your environment with loading strategies or hyperopt classes: modules with strategies or hyperopt classes that contain errors and failed to load are printed in red (LOAD FAILED), while strategies or hyperopt classes with duplicate names are printed in yellow (DUPLICATE NAME). + ``` -freqtrade list-strategies --help -usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--strategy-path PATH] [-1] +usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] + [--strategy-path PATH] [-1] [--no-color] optional arguments: -h, --help show this help message and exit --strategy-path PATH Specify additional strategy lookup path. -1, --one-column Print output in one column. + --no-color Disable colorization of hyperopt results. May be + useful if you are redirecting output to a file. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` - to read config from stdin. + Specify configuration file (default: `config.json`). + Multiple --config options may be used. Can be set to + `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH Path to userdata directory. ``` ``` -freqtrade list-hyperopts --help usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] - [--hyperopt-path PATH] [-1] + [--hyperopt-path PATH] [-1] [--no-color] optional arguments: -h, --help show this help message and exit --hyperopt-path PATH Specify additional lookup path for Hyperopt and Hyperopt Loss functions. -1, --one-column Print output in one column. + --no-color Disable colorization of hyperopt results. May be + useful if you are redirecting output to a file. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). From 87b506972f5b99f11e4f5c97a54f69c716283558 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 15 Feb 2020 13:12:29 +0100 Subject: [PATCH 0523/1106] Fix edge documentation rendering --- docs/edge.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/edge.md b/docs/edge.md index dcefe7451..6a301b044 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -145,19 +145,19 @@ Edge module has following configuration options: | Parameter | Description | |------------|-------------| -| `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* -| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* -| `capital_available_percentage` | **DEPRECATED - [replaced with `tradable_balance_ratio`](configuration.md#Available balance)** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* -| `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* -| `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* -| `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* -| `stoploss_range_step` | As an example if this is set to -0.01 then Edge will test the strategy for `[-0.01, -0,02, -0,03 ..., -0.09, -0.10]` ranges.
**Note** than having a smaller step means having a bigger range which could lead to slow calculation.
If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10.
*Defaults to `-0.001`.*
***Datatype:*** *Float* -| `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate.
This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio.
*Defaults to `0.60`.*
***Datatype:*** *Float* -| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number.
Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return.
*Defaults to `0.20`.*
***Datatype:*** *Float* -| `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable.
Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something.
*Defaults to `10` (it is highly recommended not to decrease this number).*
***Datatype:*** *Integer* -| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
*Defaults to `1440` (one day).*
***Datatype:*** *Integer* -| `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
**Datatype:** Boolean +| `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
**Datatype:** Integer +| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
**Datatype:** Integer +| `capital_available_percentage` | **DEPRECATED - [replaced with `tradable_balance_ratio`](configuration.md#Available balance)** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
**Datatype:** Float +| `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
**Datatype:** Float +| `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
**Datatype:** Float +| `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
**Datatype:** Float +| `stoploss_range_step` | As an example if this is set to -0.01 then Edge will test the strategy for `[-0.01, -0,02, -0,03 ..., -0.09, -0.10]` ranges.
**Note** than having a smaller step means having a bigger range which could lead to slow calculation.
If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10.
*Defaults to `-0.001`.*
**Datatype:** Float +| `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate.
This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio.
*Defaults to `0.60`.*
**Datatype:** Float +| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number.
Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return.
*Defaults to `0.20`.*
**Datatype:** Float +| `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable.
Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something.
*Defaults to `10` (it is highly recommended not to decrease this number).*
**Datatype:** Integer +| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
*Defaults to `1440` (one day).*
**Datatype:** Integer +| `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.
*Defaults to `false`.*
**Datatype:** Boolean ## Running Edge independently From 6139239b863b36522a7d96efdb859e830403bad9 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 15 Feb 2020 20:43:11 +0300 Subject: [PATCH 0524/1106] Address points stated in comments --- freqtrade/commands/list_commands.py | 15 +++-- freqtrade/resolvers/iresolver.py | 2 +- tests/strategy/failing_strategy.py | 86 ++--------------------------- 3 files changed, 14 insertions(+), 89 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 0cfc78596..49674b81a 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -41,18 +41,21 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: def _print_objs_tabular(objs: List, print_colorized: bool) -> None: if print_colorized: colorama_init(autoreset=True) + red = Fore.RED + yellow = Fore.YELLOW + reset = Style.RESET_ALL + else: + red = '' + yellow = '' + reset = '' names = [s['name'] for s in objs] objss_to_print = [{ 'name': s['name'] if s['name'] else "--", 'location': s['location'].name, - 'status': (((Fore.RED if print_colorized else '') + - "LOAD FAILED" + (Style.RESET_ALL if print_colorized else '')) - if s['class'] is None + 'status': (red + "LOAD FAILED" + reset if s['class'] is None else "OK" if names.count(s['name']) == 1 - else ((Fore.YELLOW if print_colorized else '') + - "DUPLICATE NAME" + - (Style.RESET_ALL if print_colorized else ''))) + else yellow + "DUPLICATE NAME" + reset) } for s in objs] print(tabulate(objss_to_print, headers='keys', tablefmt='pipe')) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 34f3934b6..922a2700a 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -87,7 +87,7 @@ class IResolver: continue module_path = entry.resolve() - obj = next(cls._get_valid_object(module_path, object_name), None) # noqa + obj = next(cls._get_valid_object(module_path, object_name), None) if obj: return (obj, module_path) diff --git a/tests/strategy/failing_strategy.py b/tests/strategy/failing_strategy.py index 57a8cc1ae..f8eaac3c3 100644 --- a/tests/strategy/failing_strategy.py +++ b/tests/strategy/failing_strategy.py @@ -1,87 +1,9 @@ - -# --- Do not remove these libs --- -from freqtrade.strategy.interface import IStrategy -from pandas import DataFrame -# -------------------------------- - -# Add your lib to import here -import talib.abstract as ta +# The strategy which fails to load due to non-existent dependency import nonexiting_module # noqa +from freqtrade.strategy.interface import IStrategy + -# This class is a sample. Feel free to customize it. class TestStrategyLegacy(IStrategy): - """ - This is a test strategy using the legacy function headers, which will be - removed in a future update. - Please do not use this as a template, but refer to user_data/strategy/sample_strategy.py - for a uptodate version of this template. - """ - - # Minimal ROI designed for the strategy. - # This attribute will be overridden if the config file contains "minimal_roi" - minimal_roi = { - "40": 0.0, - "30": 0.01, - "20": 0.02, - "0": 0.04 - } - - # Optimal stoploss designed for the strategy - # This attribute will be overridden if the config file contains "stoploss" - stoploss = -0.10 - - # Optimal ticker interval for the strategy - ticker_interval = '5m' - - def populate_indicators(self, dataframe: DataFrame) -> 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. - """ - - # Momentum Indicator - # ------------------------------------ - - # ADX - dataframe['adx'] = ta.ADX(dataframe) - - # TEMA - Triple Exponential Moving Average - dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) - - return dataframe - - def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: - """ - Based on TA indicators, populates the buy signal for the given dataframe - :param dataframe: DataFrame - :return: DataFrame with buy column - """ - dataframe.loc[ - ( - (dataframe['adx'] > 30) & - (dataframe['tema'] > dataframe['tema'].shift(1)) & - (dataframe['volume'] > 0) - ), - 'buy'] = 1 - - return dataframe - - def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: - """ - Based on TA indicators, populates the sell signal for the given dataframe - :param dataframe: DataFrame - :return: DataFrame with buy column - """ - dataframe.loc[ - ( - (dataframe['adx'] > 70) & - (dataframe['tema'] < dataframe['tema'].shift(1)) & - (dataframe['volume'] > 0) - ), - 'sell'] = 1 - return dataframe + pass From 6e71f2f1662246b848d8137223c8449068f2348e Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 15 Feb 2020 20:55:12 +0100 Subject: [PATCH 0525/1106] my fix --- freqtrade/rpc/rpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index c182aad2b..f6ac999f7 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -168,9 +168,9 @@ class RPC: profit_str += f" ({fiat_profit:.2f})" trades_list.append([ trade.id, - trade.pair + '*' if (trade.open_order_id is not None - and trade.close_rate_requested is None) else '' - + '**' if (trade.close_rate_requested is not None) else '', + trade.pair + ['', '*'][trade.open_order_id is not None + and trade.close_rate_requested is None] + + ['', '**'][trade.close_rate_requested is not None], shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ]) From 180939a962e1214b744999c449753be26024edad Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 15 Feb 2020 21:01:45 +0100 Subject: [PATCH 0526/1106] winner, readability, with brackets as fix --- freqtrade/rpc/rpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index f6ac999f7..3411318bb 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -168,9 +168,9 @@ class RPC: profit_str += f" ({fiat_profit:.2f})" trades_list.append([ trade.id, - trade.pair + ['', '*'][trade.open_order_id is not None - and trade.close_rate_requested is None] - + ['', '**'][trade.close_rate_requested is not None], + trade.pair + ('*' if (trade.open_order_id is not None + and trade.close_rate_requested is None) else '') + + ('**' if (trade.close_rate_requested is not None) else ''), shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)), profit_str ]) From 161dd1a3e60e70928d7bab25f1a8913a079420f9 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 16 Feb 2020 03:55:16 +0300 Subject: [PATCH 0527/1106] Rename risk_free_return to minumum_accepted_return --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index d869a4e4e..72f70e3f9 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -31,8 +31,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): resample_freq = '1D' slippage_per_trade_ratio = 0.0005 days_in_year = 365 - annual_risk_free_rate = 0.0 - risk_free_rate = annual_risk_free_rate / days_in_year + minimum_acceptable_return = 0.0 # apply slippage per trade to profit_percent results.loc[:, 'profit_percent_after_slippage'] = \ @@ -47,7 +46,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): {"profit_percent_after_slippage": sum}).reindex(t_index).fillna(0) ) - total_profit = sum_daily["profit_percent_after_slippage"] - risk_free_rate + total_profit = sum_daily["profit_percent_after_slippage"] - minimum_acceptable_return expected_returns_mean = total_profit.mean() sum_daily['downside_returns'] = 0 From 1e84b2770cfa2e0e5e8177615dfee178ac136c1f Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 16 Feb 2020 04:10:53 +0300 Subject: [PATCH 0528/1106] Fix values of downside_returns --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 72f70e3f9..26eb54c25 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -50,8 +50,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): expected_returns_mean = total_profit.mean() sum_daily['downside_returns'] = 0 - sum_daily.loc[total_profit < 0, - 'downside_returns'] = sum_daily['profit_percent_after_slippage'] + sum_daily.loc[total_profit < 0, 'downside_returns'] = total_profit total_downside = sum_daily['downside_returns'] down_stdev = total_downside.std() From fbe5cc44da260d50db28dedf5acd12aad06913ce Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 16 Feb 2020 13:43:23 +0300 Subject: [PATCH 0529/1106] Use statistics.pstdev --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 26eb54c25..09042cb48 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -5,6 +5,7 @@ This module defines the alternative HyperOptLoss class which can be used for Hyperoptimization. """ import math +import statistics from datetime import datetime from pandas import DataFrame, date_range @@ -52,7 +53,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): sum_daily['downside_returns'] = 0 sum_daily.loc[total_profit < 0, 'downside_returns'] = total_profit total_downside = sum_daily['downside_returns'] - down_stdev = total_downside.std() + down_stdev = statistics.pstdev(total_downside, 0) if (down_stdev != 0.): sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year) From 42dfda92316b4678107eac65359d56d5e8b6ee0a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 16 Feb 2020 13:46:07 +0300 Subject: [PATCH 0530/1106] Adjust docstring --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 09042cb48..22cd93984 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -28,6 +28,9 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): Objective function, returns smaller number for more optimal results. Uses Sortino Ratio calculation. + + Sortino Ratio calculated as described in + http://www.redrockcapital.com/Sortino__A__Sharper__Ratio_Red_Rock_Capital.pdf """ resample_freq = '1D' slippage_per_trade_ratio = 0.0005 From 3787ac7b980e16d615cebe5a942a8d45490ba72c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 Feb 2020 13:20:11 +0100 Subject: [PATCH 0531/1106] increment limit to adjust to FTX defaults (1500 candles) --- freqtrade/exchange/__init__.py | 18 ++++++++++-------- freqtrade/exchange/ftx.py | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 freqtrade/exchange/ftx.py diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index df18bca02..a39f8f5df 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -1,18 +1,20 @@ -from freqtrade.exchange.common import MAP_EXCHANGE_CHILDCLASS # noqa: F401 -from freqtrade.exchange.exchange import Exchange # noqa: F401 -from freqtrade.exchange.exchange import (get_exchange_bad_reason, # noqa: F401 +# flake8: noqa: F401 +from freqtrade.exchange.common import MAP_EXCHANGE_CHILDCLASS +from freqtrade.exchange.exchange import Exchange +from freqtrade.exchange.exchange import (get_exchange_bad_reason, is_exchange_bad, is_exchange_known_ccxt, is_exchange_officially_supported, ccxt_exchanges, available_exchanges) -from freqtrade.exchange.exchange import (timeframe_to_seconds, # noqa: F401 +from freqtrade.exchange.exchange import (timeframe_to_seconds, timeframe_to_minutes, timeframe_to_msecs, timeframe_to_next_date, timeframe_to_prev_date) -from freqtrade.exchange.exchange import (market_is_active, # noqa: F401 +from freqtrade.exchange.exchange import (market_is_active, symbol_is_pair) -from freqtrade.exchange.kraken import Kraken # noqa: F401 -from freqtrade.exchange.binance import Binance # noqa: F401 -from freqtrade.exchange.bibox import Bibox # noqa: F401 +from freqtrade.exchange.kraken import Kraken +from freqtrade.exchange.binance import Binance +from freqtrade.exchange.bibox import Bibox +from freqtrade.exchange.ftx import Ftx diff --git a/freqtrade/exchange/ftx.py b/freqtrade/exchange/ftx.py new file mode 100644 index 000000000..75915122b --- /dev/null +++ b/freqtrade/exchange/ftx.py @@ -0,0 +1,14 @@ +""" FTX exchange subclass """ +import logging +from typing import Dict + +from freqtrade.exchange import Exchange + +logger = logging.getLogger(__name__) + + +class Ftx(Exchange): + + _ft_has: Dict = { + "ohlcv_candle_limit": 1500, + } From 674898bd32eede682dad5a688ee1428b89a8805c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 16 Feb 2020 15:26:40 +0300 Subject: [PATCH 0532/1106] Fix usage of vars in the commented out line --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 22cd93984..0f81ffca5 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -65,5 +65,5 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): sortino_ratio = -20. # print(t_index, sum_daily, total_profit) - # print(risk_free_rate, expected_returns_mean, down_stdev, sortino_ratio) + # print(minimum_acceptable_return, expected_returns_mean, down_stdev, sortino_ratio) return -sortino_ratio From bec86b13258f97dba75b7b5b8cc39f773490d7fa Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 Feb 2020 15:42:41 +0100 Subject: [PATCH 0533/1106] Add github actions badge --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1feeab67..59799da84 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Freqtrade -[![Build Status](https://travis-ci.org/freqtrade/freqtrade.svg?branch=develop)](https://travis-ci.org/freqtrade/freqtrade) +[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/) [![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop) [![Documentation](https://readthedocs.org/projects/freqtrade/badge/)](https://www.freqtrade.io) [![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability) diff --git a/docs/index.md b/docs/index.md index f0ee831e3..adc661300 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,5 @@ # Freqtrade -[![Build Status](https://travis-ci.org/freqtrade/freqtrade.svg?branch=develop)](https://travis-ci.org/freqtrade/freqtrade) +[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/) [![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop) [![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability) From 212d20ed087161cc4abefdbe47a0c4c345e955e7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:03:37 +0000 Subject: [PATCH 0534/1106] Bump ccxt from 1.22.39 to 1.22.61 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.39 to 1.22.61. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.22.39...1.22.61) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index f641dd2ad..e89afceed 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.22.39 +ccxt==1.22.61 SQLAlchemy==1.3.13 python-telegram-bot==12.4.1 arrow==0.15.5 From c6a3038f5274fe974fd34e51b313689ce5112c52 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:03:57 +0000 Subject: [PATCH 0535/1106] Bump coveralls from 1.10.0 to 1.11.1 Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.10.0 to 1.11.1. - [Release notes](https://github.com/coveralls-clients/coveralls-python/releases) - [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.10.0...1.11.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 268c5f777..1e58ae6e0 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,7 +3,7 @@ -r requirements-plot.txt -r requirements-hyperopt.txt -coveralls==1.10.0 +coveralls==1.11.1 flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 From 500e1c77de3912c989612fd2a823c5c72a3a8415 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:04:21 +0000 Subject: [PATCH 0536/1106] Bump wrapt from 1.11.2 to 1.12.0 Bumps [wrapt](https://github.com/GrahamDumpleton/wrapt) from 1.11.2 to 1.12.0. - [Release notes](https://github.com/GrahamDumpleton/wrapt/releases) - [Changelog](https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst) - [Commits](https://github.com/GrahamDumpleton/wrapt/compare/1.11.2...1.12.0) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index f641dd2ad..df67c1691 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -7,7 +7,7 @@ arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 urllib3==1.25.8 -wrapt==1.11.2 +wrapt==1.12.0 jsonschema==3.2.0 TA-Lib==0.4.17 tabulate==0.8.6 From 9435950fc968899d697263244096872cded9951c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:04:40 +0000 Subject: [PATCH 0537/1106] Bump mkdocs-material from 4.6.2 to 4.6.3 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.2 to 4.6.3. - [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/4.6.2...4.6.3) Signed-off-by: dependabot-preview[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 3980ecd64..48ade026e 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==4.6.2 +mkdocs-material==4.6.3 mdx_truly_sane_lists==1.2 From 0fd3d74fc4ab745833b682cc69a6eb3581de30da Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:05:00 +0000 Subject: [PATCH 0538/1106] Bump scikit-optimize from 0.7.1 to 0.7.2 Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.7.1 to 0.7.2. - [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases) - [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md) - [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.7.1...v0.7.2) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 202806cef..e97e7f6be 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -4,6 +4,6 @@ # Required for hyperopt scipy==1.4.1 scikit-learn==0.22.1 -scikit-optimize==0.7.1 +scikit-optimize==0.7.2 filelock==3.0.12 joblib==0.14.1 From 582b59044c3d6388ca1847643c8816b9613156e3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:47:39 +0000 Subject: [PATCH 0539/1106] Bump python-telegram-bot from 12.4.1 to 12.4.2 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.4.1 to 12.4.2. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.4.1...v12.4.2) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e89afceed..6cc8e3809 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.22.61 SQLAlchemy==1.3.13 -python-telegram-bot==12.4.1 +python-telegram-bot==12.4.2 arrow==0.15.5 cachetools==4.0.0 requests==2.22.0 From 0b33b798e4a9d5e6f13df7a3d3a0e90dbe34643e Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 17 Feb 2020 20:16:24 +0100 Subject: [PATCH 0540/1106] Add pypi build step --- .github/workflows/ci.yml | 29 ++++++++++++++++++++++++++++- freqtrade/__init__.py | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05d151a88..cc8906af5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,8 @@ on: - develop - github_actions_tests tags: + release: + types: [published] pull_request: schedule: - cron: '0 5 * * 4' @@ -191,15 +193,40 @@ jobs: deploy: needs: [ build, build_windows, docs_check ] runs-on: ubuntu-18.04 - if: (github.event_name == 'push' || github.event_name == 'schedule') && github.repository == 'freqtrade/freqtrade' + if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade' steps: - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Extract branch name shell: bash run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" id: extract_branch + - name: Build distribution + run: | + pip install -U setuptools wheel + python setup.py sdist bdist_wheel + + - name: Publish to PyPI (Test) + uses: pypa/gh-action-pypi-publish@master + if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release') + with: + user: __token__ + password: ${{ secrets.pypi_test_password }} + repository_url: https://test.pypi.org/legacy/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@master + if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release') + with: + user: __token__ + password: ${{ secrets.pypi_password }} + - name: Build and test and push docker image env: IMAGE_NAME: freqtradeorg/freqtrade diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index e1f65d4fe..f2ae5dc63 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -1,4 +1,4 @@ -""" FreqTrade bot """ +""" Freqtrade bot """ __version__ = 'develop' if __version__ == 'develop': From 1172c958174424e138d9391dfcd90db6e6856705 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 17 Feb 2020 20:17:08 +0100 Subject: [PATCH 0541/1106] Use different versioning scheme --- freqtrade/__init__.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index f2ae5dc63..23ab945b4 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -5,9 +5,23 @@ if __version__ == 'develop': try: import subprocess - __version__ = 'develop-' + subprocess.check_output( - ['git', 'log', '--format="%h"', '-n 1'], - stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') + + # __version__ = 'develop-' + 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: # git not available, ignore pass From e6dd463ca3ad7803e1e6df391d3917d32142368e Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 17 Feb 2020 20:17:36 +0100 Subject: [PATCH 0542/1106] Revert versioning --- freqtrade/__init__.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 23ab945b4..ad432a20b 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -6,18 +6,18 @@ if __version__ == 'develop': try: import subprocess - # __version__ = 'develop-' + subprocess.check_output( - # ['git', 'log', '--format="%h"', '-n 1'], - # stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') + __version__ = 'develop-' + 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}" + # 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'], From 1634297685489bd1dd47802801bef7daae1a7238 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 18 Feb 2020 20:12:10 +0100 Subject: [PATCH 0543/1106] Move strategies to test subfolder --- tests/commands/test_commands.py | 4 ++-- tests/conftest.py | 1 + .../strategy/strats}/default_strategy.py | 0 tests/strategy/{ => strats}/failing_strategy.py | 0 tests/strategy/{ => strats}/legacy_strategy.py | 0 tests/strategy/test_default_strategy.py | 2 +- tests/strategy/test_interface.py | 2 +- tests/strategy/test_strategy.py | 14 +++++++------- 8 files changed, 12 insertions(+), 11 deletions(-) rename {freqtrade/strategy => tests/strategy/strats}/default_strategy.py (100%) rename tests/strategy/{ => strats}/failing_strategy.py (100%) rename tests/strategy/{ => strats}/legacy_strategy.py (100%) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index ee1db5db5..55bd7306d 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -640,7 +640,7 @@ def test_start_list_strategies(mocker, caplog, capsys): args = [ "list-strategies", "--strategy-path", - str(Path(__file__).parent.parent / "strategy"), + str(Path(__file__).parent.parent / "strategy" / "strats"), "-1" ] pargs = get_args(args) @@ -655,7 +655,7 @@ def test_start_list_strategies(mocker, caplog, capsys): args = [ "list-strategies", "--strategy-path", - str(Path(__file__).parent.parent / "strategy"), + str(Path(__file__).parent.parent / "strategy" / "strats"), ] pargs = get_args(args) # pargs['config'] = None diff --git a/tests/conftest.py b/tests/conftest.py index e897dbccd..acb730330 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -257,6 +257,7 @@ def default_conf(testdatadir): "db_url": "sqlite://", "user_data_dir": Path("user_data"), "verbosity": 3, + "strategy_path": str(Path(__file__).parent / "strategy" / "strats"), "strategy": "DefaultStrategy" } return configuration diff --git a/freqtrade/strategy/default_strategy.py b/tests/strategy/strats/default_strategy.py similarity index 100% rename from freqtrade/strategy/default_strategy.py rename to tests/strategy/strats/default_strategy.py diff --git a/tests/strategy/failing_strategy.py b/tests/strategy/strats/failing_strategy.py similarity index 100% rename from tests/strategy/failing_strategy.py rename to tests/strategy/strats/failing_strategy.py diff --git a/tests/strategy/legacy_strategy.py b/tests/strategy/strats/legacy_strategy.py similarity index 100% rename from tests/strategy/legacy_strategy.py rename to tests/strategy/strats/legacy_strategy.py diff --git a/tests/strategy/test_default_strategy.py b/tests/strategy/test_default_strategy.py index 17d6b8ee0..0b8ea9f85 100644 --- a/tests/strategy/test_default_strategy.py +++ b/tests/strategy/test_default_strategy.py @@ -1,6 +1,6 @@ from pandas import DataFrame -from freqtrade.strategy.default_strategy import DefaultStrategy +from .strats.default_strategy import DefaultStrategy def test_default_strategy_structure(): diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index a28519383..def64425e 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -11,7 +11,7 @@ from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.persistence import Trade from freqtrade.resolvers import StrategyResolver -from freqtrade.strategy.default_strategy import DefaultStrategy +from .strats.default_strategy import DefaultStrategy from tests.conftest import get_patched_exchange, log_has # Avoid to reinit the same object again and again diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 379260599..5c6de8260 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -31,21 +31,21 @@ def test_search_strategy(): def test_search_all_strategies_no_failed(): - directory = Path(__file__).parent + directory = Path(__file__).parent / "strats" strategies = StrategyResolver.search_all_objects(directory, enum_failed=False) assert isinstance(strategies, list) - assert len(strategies) == 3 + assert len(strategies) == 2 assert isinstance(strategies[0], dict) def test_search_all_strategies_with_failed(): - directory = Path(__file__).parent + directory = Path(__file__).parent / "strats" strategies = StrategyResolver.search_all_objects(directory, enum_failed=True) assert isinstance(strategies, list) - assert len(strategies) == 4 + assert len(strategies) == 3 # with enum_failed=True search_all_objects() shall find 3 good strategies # and 1 which fails to load - assert len([x for x in strategies if x['class'] is not None]) == 3 + assert len([x for x in strategies if x['class'] is not None]) == 2 assert len([x for x in strategies if x['class'] is None]) == 1 @@ -326,7 +326,7 @@ def test_strategy_override_use_sell_profit_only(caplog, default_conf): @pytest.mark.filterwarnings("ignore:deprecated") def test_deprecate_populate_indicators(result, default_conf): - default_location = path.join(path.dirname(path.realpath(__file__))) + default_location = Path(__file__).parent / "strats" default_conf.update({'strategy': 'TestStrategyLegacy', 'strategy_path': default_location}) strategy = StrategyResolver.load_strategy(default_conf) @@ -360,7 +360,7 @@ def test_deprecate_populate_indicators(result, default_conf): @pytest.mark.filterwarnings("ignore:deprecated") def test_call_deprecated_function(result, monkeypatch, default_conf): - default_location = path.join(path.dirname(path.realpath(__file__))) + default_location = Path(__file__).parent / "strats" default_conf.update({'strategy': 'TestStrategyLegacy', 'strategy_path': default_location}) strategy = StrategyResolver.load_strategy(default_conf) From d91b9d125314c62119b75142fb833ffd0a829bc1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 18 Feb 2020 20:26:20 +0100 Subject: [PATCH 0544/1106] Fix some tests, don't default to freqtrade/strategy for imports --- freqtrade/resolvers/iresolver.py | 4 +++- freqtrade/resolvers/strategy_resolver.py | 2 +- tests/strategy/test_strategy.py | 10 ++++------ tests/test_configuration.py | 1 + 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 922a2700a..764759289 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -28,7 +28,9 @@ class IResolver: def build_search_paths(cls, config: Dict[str, Any], user_subdir: Optional[str] = None, extra_dir: Optional[str] = None) -> List[Path]: - abs_paths: List[Path] = [cls.initial_search_path] + abs_paths: List[Path] = [] + if cls.initial_search_path: + abs_paths.append(cls.initial_search_path) if user_subdir: abs_paths.insert(0, config['user_data_dir'].joinpath(user_subdir)) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index bb8ff870e..cddc7c9cd 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -27,7 +27,7 @@ class StrategyResolver(IResolver): object_type = IStrategy object_type_str = "Strategy" user_subdir = USERPATH_STRATEGIES - initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve() + initial_search_path = None @staticmethod def load_strategy(config: Dict[str, Any] = None) -> IStrategy: diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 5c6de8260..27bbb2d3b 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -2,7 +2,6 @@ import logging import warnings from base64 import urlsafe_b64encode -from os import path from pathlib import Path import pytest @@ -15,7 +14,7 @@ from tests.conftest import log_has, log_has_re def test_search_strategy(): - default_location = Path(__file__).parent.parent.joinpath('strategy').resolve() + default_location = Path(__file__).parent / 'strats' s, _ = StrategyResolver._search_object( directory=default_location, @@ -72,13 +71,12 @@ def test_load_strategy_base64(result, caplog, default_conf): def test_load_strategy_invalid_directory(result, caplog, default_conf): default_conf['strategy'] = 'DefaultStrategy' extra_dir = Path.cwd() / 'some/path' - strategy = StrategyResolver._load_strategy('DefaultStrategy', config=default_conf, - extra_dir=extra_dir) + with pytest.raises(OperationalException): + StrategyResolver._load_strategy('DefaultStrategy', config=default_conf, + extra_dir=extra_dir) assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog) - assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'}) - def test_load_not_found_strategy(default_conf): default_conf['strategy'] = 'NotFoundStrategy' diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 74de166c1..d810305db 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -212,6 +212,7 @@ def test_load_config_file_exception(mocker) -> None: def test_load_config(default_conf, mocker) -> None: + del default_conf['strategy_path'] patched_configuration_load_config_file(mocker, default_conf) args = Arguments(['trade']).get_parsed_arg() From 2058b492eb2b668616f06d0d001e01ffca17e38f Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Tue, 18 Feb 2020 22:46:53 +0100 Subject: [PATCH 0545/1106] Added function to print hyperopt-list as table using tabulate --- docs/utils.md | 1 + freqtrade/commands/arguments.py | 3 +- freqtrade/commands/cli_options.py | 6 +++ freqtrade/commands/hyperopt_commands.py | 36 ++++++++++-------- freqtrade/configuration/configuration.py | 3 ++ freqtrade/optimize/hyperopt.py | 47 +++++++++++++++++++++++- tests/commands/test_commands.py | 16 ++++++++ 7 files changed, 95 insertions(+), 17 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index abb7fd0db..6ca0b7920 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -440,6 +440,7 @@ optional arguments: --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. + --print-table Print results in table format. --no-details Do not print best epoch details. Common arguments: diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index fe6f49039..0f6478a60 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -66,7 +66,8 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", - "print_colorized", "print_json", "hyperopt_list_no_details"] + "print_colorized", "print_json", "print_table", + "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 1776955b1..9efc1151a 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -220,6 +220,12 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), + "print_table": Arg( + '--print-table', + help='Print results in table format.', + action='store_true', + default=False, + ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 8c1c80d98..88cd79468 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -21,6 +21,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) + print_table = config.get('print_table', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False @@ -52,14 +53,20 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: if print_colorized: colorama_init(autoreset=True) - try: - # Human-friendly indexes used here (starting from 1) - for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, - not filteroptions['only_best'], print_colorized) - - except KeyboardInterrupt: - print('User interrupted..') + if print_table: + try: + Hyperopt.print_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') + else: + try: + # Human-friendly indexes used here (starting from 1) + for val in trials[epoch_start:epoch_stop]: + Hyperopt.print_results_explanation(val, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) @@ -75,6 +82,12 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + print_json = config.get('print_json', False) + no_header = config.get('hyperopt_show_no_header', False) + trials_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') + n = config.get('hyperopt_show_index', -1) + filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), @@ -87,10 +100,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } - no_header = config.get('hyperopt_show_no_header', False) - - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) @@ -99,7 +108,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: trials = _hyperopt_filter_trials(trials, filteroptions) trials_epochs = len(trials) - n = config.get('hyperopt_show_index', -1) if n > trials_epochs: raise OperationalException( f"The index of the epoch to show should be less than {trials_epochs + 1}.") @@ -111,8 +119,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: if n > 0: n -= 1 - print_json = config.get('print_json', False) - if trials: val = trials[n] Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index c2613ba99..0adfe03e7 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -286,6 +286,9 @@ class Configuration: self._args_to_config(config, argname='print_json', logstring='Parameter --print-json detected ...') + self._args_to_config(config, argname='print_table', + logstring='Parameter --print-table detected: {}') + self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ff6e7f3bc..72b3516c7 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -20,7 +20,8 @@ from colorama import Fore, Style from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) -from pandas import DataFrame +from pandas import DataFrame, json_normalize, isna +from tabulate import tabulate from freqtrade.data.history import get_timerange, trim_dataframe from freqtrade.exceptions import OperationalException @@ -295,6 +296,50 @@ class Hyperopt: f"{results['results_explanation']} " + f"Objective: {results['loss']:.5f}") + @staticmethod + def print_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool, + print_colorized: bool) -> None: + """ + Log result table + """ + if not results: + return + + trials = json_normalize(results, max_level=1) + trials = trials[['is_best', 'current_epoch', + 'results_metrics.trade_count', 'results_metrics.avg_profit', + 'results_metrics.total_profit', 'results_metrics.profit', + 'results_metrics.duration', 'loss']] + trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', + 'Profit', 'Avg duration', 'Objective'] + + trials['Best'] = trials['Best'].apply(lambda x: '*' if x else '') + trials['Objective'] = trials['Objective'].astype(str) + + if print_colorized: + for i in range(len(trials)): + if trials.loc[i]['Total profit'] > 0: + trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Fore.RESET) + if '*' in trials.loc[i]['Best'] and highlight_best: + trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Style.RESET_ALL) + + trials['Epoch'] = trials['Epoch'].apply( + lambda x: "{}/{}".format(x, total_epochs)) + trials['Avg profit'] = trials['Avg profit'].apply( + lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + trials['Profit'] = trials['Profit'].apply( + lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + trials['Total profit'] = trials['Total profit'].apply( + lambda x: '{: 11.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) + trials['Avg duration'] = trials['Avg duration'].apply( + lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) + + print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql')) + def has_space(self, space: str) -> bool: """ Tell if the space value is contained in the configuration diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index ee1db5db5..9ecd990ec 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -893,6 +893,22 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--print-table", + "--max-trades", "20" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 10/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12", " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From 585545405dea4d34bc1ce6d8296ceb38861a7b85 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Wed, 19 Feb 2020 00:51:44 +0100 Subject: [PATCH 0546/1106] Changed tests --- tests/commands/test_commands.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 9ecd990ec..9c233019c 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -895,20 +895,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", - "--profitable", "--no-details", "--print-table", - "--max-trades", "20" + "--min-trades", "100", + "--print-json" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out - for x in [" 2/12", " 10/12"]) + for x in [" 3/12", " 7/12", " 9/12", " 11/12"]) assert all(x not in captured.out - for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", - " 11/12", " 12/12"]) + for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 6/12", " 8/12", " 10/12" + " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From df26c357d293f69e57cffc4de60284776d183026 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 19 Feb 2020 01:31:25 +0100 Subject: [PATCH 0547/1106] doc updates --- docs/bot-usage.md | 12 +++++++----- docs/hyperopt.md | 14 ++++++++------ freqtrade/commands/cli_options.py | 3 ++- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 56e6008a1..e0d96a8c2 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -270,7 +270,7 @@ Check the corresponding [Data Downloading](data-download.md) section for more de ## Hyperopt commands To optimize your strategy, you can use hyperopt parameter hyperoptimization -to find optimal parameter values for your stategy. +to find optimal parameter values for your strategy. ``` usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] @@ -318,7 +318,7 @@ optional arguments: --print-all Print all results, not only the best ones. --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. - --print-json Print best result detailization in JSON format. + --print-json Print best results in JSON format. -j JOBS, --job-workers JOBS The number of concurrently running jobs for hyperoptimization (hyperopt worker processes). If -1 @@ -336,9 +336,11 @@ optional arguments: class (IHyperOptLoss). Different functions can generate completely different results, since the target for optimization is different. Built-in - Hyperopt-loss-functions are: DefaultHyperOptLoss, - OnlyProfitHyperOptLoss, SharpeHyperOptLoss, - SharpeHyperOptLossDaily (default: `DefaultHyperOptLoss`). + Hyperopt-loss-functions are: + DefaultHyperOptLoss, OnlyProfitHyperOptLoss, + SharpeHyperOptLoss, SharpeHyperOptLossDaily, + SortinoHyperOptLoss, SortinoHyperOptLossDaily. + (default: `DefaultHyperOptLoss`). Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 3e10f66da..3fb7ce7ba 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -81,11 +81,11 @@ There are two places you need to change in your hyperopt file to add a new buy h There you have two different types of indicators: 1. `guards` and 2. `triggers`. 1. Guards are conditions like "never buy if ADX < 10", or never buy if current price is over EMA10. -2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower bollinger band". +2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower Bollinger band". Hyperoptimization will, for each eval round, pick one trigger and possibly multiple guards. The constructed strategy will be something like -"*buy exactly when close price touches lower bollinger band, BUT only if +"*buy exactly when close price touches lower Bollinger band, BUT only if ADX > 10*". If you have updated the buy strategy, i.e. changed the contents of @@ -172,7 +172,7 @@ So let's write the buy strategy using these values: Hyperopting will now call this `populate_buy_trend` as many times you ask it (`epochs`) with different value combinations. It will then use the given historical data and make buys based on the buy signals generated with the above function and based on the results -it will end with telling you which paramter combination produced the best profits. +it will end with telling you which parameter combination produced the best profits. The above setup expects to find ADX, RSI and Bollinger Bands in the populated indicators. When you want to test an indicator that isn't used by the bot currently, remember to @@ -191,8 +191,10 @@ Currently, the following loss functions are builtin: * `DefaultHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function) * `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration) -* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on the trade returns) -* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on daily trade returns) +* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on trade returns relative to **upside** standard deviation) +* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on **daily** trade returns relative to **upside** standard deviation) +* `SortinoHyperOptLoss` (optimizes Sortino Ratio calculated on trade returns relative to **downside** standard deviation) +* `SortinoHyperOptLossDaily` (optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation) Creation of a custom loss function is covered in the [Advanced Hyperopt](advanced-hyperopt.md) part of the documentation. @@ -272,7 +274,7 @@ In some situations, you may need to run Hyperopt (and Backtesting) with the By default, hyperopt emulates the behavior of the Freqtrade Live Run/Dry Run, where only one open trade is allowed for every traded pair. The total number of trades open for all pairs is also limited by the `max_open_trades` setting. During Hyperopt/Backtesting this may lead to -some potential trades to be hidden (or masked) by previosly open trades. +some potential trades to be hidden (or masked) by previously open trades. The `--eps`/`--enable-position-stacking` argument allows emulation of buying the same pair multiple times, while `--dmmp`/`--disable-max-market-positions` disables applying `max_open_trades` diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 6d8d13129..5faff1a97 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -256,7 +256,8 @@ AVAILABLE_CLI_OPTIONS = { help='Specify the class name of the hyperopt loss function class (IHyperOptLoss). ' 'Different functions can generate completely different results, ' 'since the target for optimization is different. Built-in Hyperopt-loss-functions are: ' - 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily.' + 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily, ' + 'SortinoHyperOptLoss, SortinoHyperOptLossDaily.' '(default: `%(default)s`).', metavar='NAME', default=constants.DEFAULT_HYPEROPT_LOSS, From 41b4fa3b7f93018a5c01042b8aa8734108e57407 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 19 Feb 2020 02:59:51 +0100 Subject: [PATCH 0548/1106] fixed two more typos --- docs/hyperopt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index b471f849e..1f9907b83 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -31,9 +31,9 @@ This will create a new hyperopt file from a template, which will be located unde Depending on the space you want to optimize, only some of the below are required: * fill `buy_strategy_generator` - for buy signal optimization -* fill `indicator_space` - for buy signal optimzation +* fill `indicator_space` - for buy signal optimization * fill `sell_strategy_generator` - for sell signal optimization -* fill `sell_indicator_space` - for sell signal optimzation +* fill `sell_indicator_space` - for sell signal optimization !!! Note `populate_indicators` needs to create all indicators any of thee spaces may use, otherwise hyperopt will not work. From 09d89fbfb39b5aa5f75a589b82bdba11800656b0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 07:15:55 +0100 Subject: [PATCH 0549/1106] Fix last test --- tests/optimize/test_backtesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index bba15c156..9cfd662c1 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -759,7 +759,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), - '--strategy-path', str(Path(__file__).parents[2] / 'freqtrade/templates'), + '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--ticker-interval', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', From 882d0a59330d81c65ca79bc93270247d9cd439ae Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 12:54:59 +0100 Subject: [PATCH 0550/1106] implement documentation feedback after review --- docs/data-download.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/data-download.md b/docs/data-download.md index f747123d0..a01aaf4f6 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -52,8 +52,8 @@ Common arguments: ### Data format -Freqtrade currently supports 2 dataformats, `json` and `jsongz`, a zipped version of json files. -By default, OHLCV data is stored as json data, while trades data is stored as `jsongz` data. +Freqtrade currently supports 2 dataformats, `json` (plain "text" json files) and `jsongz` (a gzipped version of json files). +By default, OHLCV data is stored as `json` data, while trades data is stored as `jsongz` data. This can be changed via the `--data-format` and `--data-format-trades` parameters respectivly. @@ -105,8 +105,8 @@ Common arguments: ##### Example converting data -The following command will convert all Candle data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process. -It'll also remove source files (`--erase` parameter). +The following command will convert all ohlcv (candle) data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process. +It'll also remove original json data files (`--erase` parameter). ``` bash freqtrade convert-data --format-from json --format-to jsongz --data-dir ~/.freqtrade/data/binance -t 5m 15m --erase @@ -151,8 +151,8 @@ Common arguments: ##### Example converting trades -The following command will convert all available trade-data in `~/.freqtrade/data/kraken` from json to jsongz, saving diskspace in the process. -It'll also remove source files (`--erase` parameter). +The following command will convert all available trade-data in `~/.freqtrade/data/kraken` from jsongz to json. +It'll also remove original jsongz data files (`--erase` parameter). ``` bash freqtrade convert-trade-data --format-from jsongz --format-to json --data-dir ~/.freqtrade/data/kraken --erase From 29b369c65ed034f8dadbf6e237a0cefbeb11b7f4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 14:53:54 +0100 Subject: [PATCH 0551/1106] Rename cli argument --- docs/data-download.md | 6 +++--- freqtrade/commands/cli_options.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data-download.md b/docs/data-download.md index a01aaf4f6..76e22f4ea 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -18,7 +18,7 @@ Otherwise `--exchange` becomes mandatory. usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-p PAIRS [PAIRS ...]] [--pairs-file FILE] [--days INT] [--dl-trades] [--exchange EXCHANGE] [-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]] - [--erase] [--data-format {json,jsongz}] [--data-format-trades {json,jsongz}] + [--erase] [--data-format-ohlcv {json,jsongz}] [--data-format-trades {json,jsongz}] optional arguments: -h, --help show this help message and exit @@ -32,7 +32,7 @@ optional arguments: -t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...] Specify which tickers to download. Space-separated list. Default: `1m 5m`. --erase Clean all existing data for the selected exchange/pairs/timeframes. - --data-format {json,jsongz} + --data-format-ohlcv {json,jsongz} Storage format for downloaded ohlcv data. (default: `json`). --data-format-trades {json,jsongz} Storage format for downloaded trades data. (default: `jsongz`). @@ -55,7 +55,7 @@ Common arguments: Freqtrade currently supports 2 dataformats, `json` (plain "text" json files) and `jsongz` (a gzipped version of json files). By default, OHLCV data is stored as `json` data, while trades data is stored as `jsongz` data. -This can be changed via the `--data-format` and `--data-format-trades` parameters respectivly. +This can be changed via the `--data-format-ohlcv` and `--data-format-trades` parameters respectivly. If the default dataformat has been changed during download, then the keys `dataformat_ohlcv` and `dataformat_trades` in the configuration file need to be adjusted to the selected dataformat as well. diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 58cb1e83b..a8d4bc198 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -346,7 +346,7 @@ AVAILABLE_CLI_OPTIONS = { required=True, ), "dataformat_ohlcv": Arg( - '--data-format', + '--data-format-ohlcv', help='Storage format for downloaded ohlcv data. (default: `%(default)s`).', choices=constants.AVAILABLE_DATAHANDLERS, default='json' From d22384c7fba439a5cbe01099dd95844c59934474 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 19:21:48 +0100 Subject: [PATCH 0552/1106] Full support for kraken stoploss --- freqtrade/persistence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 5b0046091..fa041abc3 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -318,10 +318,10 @@ class Trade(_DECL_BASE): elif order_type in ('market', 'limit') and order['side'] == 'sell': self.close(order['price']) logger.info('%s_SELL has been fulfilled for %s.', order_type.upper(), self) - elif order_type == 'stop_loss_limit': + elif order_type in ('stop_loss_limit', 'stop-loss'): self.stoploss_order_id = None self.close_rate_requested = self.stop_loss - logger.info('STOP_LOSS_LIMIT is hit for %s.', self) + logger.info('%s is hit for %s.', order_type.upper(), self) self.close(order['average']) else: raise ValueError(f'Unknown order type: {order_type}') From a7342bd9106ac1028fc12b3391c2ab633b9b3919 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 19:42:04 +0100 Subject: [PATCH 0553/1106] Fix non-existing strategy loading --- tests/optimize/test_backtesting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 9cfd662c1..337194ab1 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -766,7 +766,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): '--disable-max-market-positions', '--strategy-list', 'DefaultStrategy', - 'SampleStrategy', + 'TestStrategyLegacy', ] args = get_args(args) start_backtesting(args) @@ -789,7 +789,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Parameter --enable-position-stacking detected ...', 'Running backtesting for Strategy DefaultStrategy', - 'Running backtesting for Strategy SampleStrategy', + 'Running backtesting for Strategy TestStrategyLegacy', ] for line in exists: From 5adbe3c2d3ac75eb20b08b93d8902cf3ab25a643 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 19 Feb 2020 19:50:01 +0100 Subject: [PATCH 0554/1106] initial search path is optional ... --- freqtrade/resolvers/iresolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/resolvers/iresolver.py b/freqtrade/resolvers/iresolver.py index 764759289..52d944f2c 100644 --- a/freqtrade/resolvers/iresolver.py +++ b/freqtrade/resolvers/iresolver.py @@ -22,7 +22,7 @@ class IResolver: object_type: Type[Any] object_type_str: str user_subdir: Optional[str] = None - initial_search_path: Path + initial_search_path: Optional[Path] @classmethod def build_search_paths(cls, config: Dict[str, Any], user_subdir: Optional[str] = None, From 09a1c9eed6b629fe9f4502cbcf805b8e78b8da13 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Wed, 19 Feb 2020 22:25:34 +0100 Subject: [PATCH 0555/1106] fixed docs description of hyperopts --- docs/hyperopt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 1f9907b83..9bc5888ce 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -191,8 +191,8 @@ Currently, the following loss functions are builtin: * `DefaultHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function) * `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration) -* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on trade returns relative to **upside** standard deviation) -* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on **daily** trade returns relative to **upside** standard deviation) +* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on trade returns relative to standard deviation) +* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on **daily** trade returns relative to standard deviation) * `SortinoHyperOptLoss` (optimizes Sortino Ratio calculated on trade returns relative to **downside** standard deviation) * `SortinoHyperOptLossDaily` (optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation) From bca5f804a87d2b2e1556711a1f96d35161d279a2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 20 Feb 2020 08:17:24 +0300 Subject: [PATCH 0556/1106] Move divider log message --- freqtrade/worker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 64cc97026..509ba018e 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -109,14 +109,14 @@ class Worker: """ start = time.time() result = func(*args, **kwargs) + logger.debug("========================================") end = time.time() duration = max(min_secs - (end - start), 0.0) - logger.debug('Throttling %s for %.2f seconds', func.__name__, duration) + logger.debug(f"Throttling {func.__name__} for {duration:.2f} seconds") time.sleep(duration) return result def _process(self) -> None: - logger.debug("========================================") try: self.freqtrade.process() except TemporaryError as error: From 56a06cbd331daa07216b77094d6b98ce0a651439 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 20 Feb 2020 08:19:22 +0300 Subject: [PATCH 0557/1106] Update strings to f-strings --- freqtrade/worker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 509ba018e..b3b3b712a 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -26,7 +26,7 @@ class Worker: """ Init all variables and objects the bot needs to work """ - logger.info('Starting worker %s', __version__) + logger.info(f"Starting worker {__version__}") self._args = args self._config = config @@ -77,7 +77,7 @@ class Worker: if state != old_state: self.freqtrade.notify_status(f'{state.name.lower()}') - logger.info('Changing state to: %s', state.name) + logger.info(f"Changing state to: {state.name}") if state == State.RUNNING: self.freqtrade.startup() From 10668bb2490c2ed56f47f5536fdf0892c2173648 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 20 Feb 2020 06:22:36 +0100 Subject: [PATCH 0558/1106] Update tests/strategy/test_strategy.py Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- tests/strategy/test_strategy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/strategy/test_strategy.py b/tests/strategy/test_strategy.py index 27bbb2d3b..13ca68bf0 100644 --- a/tests/strategy/test_strategy.py +++ b/tests/strategy/test_strategy.py @@ -42,7 +42,7 @@ def test_search_all_strategies_with_failed(): strategies = StrategyResolver.search_all_objects(directory, enum_failed=True) assert isinstance(strategies, list) assert len(strategies) == 3 - # with enum_failed=True search_all_objects() shall find 3 good strategies + # with enum_failed=True search_all_objects() shall find 2 good strategies # and 1 which fails to load assert len([x for x in strategies if x['class'] is not None]) == 2 assert len([x for x in strategies if x['class'] is None]) == 1 From 78ee36a8c6e8d17289059be945324c8166d514dd Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 20 Feb 2020 15:18:26 +0300 Subject: [PATCH 0559/1106] Use _throttle() in stopped state instead of sleep() --- freqtrade/worker.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index b3b3b712a..c397beaab 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -87,7 +87,7 @@ class Worker: logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: STOPPED.") self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: STOPPED.") - time.sleep(throttle_secs) + self._throttle(func=self._process_stopped, min_secs=throttle_secs) elif state == State.RUNNING: # Ping systemd watchdog before throttling @@ -95,7 +95,7 @@ class Worker: logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: RUNNING.") self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: RUNNING.") - self._throttle(func=self._process, min_secs=throttle_secs) + self._throttle(func=self._process_running, min_secs=throttle_secs) return state @@ -116,7 +116,11 @@ class Worker: time.sleep(duration) return result - def _process(self) -> None: + def _process_stopped(self) -> None: + # Maybe do here something in the future... + pass + + def _process_running(self) -> None: try: self.freqtrade.process() except TemporaryError as error: From 945ff09e27c31d5953231f6ecfa661434d6fb4fb Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 20 Feb 2020 14:19:24 +0100 Subject: [PATCH 0560/1106] Use correct strategy path for docker testing --- build_helpers/publish_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_helpers/publish_docker.sh b/build_helpers/publish_docker.sh index 17d5230c9..013644563 100755 --- a/build_helpers/publish_docker.sh +++ b/build_helpers/publish_docker.sh @@ -23,7 +23,7 @@ if [ $? -ne 0 ]; then fi # Run backtest -docker run --rm -v $(pwd)/config.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy DefaultStrategy +docker run --rm -v $(pwd)/config.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy DefaultStrategy if [ $? -ne 0 ]; then echo "failed running backtest" From e7b12704dec4c8265e5adf51dfb3d7f36367adae Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 20 Feb 2020 19:12:55 +0100 Subject: [PATCH 0561/1106] Added test for details --- tests/commands/test_commands.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 9c233019c..dfaa936ed 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -778,6 +778,19 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", From 09226fd5d5e378e9f7ee11382528ec6c06ac7571 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 20 Feb 2020 19:18:42 +0100 Subject: [PATCH 0562/1106] PEP8 correction --- tests/commands/test_commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index dfaa936ed..ceae6f372 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -787,7 +787,8 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out - for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss"]) + for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", + "Sell hyperspace params", "ROI table", "Stoploss"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) From 04aa74e5add9425f73e2485a98a319c32b3ca2ad Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 03:37:38 +0300 Subject: [PATCH 0563/1106] Better throttling --- freqtrade/worker.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index c397beaab..40bfb54d8 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -108,12 +108,13 @@ class Worker: :return: Any """ start = time.time() - result = func(*args, **kwargs) logger.debug("========================================") - end = time.time() - duration = max(min_secs - (end - start), 0.0) - logger.debug(f"Throttling {func.__name__} for {duration:.2f} seconds") - time.sleep(duration) + result = func(*args, **kwargs) + time_passed = time.time() - start + sleep_duration = max(min_secs - time_passed, 0.0) + logger.debug(f"Throttling with '{func.__name__}()': sleep for {sleep_duration:.2f} s, " + f"last iteration took {time_passed:.2f} s.") + time.sleep(sleep_duration) return result def _process_stopped(self) -> None: From e0800b7c29fb0fe3b53afe2fa6732da7f37e06c1 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 03:52:14 +0300 Subject: [PATCH 0564/1106] Make throttle start time an worker object attribute --- freqtrade/worker.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 40bfb54d8..dc8f9109f 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -32,6 +32,8 @@ class Worker: self._config = config self._init(False) + self.last_throttle_start_time: float = None + # Tell systemd that we completed initialization phase if self._sd_notify: logger.debug("sd_notify: READY=1") @@ -107,10 +109,10 @@ class Worker: :param min_secs: minimum execution time in seconds :return: Any """ - start = time.time() + self.last_throttle_start_time = time.time() logger.debug("========================================") result = func(*args, **kwargs) - time_passed = time.time() - start + time_passed = time.time() - self.last_throttle_start_time sleep_duration = max(min_secs - time_passed, 0.0) logger.debug(f"Throttling with '{func.__name__}()': sleep for {sleep_duration:.2f} s, " f"last iteration took {time_passed:.2f} s.") From 881f602f91b6afa5607f44eed8ad06165951ebe6 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 04:00:23 +0300 Subject: [PATCH 0565/1106] Adjust methods params --- freqtrade/worker.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index dc8f9109f..088526d85 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -32,7 +32,7 @@ class Worker: self._config = config self._init(False) - self.last_throttle_start_time: float = None + self.last_throttle_start_time: Optional[float] = None # Tell systemd that we completed initialization phase if self._sd_notify: @@ -65,15 +65,13 @@ class Worker: if state == State.RELOAD_CONF: self._reconfigure() - def _worker(self, old_state: Optional[State], throttle_secs: Optional[float] = None) -> State: + def _worker(self, old_state: Optional[State]) -> State: """ Trading routine that must be run at each loop :param old_state: the previous service state from the previous call :return: current service state """ state = self.freqtrade.state - if throttle_secs is None: - throttle_secs = self._throttle_secs # Log state transition if state != old_state: @@ -89,7 +87,7 @@ class Worker: logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: STOPPED.") self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: STOPPED.") - self._throttle(func=self._process_stopped, min_secs=throttle_secs) + self._throttle(func=self._process_stopped, throttle_secs=self._throttle_secs) elif state == State.RUNNING: # Ping systemd watchdog before throttling @@ -97,23 +95,23 @@ class Worker: logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: RUNNING.") self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: RUNNING.") - self._throttle(func=self._process_running, min_secs=throttle_secs) + self._throttle(func=self._process_running, throttle_secs=self._throttle_secs) return state - def _throttle(self, func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any: + def _throttle(self, func: Callable[..., Any], throttle_secs: float, *args, **kwargs) -> Any: """ Throttles the given callable that it takes at least `min_secs` to finish execution. :param func: Any callable - :param min_secs: minimum execution time in seconds - :return: Any + :param throttle_secs: throttling interation execution time limit in seconds + :return: Any (result of execution of func) """ self.last_throttle_start_time = time.time() logger.debug("========================================") result = func(*args, **kwargs) time_passed = time.time() - self.last_throttle_start_time - sleep_duration = max(min_secs - time_passed, 0.0) + sleep_duration = max(throttle_secs - time_passed, 0.0) logger.debug(f"Throttling with '{func.__name__}()': sleep for {sleep_duration:.2f} s, " f"last iteration took {time_passed:.2f} s.") time.sleep(sleep_duration) From 269a669af82b586e69d061ed5866b8c56af173d0 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 05:07:31 +0300 Subject: [PATCH 0566/1106] Move heartbeat to worker --- freqtrade/freqtradebot.py | 10 ---------- freqtrade/worker.py | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 127586437..00d5c369a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -6,7 +6,6 @@ import logging import traceback from datetime import datetime from math import isclose -from os import getpid from threading import Lock from typing import Any, Dict, List, Optional, Tuple @@ -52,10 +51,6 @@ class FreqtradeBot: # Init objects self.config = config - self._heartbeat_msg = 0 - - self.heartbeat_interval = self.config.get('internals', {}).get('heartbeat_interval', 60) - self.strategy: IStrategy = StrategyResolver.load_strategy(self.config) # Check config consistency here since strategies can set certain options @@ -159,11 +154,6 @@ class FreqtradeBot: self.check_handle_timedout() Trade.session.flush() - if (self.heartbeat_interval - and (arrow.utcnow().timestamp - self._heartbeat_msg > self.heartbeat_interval)): - logger.info(f"Bot heartbeat. PID={getpid()}") - self._heartbeat_msg = arrow.utcnow().timestamp - def _refresh_whitelist(self, trades: List[Trade] = []) -> List[str]: """ Refresh whitelist from pairlist or edge and extend it with trades. diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 088526d85..adce7ddda 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -4,8 +4,10 @@ Main Freqtrade worker class. import logging import time import traceback +from os import getpid from typing import Any, Callable, Dict, Optional +import arrow import sdnotify from freqtrade import __version__, constants @@ -33,6 +35,7 @@ class Worker: self._init(False) self.last_throttle_start_time: Optional[float] = None + self._heartbeat_msg = 0 # Tell systemd that we completed initialization phase if self._sd_notify: @@ -50,10 +53,10 @@ class Worker: # Init the instance of the bot self.freqtrade = FreqtradeBot(self._config) - self._throttle_secs = self._config.get('internals', {}).get( - 'process_throttle_secs', - constants.PROCESS_THROTTLE_SECS - ) + internals_config = self._config.get('internals', {}) + self._throttle_secs = internals_config.get('process_throttle_secs', + constants.PROCESS_THROTTLE_SECS) + self._heartbeat_interval = internals_config.get('heartbeat_interval', 60) self._sd_notify = sdnotify.SystemdNotifier() if \ self._config.get('internals', {}).get('sd_notify', False) else None @@ -97,6 +100,11 @@ class Worker: self._throttle(func=self._process_running, throttle_secs=self._throttle_secs) + if (self._heartbeat_interval + and (arrow.utcnow().timestamp - self._heartbeat_msg > self._heartbeat_interval)): + logger.info(f"Bot heartbeat. PID={getpid()}") + self._heartbeat_msg = arrow.utcnow().timestamp + return state def _throttle(self, func: Callable[..., Any], throttle_secs: float, *args, **kwargs) -> Any: From d2e20d86bb8808ac11427b08b9d2c3b1d27723bd Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 05:31:21 +0300 Subject: [PATCH 0567/1106] Align heartbeat to throttling logging --- freqtrade/worker.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index adce7ddda..523b9038f 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -7,7 +7,6 @@ import traceback from os import getpid from typing import Any, Callable, Dict, Optional -import arrow import sdnotify from freqtrade import __version__, constants @@ -34,8 +33,8 @@ class Worker: self._config = config self._init(False) - self.last_throttle_start_time: Optional[float] = None - self._heartbeat_msg = 0 + self.last_throttle_start_time: float = 0 + self._heartbeat_msg: float = 0 # Tell systemd that we completed initialization phase if self._sd_notify: @@ -100,10 +99,11 @@ class Worker: self._throttle(func=self._process_running, throttle_secs=self._throttle_secs) - if (self._heartbeat_interval - and (arrow.utcnow().timestamp - self._heartbeat_msg > self._heartbeat_interval)): - logger.info(f"Bot heartbeat. PID={getpid()}") - self._heartbeat_msg = arrow.utcnow().timestamp + if self._heartbeat_interval: + now = time.time() + if (now - self._heartbeat_msg) > self._heartbeat_interval: + logger.info(f"Bot heartbeat. PID={getpid()}") + self._heartbeat_msg = now return state From d9ecf3e4bfbdf2969c772ffb06e88ddecba4cf56 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 21 Feb 2020 12:26:32 +0300 Subject: [PATCH 0568/1106] Add version and state to heartbeat message --- freqtrade/worker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 523b9038f..f4b9f275b 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -102,7 +102,8 @@ class Worker: if self._heartbeat_interval: now = time.time() if (now - self._heartbeat_msg) > self._heartbeat_interval: - logger.info(f"Bot heartbeat. PID={getpid()}") + logger.info(f"Bot heartbeat. PID={getpid()}, " + f"version='{__version__}', state='{state.name}'") self._heartbeat_msg = now return state From 8c1a9332215bc6dedc813188cae09b3a343e83e0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 21 Feb 2020 20:23:43 +0100 Subject: [PATCH 0569/1106] cancel_order should return a dict --- freqtrade/exchange/exchange.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b3b347016..7fc2af308 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -894,9 +894,9 @@ class Exchange: until=until, from_id=from_id)) @retrier - def cancel_order(self, order_id: str, pair: str) -> None: + def cancel_order(self, order_id: str, pair: str) -> Dict: if self._config['dry_run']: - return + return {} try: return self._api.cancel_order(order_id, pair) From 6c01542fed34a71f44ae3b4aa75a0c8bce0b302f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 21 Feb 2020 20:27:13 +0100 Subject: [PATCH 0570/1106] Ad check_sell_timeout --- freqtrade/freqtradebot.py | 6 +++++- freqtrade/strategy/interface.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f458f91d6..aa41c2f2a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -830,7 +830,11 @@ class FreqtradeBot: self.wallets.update() elif ((order['side'] == 'sell' and order['status'] == 'canceled') - or (self._check_timed_out('sell', order))): + or (self._check_timed_out('sell', order)) + or strategy_safe_wrapper(self.strategy.check_sell_timeout, + default_retval=False)(pair=trade.pair, + trade=trade, + order=order)): self.handle_timedout_limit_sell(trade, order) self.wallets.update() diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index de08b7cda..681d2ccfb 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -167,6 +167,24 @@ class IStrategy(ABC): """ return False + def check_sell_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + """ + Check sell timeout function callback. + This method can be used to override the sell-timeout. + It is called whenever a limit sell order has been created, + and is not yet fully filled. + Configuration options in `unfilledtimeout` will be verified before this, + so ensure to set these timeouts high enough. + + When not implemented by a strategy, this simply returns False. + :param pair: Pair the trade is for + :param trade: trade object. + :param order: Order dictionary as returned from CCXT. + :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. + :return bool: When True is returned, then the sell-order is cancelled. + """ + return False + def informative_pairs(self) -> List[Tuple[str, str]]: """ Define additional, informative pair/interval combinations to be cached from the exchange. From 135d9ddf7ac4138ebd3b0650cf25655e67ecba32 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 21 Feb 2020 20:35:13 +0100 Subject: [PATCH 0571/1106] Fix test due to changed dry-run cancel 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 8b2e439c3..acef073f1 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1634,7 +1634,7 @@ def test_get_historic_trades_notsupported(default_conf, mocker, caplog, exchange def test_cancel_order_dry_run(default_conf, mocker, exchange_name): default_conf['dry_run'] = True exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) - assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None + assert exchange.cancel_order(order_id='123', pair='TKN/BTC') == {} # Ensure that if not dry_run, we should call API From bc30162a31b99078a3866659377210b084fccbbe Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 21 Feb 2020 20:54:21 +0100 Subject: [PATCH 0572/1106] Add some documentation --- docs/strategy-customization.md | 3 +-- mkdocs.yml | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 07833da34..5746cc613 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -1,7 +1,6 @@ # Strategy Customization -This page explains where to customize your strategies, and add new -indicators. +This page explains where to customize your strategies, and add new indicators. ## Install a custom strategy file diff --git a/mkdocs.yml b/mkdocs.yml index d53687c64..528b77eb5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,7 @@ nav: - Plotting: plotting.md - SQL Cheatsheet: sql_cheatsheet.md - Advanced Post-installation Tasks: advanced-setup.md + - Advanced Strategy: strategy-advanced.md - Advanced Hyperopt: advanced-hyperopt.md - Sandbox Testing: sandbox-testing.md - Deprecated Features: deprecated.md From 63502ed976a9cd5ffc75d09b8b5295fc34dca1e4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 08:14:08 +0100 Subject: [PATCH 0573/1106] Add new advanced-strategy documentation file --- docs/strategy-advanced.md | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/strategy-advanced.md diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md new file mode 100644 index 000000000..bdb380276 --- /dev/null +++ b/docs/strategy-advanced.md @@ -0,0 +1,59 @@ +# Advanced Strategies + +This page explains some advanced concepts available for strategies. +If you're just getting started, please be familiar with the methods described in the [Strategy Customization](strategy-customization.md) documentation first. + +## Custom order timeout rules + +Simple, timebased order-timeouts can be configured either via strategy or in the configuration in the `unfilledtimeout` section. + +However, freqtrade also offers a custom callback for both ordertypes, which allows you to decide based on custom criteria if a order did time out or not. + +!!! Note: + Unfilled order timeouts are not relevant during backtesting or hyperopt, and are only relevant during real (live) trading. Therefore these methods are only called in these circumstances. + +### Custom order timeout example + +A simple example, which applies different unfilled-timeouts depending on the price of the asset can be seen below. +It applies a tight timeout for higher priced assets, while allowing more time to fill on cheap coins. + +The function must return either `True` (cancel order) or `False` (keep order alive). + +``` python +from datetime import datetime, timestamp +from freqtrade.persistence import Trade + +class Awesomestrategy(IStrategy): + + # ... populate_* methods + + # Set unfilledtimeout to 25 hours, since our maximum timeout from below is 24 hours. + unfilledtimeout = { + 'buy': 60 * 25, + 'sell': 60 * 25 + } + + def check_buy_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5): + return True + elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3): + return True + elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24): + return True + return True + + + def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5): + return True + elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3): + return True + elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24): + return True + return True +``` + +!!! Note: + For the above example, `unfilledtimeout` must be set to something bigger than 24h, otherwise that type of timeout will apply first. + + From f5b4a6d3d72fea870d912e6a1b28c47ccd3247dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:03:25 +0100 Subject: [PATCH 0574/1106] Remove fetch_ticker caching --- freqtrade/exchange/exchange.py | 35 +++++++++++---------------------- freqtrade/freqtradebot.py | 4 ++-- tests/exchange/test_exchange.py | 15 +++----------- tests/rpc/test_rpc.py | 6 ------ 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b3b347016..e45238b07 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -66,8 +66,6 @@ class Exchange: self._config.update(config) - self._cached_ticker: Dict[str, Any] = {} - # Holds last candle refreshed time of each pair self._pairs_last_refresh_time: Dict[Tuple[str, str], int] = {} # Timestamp of last markets refresh @@ -591,28 +589,17 @@ class Exchange: raise OperationalException(e) from e @retrier - def fetch_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: - if refresh or pair not in self._cached_ticker.keys(): - try: - if pair not in self._api.markets or not self._api.markets[pair].get('active'): - raise DependencyException(f"Pair {pair} not available") - data = self._api.fetch_ticker(pair) - try: - self._cached_ticker[pair] = { - 'bid': float(data['bid']), - 'ask': float(data['ask']), - } - except KeyError: - logger.debug("Could not cache ticker data for %s", pair) - return data - except (ccxt.NetworkError, ccxt.ExchangeError) as e: - raise TemporaryError( - f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e - except ccxt.BaseError as e: - raise OperationalException(e) from e - else: - logger.info("returning cached ticker-data for %s", pair) - return self._cached_ticker[pair] + def fetch_ticker(self, pair: str) -> dict: + try: + if pair not in self._api.markets or not self._api.markets[pair].get('active'): + raise DependencyException(f"Pair {pair} not available") + data = self._api.fetch_ticker(pair) + return data + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e + except ccxt.BaseError as e: + raise OperationalException(e) from e def get_historic_ohlcv(self, pair: str, timeframe: str, since_ms: int) -> List: diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 127586437..032e3e8f7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -253,7 +253,7 @@ class FreqtradeBot: else: if not tick: logger.info('Using Last Ask / Last Price') - ticker = self.exchange.fetch_ticker(pair, refresh) + ticker = self.exchange.fetch_ticker(pair) else: ticker = tick if ticker['ask'] < ticker['last']: @@ -631,7 +631,7 @@ class FreqtradeBot: rate = order_book['bids'][0][0] else: - rate = self.exchange.fetch_ticker(pair, refresh)['bid'] + rate = self.exchange.fetch_ticker(pair)['bid'] return rate def handle_trade(self, trade: Trade) -> bool: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8b2e439c3..3830d0acb 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1121,25 +1121,16 @@ def test_fetch_ticker(default_conf, mocker, exchange_name): assert ticker['bid'] == 0.5 assert ticker['ask'] == 1 - assert 'ETH/BTC' in exchange._cached_ticker - assert exchange._cached_ticker['ETH/BTC']['bid'] == 0.5 - assert exchange._cached_ticker['ETH/BTC']['ask'] == 1 - - # Test caching - api_mock.fetch_ticker = MagicMock() - exchange.fetch_ticker(pair='ETH/BTC', refresh=False) - assert api_mock.fetch_ticker.call_count == 0 - ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, "fetch_ticker", "fetch_ticker", - pair='ETH/BTC', refresh=True) + pair='ETH/BTC') api_mock.fetch_ticker = MagicMock(return_value={}) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) - exchange.fetch_ticker(pair='ETH/BTC', refresh=True) + exchange.fetch_ticker(pair='ETH/BTC') with pytest.raises(DependencyException, match=r'Pair XRP/ETH not available'): - exchange.fetch_ticker(pair='XRP/ETH', refresh=True) + exchange.fetch_ticker(pair='XRP/ETH') @pytest.mark.parametrize("exchange_name", EXCHANGES) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index a35bfa0d6..2d1fa5b2d 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -67,8 +67,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) - # invalidate ticker cache - rpc._freqtrade.exchange._cached_ticker = {} results = rpc._rpc_trade_status() assert isnan(results[0]['current_profit']) assert isnan(results[0]['current_rate']) @@ -136,8 +134,6 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) - # invalidate ticker cache - rpc._freqtrade.exchange._cached_ticker = {} result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert 'instantly' == result[0][2] assert 'ETH/BTC' in result[0][1] @@ -262,8 +258,6 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, # Test non-available pair mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) - # invalidate ticker cache - rpc._freqtrade.exchange._cached_ticker = {} stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) assert stats['trade_count'] == 2 assert stats['first_trade_date'] == 'just now' From 97e6e5e9766c87bb728fe396f4f5119616eeda1a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:12:33 +0100 Subject: [PATCH 0575/1106] Implement caching in the correct place --- freqtrade/freqtradebot.py | 32 ++++++++++++++++++++++++++------ tests/rpc/test_rpc.py | 6 +++--- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 032e3e8f7..d9126370b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -11,6 +11,7 @@ from threading import Lock from typing import Any, Dict, List, Optional, Tuple import arrow +from cachetools import TTLCache from requests.exceptions import RequestException from freqtrade import __version__, constants, persistence @@ -54,6 +55,9 @@ class FreqtradeBot: self._heartbeat_msg = 0 + self._sell_rate_cache = TTLCache(maxsize=100, ttl=5) + self._buy_rate_cache = TTLCache(maxsize=100, ttl=5) + self.heartbeat_interval = self.config.get('internals', {}).get('heartbeat_interval', 60) self.strategy: IStrategy = StrategyResolver.load_strategy(self.config) @@ -234,11 +238,19 @@ class FreqtradeBot: return trades_created - def get_buy_rate(self, pair: str, refresh: bool, tick: Dict = None) -> float: + def get_buy_rate(self, pair: str, refresh: bool) -> float: """ Calculates bid target between current ask price and last price + :param pair: Pair to get rate for + :param refresh: allow cached data :return: float: Price """ + if not refresh: + rate = self._sell_rate_cache.get(pair) + # Check if cache has been invalidated + if rate: + return rate + config_bid_strategy = self.config.get('bid_strategy', {}) if 'use_order_book' in config_bid_strategy and\ config_bid_strategy.get('use_order_book', False): @@ -251,11 +263,8 @@ class FreqtradeBot: logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate) used_rate = order_book_rate else: - if not tick: - logger.info('Using Last Ask / Last Price') - ticker = self.exchange.fetch_ticker(pair) - else: - ticker = tick + logger.info('Using Last Ask / Last Price') + ticker = self.exchange.fetch_ticker(pair) if ticker['ask'] < ticker['last']: ticker_rate = ticker['ask'] else: @@ -263,6 +272,8 @@ class FreqtradeBot: ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) used_rate = ticker_rate + self._buy_rate_cache[pair] = used_rate + return used_rate def get_trade_stake_amount(self, pair: str) -> float: @@ -621,8 +632,16 @@ class FreqtradeBot: The orderbook portion is only used for rpc messaging, which would otherwise fail for BitMex (has no bid/ask in fetch_ticker) or remain static in any other case since it's not updating. + :param pair: Pair to get rate for + :param refresh: allow cached data :return: Bid rate """ + if not refresh: + rate = self._sell_rate_cache.get(pair) + # Check if cache has been invalidated + if rate: + return rate + config_ask_strategy = self.config.get('ask_strategy', {}) if config_ask_strategy.get('use_order_book', False): logger.debug('Using order book to get sell rate') @@ -632,6 +651,7 @@ class FreqtradeBot: else: rate = self.exchange.fetch_ticker(pair)['bid'] + self._sell_rate_cache[pair] = rate return rate def handle_trade(self, trade: Trade) -> bool: diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 2d1fa5b2d..40b2d6627 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -65,7 +65,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_order': '(limit buy rem=0.00000000)' } == results[0] - mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) results = rpc._rpc_trade_status() assert isnan(results[0]['current_profit']) @@ -132,7 +132,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert 'ETH/BTC' in result[0][1] assert '-0.59% (-0.09)' == result[0][3] - mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert 'instantly' == result[0][2] @@ -256,7 +256,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, assert prec_satoshi(stats['best_rate'], 6.2) # Test non-available pair - mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) assert stats['trade_count'] == 2 From 77ef3240cd17b932f499a19e7820e39818cf1aa9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:16:20 +0100 Subject: [PATCH 0576/1106] Implement log messages --- freqtrade/freqtradebot.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d9126370b..4b54b79e1 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -246,9 +246,10 @@ class FreqtradeBot: :return: float: Price """ if not refresh: - rate = self._sell_rate_cache.get(pair) + rate = self._buy_rate_cache.get(pair) # Check if cache has been invalidated if rate: + logger.info(f"Using cached buy rate for {pair}.") return rate config_bid_strategy = self.config.get('bid_strategy', {}) @@ -577,7 +578,7 @@ class FreqtradeBot: """ Sends rpc notification when a buy cancel occured. """ - current_rate = self.get_buy_rate(trade.pair, True) + current_rate = self.get_buy_rate(trade.pair, False) msg = { 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, @@ -640,6 +641,7 @@ class FreqtradeBot: rate = self._sell_rate_cache.get(pair) # Check if cache has been invalidated if rate: + logger.info(f"Using cached sell rate for {pair}.") return rate config_ask_strategy = self.config.get('ask_strategy', {}) @@ -1078,7 +1080,7 @@ class FreqtradeBot: """ profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) - current_rate = self.get_sell_rate(trade.pair, True) + current_rate = self.get_sell_rate(trade.pair, False) profit_percent = trade.calc_profit_ratio(profit_rate) gain = "profit" if profit_percent > 0 else "loss" From 2fe7b683cb3a11b4c629b7a796b30ff5838a5682 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:23:13 +0100 Subject: [PATCH 0577/1106] Add tests for cached rates --- tests/test_freqtradebot.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5ed4d296c..c7a70be8c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -915,13 +915,21 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: (5, 10, 1.0, 5), # last bigger than ask (5, 10, 0.5, 5), # last bigger than ask ]) -def test_get_buy_rate(mocker, default_conf, ask, last, last_ab, expected) -> None: +def test_get_buy_rate(mocker, default_conf, caplog, ask, last, last_ab, expected) -> None: default_conf['bid_strategy']['ask_last_balance'] = last_ab freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={'ask': ask, 'last': last})) assert freqtrade.get_buy_rate('ETH/BTC', True) == expected + assert not log_has("Using cached buy rate for ETH/BTC.", caplog) + + assert freqtrade.get_buy_rate('ETH/BTC', False) == expected + assert log_has("Using cached buy rate for ETH/BTC.", caplog) + # Running a 2nd time with Refresh on! + caplog.clear() + assert freqtrade.get_buy_rate('ETH/BTC', True) == expected + assert not log_has("Using cached buy rate for ETH/BTC.", caplog) def test_execute_buy(mocker, default_conf, fee, limit_buy_order) -> None: @@ -3614,7 +3622,7 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order assert freqtrade.handle_trade(trade) is True -def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: +def test_get_sell_rate(default_conf, mocker, caplog, ticker, order_book_l2) -> None: mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -3626,8 +3634,15 @@ def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: # Test regular mode ft = get_patched_freqtradebot(mocker, default_conf) rate = ft.get_sell_rate(pair, True) + assert not log_has("Using cached sell rate for ETH/BTC.", caplog) assert isinstance(rate, float) assert rate == 0.00001098 + # Use caching + rate = ft.get_sell_rate(pair, False) + assert rate == 0.00001098 + assert log_has("Using cached sell rate for ETH/BTC.", caplog) + + caplog.clear() # Test orderbook mode default_conf['ask_strategy']['use_order_book'] = True @@ -3635,8 +3650,12 @@ def test_get_sell_rate(default_conf, mocker, ticker, order_book_l2) -> None: default_conf['ask_strategy']['order_book_max'] = 2 ft = get_patched_freqtradebot(mocker, default_conf) rate = ft.get_sell_rate(pair, True) + assert not log_has("Using cached sell rate for ETH/BTC.", caplog) assert isinstance(rate, float) assert rate == 0.043936 + rate = ft.get_sell_rate(pair, False) + assert rate == 0.043936 + assert log_has("Using cached sell rate for ETH/BTC.", caplog) def test_startup_state(default_conf, mocker): From 4a188525ec610b8e0b41bb028f9803bf98abaa8a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:28:13 +0100 Subject: [PATCH 0578/1106] Fix documentation note syntax --- docs/strategy-advanced.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index bdb380276..a60a6ea47 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -9,7 +9,7 @@ Simple, timebased order-timeouts can be configured either via strategy or in the However, freqtrade also offers a custom callback for both ordertypes, which allows you to decide based on custom criteria if a order did time out or not. -!!! Note: +!!! Note Unfilled order timeouts are not relevant during backtesting or hyperopt, and are only relevant during real (live) trading. Therefore these methods are only called in these circumstances. ### Custom order timeout example @@ -53,7 +53,5 @@ class Awesomestrategy(IStrategy): return True ``` -!!! Note: +!!! Note For the above example, `unfilledtimeout` must be set to something bigger than 24h, otherwise that type of timeout will apply first. - - From 365fdf4c3732bdbe588e18f052b81648d0c551f7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:41:22 +0100 Subject: [PATCH 0579/1106] Add docstring to strategy wrapper --- freqtrade/strategy/strategy_wrapper.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py index 4f35bfbab..597432255 100644 --- a/freqtrade/strategy/strategy_wrapper.py +++ b/freqtrade/strategy/strategy_wrapper.py @@ -6,6 +6,11 @@ logger = logging.getLogger(__name__) def strategy_safe_wrapper(f, message: str = "", default_retval=None): + """ + Wrapper around user-provided methods and functions. + Caches all exceptions and returns either the default_retval (if it's not None) or raises + a StrategyError exception, which then needs to be handled by the calling method. + """ def wrapper(*args, **kwargs): try: return f(*args, **kwargs) @@ -15,14 +20,14 @@ def strategy_safe_wrapper(f, message: str = "", default_retval=None): f"Strategy caused the following exception: {error}" f"{f}" ) - if not default_retval: + if default_retval is None: raise StrategyError(str(error)) from error return default_retval except Exception as error: logger.exception( f"Unexpected error {error} calling {f}" ) - if not default_retval: + if default_retval is None: raise StrategyError(str(error)) from error return default_retval From 8cd77b2e2708a30fd3c01002f21aca8c23673e7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 11:52:39 +0100 Subject: [PATCH 0580/1106] Add some tests for strategy_wrapper --- freqtrade/strategy/strategy_wrapper.py | 1 + tests/strategy/test_interface.py | 38 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/freqtrade/strategy/strategy_wrapper.py b/freqtrade/strategy/strategy_wrapper.py index 597432255..7b9da9140 100644 --- a/freqtrade/strategy/strategy_wrapper.py +++ b/freqtrade/strategy/strategy_wrapper.py @@ -25,6 +25,7 @@ def strategy_safe_wrapper(f, message: str = "", default_retval=None): return default_retval except Exception as error: logger.exception( + f"{message}" f"Unexpected error {error} calling {f}" ) if default_retval is None: diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index ca9bdc504..1db01b3ac 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -4,12 +4,15 @@ import logging from unittest.mock import MagicMock import arrow +import pytest from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.data.history import load_data +from freqtrade.exceptions import StrategyError from freqtrade.persistence import Trade from freqtrade.resolvers import StrategyResolver +from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from tests.conftest import get_patched_exchange, log_has, log_has_re from .strats.default_strategy import DefaultStrategy @@ -323,3 +326,38 @@ def test_is_pair_locked(default_conf): pair = 'ETH/BTC' strategy.unlock_pair(pair) assert not strategy.is_pair_locked(pair) + + +@pytest.mark.parametrize('error', [ + ValueError, KeyError, Exception, +]) +def test_strategy_safe_wrapper_error(caplog, error): + def failing_method(): + raise error('This is an error.') + + def working_method(argumentpassedin): + return argumentpassedin + + with pytest.raises(StrategyError, match=r'This is an error.'): + strategy_safe_wrapper(failing_method, message='DeadBeef')() + + assert log_has_re(r'DeadBeef.*', caplog) + ret = strategy_safe_wrapper(failing_method, message='DeadBeef', default_retval=True)() + + assert isinstance(ret, bool) + assert ret + + +@pytest.mark.parametrize('value', [ + 1, 22, 55, True, False, {'a': 1, 'b': '112'}, + [1, 2, 3, 4], (4, 2, 3, 6) +]) +def test_strategy_safe_wrapper(value): + + def working_method(argumentpassedin): + return argumentpassedin + + ret = strategy_safe_wrapper(working_method, message='DeadBeef')(value) + + assert type(ret) == type(value) + assert ret == value From 7ecc56fa44d56d3ceaf70cc81b205cbcaff90795 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 13:10:41 +0100 Subject: [PATCH 0581/1106] Load ohlcv data as float --- freqtrade/data/history/jsondatahandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 17b9fd7d7..7219d8c01 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -69,7 +69,7 @@ class JsonDataHandler(IDataHandler): filename = self._pair_data_filename(self._datadir, pair, timeframe) if not filename.exists(): return DataFrame(columns=self._columns) - pairdata = read_json(filename, orient='values') + pairdata = read_json(filename, orient='values', dtype='float64') pairdata.columns = self._columns pairdata['date'] = to_datetime(pairdata['date'], unit='ms', From 3186add87b82837018e8e9e46a0fb5c5d71a2b23 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Feb 2020 14:46:54 +0100 Subject: [PATCH 0582/1106] Use explicit column list for float parsing --- freqtrade/data/history/jsondatahandler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 7219d8c01..606018f34 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -69,7 +69,9 @@ class JsonDataHandler(IDataHandler): filename = self._pair_data_filename(self._datadir, pair, timeframe) if not filename.exists(): return DataFrame(columns=self._columns) - pairdata = read_json(filename, orient='values', dtype='float64') + pairdata = read_json(filename, orient='values', + dtype={'open': 'float', 'high': 'float', + 'low': 'float', 'close': 'float', 'volume': 'float'}) pairdata.columns = self._columns pairdata['date'] = to_datetime(pairdata['date'], unit='ms', From c651e0ac8278c854dc5901189d598b247e8d64ea Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 22 Feb 2020 19:46:40 +0300 Subject: [PATCH 0583/1106] Fix #2948 --- freqtrade/data/history/jsondatahandler.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 606018f34..ee653d937 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -69,10 +69,11 @@ class JsonDataHandler(IDataHandler): filename = self._pair_data_filename(self._datadir, pair, timeframe) if not filename.exists(): return DataFrame(columns=self._columns) - pairdata = read_json(filename, orient='values', - dtype={'open': 'float', 'high': 'float', - 'low': 'float', 'close': 'float', 'volume': 'float'}) + pairdata = read_json(filename, orient='values') pairdata.columns = self._columns + pairdata = pairdata.astype(copy=False, + dtype={'open': 'float', 'high': 'float', + 'low': 'float', 'close': 'float', 'volume': 'float'}) pairdata['date'] = to_datetime(pairdata['date'], unit='ms', utc=True, From e2e6b940a3252985a7167ab49625e03131af0090 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 22 Feb 2020 19:54:19 +0300 Subject: [PATCH 0584/1106] copy=False does not make the changes inline anyway, so not needed --- freqtrade/data/history/jsondatahandler.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index ee653d937..2b738a94a 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -71,8 +71,7 @@ class JsonDataHandler(IDataHandler): return DataFrame(columns=self._columns) pairdata = read_json(filename, orient='values') pairdata.columns = self._columns - pairdata = pairdata.astype(copy=False, - dtype={'open': 'float', 'high': 'float', + pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float', 'volume': 'float'}) pairdata['date'] = to_datetime(pairdata['date'], unit='ms', From ca8e52dc2cd61a80822cb158e1221d3d24ba62e7 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 23 Feb 2020 00:21:19 +0300 Subject: [PATCH 0585/1106] Show heartbeat message earlier after changing the state --- freqtrade/worker.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index f4b9f275b..e17f61f2f 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -83,6 +83,10 @@ class Worker: if state == State.RUNNING: self.freqtrade.startup() + # Reset heartbeat timestamp to log the heartbeat message at + # first throttling iteration when the state changes + self._heartbeat_msg = 0 + if state == State.STOPPED: # Ping systemd watchdog before sleeping in the stopped state if self._sd_notify: From 259dc75a3083b76980bf12d6575764eac96dd202 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 22 Feb 2020 23:10:46 +0100 Subject: [PATCH 0586/1106] some order and added weighted BB indicator to list --- .../templates/subtemplates/indicators_full.j2 | 103 +++++++++++------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/freqtrade/templates/subtemplates/indicators_full.j2 b/freqtrade/templates/subtemplates/indicators_full.j2 index 879a2daa0..87b385dd0 100644 --- a/freqtrade/templates/subtemplates/indicators_full.j2 +++ b/freqtrade/templates/subtemplates/indicators_full.j2 @@ -2,12 +2,17 @@ # Momentum Indicators # ------------------------------------ -# RSI -dataframe['rsi'] = ta.RSI(dataframe) - # ADX dataframe['adx'] = ta.ADX(dataframe) +# # Plus Directional Indicator / Movement +# dataframe['plus_dm'] = ta.PLUS_DM(dataframe) +# dataframe['plus_di'] = ta.PLUS_DI(dataframe) + +# # Minus Directional Indicator / Movement +# dataframe['minus_dm'] = ta.MINUS_DM(dataframe) +# dataframe['minus_di'] = ta.MINUS_DI(dataframe) + # # Aroon, Aroon Oscillator # aroon = ta.AROON(dataframe) # dataframe['aroonup'] = aroon['aroonup'] @@ -20,6 +25,31 @@ dataframe['adx'] = ta.ADX(dataframe) # # Commodity Channel Index: values Oversold:<-100, Overbought:>100 # dataframe['cci'] = ta.CCI(dataframe) +# RSI +dataframe['rsi'] = ta.RSI(dataframe) + +# # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy) +# rsi = 0.1 * (dataframe['rsi'] - 50) +# dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) + +# # Inverse Fisher transform on RSI normalized: values [0.0, 100.0] (https://goo.gl/2JGGoy) +# dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1) + +# # Stochastic Slow +# stoch = ta.STOCH(dataframe) +# dataframe['slowd'] = stoch['slowd'] +# dataframe['slowk'] = stoch['slowk'] + +# Stochastic Fast +stoch_fast = ta.STOCHF(dataframe) +dataframe['fastd'] = stoch_fast['fastd'] +dataframe['fastk'] = stoch_fast['fastk'] + +# # Stochastic RSI +# stoch_rsi = ta.STOCHRSI(dataframe) +# dataframe['fastd_rsi'] = stoch_rsi['fastd'] +# dataframe['fastk_rsi'] = stoch_rsi['fastk'] + # MACD macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] @@ -29,60 +59,57 @@ dataframe['macdhist'] = macd['macdhist'] # MFI dataframe['mfi'] = ta.MFI(dataframe) -# # Minus Directional Indicator / Movement -# dataframe['minus_dm'] = ta.MINUS_DM(dataframe) -# dataframe['minus_di'] = ta.MINUS_DI(dataframe) - -# # Plus Directional Indicator / Movement -# dataframe['plus_dm'] = ta.PLUS_DM(dataframe) -# dataframe['plus_di'] = ta.PLUS_DI(dataframe) -# dataframe['minus_di'] = ta.MINUS_DI(dataframe) - # # ROC # dataframe['roc'] = ta.ROC(dataframe) -# # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy) -# rsi = 0.1 * (dataframe['rsi'] - 50) -# dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) - -# # Inverse Fisher transform on RSI normalized, value [0.0, 100.0] (https://goo.gl/2JGGoy) -# dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1) - -# # Stoch -# stoch = ta.STOCH(dataframe) -# dataframe['slowd'] = stoch['slowd'] -# dataframe['slowk'] = stoch['slowk'] - -# Stoch fast -stoch_fast = ta.STOCHF(dataframe) -dataframe['fastd'] = stoch_fast['fastd'] -dataframe['fastk'] = stoch_fast['fastk'] - -# # Stoch RSI -# stoch_rsi = ta.STOCHRSI(dataframe) -# dataframe['fastd_rsi'] = stoch_rsi['fastd'] -# dataframe['fastk_rsi'] = stoch_rsi['fastk'] - # Overlap Studies # ------------------------------------ -# Bollinger bands +# 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'] +dataframe["bb_percent"] = ( + (dataframe["close"] - dataframe["bb_lowerband"]) / + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) +) +dataframe["bb_width"] = ( + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] +) + +# Bollinger Bands - Weighted (EMA based instead of SMA) +# weighted_bollinger = qtpylib.weighted_bollinger_bands( +# qtpylib.typical_price(dataframe), window=20, stds=2 +# ) +# dataframe["wbb_upperband"] = weighted_bollinger["upper"] +# dataframe["wbb_lowerband"] = weighted_bollinger["lower"] +# dataframe["wbb_middleband"] = weighted_bollinger["mid"] +# dataframe["wbb_percent"] = ( +# (dataframe["close"] - dataframe["wbb_lowerband"]) / +# (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) +# ) +# dataframe["wbb_width"] = ( +# (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) / dataframe["wbb_middleband"] +# ) # # EMA - Exponential Moving Average # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3) # dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) # dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) +# dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21) # dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) # dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) # # SMA - Simple Moving Average -# dataframe['sma'] = ta.SMA(dataframe, timeperiod=40) +# dataframe['sma3'] = ta.SMA(dataframe, timeperiod=3) +# dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5) +# dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10) +# dataframe['sma21'] = ta.SMA(dataframe, timeperiod=21) +# dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50) +# dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) -# SAR Parabol +# Parabolic SAR dataframe['sar'] = ta.SAR(dataframe) # TEMA - Triple Exponential Moving Average @@ -142,7 +169,7 @@ dataframe['htleadsine'] = hilbert['leadsine'] # # Chart type # # ------------------------------------ -# # Heikinashi stategy +# # Heikin Ashi Strategy # heikinashi = qtpylib.heikinashi(dataframe) # dataframe['ha_open'] = heikinashi['open'] # dataframe['ha_close'] = heikinashi['close'] From b49b9b515ed14d1c501e9350fe727f0f16a7722d Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 22 Feb 2020 23:37:15 +0100 Subject: [PATCH 0587/1106] final touches --- freqtrade/templates/subtemplates/indicators_full.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/templates/subtemplates/indicators_full.j2 b/freqtrade/templates/subtemplates/indicators_full.j2 index 87b385dd0..cd106451e 100644 --- a/freqtrade/templates/subtemplates/indicators_full.j2 +++ b/freqtrade/templates/subtemplates/indicators_full.j2 @@ -19,7 +19,7 @@ dataframe['adx'] = ta.ADX(dataframe) # dataframe['aroondown'] = aroon['aroondown'] # dataframe['aroonosc'] = ta.AROONOSC(dataframe) -# # Awesome oscillator +# # Awesome Oscillator # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) # # Commodity Channel Index: values Oversold:<-100, Overbought:>100 From 2957756275367bcd35734989cfe61558356a4a09 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 22 Feb 2020 23:39:01 +0100 Subject: [PATCH 0588/1106] final touches plus --- freqtrade/templates/subtemplates/indicators_full.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/templates/subtemplates/indicators_full.j2 b/freqtrade/templates/subtemplates/indicators_full.j2 index cd106451e..903aebb73 100644 --- a/freqtrade/templates/subtemplates/indicators_full.j2 +++ b/freqtrade/templates/subtemplates/indicators_full.j2 @@ -22,7 +22,7 @@ dataframe['adx'] = ta.ADX(dataframe) # # Awesome Oscillator # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) -# # Commodity Channel Index: values Oversold:<-100, Overbought:>100 +# # Commodity Channel Index: values Oversold:-100, Overbought:100 # dataframe['cci'] = ta.CCI(dataframe) # RSI From 5ac624446587f95af22b322b53caddd87692f021 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 22 Feb 2020 23:50:26 +0100 Subject: [PATCH 0589/1106] added keltner channel and uo --- .../templates/subtemplates/indicators_full.j2 | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/freqtrade/templates/subtemplates/indicators_full.j2 b/freqtrade/templates/subtemplates/indicators_full.j2 index 903aebb73..af472faef 100644 --- a/freqtrade/templates/subtemplates/indicators_full.j2 +++ b/freqtrade/templates/subtemplates/indicators_full.j2 @@ -22,7 +22,23 @@ dataframe['adx'] = ta.ADX(dataframe) # # Awesome Oscillator # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) -# # Commodity Channel Index: values Oversold:-100, Overbought:100 +# # Keltner Channel +# keltner = qtpylib.keltner_channel(dataframe) +# dataframe["kc_upperband"] = keltner["upper"] +# dataframe["kc_lowerband"] = keltner["lower"] +# dataframe["kc_middleband"] = keltner["mid"] +# dataframe["kc_percent"] = ( +# (dataframe["close"] - dataframe["kc_lowerband"]) / +# (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) +# ) +# dataframe["kc_width"] = ( +# (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) / dataframe["kc_middleband"] +# ) + +# # Ultimate Oscillator +# dataframe['ao'] = ta.ULTOSC(dataframe) + +# # Commodity Channel Index: values [Oversold:-100, Overbought:100] # dataframe['cci'] = ta.CCI(dataframe) # RSI From d2181bdd9492d16be409d82cd2fa5f0782c15838 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 23 Feb 2020 01:45:15 +0300 Subject: [PATCH 0590/1106] Adjust tests --- tests/test_freqtradebot.py | 28 ++--------------- tests/test_worker.py | 62 ++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5ed4d296c..20db46fac 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -782,7 +782,7 @@ def test_process_exchange_failures(default_conf, ticker, mocker) -> None: worker = Worker(args=None, config=default_conf) patch_get_signal(worker.freqtrade) - worker._process() + worker._process_running() assert sleep_mock.has_calls() @@ -799,7 +799,7 @@ def test_process_operational_exception(default_conf, ticker, mocker) -> None: assert worker.freqtrade.state == State.RUNNING - worker._process() + worker._process_running() assert worker.freqtrade.state == State.STOPPED assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]['status'] @@ -3665,30 +3665,6 @@ def test_startup_trade_reinit(default_conf, edge_conf, mocker): assert reinit_mock.call_count == 0 -def test_process_i_am_alive(default_conf, mocker, caplog): - patch_RPCManager(mocker) - patch_exchange(mocker) - mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True)) - - ftbot = get_patched_freqtradebot(mocker, default_conf) - message = r"Bot heartbeat\. PID=.*" - ftbot.process() - assert log_has_re(message, caplog) - assert ftbot._heartbeat_msg != 0 - - caplog.clear() - # Message is not shown before interval is up - ftbot.process() - assert not log_has_re(message, caplog) - - caplog.clear() - # Set clock - 70 seconds - ftbot._heartbeat_msg -= 70 - - ftbot.process() - assert log_has_re(message, caplog) - - @pytest.mark.usefixtures("init_persistence") def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, caplog): default_conf['dry_run'] = True diff --git a/tests/test_worker.py b/tests/test_worker.py index 2fb42d47e..7b446ac6a 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock, PropertyMock from freqtrade.data.dataprovider import DataProvider from freqtrade.state import State from freqtrade.worker import Worker -from tests.conftest import get_patched_worker, log_has +from tests.conftest import get_patched_worker, log_has, log_has_re def test_worker_state(mocker, default_conf, markets) -> None: @@ -38,15 +38,13 @@ def test_worker_running(mocker, default_conf, caplog) -> None: def test_worker_stopped(mocker, default_conf, caplog) -> None: mock_throttle = MagicMock() mocker.patch('freqtrade.worker.Worker._throttle', mock_throttle) - mock_sleep = mocker.patch('time.sleep', return_value=None) worker = get_patched_worker(mocker, default_conf) worker.freqtrade.state = State.STOPPED state = worker._worker(old_state=State.RUNNING) assert state is State.STOPPED assert log_has('Changing state to: STOPPED', caplog) - assert mock_throttle.call_count == 0 - assert mock_sleep.call_count == 1 + assert mock_throttle.call_count == 1 def test_throttle(mocker, default_conf, caplog) -> None: @@ -57,14 +55,14 @@ def test_throttle(mocker, default_conf, caplog) -> None: worker = get_patched_worker(mocker, default_conf) start = time.time() - result = worker._throttle(throttled_func, min_secs=0.1) + result = worker._throttle(throttled_func, throttle_secs=0.1) end = time.time() assert result == 42 assert end - start > 0.1 - assert log_has('Throttling throttled_func for 0.10 seconds', caplog) + assert log_has_re(r"Throttling with 'throttled_func\(\)': sleep for 0\.10 s.*", caplog) - result = worker._throttle(throttled_func, min_secs=-1) + result = worker._throttle(throttled_func, throttle_secs=-1) assert result == 42 @@ -74,8 +72,54 @@ def test_throttle_with_assets(mocker, default_conf) -> None: worker = get_patched_worker(mocker, default_conf) - result = worker._throttle(throttled_func, min_secs=0.1, nb_assets=666) + result = worker._throttle(throttled_func, throttle_secs=0.1, nb_assets=666) assert result == 666 - result = worker._throttle(throttled_func, min_secs=0.1) + result = worker._throttle(throttled_func, throttle_secs=0.1) assert result == -1 + + +def test_worker_heartbeat_running(default_conf, mocker, caplog): + message = r"Bot heartbeat\. PID=.*state='RUNNING'" + + mock_throttle = MagicMock() + mocker.patch('freqtrade.worker.Worker._throttle', mock_throttle) + worker = get_patched_worker(mocker, default_conf) + + worker.freqtrade.state = State.RUNNING + worker._worker(old_state=State.STOPPED) + assert log_has_re(message, caplog) + + caplog.clear() + # Message is not shown before interval is up + worker._worker(old_state=State.RUNNING) + assert not log_has_re(message, caplog) + + caplog.clear() + # Set clock - 70 seconds + worker._heartbeat_msg -= 70 + worker._worker(old_state=State.RUNNING) + assert log_has_re(message, caplog) + + +def test_worker_heartbeat_stopped(default_conf, mocker, caplog): + message = r"Bot heartbeat\. PID=.*state='STOPPED'" + + mock_throttle = MagicMock() + mocker.patch('freqtrade.worker.Worker._throttle', mock_throttle) + worker = get_patched_worker(mocker, default_conf) + + worker.freqtrade.state = State.STOPPED + worker._worker(old_state=State.RUNNING) + assert log_has_re(message, caplog) + + caplog.clear() + # Message is not shown before interval is up + worker._worker(old_state=State.STOPPED) + assert not log_has_re(message, caplog) + + caplog.clear() + # Set clock - 70 seconds + worker._heartbeat_msg -= 70 + worker._worker(old_state=State.STOPPED) + assert log_has_re(message, caplog) From e04c2dda2cfd3c18690be04dd3b22f98731b0b04 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sat, 22 Feb 2020 23:58:31 +0100 Subject: [PATCH 0591/1106] fixed typo --- freqtrade/templates/subtemplates/indicators_full.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/templates/subtemplates/indicators_full.j2 b/freqtrade/templates/subtemplates/indicators_full.j2 index af472faef..60a358bec 100644 --- a/freqtrade/templates/subtemplates/indicators_full.j2 +++ b/freqtrade/templates/subtemplates/indicators_full.j2 @@ -36,7 +36,7 @@ dataframe['adx'] = ta.ADX(dataframe) # ) # # Ultimate Oscillator -# dataframe['ao'] = ta.ULTOSC(dataframe) +# dataframe['uo'] = ta.ULTOSC(dataframe) # # Commodity Channel Index: values [Oversold:-100, Overbought:100] # dataframe['cci'] = ta.CCI(dataframe) From 634e7cc34a7f7adc10216d00418532780753a067 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 13:04:40 +0100 Subject: [PATCH 0592/1106] Implement handle_buy_trade_customcallback --- tests/test_freqtradebot.py | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5ed4d296c..68ce733b1 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1914,6 +1914,53 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, freqtrade.handle_trade(trade) +def test_check_handle_timedout_buy_usercustom(default_conf, ticker, limit_buy_order_old, open_trade, + fee, mocker) -> None: + default_conf["unfilledtimeout"] = {"buy": 1400, "sell": 30} + + rpc_mock = patch_RPCManager(mocker) + cancel_order_mock = MagicMock(return_value=limit_buy_order_old) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + fetch_ticker=ticker, + get_order=MagicMock(return_value=limit_buy_order_old), + cancel_order=cancel_order_mock, + get_fee=fee + ) + freqtrade = FreqtradeBot(default_conf) + + Trade.session.add(open_trade) + + # Return false - trade remains open + freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False) + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 + trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() + nb_trades = len(trades) + assert nb_trades == 1 + assert freqtrade.strategy.check_buy_timeout.call_count == 1 + + # Raise Keyerror ... (no impact on trade) + freqtrade.strategy.check_buy_timeout = MagicMock(side_effect=KeyError) + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 + trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() + nb_trades = len(trades) + assert nb_trades == 1 + assert freqtrade.strategy.check_buy_timeout.call_count == 1 + + freqtrade.strategy.check_buy_timeout = MagicMock(return_value=True) + # Trade should be closed since the function returns true + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 1 + assert rpc_mock.call_count == 1 + trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() + nb_trades = len(trades) + assert nb_trades == 0 + assert freqtrade.strategy.check_buy_timeout.call_count == 1 + + def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, open_trade, fee, mocker) -> None: rpc_mock = patch_RPCManager(mocker) From 9301f81fc8f5eca1003586290c86514bc22e72de Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 13:09:46 +0100 Subject: [PATCH 0593/1106] Add test for user-sell_timeout handling --- tests/test_freqtradebot.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 68ce733b1..e4b9a28ce 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2040,6 +2040,51 @@ def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_ord assert nb_trades == 1 +def test_check_handle_timedout_sell_usercustom(default_conf, ticker, limit_sell_order_old, mocker, + open_trade) -> None: + default_conf["unfilledtimeout"] = {"buy": 1440, "sell": 1440} + rpc_mock = patch_RPCManager(mocker) + cancel_order_mock = MagicMock() + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + fetch_ticker=ticker, + get_order=MagicMock(return_value=limit_sell_order_old), + cancel_order=cancel_order_mock + ) + freqtrade = FreqtradeBot(default_conf) + + open_trade.open_date = arrow.utcnow().shift(hours=-5).datetime + open_trade.close_date = arrow.utcnow().shift(minutes=-601).datetime + open_trade.is_open = False + + Trade.session.add(open_trade) + + freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False) + # Return false - No impact + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 + assert rpc_mock.call_count == 0 + assert open_trade.is_open is False + assert freqtrade.strategy.check_sell_timeout.call_count == 1 + + freqtrade.strategy.check_sell_timeout = MagicMock(side_effect=KeyError) + # Return Error - No impact + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 + assert rpc_mock.call_count == 0 + assert open_trade.is_open is False + assert freqtrade.strategy.check_sell_timeout.call_count == 1 + + # Return True - sells! + freqtrade.strategy.check_sell_timeout = MagicMock(return_value=True) + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 1 + assert rpc_mock.call_count == 1 + assert open_trade.is_open is True + assert freqtrade.strategy.check_sell_timeout.call_count == 1 + + def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old, mocker, open_trade) -> None: rpc_mock = patch_RPCManager(mocker) From e37f055dad850b366439ff6531777ca17f268ed5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 13:11:33 +0100 Subject: [PATCH 0594/1106] Improve some tests --- tests/test_freqtradebot.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e4b9a28ce..0766d7f33 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1977,6 +1977,7 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, op Trade.session.add(open_trade) + freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False) # check it does cancel buy orders over the time limit freqtrade.check_handle_timedout() assert cancel_order_mock.call_count == 1 @@ -1984,6 +1985,8 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, op trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() nb_trades = len(trades) assert nb_trades == 0 + # Custom user buy-timeout is never called + assert freqtrade.strategy.check_buy_timeout.call_count == 0 def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old, open_trade, @@ -2104,11 +2107,14 @@ def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old, Trade.session.add(open_trade) + freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False) # check it does cancel sell orders over the time limit freqtrade.check_handle_timedout() assert cancel_order_mock.call_count == 1 assert rpc_mock.call_count == 1 assert open_trade.is_open is True + # Custom user sell-timeout is never called + assert freqtrade.strategy.check_sell_timeout.call_count == 0 def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old, open_trade, From f25d6224ddeab8a3889daa69c1fac8eb375d169b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sun, 23 Feb 2020 16:22:19 +0100 Subject: [PATCH 0595/1106] modified sample_strategy --- freqtrade/templates/sample_strategy.py | 136 ++++++++++++++++--------- 1 file changed, 90 insertions(+), 46 deletions(-) diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index 92f6aefba..8a4b27c72 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -124,11 +124,16 @@ class SampleStrategy(IStrategy): # Momentum Indicators # ------------------------------------ - # RSI - dataframe['rsi'] = ta.RSI(dataframe) - # ADX - dataframe['adx'] = ta.ADX(dataframe) + # dataframe['adx'] = ta.ADX(dataframe) + + # # Plus Directional Indicator / Movement + # dataframe['plus_dm'] = ta.PLUS_DM(dataframe) + # dataframe['plus_di'] = ta.PLUS_DI(dataframe) + + # # Minus Directional Indicator / Movement + # dataframe['minus_dm'] = ta.MINUS_DM(dataframe) + # dataframe['minus_di'] = ta.MINUS_DI(dataframe) # # Aroon, Aroon Oscillator # aroon = ta.AROON(dataframe) @@ -136,12 +141,53 @@ class SampleStrategy(IStrategy): # dataframe['aroondown'] = aroon['aroondown'] # dataframe['aroonosc'] = ta.AROONOSC(dataframe) - # # Awesome oscillator + # # Awesome Oscillator # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe) - # # Commodity Channel Index: values Oversold:<-100, Overbought:>100 + # # Keltner Channel + # keltner = qtpylib.keltner_channel(dataframe) + # dataframe["kc_upperband"] = keltner["upper"] + # dataframe["kc_lowerband"] = keltner["lower"] + # dataframe["kc_middleband"] = keltner["mid"] + # dataframe["kc_percent"] = ( + # (dataframe["close"] - dataframe["kc_lowerband"]) / + # (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) + # ) + # dataframe["kc_width"] = ( + # (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) / dataframe["kc_middleband"] + # ) + + # # Ultimate Oscillator + # dataframe['uo'] = ta.ULTOSC(dataframe) + + # # Commodity Channel Index: values [Oversold:-100, Overbought:100] # dataframe['cci'] = ta.CCI(dataframe) + # RSI + dataframe['rsi'] = ta.RSI(dataframe) + + # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy) + # rsi = 0.1 * (dataframe['rsi'] - 50) + # dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) + + # # Inverse Fisher transform on RSI normalized: values [0.0, 100.0] (https://goo.gl/2JGGoy) + # dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1) + + # # Stochastic Slow + # stoch = ta.STOCH(dataframe) + # dataframe['slowd'] = stoch['slowd'] + # dataframe['slowk'] = stoch['slowk'] + + # Stochastic Fast + stoch_fast = ta.STOCHF(dataframe) + dataframe['fastd'] = stoch_fast['fastd'] + dataframe['fastk'] = stoch_fast['fastk'] + + # # Stochastic RSI + # stoch_rsi = ta.STOCHRSI(dataframe) + # dataframe['fastd_rsi'] = stoch_rsi['fastd'] + # dataframe['fastk_rsi'] = stoch_rsi['fastk'] + # MACD macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] @@ -151,71 +197,69 @@ class SampleStrategy(IStrategy): # MFI dataframe['mfi'] = ta.MFI(dataframe) - # # Minus Directional Indicator / Movement - # dataframe['minus_dm'] = ta.MINUS_DM(dataframe) - # dataframe['minus_di'] = ta.MINUS_DI(dataframe) - - # # Plus Directional Indicator / Movement - # dataframe['plus_dm'] = ta.PLUS_DM(dataframe) - # dataframe['plus_di'] = ta.PLUS_DI(dataframe) - # dataframe['minus_di'] = ta.MINUS_DI(dataframe) - # # ROC # dataframe['roc'] = ta.ROC(dataframe) - # # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy) - # rsi = 0.1 * (dataframe['rsi'] - 50) - # dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1) - - # # Inverse Fisher transform on RSI normalized, value [0.0, 100.0] (https://goo.gl/2JGGoy) - # dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1) - - # # Stoch - # stoch = ta.STOCH(dataframe) - # dataframe['slowd'] = stoch['slowd'] - # dataframe['slowk'] = stoch['slowk'] - - # Stoch fast - stoch_fast = ta.STOCHF(dataframe) - dataframe['fastd'] = stoch_fast['fastd'] - dataframe['fastk'] = stoch_fast['fastk'] - - # # Stoch RSI - # stoch_rsi = ta.STOCHRSI(dataframe) - # dataframe['fastd_rsi'] = stoch_rsi['fastd'] - # dataframe['fastk_rsi'] = stoch_rsi['fastk'] - # Overlap Studies # ------------------------------------ - # Bollinger bands + # 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'] + dataframe["bb_percent"] = ( + (dataframe["close"] - dataframe["bb_lowerband"]) / + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) + ) + dataframe["bb_width"] = ( + (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] + ) + + # Bollinger Bands - Weighted (EMA based instead of SMA) + # weighted_bollinger = qtpylib.weighted_bollinger_bands( + # qtpylib.typical_price(dataframe), window=20, stds=2 + # ) + # dataframe["wbb_upperband"] = weighted_bollinger["upper"] + # dataframe["wbb_lowerband"] = weighted_bollinger["lower"] + # dataframe["wbb_middleband"] = weighted_bollinger["mid"] + # dataframe["wbb_percent"] = ( + # (dataframe["close"] - dataframe["wbb_lowerband"]) / + # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) + # ) + # dataframe["wbb_width"] = ( + # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) / + # dataframe["wbb_middleband"] + # ) # # EMA - Exponential Moving Average # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3) # dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5) # dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10) + # dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21) # dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50) # dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100) # # SMA - Simple Moving Average - # dataframe['sma'] = ta.SMA(dataframe, timeperiod=40) + # dataframe['sma3'] = ta.SMA(dataframe, timeperiod=3) + # dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5) + # dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10) + # dataframe['sma21'] = ta.SMA(dataframe, timeperiod=21) + # dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50) + # dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) - # SAR Parabol - dataframe['sar'] = ta.SAR(dataframe) + # Parabolic SAR + # dataframe['sar'] = ta.SAR(dataframe) # TEMA - Triple Exponential Moving Average - dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + # dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) # Cycle Indicator # ------------------------------------ # Hilbert Transform Indicator - SineWave - hilbert = ta.HT_SINE(dataframe) - dataframe['htsine'] = hilbert['sine'] - dataframe['htleadsine'] = hilbert['leadsine'] + # hilbert = ta.HT_SINE(dataframe) + # dataframe['htsine'] = hilbert['sine'] + # dataframe['htleadsine'] = hilbert['leadsine'] # Pattern Recognition - Bullish candlestick patterns # ------------------------------------ @@ -264,7 +308,7 @@ class SampleStrategy(IStrategy): # # Chart type # # ------------------------------------ - # # Heikinashi stategy + # # Heikin Ashi Strategy # heikinashi = qtpylib.heikinashi(dataframe) # dataframe['ha_open'] = heikinashi['open'] # dataframe['ha_close'] = heikinashi['close'] From 0eeafcd157c17d6f7de92ab66c6f267c454bcec2 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Sun, 23 Feb 2020 16:56:55 +0100 Subject: [PATCH 0596/1106] matched commenting on previous sample_strategy.py --- freqtrade/templates/sample_strategy.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index 8a4b27c72..17372e1e0 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -125,7 +125,7 @@ class SampleStrategy(IStrategy): # ------------------------------------ # ADX - # dataframe['adx'] = ta.ADX(dataframe) + dataframe['adx'] = ta.ADX(dataframe) # # Plus Directional Indicator / Movement # dataframe['plus_dm'] = ta.PLUS_DM(dataframe) @@ -249,17 +249,17 @@ class SampleStrategy(IStrategy): # dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) # Parabolic SAR - # dataframe['sar'] = ta.SAR(dataframe) + dataframe['sar'] = ta.SAR(dataframe) # TEMA - Triple Exponential Moving Average - # dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) + dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9) # Cycle Indicator # ------------------------------------ # Hilbert Transform Indicator - SineWave - # hilbert = ta.HT_SINE(dataframe) - # dataframe['htsine'] = hilbert['sine'] - # dataframe['htleadsine'] = hilbert['leadsine'] + hilbert = ta.HT_SINE(dataframe) + dataframe['htsine'] = hilbert['sine'] + dataframe['htleadsine'] = hilbert['leadsine'] # Pattern Recognition - Bullish candlestick patterns # ------------------------------------ From e545ef563c0b5aaafc618bc3501c1d1e43f68c07 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:50:58 +0300 Subject: [PATCH 0597/1106] Wording adjusted in helpstring --- freqtrade/worker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index e17f61f2f..4c28ecaeb 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -69,7 +69,7 @@ class Worker: def _worker(self, old_state: Optional[State]) -> State: """ - Trading routine that must be run at each loop + The main routine that runs each throttling iteration and handles the states. :param old_state: the previous service state from the previous call :return: current service state """ From 7eb62ed32e7acc7004821a9213c7752fe31f1f9c Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 00:33:01 +0100 Subject: [PATCH 0598/1106] Remove old print option for hyperopt-list and made table as default --- docs/utils.md | 1 - freqtrade/commands/arguments.py | 3 +-- freqtrade/commands/cli_options.py | 6 ------ freqtrade/commands/hyperopt_commands.py | 23 +++++------------------ freqtrade/configuration/configuration.py | 3 --- tests/commands/test_commands.py | 16 ---------------- 6 files changed, 6 insertions(+), 46 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 6ca0b7920..abb7fd0db 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -440,7 +440,6 @@ optional arguments: --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. - --print-table Print results in table format. --no-details Do not print best epoch details. Common arguments: diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 0f6478a60..fe6f49039 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -66,8 +66,7 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", - "print_colorized", "print_json", "print_table", - "hyperopt_list_no_details"] + "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 9efc1151a..1776955b1 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -220,12 +220,6 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), - "print_table": Arg( - '--print-table', - help='Print results in table format.', - action='store_true', - default=False, - ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 88cd79468..ccaa59e54 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -21,7 +21,6 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) - print_table = config.get('print_table', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False @@ -47,26 +46,14 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: trials = _hyperopt_filter_trials(trials, filteroptions) - # TODO: fetch the interval for epochs to print from the cli option - epoch_start, epoch_stop = 0, None - if print_colorized: colorama_init(autoreset=True) - if print_table: - try: - Hyperopt.print_result_table(config, trials, total_epochs, - not filteroptions['only_best'], print_colorized) - except KeyboardInterrupt: - print('User interrupted..') - else: - try: - # Human-friendly indexes used here (starting from 1) - for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, - not filteroptions['only_best'], print_colorized) - except KeyboardInterrupt: - print('User interrupted..') + try: + Hyperopt.print_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 0adfe03e7..c2613ba99 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -286,9 +286,6 @@ class Configuration: self._args_to_config(config, argname='print_json', logstring='Parameter --print-json detected ...') - self._args_to_config(config, argname='print_table', - logstring='Parameter --print-table detected: {}') - self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index ceae6f372..995b504c5 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -907,22 +907,6 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) - args = [ - "hyperopt-list", - "--no-details", - "--print-table", - "--min-trades", "100", - "--print-json" - ] - pargs = get_args(args) - pargs['config'] = None - start_hyperopt_list(pargs) - captured = capsys.readouterr() - assert all(x in captured.out - for x in [" 3/12", " 7/12", " 9/12", " 11/12"]) - assert all(x not in captured.out - for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 6/12", " 8/12", " 10/12" - " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From 353f722dc54dcd6eab646a844596383eccc5d326 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 08:04:07 +0000 Subject: [PATCH 0599/1106] Bump requests from 2.22.0 to 2.23.0 Bumps [requests](https://github.com/psf/requests) from 2.22.0 to 2.23.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.22.0...v2.23.0) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 2be51ba73..61809c698 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -5,7 +5,7 @@ SQLAlchemy==1.3.13 python-telegram-bot==12.4.2 arrow==0.15.5 cachetools==4.0.0 -requests==2.22.0 +requests==2.23.0 urllib3==1.25.8 wrapt==1.12.0 jsonschema==3.2.0 From 4054dec7a029594503222de5af6677669956d1cd Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 08:04:32 +0000 Subject: [PATCH 0600/1106] Bump plotly from 4.5.0 to 4.5.1 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.5.0...v4.5.1) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 26467d90b..5e62a5e95 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.5.0 +plotly==4.5.1 From ff69b511e311bb73d36d0d2661f7e4100a46d283 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 08:04:44 +0000 Subject: [PATCH 0601/1106] Bump scikit-optimize from 0.7.2 to 0.7.4 Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.7.2 to 0.7.4. - [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases) - [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md) - [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.7.2...v0.7.4) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index e97e7f6be..2984229c1 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -4,6 +4,6 @@ # Required for hyperopt scipy==1.4.1 scikit-learn==0.22.1 -scikit-optimize==0.7.2 +scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 From d63aaf3bfd7eb511387625b76435ea873e51e444 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 08:05:15 +0000 Subject: [PATCH 0602/1106] Bump ccxt from 1.22.61 to 1.22.95 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.61 to 1.22.95. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.22.61...1.22.95) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 2be51ba73..f792f5348 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.22.61 +ccxt==1.22.95 SQLAlchemy==1.3.13 python-telegram-bot==12.4.2 arrow==0.15.5 From 23bf135b8aeb704c64e775dba8a12b166a692a41 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 11:01:14 +0100 Subject: [PATCH 0603/1106] Alignment of table content, changed coloring, changed 'Best' column to show if it's initial_point or best --- freqtrade/optimize/hyperopt.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 72b3516c7..7ff5c3500 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -306,15 +306,18 @@ class Hyperopt: return trials = json_normalize(results, max_level=1) - trials = trials[['is_best', 'current_epoch', - 'results_metrics.trade_count', 'results_metrics.avg_profit', - 'results_metrics.total_profit', 'results_metrics.profit', - 'results_metrics.duration', 'loss']] + trials['Best'] = '' + trials = trials[['Best', 'current_epoch', 'results_metrics.trade_count', + 'results_metrics.avg_profit', 'results_metrics.total_profit', + 'results_metrics.profit', 'results_metrics.duration', + 'loss', 'is_initial_point', 'is_best']] trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', - 'Profit', 'Avg duration', 'Objective'] + 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] - trials['Best'] = trials['Best'].apply(lambda x: '*' if x else '') + trials.loc[trials['is_initial_point'], 'Best'] = '*' + trials.loc[trials['is_best'], 'Best'] = 'Best' trials['Objective'] = trials['Objective'].astype(str) + trials = trials.drop(columns=['is_initial_point', 'is_best']) if print_colorized: for i in range(len(trials)): @@ -322,10 +325,10 @@ class Hyperopt: trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], Fore.RESET) - if '*' in trials.loc[i]['Best'] and highlight_best: - trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Style.RESET_ALL) + if 'Best' in trials.loc[i]['Best'] and highlight_best: + trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Style.RESET_ALL) trials['Epoch'] = trials['Epoch'].apply( lambda x: "{}/{}".format(x, total_epochs)) @@ -338,7 +341,8 @@ class Hyperopt: trials['Avg duration'] = trials['Avg duration'].apply( lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) - print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql')) + print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql', + stralign="right")) def has_space(self, space: str) -> bool: """ From 23b47b66eccb408d56ba0abd6e6e5ab71b8ae3f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Feb 2020 20:11:25 +0100 Subject: [PATCH 0604/1106] Update install-script documentation and reorder installation steps --- docs/installation.md | 8 ++++---- mkdocs.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 054cafe9b..0feaf509d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -65,11 +65,11 @@ usage: ** --install ** -With this option, the script will install everything you need to run the bot: +With this option, the script will install the bot and most dependencies: +You will need to have git and python3.6+ installed beforehand for this to work. * Mandatory software as: `ta-lib` -* Setup your virtualenv -* Configure your `config.json` file +* Setup your virtualenv under `.env/` This option is a combination of installation tasks, `--reset` and `--config`. @@ -83,7 +83,7 @@ This option will hard reset your branch (only if you are on either `master` or ` ** --config ** -Use this option to configure the `config.json` configuration file. The script will interactively ask you questions to setup your bot and create your `config.json`. +DEPRECATED - use `freqtrade new-config -c config.json` instead. ------ diff --git a/mkdocs.yml b/mkdocs.yml index d53687c64..4e7e6ff75 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,8 +1,8 @@ site_name: Freqtrade nav: - - About: index.md - - Installation: installation.md + - Home: index.md - Installation Docker: docker.md + - Installation: installation.md - Configuration: configuration.md - Strategy Customization: strategy-customization.md - Stoploss: stoploss.md From 2f349e0504d014e01f428e8fc0b6e8f8a619aeef Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Feb 2020 20:21:25 +0100 Subject: [PATCH 0605/1106] Improve install documentation by streamlining the process --- docs/configuration.md | 14 +++++++++++--- docs/installation.md | 12 +++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 0b9519688..234ff49ba 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -626,6 +626,11 @@ In production mode, the bot will engage your money. Be careful, since a wrong strategy can lose all your money. Be aware of what you are doing when you run it in production mode. +### Setup your exchange account + +You will need to create API Keys (usually you get `key` and `secret`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. +API Keys are usually only required for real / production trading, but are not required for paper-trading / dry-run. + ### To switch your bot in production mode **Edit your `config.json` file.** @@ -647,11 +652,14 @@ you run it in production mode. } ``` -!!! Note - If you have an exchange API key yet, [see our tutorial](installation.md#setup-your-exchange-account). - You should also make sure to read the [Exchanges](exchanges.md) section of the documentation to be aware of potential configuration details specific to your exchange. +### Setup your exchange account + +You will need to create API Keys (usually you get `key` and `secret`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. +API Keys are usually only required for real / production trading, but are not required for paper-trading / dry-run. + + ### Using proxy with Freqtrade To use a proxy with freqtrade, add the kwarg `"aiohttp_trust_env"=true` to the `"ccxt_async_kwargs"` dict in the exchange section of the configuration. diff --git a/docs/installation.md b/docs/installation.md index 0feaf509d..5a15be234 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,6 +2,8 @@ This page explains how to prepare your environment for running the bot. +Please consider using the prebuilt [docker images](docker.md) to get started quickly while trying out freqtrade. + ## Prerequisite ### Requirements @@ -14,15 +16,7 @@ Click each one for install guide: * [virtualenv](https://virtualenv.pypa.io/en/stable/installation/) (Recommended) * [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html) (install instructions below) -### API keys - -Before running your bot in production you will need to setup few -external API. In production mode, the bot will require valid Exchange API -credentials. We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot) (optional but recommended). - -### Setup your exchange account - -You will need to create API Keys (Usually you get `key` and `secret`) from the Exchange website and insert this into the appropriate fields in the configuration or when asked by the installation script. + We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot), which is optional but recommended. ## Quick start From 6581ba56cab28f025c7444bd57e2e09beefb7ded Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Feb 2020 20:41:45 +0100 Subject: [PATCH 0606/1106] Use markets.quote to validate --- freqtrade/pairlist/IPairList.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index 1ad4da523..7d489ece7 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -99,7 +99,8 @@ class IPairList(ABC): logger.warning(f"Pair {pair} is not compatible with exchange " f"{self._exchange.name}. Removing it from whitelist..") continue - if not pair.endswith(self._config['stake_currency']): + + if markets[pair]['quote'] != self._config['stake_currency']: logger.warning(f"Pair {pair} is not compatible with your stake currency " f"{self._config['stake_currency']}. Removing it from whitelist..") continue From 3e4f663418236f84123eeb186fa0f642f84de89e Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Feb 2020 21:22:58 +0100 Subject: [PATCH 0607/1106] Move pairlist validation to exchange (we need to use .quote) from markets --- freqtrade/configuration/config_validation.py | 12 ------ freqtrade/exchange/exchange.py | 8 +++- tests/exchange/test_exchange.py | 42 ++++++++++++++++++-- tests/test_configuration.py | 7 ---- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 5183ad0b4..5ba7ff294 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -150,15 +150,3 @@ def _validate_whitelist(conf: Dict[str, Any]) -> None: if (pl.get('method') == 'StaticPairList' and not conf.get('exchange', {}).get('pair_whitelist')): raise OperationalException("StaticPairList requires pair_whitelist to be set.") - - if pl.get('method') == 'StaticPairList': - stake = conf['stake_currency'] - invalid_pairs = [] - for pair in conf['exchange'].get('pair_whitelist'): - if not pair.endswith(f'/{stake}'): - invalid_pairs.append(pair) - - if invalid_pairs: - raise OperationalException( - f"Stake-currency '{stake}' not compatible with pair-whitelist. " - f"Please remove the following pairs: {invalid_pairs}") diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b3b347016..8023417a3 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -300,7 +300,7 @@ class Exchange: if not self.markets: logger.warning('Unable to validate pairs (assuming they are correct).') return - + invalid_pairs = [] for pair in pairs: # Note: ccxt has BaseCurrency/QuoteCurrency format for pairs # TODO: add a support for having coins in BTC/USDT format @@ -322,6 +322,12 @@ class Exchange: logger.warning(f"Pair {pair} is restricted for some users on this exchange." f"Please check if you are impacted by this restriction " f"on the exchange and eventually remove {pair} from your whitelist.") + if not self.markets[pair].get('quote') == self._config['stake_currency']: + invalid_pairs.append(pair) + if invalid_pairs: + raise OperationalException( + f"Stake-currency '{self._config['stake_currency']}' not compatible with " + f"pair-whitelist. Please remove the following pairs: {invalid_pairs}") def get_valid_pair_combination(self, curr_1: str, curr_2: str) -> str: """ diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8b2e439c3..d1c105591 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -406,7 +406,10 @@ def test_get_quote_currencies(default_conf, mocker): def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ - 'ETH/BTC': {}, 'LTC/BTC': {}, 'XRP/BTC': {}, 'NEO/BTC': {} + 'ETH/BTC': {'quote': 'BTC'}, + 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/BTC': {'quote': 'BTC'}, + 'NEO/BTC': {'quote': 'BTC'}, }) id_mock = PropertyMock(return_value='test_exchange') type(api_mock).id = id_mock @@ -454,9 +457,9 @@ def test_validate_pairs_exception(default_conf, mocker, caplog): def test_validate_pairs_restricted(default_conf, mocker, caplog): api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ - 'ETH/BTC': {}, 'LTC/BTC': {}, - 'XRP/BTC': {'info': {'IsRestricted': True}}, - 'NEO/BTC': {'info': 'TestString'}, # info can also be a string ... + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/BTC': {'quote': 'BTC', 'info': {'IsRestricted': True}}, + 'NEO/BTC': {'quote': 'BTC', 'info': 'TestString'}, # info can also be a string ... }) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') @@ -469,6 +472,37 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog): f"on the exchange and eventually remove XRP/BTC from your whitelist.", caplog) +def test_validate_pairs_stakecompatibility(default_conf, mocker, caplog): + api_mock = MagicMock() + type(api_mock).markets = PropertyMock(return_value={ + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/BTC': {'quote': 'BTC'}, 'NEO/BTC': {'quote': 'BTC'}, + 'HELLO-WORLD': {'quote': 'BTC'}, + }) + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') + + Exchange(default_conf) + + +def test_validate_pairs_stakecompatibility_fail(default_conf, mocker, caplog): + default_conf['exchange']['pair_whitelist'].append('HELLO-WORLD') + api_mock = MagicMock() + type(api_mock).markets = PropertyMock(return_value={ + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/BTC': {'quote': 'BTC'}, 'NEO/BTC': {'quote': 'BTC'}, + 'HELLO-WORLD': {'quote': 'USDT'}, + }) + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') + + with pytest.raises(OperationalException, match=r"Stake-currency 'BTC' not compatible with.*"): + Exchange(default_conf) + @pytest.mark.parametrize("timeframe", [ ('5m'), ("1m"), ("15m"), ("1h") ]) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index d810305db..828db4d83 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -810,13 +810,6 @@ def test_validate_whitelist(default_conf): validate_config_consistency(conf) - conf = deepcopy(default_conf) - conf['stake_currency'] = 'USDT' - with pytest.raises(OperationalException, - match=r"Stake-currency 'USDT' not compatible with pair-whitelist.*"): - validate_config_consistency(conf) - - def test_load_config_test_comments() -> None: """ Load config with comments From 61037ab7b8f3f2467555c1a2a767580ea25f43a6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 24 Feb 2020 21:50:27 +0100 Subject: [PATCH 0608/1106] Implement get_pair_base_curr and get_pair_quote_curr --- freqtrade/exchange/exchange.py | 12 ++++++++++++ freqtrade/freqtradebot.py | 6 ++++-- tests/commands/test_commands.py | 31 ++++++++++++++++--------------- tests/conftest.py | 29 ++++++++++++++++++++++++++++- tests/exchange/test_exchange.py | 15 ++++++++------- tests/test_freqtradebot.py | 2 ++ 6 files changed, 70 insertions(+), 25 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 8023417a3..0e0d2dabe 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -228,6 +228,18 @@ class Exchange: markets = self.markets return sorted(set([x['quote'] for _, x in markets.items()])) + def get_pair_quote_currency(self, pair: str) -> str: + """ + Return a pair's quote currency + """ + return self.markets[pair].get('quote') + + def get_pair_base_currency(self, pair: str) -> str: + """ + Return a pair's quote currency + """ + return self.markets[pair].get('base') + def klines(self, pair_interval: Tuple[str, str], copy: bool = True) -> DataFrame: if pair_interval in self._klines: return self._klines[pair_interval].copy() if copy else self._klines[pair_interval] diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 00d5c369a..38583b5ad 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1125,12 +1125,13 @@ class FreqtradeBot: if trade.fee_open == 0 or order['status'] == 'open': return order_amount + trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible if ('fee' in order and order['fee'] is not None and (order['fee'].keys() >= {'currency', 'cost'})): if (order['fee']['currency'] is not None and order['fee']['cost'] is not None and - trade.pair.startswith(order['fee']['currency'])): + trade_base_currency == order['fee']['currency']): new_amount = order_amount - order['fee']['cost'] logger.info("Applying fee on amount for %s (from %s to %s) from Order", trade, order['amount'], new_amount) @@ -1145,6 +1146,7 @@ class FreqtradeBot: return order_amount amount = 0 fee_abs = 0 + trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) for exectrade in trades: amount += exectrade['amount'] if ("fee" in exectrade and exectrade['fee'] is not None and @@ -1152,7 +1154,7 @@ class FreqtradeBot: # only applies if fee is in quote currency! if (exectrade['fee']['currency'] is not None and exectrade['fee']['cost'] is not None and - trade.pair.startswith(exectrade['fee']['currency'])): + trade_base_currency == exectrade['fee']['currency']): fee_abs += exectrade['fee']['cost'] if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index a9fe0f637..fd8df4b56 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -217,8 +217,9 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ("Exchange Bittrex has 9 active markets: " - "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n" + assert ("Exchange Bittrex has 10 active markets: " + "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, " + "TKN/BTC, XLTCUSDT, XRP/BTC.\n" in captured.out) patch_exchange(mocker, api_mock=api_mock, id="binance") @@ -231,7 +232,7 @@ def test_list_markets(mocker, markets, capsys): pargs['config'] = None start_list_markets(pargs, False) captured = capsys.readouterr() - assert re.match("\nExchange Binance has 9 active markets:\n", + assert re.match("\nExchange Binance has 10 active markets:\n", captured.out) patch_exchange(mocker, api_mock=api_mock, id="bittrex") @@ -243,8 +244,8 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ("Exchange Bittrex has 11 markets: " - "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, LTC/USDT, NEO/BTC, " + assert ("Exchange Bittrex has 12 markets: " + "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, " "TKN/BTC, XLTCUSDT, XRP/BTC.\n" in captured.out) @@ -256,8 +257,8 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), True) captured = capsys.readouterr() - assert ("Exchange Bittrex has 8 active pairs: " - "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, NEO/BTC, TKN/BTC, XRP/BTC.\n" + assert ("Exchange Bittrex has 9 active pairs: " + "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, TKN/BTC, XRP/BTC.\n" in captured.out) # Test list-pairs subcommand with --all: all pairs @@ -268,8 +269,8 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), True) captured = capsys.readouterr() - assert ("Exchange Bittrex has 10 pairs: " - "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, LTC/USDT, NEO/BTC, " + assert ("Exchange Bittrex has 11 pairs: " + "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, " "TKN/BTC, XRP/BTC.\n" in captured.out) @@ -282,8 +283,8 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ("Exchange Bittrex has 5 active markets with ETH, LTC as base currencies: " - "ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, XLTCUSDT.\n" + assert ("Exchange Bittrex has 6 active markets with ETH, LTC as base currencies: " + "ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n" in captured.out) # active markets, base=LTC @@ -295,8 +296,8 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ("Exchange Bittrex has 3 active markets with LTC as base currency: " - "LTC/BTC, LTC/USD, XLTCUSDT.\n" + assert ("Exchange Bittrex has 4 active markets with LTC as base currency: " + "LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n" in captured.out) # active markets, quote=USDT, USD @@ -384,7 +385,7 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ("Exchange Bittrex has 9 active markets:\n" + assert ("Exchange Bittrex has 10 active markets:\n" in captured.out) # Test tabular output, no markets found @@ -407,7 +408,7 @@ def test_list_markets(mocker, markets, capsys): ] start_list_markets(get_args(args), False) captured = capsys.readouterr() - assert ('["BLK/BTC","ETH/BTC","ETH/USDT","LTC/BTC","LTC/USD","NEO/BTC",' + assert ('["BLK/BTC","ETH/BTC","ETH/USDT","LTC/BTC","LTC/ETH","LTC/USD","NEO/BTC",' '"TKN/BTC","XLTCUSDT","XRP/BTC"]' in captured.out) diff --git a/tests/conftest.py b/tests/conftest.py index acb730330..000f62868 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -575,7 +575,34 @@ def get_markets(): } }, 'info': {}, - } + }, + 'LTC/ETH': { + 'id': 'LTCETH', + 'symbol': 'LTC/ETH', + 'base': 'LTC', + 'quote': 'ETH', + 'active': True, + 'precision': { + 'base': 8, + 'quote': 8, + 'amount': 3, + 'price': 5 + }, + 'limits': { + 'amount': { + 'min': 0.001, + 'max': 10000000.0 + }, + 'price': { + 'min': 1e-05, + 'max': 1000.0 + }, + 'cost': { + 'min': 0.01, + 'max': None + } + }, + }, } diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index d1c105591..98edd0dbb 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -400,7 +400,7 @@ def test_validate_stake_currency_error(default_conf, mocker, caplog): def test_get_quote_currencies(default_conf, mocker): ex = get_patched_exchange(mocker, default_conf) - assert set(ex.get_quote_currencies()) == set(['USD', 'BTC', 'USDT']) + assert set(ex.get_quote_currencies()) == set(['USD', 'ETH', 'BTC', 'USDT']) def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly @@ -1862,6 +1862,7 @@ def test_get_valid_pair_combination(default_conf, mocker, markets): # 'ETH/BTC': 'active': True # 'ETH/USDT': 'active': True # 'LTC/BTC': 'active': False + # 'LTC/ETH': 'active': True # 'LTC/USD': 'active': True # 'LTC/USDT': 'active': True # 'NEO/BTC': 'active': False @@ -1870,26 +1871,26 @@ def test_get_valid_pair_combination(default_conf, mocker, markets): # 'XRP/BTC': 'active': False # all markets ([], [], False, False, - ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', + ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']), # active markets ([], [], False, True, - ['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'NEO/BTC', + ['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']), # all pairs ([], [], True, False, - ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', + ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XRP/BTC']), # active pairs ([], [], True, True, - ['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'NEO/BTC', + ['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'NEO/BTC', 'TKN/BTC', 'XRP/BTC']), # all markets, base=ETH, LTC (['ETH', 'LTC'], [], False, False, - ['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']), + ['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']), # all markets, base=LTC (['LTC'], [], False, False, - ['LTC/BTC', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']), + ['LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']), # all markets, quote=USDT ([], ['USDT'], False, False, ['ETH/USDT', 'LTC/USDT', 'XLTCUSDT']), diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 20db46fac..9a7816d35 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2192,6 +2192,7 @@ def test_handle_timedout_limit_buy(mocker, default_conf, limit_buy_order) -> Non Trade.session = MagicMock() trade = MagicMock() + trade.pair = 'LTC/ETH' limit_buy_order['remaining'] = limit_buy_order['amount'] assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 @@ -2215,6 +2216,7 @@ def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_ Trade.session = MagicMock() trade = MagicMock() + trade.pair = 'LTC/ETH' limit_buy_order['remaining'] = limit_buy_order['amount'] assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 From cd7efde6c0618c3a40d44432dece4592510e5c87 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 22:06:21 +0100 Subject: [PATCH 0609/1106] Fixed coloring so it's only targeting the values not the table borders --- freqtrade/optimize/hyperopt.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 7ff5c3500..9c18d6803 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -313,22 +313,12 @@ class Hyperopt: 'loss', 'is_initial_point', 'is_best']] trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] - + trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' trials.loc[trials['is_best'], 'Best'] = 'Best' trials['Objective'] = trials['Objective'].astype(str) - trials = trials.drop(columns=['is_initial_point', 'is_best']) - - if print_colorized: - for i in range(len(trials)): - if trials.loc[i]['Total profit'] > 0: - trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Fore.RESET) - if 'Best' in trials.loc[i]['Best'] and highlight_best: - trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Style.RESET_ALL) + trials.loc[trials['Total profit'] > 0, 'is_profit'] = True + trials['Trades'] = trials['Trades'].astype(str) trials['Epoch'] = trials['Epoch'].apply( lambda x: "{}/{}".format(x, total_epochs)) @@ -340,9 +330,21 @@ class Hyperopt: lambda x: '{: 11.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) trials['Avg duration'] = trials['Avg duration'].apply( lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) + if print_colorized: + for i in range(len(trials)): + if trials.loc[i]['is_profit']: + for z in range(len(trials.loc[i])-3): + trials.iat[i, z] = "{}{}{}".format(Fore.GREEN, + str(trials.loc[i][z]), Fore.RESET) + if trials.loc[i]['is_best'] and highlight_best: + for z in range(len(trials.loc[i])-3): + trials.iat[i, z] = "{}{}{}".format(Style.BRIGHT, + str(trials.loc[i][z]), Style.RESET_ALL) + + trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql', - stralign="right")) + stralign="right")) def has_space(self, space: str) -> bool: """ From e9448dc5e248f702b80ddd9be62faefd6e1526d1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 07:01:23 +0100 Subject: [PATCH 0610/1106] Add tsts for quote and base currency --- tests/exchange/test_exchange.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 98edd0dbb..def4e6ab6 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -403,6 +403,28 @@ def test_get_quote_currencies(default_conf, mocker): assert set(ex.get_quote_currencies()) == set(['USD', 'ETH', 'BTC', 'USDT']) +@pytest.mark.parametrize('pair,expected', [ + ('XRP/BTC', 'BTC'), + ('LTC/USD', 'USD'), + ('ETH/USDT', 'USDT'), + ('XLTCUSDT', 'USDT'), +]) +def test_get_pair_quote_currency(default_conf, mocker, pair, expected): + ex = get_patched_exchange(mocker, default_conf) + assert ex.get_pair_quote_currency(pair) == expected + + +@pytest.mark.parametrize('pair,expected', [ + ('XRP/BTC', 'XRP'), + ('LTC/USD', 'LTC'), + ('ETH/USDT', 'ETH'), + ('XLTCUSDT', 'LTC'), +]) +def test_get_pair_base_currency(default_conf, mocker, pair, expected): + ex = get_patched_exchange(mocker, default_conf) + assert ex.get_pair_base_currency(pair) == expected + + def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly api_mock = MagicMock() type(api_mock).markets = PropertyMock(return_value={ From e8eaa8920ea397a9403ece95d27c3a647ed428d8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 07:01:31 +0100 Subject: [PATCH 0611/1106] Use get_base_currency instead of splitting by / --- freqtrade/freqtradebot.py | 3 +-- freqtrade/wallets.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 38583b5ad..424a6a220 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -938,8 +938,7 @@ class FreqtradeBot: """ # Update wallets to ensure amounts tied up in a stoploss is now free! self.wallets.update() - - wallet_amount = self.wallets.get_free(pair.split('/')[0]) + wallet_amount = self.wallets.get_free(self.exchange.get_pair_base_currency(pair)) logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount >= amount: return amount diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index dd5e34fe6..b913155bc 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -74,7 +74,7 @@ class Wallets: ) for trade in open_trades: - curr = trade.pair.split('/')[0] + curr = self._exchange.get_pair_base_currency(trade.pair) _wallets[curr] = Wallet( curr, trade.amount, From d34515a5de5b08e21cfc2e6854d4037758fc1f11 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 07:03:11 +0100 Subject: [PATCH 0612/1106] Remove constraint to have pairs in base/quote format --- freqtrade/constants.py | 2 -- tests/exchange/test_exchange.py | 1 + tests/test_configuration.py | 8 +------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 105cd6b53..1504d1f1c 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -251,7 +251,6 @@ CONF_SCHEMA = { 'type': 'array', 'items': { 'type': 'string', - 'pattern': '^[0-9A-Z]+/[0-9A-Z]+$' }, 'uniqueItems': True }, @@ -259,7 +258,6 @@ CONF_SCHEMA = { 'type': 'array', 'items': { 'type': 'string', - 'pattern': '^[0-9A-Z]+/[0-9A-Z]+$' }, 'uniqueItems': True }, diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index def4e6ab6..ca2bedb01 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -525,6 +525,7 @@ def test_validate_pairs_stakecompatibility_fail(default_conf, mocker, caplog): with pytest.raises(OperationalException, match=r"Stake-currency 'BTC' not compatible with.*"): Exchange(default_conf) + @pytest.mark.parametrize("timeframe", [ ('5m'), ("1m"), ("15m"), ("1h") ]) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 828db4d83..a58e88ea0 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -34,13 +34,6 @@ def all_conf(): return conf -def test_load_config_invalid_pair(default_conf) -> None: - default_conf['exchange']['pair_whitelist'].append('ETH-BTC') - - with pytest.raises(ValidationError, match=r'.*does not match.*'): - validate_config_schema(default_conf) - - def test_load_config_missing_attributes(default_conf) -> None: conf = deepcopy(default_conf) conf.pop('exchange') @@ -810,6 +803,7 @@ def test_validate_whitelist(default_conf): validate_config_consistency(conf) + def test_load_config_test_comments() -> None: """ Load config with comments From 31ac4598ba966b60be897ef22884442fa63eeb6f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 07:16:37 +0100 Subject: [PATCH 0613/1106] Fix last occurances of pair splitting --- freqtrade/exchange/exchange.py | 4 ++-- freqtrade/pairlist/VolumePairList.py | 4 ++-- freqtrade/rpc/rpc.py | 4 ++-- tests/rpc/test_rpc.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 0e0d2dabe..6964986b0 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -232,13 +232,13 @@ class Exchange: """ Return a pair's quote currency """ - return self.markets[pair].get('quote') + return self.markets.get(pair, {}).get('quote') def get_pair_base_currency(self, pair: str) -> str: """ Return a pair's quote currency """ - return self.markets[pair].get('base') + return self.markets.get(pair, {}).get('base') def klines(self, pair_interval: Tuple[str, str], copy: bool = True) -> DataFrame: if pair_interval in self._klines: diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index e50dafb63..e1cdb4a43 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -91,9 +91,9 @@ class VolumePairList(IPairList): if self._pairlist_pos == 0: # If VolumePairList is the first in the list, use fresh pairlist - # check length so that we make sure that '/' is actually in the string + # check base currency equals to stake currency. filtered_tickers = [v for k, v in tickers.items() - if (len(k.split('/')) == 2 and k.split('/')[1] == base_currency + if (self._exchange.get_pair_quote_currency(k) == base_currency and v[key] is not None)] else: # If other pairlist is in front, use the incomming pairlist. diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 3411318bb..d680d36b1 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -462,7 +462,7 @@ class RPC: # Check pair is in stake currency stake_currency = self._freqtrade.config.get('stake_currency') - if not pair.endswith(stake_currency): + if not self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency: raise RPCException( f'Wrong pair selected. Please pairs with stake {stake_currency} pairs only') # check if valid pair @@ -517,7 +517,7 @@ class RPC: if add: stake_currency = self._freqtrade.config.get('stake_currency') for pair in add: - if (pair.endswith(stake_currency) + if (self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency and pair not in self._freqtrade.pairlists.blacklist): self._freqtrade.pairlists.blacklist.append(pair) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index a35bfa0d6..3c99e6b92 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -687,7 +687,7 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, limit_buy_order) -> None # Test buy pair not with stakes with pytest.raises(RPCException, match=r'Wrong pair selected. Please pairs with stake.*'): - rpc._rpc_forcebuy('XRP/ETH', 0.0001) + rpc._rpc_forcebuy('LTC/ETH', 0.0001) pair = 'XRP/BTC' # Test not buying From 47e46bf205602caaa19b88fdfb863a308ba1a18b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 14:48:46 +0100 Subject: [PATCH 0614/1106] Add second example using dataprovider and current price --- docs/strategy-advanced.md | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index a60a6ea47..bdcd29f46 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -40,7 +40,7 @@ class Awesomestrategy(IStrategy): return True elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24): return True - return True + return False def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: @@ -50,8 +50,43 @@ class Awesomestrategy(IStrategy): return True elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24): return True - return True + return False ``` !!! Note For the above example, `unfilledtimeout` must be set to something bigger than 24h, otherwise that type of timeout will apply first. + + +### Custom order timeout example (using additional data) + +``` python +from datetime import datetime, timestamp +from freqtrade.persistence import Trade + +class Awesomestrategy(IStrategy): + + # ... populate_* methods + + # Set unfilledtimeout to 25 hours, since our maximum timeout from below is 24 hours. + unfilledtimeout = { + 'buy': 60 * 25, + 'sell': 60 * 25 + } + + def check_buy_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + ob = self.dp.orderbook(pair, 1) + current_price = ob['bids'][0][0] + # Cancel buy order if price is more than 2% above the order. + if order['price'] * 0.98 < best_bid: + return True + return False + + + def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + ob = self.dp.orderbook(pair, 1) + current_price = ob['asks'][0][0] + # Cancel sell order if price is more than 2% below the order. + if order['price'] * 1.02 > current_price: + return True + return False +``` From cfc22577bed042947d40cfa15676c1456aa6f7d4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 16:52:01 +0100 Subject: [PATCH 0615/1106] Add timeframe_to_minutes to ROI documentation --- docs/strategy-customization.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 07833da34..0dfeb3978 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -249,6 +249,22 @@ minimal_roi = { While technically not completely disabled, this would sell once the trade reaches 10000% Profit. +To use times based on candles, the following snippet can be handy. +This will allow you to change the ticket_interval, and ROI will be set as candles (e.g. after 3 candles ...) + +``` python +from freqtrade.exchange import timeframe_to_minutes + +class AwesomeStrategy(IStrategy): + + ticker_interval = '1d' + ticker_interval_mins = timeframe_to_minutes(ticker_interval) + minimal_roi = { + (ticker_interval_mins * 3): 0.02, # After 3 candles + (ticker_interval_mins * 6): 0.01, # After 6 candles + } +``` + ### Stoploss Setting a stoploss is highly recommended to protect your capital from strong moves against you. From d44f6651c4a63030dcaaecbda1431a020cc21ef0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 19:55:23 +0100 Subject: [PATCH 0616/1106] Fix small parenteses bug --- docs/strategy-advanced.md | 4 ++-- freqtrade/freqtradebot.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index bdcd29f46..8d241cc86 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -77,7 +77,7 @@ class Awesomestrategy(IStrategy): ob = self.dp.orderbook(pair, 1) current_price = ob['bids'][0][0] # Cancel buy order if price is more than 2% above the order. - if order['price'] * 0.98 < best_bid: + if order['price'] > current_price * 1.02: return True return False @@ -86,7 +86,7 @@ class Awesomestrategy(IStrategy): ob = self.dp.orderbook(pair, 1) current_price = ob['asks'][0][0] # Cancel sell order if price is more than 2% below the order. - if order['price'] * 1.02 > current_price: + if order['price'] < current_price * 0.98: return True return False ``` diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5adbe76f4..05cd60e5e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -847,24 +847,24 @@ class FreqtradeBot: self.wallets.update() continue - if ((order['side'] == 'buy' and order['status'] == 'canceled') + if (order['side'] == 'buy' and (order['status'] == 'canceled' or self._check_timed_out('buy', order) or strategy_safe_wrapper(self.strategy.check_buy_timeout, default_retval=False)(pair=trade.pair, trade=trade, - order=order)): + order=order))): self.handle_timedout_limit_buy(trade, order) self.wallets.update() order_type = self.strategy.order_types['buy'] self._notify_buy_cancel(trade, order_type) - elif ((order['side'] == 'sell' and order['status'] == 'canceled') + elif (order['side'] == 'sell' and (order['status'] == 'canceled' or self._check_timed_out('sell', order) or strategy_safe_wrapper(self.strategy.check_sell_timeout, default_retval=False)(pair=trade.pair, trade=trade, - order=order)): + order=order))): self.handle_timedout_limit_sell(trade, order) self.wallets.update() order_type = self.strategy.order_types['sell'] From a030ce9348bd5229005631fbdd2e91908f057f7a Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 25 Feb 2020 20:22:59 +0100 Subject: [PATCH 0617/1106] Reformat if condition --- freqtrade/freqtradebot.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 05cd60e5e..fa0981448 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -847,7 +847,8 @@ class FreqtradeBot: self.wallets.update() continue - if (order['side'] == 'buy' and (order['status'] == 'canceled' + if (order['side'] == 'buy' and ( + order['status'] == 'canceled' or self._check_timed_out('buy', order) or strategy_safe_wrapper(self.strategy.check_buy_timeout, default_retval=False)(pair=trade.pair, @@ -859,7 +860,8 @@ class FreqtradeBot: order_type = self.strategy.order_types['buy'] self._notify_buy_cancel(trade, order_type) - elif (order['side'] == 'sell' and (order['status'] == 'canceled' + elif (order['side'] == 'sell' and ( + order['status'] == 'canceled' or self._check_timed_out('sell', order) or strategy_safe_wrapper(self.strategy.check_sell_timeout, default_retval=False)(pair=trade.pair, From 7d7318a3ea5af47dada77e6595142e8c4bba8237 Mon Sep 17 00:00:00 2001 From: gaugau3000 Date: Tue, 25 Feb 2020 19:41:20 +0000 Subject: [PATCH 0618/1106] fix_wrong_order_type --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 0b9519688..6f139bebe 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -340,7 +340,7 @@ This is most of the time the default time in force. It means the order will rema on exchange till it is canceled by user. It can be fully or partially fulfilled. If partially fulfilled, the remaining will stay on the exchange till cancelled. -**FOK (Full Or Kill):** +**FOK (Fill Or Kill):** It means if the order is not executed immediately AND fully then it is canceled by the exchange. From 76c449c0c232032d128a854764356cebfe504fcb Mon Sep 17 00:00:00 2001 From: gaugau3000 Date: Tue, 25 Feb 2020 19:45:23 +0000 Subject: [PATCH 0619/1106] volume_pair_list_extra_doc_infos --- docs/configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 6f139bebe..6e8813211 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -532,6 +532,8 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis `refresh_period` allows setting the period (in seconds), at which the pairlist will be refreshed. Defaults to 1800s (30 minutes). +`VolumePairList` is based on the volume of the last 24 hours. + ```json "pairlists": [{ "method": "VolumePairList", From ce2e039e5fb9eba15864a1a3df45be17120127d7 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Wed, 26 Feb 2020 01:58:32 +0300 Subject: [PATCH 0620/1106] Update docs/configuration.md --- docs/configuration.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 6e8813211..5d1820bdb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -532,7 +532,11 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis `refresh_period` allows setting the period (in seconds), at which the pairlist will be refreshed. Defaults to 1800s (30 minutes). -`VolumePairList` is based on the volume of the last 24 hours. +`VolumePairList` is based on the ticker data, as reported by the ccxt library: + +* The `bidVolume` is the volume (amount) of current best bid in the orderbook. +* The `askVolume` is the volume (amount) of current best ask in the orderbook. +* The `quoteVolume` is the amount of quote (stake) currency traded (bought or sold) in last 24 hours. ```json "pairlists": [{ From df49b98c2578a9d45c0a052f643d00e6fbba2bdd Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 06:40:13 +0100 Subject: [PATCH 0621/1106] Implement wording-changes Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/strategy-customization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 0dfeb3978..acd985287 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -249,8 +249,8 @@ minimal_roi = { While technically not completely disabled, this would sell once the trade reaches 10000% Profit. -To use times based on candles, the following snippet can be handy. -This will allow you to change the ticket_interval, and ROI will be set as candles (e.g. after 3 candles ...) +To use times based on candle duration (ticker_interval or timeframe), the following snippet can be handy. +This will allow you to change the ticket_interval for the strategy, and ROI times will still be set as candles (e.g. after 3 candles ...) ``` python from freqtrade.exchange import timeframe_to_minutes From af4469f073501150c4aaa520fcd614ea18177fad Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 06:43:15 +0100 Subject: [PATCH 0622/1106] Convert to str to avoid errors --- docs/strategy-customization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index acd985287..fd40a971e 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -260,8 +260,8 @@ class AwesomeStrategy(IStrategy): ticker_interval = '1d' ticker_interval_mins = timeframe_to_minutes(ticker_interval) minimal_roi = { - (ticker_interval_mins * 3): 0.02, # After 3 candles - (ticker_interval_mins * 6): 0.01, # After 6 candles + str(ticker_interval_mins * 3)): 0.02, # After 3 candles + str(ticker_interval_mins * 6)): 0.01, # After 6 candles } ``` From 1e869b86f279f71c42d7f2bb6a34a2eb4ed60b47 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 06:54:04 +0100 Subject: [PATCH 0623/1106] Update checkout aciton to v2 https://github.com/actions/checkout/issues/23 suggests that it's fixed in v2. --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc8906af5..dc3d324a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: python-version: [3.7, 3.8] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v1 @@ -118,7 +118,7 @@ jobs: python-version: [3.7] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v1 @@ -175,7 +175,7 @@ jobs: docs_check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Documentation syntax run: | @@ -195,7 +195,7 @@ jobs: runs-on: ubuntu-18.04 if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade' steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v1 From 1021ffa1c3051d17482a00e79eef5a2b211cd103 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 07:00:08 +0100 Subject: [PATCH 0624/1106] Apply suggestions from code review Add suggested changes to comments Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- freqtrade/pairlist/VolumePairList.py | 2 +- freqtrade/rpc/rpc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index e1cdb4a43..d067d5e8a 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -91,7 +91,7 @@ class VolumePairList(IPairList): if self._pairlist_pos == 0: # If VolumePairList is the first in the list, use fresh pairlist - # check base currency equals to stake currency. + # Check if pair quote currency equals to the stake currency. filtered_tickers = [v for k, v in tickers.items() if (self._exchange.get_pair_quote_currency(k) == base_currency and v[key] is not None)] diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index d680d36b1..1e4eaa3e0 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -460,7 +460,7 @@ class RPC: if self._freqtrade.state != State.RUNNING: raise RPCException('trader is not running') - # Check pair is in stake currency + # Check if pair quote currency equals to the stake currency. stake_currency = self._freqtrade.config.get('stake_currency') if not self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency: raise RPCException( From 4e218be51db55e16bccc5513be244b98467ccb9f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 07:08:09 +0100 Subject: [PATCH 0625/1106] Don't use markets[pair]['quote'] --- freqtrade/exchange/exchange.py | 2 +- freqtrade/freqtradebot.py | 4 ++-- freqtrade/pairlist/IPairList.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 6964986b0..cc0ecc6cd 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -334,7 +334,7 @@ class Exchange: logger.warning(f"Pair {pair} is restricted for some users on this exchange." f"Please check if you are impacted by this restriction " f"on the exchange and eventually remove {pair} from your whitelist.") - if not self.markets[pair].get('quote') == self._config['stake_currency']: + if not self.get_pair_quote_currency(pair) == self._config['stake_currency']: invalid_pairs.append(pair) if invalid_pairs: raise OperationalException( diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 424a6a220..c3b642095 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -938,7 +938,8 @@ class FreqtradeBot: """ # Update wallets to ensure amounts tied up in a stoploss is now free! self.wallets.update() - wallet_amount = self.wallets.get_free(self.exchange.get_pair_base_currency(pair)) + trade_base_currency = self.exchange.get_pair_base_currency(pair) + wallet_amount = self.wallets.get_free(trade_base_currency) logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}") if wallet_amount >= amount: return amount @@ -1145,7 +1146,6 @@ class FreqtradeBot: return order_amount amount = 0 fee_abs = 0 - trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) for exectrade in trades: amount += exectrade['amount'] if ("fee" in exectrade and exectrade['fee'] is not None and diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index 7d489ece7..d45a329dd 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -100,7 +100,7 @@ class IPairList(ABC): f"{self._exchange.name}. Removing it from whitelist..") continue - if markets[pair]['quote'] != self._config['stake_currency']: + if self._exchange.get_pair_quote_currency(pair) != self._config['stake_currency']: logger.warning(f"Pair {pair} is not compatible with your stake currency " f"{self._config['stake_currency']}. Removing it from whitelist..") continue From f38accb77b05accfbf328e62c5b417ed7613d527 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 07:09:54 +0100 Subject: [PATCH 0626/1106] Return empty string if no quote / base currency can be found --- freqtrade/exchange/exchange.py | 4 ++-- tests/exchange/test_exchange.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index cc0ecc6cd..21627679f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -232,13 +232,13 @@ class Exchange: """ Return a pair's quote currency """ - return self.markets.get(pair, {}).get('quote') + return self.markets.get(pair, {}).get('quote', '') def get_pair_base_currency(self, pair: str) -> str: """ Return a pair's quote currency """ - return self.markets.get(pair, {}).get('base') + return self.markets.get(pair, {}).get('base', '') def klines(self, pair_interval: Tuple[str, str], copy: bool = True) -> DataFrame: if pair_interval in self._klines: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index ca2bedb01..3a653edb6 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -408,6 +408,7 @@ def test_get_quote_currencies(default_conf, mocker): ('LTC/USD', 'USD'), ('ETH/USDT', 'USDT'), ('XLTCUSDT', 'USDT'), + ('XRP/NOCURRENCY', ''), ]) def test_get_pair_quote_currency(default_conf, mocker, pair, expected): ex = get_patched_exchange(mocker, default_conf) @@ -419,6 +420,7 @@ def test_get_pair_quote_currency(default_conf, mocker, pair, expected): ('LTC/USD', 'LTC'), ('ETH/USDT', 'ETH'), ('XLTCUSDT', 'LTC'), + ('XRP/NOCURRENCY', ''), ]) def test_get_pair_base_currency(default_conf, mocker, pair, expected): ex = get_patched_exchange(mocker, default_conf) From a29653b510722251debc426981e3afc1d9929a4d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 08:59:27 +0100 Subject: [PATCH 0627/1106] Wording changes to install docs Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 4 ++-- docs/installation.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 234ff49ba..3844f2812 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -656,8 +656,8 @@ You should also make sure to read the [Exchanges](exchanges.md) section of the d ### Setup your exchange account -You will need to create API Keys (usually you get `key` and `secret`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. -API Keys are usually only required for real / production trading, but are not required for paper-trading / dry-run. +You will need to create API Keys (usually you get `key` and `secret`, some exchanges supply it with `password`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. +API Keys are usually only required for live trade (trading for real money, bot running in the "production mode", executing real orders on the exchange) and are not required for the bot running in the dry-run (trade simulation) mode. When you setup the bot in the dry-run mode, you may fill these fields with empty values. ### Using proxy with Freqtrade diff --git a/docs/installation.md b/docs/installation.md index 5a15be234..88e2ef6eb 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,7 +2,7 @@ This page explains how to prepare your environment for running the bot. -Please consider using the prebuilt [docker images](docker.md) to get started quickly while trying out freqtrade. +Please consider using the prebuilt [docker images](docker.md) to get started quickly while trying out freqtrade evaluating how it operates. ## Prerequisite From 8ae0f99a960fa4e7bdb615fa19c29fac887cb9e8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 09:05:48 +0100 Subject: [PATCH 0628/1106] Remove duplicate section --- docs/configuration.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 3844f2812..e0dc43f5d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -628,8 +628,8 @@ you run it in production mode. ### Setup your exchange account -You will need to create API Keys (usually you get `key` and `secret`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. -API Keys are usually only required for real / production trading, but are not required for paper-trading / dry-run. +You will need to create API Keys (usually you get `key` and `secret`, some exchanges require an additional `password`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the `freqtrade new-config` command. +API Keys are usually only required for live trading (trading for real money, bot running in "production mode", executing real orders on the exchange) and are not required for the bot running in dry-run (trade simulation) mode. When you setup the bot in dry-run mode, you may fill these fields with empty values. ### To switch your bot in production mode @@ -654,12 +654,6 @@ API Keys are usually only required for real / production trading, but are not re You should also make sure to read the [Exchanges](exchanges.md) section of the documentation to be aware of potential configuration details specific to your exchange. -### Setup your exchange account - -You will need to create API Keys (usually you get `key` and `secret`, some exchanges supply it with `password`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the installation script. -API Keys are usually only required for live trade (trading for real money, bot running in the "production mode", executing real orders on the exchange) and are not required for the bot running in the dry-run (trade simulation) mode. When you setup the bot in the dry-run mode, you may fill these fields with empty values. - - ### Using proxy with Freqtrade To use a proxy with freqtrade, add the kwarg `"aiohttp_trust_env"=true` to the `"ccxt_async_kwargs"` dict in the exchange section of the configuration. From f91d7beaa16edea12c6837489ae2f6d55e376a87 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 13:51:16 +0100 Subject: [PATCH 0629/1106] Fix constants wrong parenteses --- freqtrade/constants.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 1504d1f1c..743070196 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -15,6 +15,7 @@ UNLIMITED_STAKE_AMOUNT = 'unlimited' DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05 REQUIRED_ORDERTIF = ['buy', 'sell'] REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange'] +ORDERBOOK_SIDES = ['ask', 'bid'] ORDERTYPE_POSSIBILITIES = ['limit', 'market'] ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', @@ -113,15 +114,15 @@ CONF_SCHEMA = { 'minimum': 0, 'maximum': 1, 'exclusiveMaximum': False, - 'use_order_book': {'type': 'boolean'}, - 'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1}, - 'check_depth_of_market': { - 'type': 'object', - 'properties': { - 'enabled': {'type': 'boolean'}, - 'bids_to_ask_delta': {'type': 'number', 'minimum': 0}, - } - }, + }, + 'use_order_book': {'type': 'boolean'}, + 'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1}, + 'check_depth_of_market': { + 'type': 'object', + 'properties': { + 'enabled': {'type': 'boolean'}, + 'bids_to_ask_delta': {'type': 'number', 'minimum': 0}, + } }, }, 'required': ['ask_last_balance'] From de48a697b0a5abdee5b012f2b5b919d0fe06cb9a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 14:06:42 +0100 Subject: [PATCH 0630/1106] Use price_side for get_sell_rate --- freqtrade/constants.py | 3 +++ freqtrade/freqtradebot.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 743070196..ac1a8a6a9 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -115,6 +115,7 @@ CONF_SCHEMA = { 'maximum': 1, 'exclusiveMaximum': False, }, + 'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'bid'}, 'use_order_book': {'type': 'boolean'}, 'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1}, 'check_depth_of_market': { @@ -130,6 +131,7 @@ CONF_SCHEMA = { 'ask_strategy': { 'type': 'object', 'properties': { + 'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'ask'}, 'use_order_book': {'type': 'boolean'}, 'order_book_min': {'type': 'integer', 'minimum': 1}, 'order_book_max': {'type': 'integer', 'minimum': 1, 'maximum': 50}, @@ -300,6 +302,7 @@ SCHEMA_TRADE_REQUIRED = [ 'last_stake_amount_min_ratio', 'dry_run', 'dry_run_wallet', + 'ask_strategy', 'bid_strategy', 'unfilledtimeout', 'stoploss', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index dffec940c..5e8f1cc98 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -639,10 +639,10 @@ class FreqtradeBot: logger.debug('Using order book to get sell rate') order_book = self.exchange.get_order_book(pair, 1) - rate = order_book['bids'][0][0] + rate = order_book[f"{config_ask_strategy['price_side']}s"][0][0] else: - rate = self.exchange.fetch_ticker(pair)['bid'] + rate = self.exchange.fetch_ticker(pair)[config_ask_strategy['price_side']] self._sell_rate_cache[pair] = rate return rate From 5f712320380824f2140b82e5d6a328ff90f53beb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 14:08:16 +0100 Subject: [PATCH 0631/1106] Refactor get_buy_rate to use rate variable --- freqtrade/freqtradebot.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5e8f1cc98..aaa66fe81 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -242,11 +242,10 @@ class FreqtradeBot: logger.info(f"Using cached buy rate for {pair}.") return rate - config_bid_strategy = self.config.get('bid_strategy', {}) - if 'use_order_book' in config_bid_strategy and\ - config_bid_strategy.get('use_order_book', False): + bid_strategy = self.config.get('bid_strategy', {}) + if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False): logger.info('Getting price from order book') - order_book_top = config_bid_strategy.get('order_book_top', 1) + order_book_top = bid_strategy.get('order_book_top', 1) order_book = self.exchange.get_order_book(pair, order_book_top) logger.debug('order_book %s', order_book) # top 1 = index 0 @@ -256,11 +255,12 @@ class FreqtradeBot: else: logger.info('Using Last Ask / Last Price') ticker = self.exchange.fetch_ticker(pair) - if ticker['ask'] < ticker['last']: - ticker_rate = ticker['ask'] + rate = ticker['ask'] + if rate < ticker['last']: + ticker_rate = rate else: balance = self.config['bid_strategy']['ask_last_balance'] - ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + ticker_rate = rate + balance * (ticker['last'] - rate) used_rate = ticker_rate self._buy_rate_cache[pair] = used_rate From e4b29491888c05444ec47599238926597ecac83a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 14:13:43 +0100 Subject: [PATCH 0632/1106] Change buy_rate calculation to use price_side --- freqtrade/freqtradebot.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aaa66fe81..2c9a960a4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -244,18 +244,20 @@ class FreqtradeBot: bid_strategy = self.config.get('bid_strategy', {}) if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False): - logger.info('Getting price from order book') + logger.info( + f"Getting price from order book {bid_strategy['price_side'].capitalize()} side." + ) order_book_top = bid_strategy.get('order_book_top', 1) order_book = self.exchange.get_order_book(pair, order_book_top) logger.debug('order_book %s', order_book) # top 1 = index 0 - order_book_rate = order_book['bids'][order_book_top - 1][0] - logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate) + order_book_rate = order_book[f"{bid_strategy['price_side']}s"][order_book_top - 1][0] + logger.info(f'...top {order_book_top} order book buy rate {order_book_rate:.8f}') used_rate = order_book_rate else: - logger.info('Using Last Ask / Last Price') + logger.info(f"Using Last {bid_strategy['price_side'].capitalize()} / Last Price") ticker = self.exchange.fetch_ticker(pair) - rate = ticker['ask'] + rate = ticker[bid_strategy['price_side']] if rate < ticker['last']: ticker_rate = rate else: From e7b9891335ba13abdcf1445b7cc354db8a51792e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 14:27:03 +0100 Subject: [PATCH 0633/1106] Adapt rpc tests to corrected price side --- tests/rpc/test_rpc.py | 24 +++++++++++----------- tests/rpc/test_rpc_apiserver.py | 8 ++++---- tests/rpc/test_rpc_telegram.py | 36 ++++++++++++++++----------------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 93b6f6058..6319ab9e6 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -51,13 +51,13 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_date_hum': ANY, 'close_date': None, 'close_date_hum': None, - 'open_rate': 1.099e-05, + 'open_rate': 1.098e-05, 'close_rate': None, - 'current_rate': 1.098e-05, - 'amount': 90.99181074, + 'current_rate': 1.099e-05, + 'amount': 91.07468124, 'stake_amount': 0.001, 'close_profit': None, - 'current_profit': -0.59, + 'current_profit': -0.41, 'stop_loss': 0.0, 'initial_stop_loss': 0.0, 'initial_stop_loss_pct': None, @@ -78,10 +78,10 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_date_hum': ANY, 'close_date': None, 'close_date_hum': None, - 'open_rate': 1.099e-05, + 'open_rate': 1.098e-05, 'close_rate': None, 'current_rate': ANY, - 'amount': 90.99181074, + 'amount': 91.07468124, 'stake_amount': 0.001, 'close_profit': None, 'current_profit': ANY, @@ -121,7 +121,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert "Pair" in headers assert 'instantly' == result[0][2] assert 'ETH/BTC' in result[0][1] - assert '-0.59%' == result[0][3] + assert '-0.41%' == result[0][3] # Test with fiatconvert rpc._fiat_converter = CryptoToFiatConverter() @@ -130,7 +130,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert "Pair" in headers assert 'instantly' == result[0][2] assert 'ETH/BTC' in result[0][1] - assert '-0.59% (-0.09)' == result[0][3] + assert '-0.41% (-0.06)' == result[0][3] mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) @@ -245,9 +245,9 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, assert prec_satoshi(stats['profit_closed_coin'], 6.217e-05) assert prec_satoshi(stats['profit_closed_percent'], 6.2) assert prec_satoshi(stats['profit_closed_fiat'], 0.93255) - assert prec_satoshi(stats['profit_all_coin'], 5.632e-05) - assert prec_satoshi(stats['profit_all_percent'], 2.81) - assert prec_satoshi(stats['profit_all_fiat'], 0.8448) + assert prec_satoshi(stats['profit_all_coin'], 5.802e-05) + assert prec_satoshi(stats['profit_all_percent'], 2.89) + assert prec_satoshi(stats['profit_all_fiat'], 0.8703) assert stats['trade_count'] == 2 assert stats['first_trade_date'] == 'just now' assert stats['latest_trade_date'] == 'just now' @@ -668,7 +668,7 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, limit_buy_order) -> None trade = rpc._rpc_forcebuy(pair, None) assert isinstance(trade, Trade) assert trade.pair == pair - assert trade.open_rate == ticker()['ask'] + assert trade.open_rate == ticker()['bid'] # Test buy duplicate with pytest.raises(RPCException, match=r'position for ETH/BTC already open - id: 1'): diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 25c971bf7..e0abd886d 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -426,20 +426,20 @@ def test_api_status(botclient, mocker, ticker, fee, markets): rc = client_get(client, f"{BASE_URI}/status") assert_response(rc) assert len(rc.json) == 1 - assert rc.json == [{'amount': 90.99181074, + assert rc.json == [{'amount': 91.07468124, 'base_currency': 'BTC', 'close_date': None, 'close_date_hum': None, 'close_profit': None, 'close_rate': None, - 'current_profit': -0.59, - 'current_rate': 1.098e-05, + 'current_profit': -0.41, + 'current_rate': 1.099e-05, 'initial_stop_loss': 0.0, 'initial_stop_loss_pct': None, 'open_date': ANY, 'open_date_hum': 'just now', 'open_order': '(limit buy rem=0.00000000)', - 'open_rate': 1.099e-05, + 'open_rate': 1.098e-05, 'pair': 'ETH/BTC', 'stake_amount': 0.001, 'stop_loss': 0.0, diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index a8b8e0c5a..fd3e4039a 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -720,13 +720,13 @@ def test_forcesell_handle(default_conf, update, ticker, fee, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': 'profit', - 'limit': 1.172e-05, - 'amount': 90.99181073703367, + 'limit': 1.173e-05, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.172e-05, - 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'open_rate': 1.098e-05, + 'current_rate': 1.173e-05, + 'profit_amount': 6.314e-05, + 'profit_percent': 0.0629778, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, @@ -779,13 +779,13 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': 'loss', - 'limit': 1.044e-05, - 'amount': 90.99181073703367, + 'limit': 1.043e-05, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.044e-05, - 'profit_amount': -5.492e-05, - 'profit_percent': -0.05478342, + 'open_rate': 1.098e-05, + 'current_rate': 1.043e-05, + 'profit_amount': -5.497e-05, + 'profit_percent': -0.05482878, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, @@ -827,13 +827,13 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': 'loss', - 'limit': 1.098e-05, - 'amount': 90.99181073703367, + 'limit': 1.099e-05, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.098e-05, - 'profit_amount': -5.91e-06, - 'profit_percent': -0.00589291, + 'open_rate': 1.098e-05, + 'current_rate': 1.099e-05, + 'profit_amount': -4.09e-06, + 'profit_percent': -0.00408133, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, From e1cb6f4ae3cd1de66df0eb0eb8128b520e170d5c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 15:06:37 +0100 Subject: [PATCH 0634/1106] fix and improve tests in test_freqtradebot --- tests/test_freqtradebot.py | 125 ++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 51 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 852b6b990..655fe4684 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -761,8 +761,8 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order, assert trade.is_open assert trade.open_date is not None assert trade.exchange == 'bittrex' - assert trade.open_rate == 0.00001099 - assert trade.amount == 90.99181073703367 + assert trade.open_rate == 0.00001098 + assert trade.amount == 91.07468123861567 assert log_has( 'Buy signal found: about create a new trade with stake_amount: 0.001 ...', caplog @@ -906,20 +906,28 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: assert ("ETH/BTC", default_conf["ticker_interval"]) in refresh_mock.call_args[0][0] -@pytest.mark.parametrize("ask,last,last_ab,expected", [ - (20, 10, 0.0, 20), # Full ask side - (20, 10, 1.0, 10), # Full last side - (20, 10, 0.5, 15), # Between ask and last - (20, 10, 0.7, 13), # Between ask and last - (20, 10, 0.3, 17), # Between ask and last - (5, 10, 1.0, 5), # last bigger than ask - (5, 10, 0.5, 5), # last bigger than ask +@pytest.mark.parametrize("side,ask,bid,last,last_ab,expected", [ + ('ask', 20, 19, 10, 0.0, 20), # Full ask side + ('ask', 20, 19, 10, 1.0, 10), # Full last side + ('ask', 20, 19, 10, 0.5, 15), # Between ask and last + ('ask', 20, 19, 10, 0.7, 13), # Between ask and last + ('ask', 20, 19, 10, 0.3, 17), # Between ask and last + ('ask', 5, 6, 10, 1.0, 5), # last bigger than ask + ('ask', 5, 6, 10, 0.5, 5), # last bigger than ask + ('bid', 10, 20, 10, 0.0, 20), # Full bid side + ('bid', 10, 20, 10, 1.0, 10), # Full last side + ('bid', 10, 20, 10, 0.5, 15), # Between bid and last + ('bid', 10, 20, 10, 0.7, 13), # Between bid and last + ('bid', 10, 20, 10, 0.3, 17), # Between bid and last + ('bid', 4, 5, 10, 1.0, 5), # last bigger than bid + ('bid', 4, 5, 10, 0.5, 5), # last bigger than bid ]) -def test_get_buy_rate(mocker, default_conf, caplog, ask, last, last_ab, expected) -> None: +def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid, last, last_ab, expected) -> None: default_conf['bid_strategy']['ask_last_balance'] = last_ab + default_conf['bid_strategy']['price_side'] = side freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', - MagicMock(return_value={'ask': ask, 'last': last})) + MagicMock(return_value={'ask': ask, 'last': last, 'bid': bid})) assert freqtrade.get_buy_rate('ETH/BTC', True) == expected assert not log_has("Using cached buy rate for ETH/BTC.", caplog) @@ -1317,7 +1325,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, stoploss_order_mock.assert_not_called() assert freqtrade.handle_trade(trade) is False - assert trade.stop_loss == 0.00002344 * 0.95 + assert trade.stop_loss == 0.00002346 * 0.95 # setting stoploss_on_exchange_interval to 0 seconds freqtrade.strategy.order_types['stoploss_on_exchange_interval'] = 0 @@ -1325,10 +1333,10 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog, assert freqtrade.handle_stoploss_on_exchange(trade) is False cancel_order_mock.assert_called_once_with(100, 'ETH/BTC') - stoploss_order_mock.assert_called_once_with(amount=85.25149190110828, + stoploss_order_mock.assert_called_once_with(amount=85.32423208191126, pair='ETH/BTC', order_types=freqtrade.strategy.order_types, - stop_price=0.00002344 * 0.95) + stop_price=0.00002346 * 0.95) # price fell below stoploss, so dry-run sells trade. mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', MagicMock(return_value={ @@ -1510,12 +1518,12 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog, assert freqtrade.handle_stoploss_on_exchange(trade) is False # stoploss should be set to 1% as trailing is on - assert trade.stop_loss == 0.00002344 * 0.99 + assert trade.stop_loss == 0.00002346 * 0.99 cancel_order_mock.assert_called_once_with(100, 'NEO/BTC') - stoploss_order_mock.assert_called_once_with(amount=2131074.168797954, + stoploss_order_mock.assert_called_once_with(amount=2132892.491467577, pair='NEO/BTC', order_types=freqtrade.strategy.order_types, - stop_price=0.00002344 * 0.99) + stop_price=0.00002346 * 0.99) def test_enter_positions(mocker, default_conf, caplog) -> None: @@ -2292,12 +2300,12 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N 'pair': 'ETH/BTC', 'gain': 'profit', 'limit': 1.172e-05, - 'amount': 90.99181073703367, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.172e-05, - 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'open_rate': 1.098e-05, + 'current_rate': 1.173e-05, + 'profit_amount': 6.223e-05, + 'profit_percent': 0.0620716, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.ROI.value, @@ -2341,12 +2349,12 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) 'pair': 'ETH/BTC', 'gain': 'loss', 'limit': 1.044e-05, - 'amount': 90.99181073703367, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.044e-05, - 'profit_amount': -5.492e-05, - 'profit_percent': -0.05478342, + 'open_rate': 1.098e-05, + 'current_rate': 1.043e-05, + 'profit_amount': -5.406e-05, + 'profit_percent': -0.05392257, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, @@ -2397,12 +2405,12 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe 'pair': 'ETH/BTC', 'gain': 'loss', 'limit': 1.08801e-05, - 'amount': 90.99181073703367, + 'amount': 91.07468123861567, 'order_type': 'limit', - 'open_rate': 1.099e-05, - 'current_rate': 1.044e-05, - 'profit_amount': -1.498e-05, - 'profit_percent': -0.01493766, + 'open_rate': 1.098e-05, + 'current_rate': 1.043e-05, + 'profit_amount': -1.408e-05, + 'profit_percent': -0.01404051, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, @@ -2587,7 +2595,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'], sell_reason=SellType.ROI) assert not trade.is_open - assert trade.close_profit == 0.0611052 + assert trade.close_profit == 0.0620716 assert rpc_mock.call_count == 2 last_msg = rpc_mock.call_args_list[-1][0][0] @@ -2597,12 +2605,12 @@ def test_execute_sell_market_order(default_conf, ticker, fee, 'pair': 'ETH/BTC', 'gain': 'profit', 'limit': 1.172e-05, - 'amount': 90.99181073703367, + 'amount': 91.07468123861567, 'order_type': 'market', - 'open_rate': 1.099e-05, - 'current_rate': 1.172e-05, - 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'open_rate': 1.098e-05, + 'current_rate': 1.173e-05, + 'profit_amount': 6.223e-05, + 'profit_percent': 0.0620716, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.ROI.value, @@ -3624,13 +3632,20 @@ def test_order_book_ask_strategy(default_conf, limit_buy_order, limit_sell_order assert freqtrade.handle_trade(trade) is True -def test_get_sell_rate(default_conf, mocker, caplog, ticker, order_book_l2) -> None: - - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - get_order_book=order_book_l2, - fetch_ticker=ticker, - ) +@pytest.mark.parametrize('side,ask,bid,expected', [ + ('bid', 10.0, 11.0, 11.0), + ('bid', 10.0, 11.2, 11.2), + ('bid', 10.0, 11.0, 11.0), + ('bid', 9.8, 11.0, 11.0), + ('bid', 0.0001, 0.002, 0.002), + ('ask', 10.0, 11.0, 10.0), + ('ask', 10.11, 11.2, 10.11), + ('ask', 0.001, 0.002, 0.001), + ('ask', 0.006, 1.0, 0.006), +]) +def test_get_sell_rate(default_conf, mocker, caplog, side, bid, ask, expected) -> None: + default_conf['ask_strategy']['price_side'] = side + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value={'ask': ask, 'bid': bid}) pair = "ETH/BTC" # Test regular mode @@ -3638,25 +3653,33 @@ def test_get_sell_rate(default_conf, mocker, caplog, ticker, order_book_l2) -> N rate = ft.get_sell_rate(pair, True) assert not log_has("Using cached sell rate for ETH/BTC.", caplog) assert isinstance(rate, float) - assert rate == 0.00001098 + assert rate == expected # Use caching rate = ft.get_sell_rate(pair, False) - assert rate == 0.00001098 + assert rate == expected assert log_has("Using cached sell rate for ETH/BTC.", caplog) - caplog.clear() +@pytest.mark.parametrize('side,expected', [ + ('bid', 0.043936), # Value from order_book_l2 fiture - bids side + ('ask', 0.043949), # Value from order_book_l2 fiture - asks side +]) +def test_get_sell_rate_orderbook(default_conf, mocker, caplog, side, expected, order_book_l2): # Test orderbook mode + default_conf['ask_strategy']['price_side'] = side default_conf['ask_strategy']['use_order_book'] = True default_conf['ask_strategy']['order_book_min'] = 1 default_conf['ask_strategy']['order_book_max'] = 2 + # TODO: min/max is irrelevant for this test until refactoring + pair = "ETH/BTC" + mocker.patch('freqtrade.exchange.Exchange.get_order_book', order_book_l2) ft = get_patched_freqtradebot(mocker, default_conf) rate = ft.get_sell_rate(pair, True) assert not log_has("Using cached sell rate for ETH/BTC.", caplog) assert isinstance(rate, float) - assert rate == 0.043936 + assert rate == expected rate = ft.get_sell_rate(pair, False) - assert rate == 0.043936 + assert rate == expected assert log_has("Using cached sell rate for ETH/BTC.", caplog) From 8edc3eb5fb8a6c4dc62f455f12d237c0d670b3d9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 15:39:12 +0100 Subject: [PATCH 0635/1106] Use generator to generate sell price scaffold testing --- freqtrade/freqtradebot.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 2c9a960a4..22a73a273 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -619,6 +619,15 @@ class FreqtradeBot: return trades_closed + def _order_book_gen(self, pair: str, side: str, order_book_max: int = 1, + order_book_min: int = 1): + """ + Helper generator to query orderbook in loop (used for early sell-order placing) + """ + order_book = self.exchange.get_order_book(pair, order_book_max) + for i in range(order_book_min, order_book_max + 1): + yield order_book[side][i - 1][0] + def get_sell_rate(self, pair: str, refresh: bool) -> float: """ Get sell rate - either using get-ticker bid or first bid based on orderbook @@ -639,9 +648,10 @@ class FreqtradeBot: config_ask_strategy = self.config.get('ask_strategy', {}) if config_ask_strategy.get('use_order_book', False): logger.debug('Using order book to get sell rate') + rate = next(self._order_book_gen(pair, f"{config_ask_strategy['price_side']}s")) - order_book = self.exchange.get_order_book(pair, 1) - rate = order_book[f"{config_ask_strategy['price_side']}s"][0][0] + # order_book = self.exchange.get_order_book(pair, 1) + # rate = order_book[f"{config_ask_strategy['price_side']}s"][0][0] else: rate = self.exchange.fetch_ticker(pair)[config_ask_strategy['price_side']] @@ -674,12 +684,12 @@ class FreqtradeBot: order_book_min = config_ask_strategy.get('order_book_min', 1) order_book_max = config_ask_strategy.get('order_book_max', 1) - order_book = self.exchange.get_order_book(trade.pair, order_book_max) - + order_book = self._order_book_gen(trade.pair, f"{config_ask_strategy['price_side']}s", + order_book_min=order_book_min, + order_book_max=order_book_max) for i in range(order_book_min, order_book_max + 1): - order_book_rate = order_book['asks'][i - 1][0] - logger.debug(' order book asks top %s: %0.8f', i, order_book_rate) - sell_rate = order_book_rate + sell_rate = next(order_book) + logger.debug(' order book asks top %s: %0.8f', i, sell_rate) if self._check_and_execute_sell(trade, sell_rate, buy, sell): return True From 3c5e716d8f5b3c527ae7683877fb10149c03ebe2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Feb 2020 16:00:34 +0100 Subject: [PATCH 0636/1106] Update some documentation regarding price_side --- docs/configuration.md | 64 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index b05dab7c9..54470f278 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -60,11 +60,13 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
*Defaults to `false`.*
**Datatype:** Boolean | `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Integer | `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Integer -| `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#buy-price-without-orderbook). +| `bid_strategy.price_side` | Select the side of the spread the bot should look at to get the buy rate. [More information below](#buy-price-side).
*Defaults to `bid`.*
**Datatype:** String (either `ask` or `bid`). +| `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#buy-price-without-orderbook-enabled). | `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled).
**Datatype:** Boolean | `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled).
*Defaults to `1`.*
**Datatype:** Positive Integer | `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market).
*Defaults to `false`.*
**Datatype:** Boolean | `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market)
*Defaults to `0`.*
**Datatype:** Float (as ratio) +| `ask_strategy.price_side` | Select the side of the spread the bot should look at to get the sell rate. [More information below](#sell-price-side).
*Defaults to `ask`.*
**Datatype:** String (either `ask` or `bid`). | `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled).
**Datatype:** Boolean | `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer | `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
*Defaults to `1`.*
**Datatype:** Positive Integer @@ -461,23 +463,71 @@ Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) s !!! Note A delta value below 1 means that `ask` (sell) orderbook side depth is greater than the depth of the `bid` (buy) orderbook side, while a value greater than 1 means opposite (depth of the buy side is higher than the depth of the sell side). +#### Buy price side + +The configuration option `bid_strategy.price_side` defines the side of the spread the bot looks for when buying. + +The following displays an orderbook. + +``` explanation +... +103 +102 +101 # ask +-------------Current spread +99 # bid +98 +97 +... +``` + +If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buying price. +In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price. + +Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary. + + #### Buy price with Orderbook enabled -When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the `bid` (buy) side of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on. +When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the configured side (`bid_strategy.price_side`) of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on. #### Buy price without Orderbook enabled -When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `ask` (sell) price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `ask` price is not below the `last` price), it calculates a rate between `ask` and `last` price. +The following section uses `side` as the configured `bid_strategy.price_side`. -The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `ask` price, while `1.0` will use the `last` price and values between those interpolate between ask 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. -Using `ask` price often guarantees quicker success in the bid, but the bot can also end up paying more than what would have been necessary. +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. ### Sell price +#### Sell price side + +The configuration option `ask_strategy.price_side` defines the side of the spread the bot looks for when selling. + +The following displays an orderbook: + +``` explanation +... +103 +102 +101 # ask +-------------Current spread +99 # bid +98 +97 +... +``` + +If `ask_strategy.price_side` is set to `"ask"`, then the bot will use 101 as selling price. +In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot will use 99 as selling price. + #### Sell price with Orderbook enabled -When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the `ask` orderbook side are validated for a profitable sell-possibility based on the strategy configuration and the sell order is placed at the first profitable spot. +When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration and the sell order is placed at the first profitable spot. + +!!! Note: + Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`. The idea here is to place the sell order early, to be ahead in the queue. @@ -488,7 +538,7 @@ A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting #### Sell price without Orderbook enabled -When not using orderbook (`ask_strategy.use_order_book=False`), the `bid` price from the ticker will be used as the sell price. +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. ## Pairlists From 0fea3a7ea74451243a9518d3059599d15ea7a9aa Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 19:49:54 +0100 Subject: [PATCH 0637/1106] Some final polish to configurable_side --- docs/configuration.md | 2 +- freqtrade/freqtradebot.py | 4 +--- tests/test_freqtradebot.py | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 54470f278..c70f3425c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -526,7 +526,7 @@ In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration and the sell order is placed at the first profitable spot. -!!! Note: +!!! Note Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`. The idea here is to place the sell order early, to be ahead in the queue. diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 22a73a273..53493ad4c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -647,12 +647,10 @@ class FreqtradeBot: config_ask_strategy = self.config.get('ask_strategy', {}) if config_ask_strategy.get('use_order_book', False): + # This code is only used for notifications, selling uses the generator directly logger.debug('Using order book to get sell rate') rate = next(self._order_book_gen(pair, f"{config_ask_strategy['price_side']}s")) - # order_book = self.exchange.get_order_book(pair, 1) - # rate = order_book[f"{config_ask_strategy['price_side']}s"][0][0] - else: rate = self.exchange.fetch_ticker(pair)[config_ask_strategy['price_side']] self._sell_rate_cache[pair] = rate diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 655fe4684..49000382f 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -922,7 +922,8 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: ('bid', 4, 5, 10, 1.0, 5), # last bigger than bid ('bid', 4, 5, 10, 0.5, 5), # last bigger than bid ]) -def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid, last, last_ab, expected) -> None: +def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid, + last, last_ab, expected) -> None: default_conf['bid_strategy']['ask_last_balance'] = last_ab default_conf['bid_strategy']['price_side'] = side freqtrade = get_patched_freqtradebot(mocker, default_conf) From b6839289ec2cba080c3bfeb2d956e1e70660770e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Feb 2020 20:03:03 +0100 Subject: [PATCH 0638/1106] Add price_side to sample config files --- config_full.json.example | 2 ++ freqtrade/templates/base_config.json.j2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config_full.json.example b/config_full.json.example index cdb7e841e..f0414bd0d 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -25,6 +25,7 @@ "sell": 30 }, "bid_strategy": { + "price_side": "bid", "use_order_book": false, "ask_last_balance": 0.0, "order_book_top": 1, @@ -34,6 +35,7 @@ } }, "ask_strategy":{ + "price_side": "ask", "use_order_book": false, "order_book_min": 1, "order_book_max": 9, diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index 88edeb1e8..0049d59a0 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -11,6 +11,7 @@ "sell": 30 }, "bid_strategy": { + "price_side": "bid", "ask_last_balance": 0.0, "use_order_book": false, "order_book_top": 1, @@ -20,6 +21,7 @@ } }, "ask_strategy": { + "price_side": "ask", "use_order_book": false, "order_book_min": 1, "order_book_max": 9, From e5ec97495ddbf331fe43a0ed55a2f938d343d943 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Feb 2020 07:01:00 +0100 Subject: [PATCH 0639/1106] Logging should be initialized first --- freqtrade/configuration/configuration.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 21b3e3bd3..035b091b3 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -96,6 +96,8 @@ class Configuration: # Keep a copy of the original configuration file config['original_config'] = deepcopy(config) + self._process_logging_options(config) + self._process_runmode(config) self._process_common_options(config) @@ -146,8 +148,6 @@ class Configuration: def _process_common_options(self, config: Dict[str, Any]) -> None: - self._process_logging_options(config) - # Set strategy if not specified in config and or if it's non default if self.args.get("strategy") or not config.get('strategy'): config.update({'strategy': self.args.get("strategy")}) @@ -379,7 +379,7 @@ class Configuration: if not self.runmode: # Handle real mode, infer dry/live from config self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE - logger.info(f"Runmode set to {self.runmode}.") + logger.info(f"Runmode set to {self.runmode.value}.") config.update({'runmode': self.runmode}) From bbb438bd4093d38e8e41e05fd151ec1fa2799411 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2020 06:18:09 +0000 Subject: [PATCH 0640/1106] Bump python from 3.8.1-slim-buster to 3.8.2-slim-buster Bumps python from 3.8.1-slim-buster to 3.8.2-slim-buster. Signed-off-by: dependabot-preview[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 923285f39..d986f20ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8.1-slim-buster +FROM python:3.8.2-slim-buster RUN apt-get update \ && apt-get -y install curl build-essential libssl-dev \ From 55d471190a3afc52984edab5035b460abd429434 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 27 Feb 2020 13:28:28 +0100 Subject: [PATCH 0641/1106] Changed table style of backtesting and alignment of headers --- freqtrade/optimize/backtesting.py | 47 +++++++++++++++---------- freqtrade/optimize/optimize_reports.py | 8 ++--- tests/optimize/test_optimize_reports.py | 43 +++++++++++----------- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index c18aefc76..94441ce24 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -423,28 +423,37 @@ class Backtesting: strategy if len(self.strategylist) > 1 else None) print(f"Result for strategy {strategy}") - print(' BACKTESTING REPORT '.center(133, '=')) - print(generate_text_table(data, - stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results)) + table = generate_text_table(data, stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results) + if isinstance(table, str): + print(' BACKTESTING REPORT '.center(len(table.splitlines()[0]), '=')) + print(table) - print(' SELL REASON STATS '.center(133, '=')) - print(generate_text_table_sell_reason(data, - stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results)) + table = generate_text_table_sell_reason(data, + stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results) + if isinstance(table, str): + print(' SELL REASON STATS '.center(len(table.splitlines()[0]), '=')) + print(table) - print(' LEFT OPEN TRADES REPORT '.center(133, '=')) - print(generate_text_table(data, - stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results.loc[results.open_at_end], skip_nan=True)) + table = generate_text_table(data, + stake_currency=self.config['stake_currency'], + max_open_trades=self.config['max_open_trades'], + results=results.loc[results.open_at_end], skip_nan=True) + if isinstance(table, str): + print(' LEFT OPEN TRADES REPORT '.center(len(table.splitlines()[0]), '=')) + print(table) + if isinstance(table, str): + print('=' * len(table.splitlines()[0])) print() if len(all_results) > 1: # Print Strategy summary table - print(' STRATEGY SUMMARY '.center(133, '=')) - print(generate_text_table_strategy(self.config['stake_currency'], - self.config['max_open_trades'], - all_results=all_results)) + table = generate_text_table_strategy(self.config['stake_currency'], + self.config['max_open_trades'], + all_results=all_results) + print(' STRATEGY SUMMARY '.center(len(table.splitlines()[0]), '=')) + print(table) + print('=' * len(table.splitlines()[0])) print('\nFor more details, please look at the detail tables above') diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index b00adbd48..39bde50a8 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -66,7 +66,7 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra ]) # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore + floatfmt=floatfmt, tablefmt="orgtbl", stralign="right") # type: ignore def generate_text_table_sell_reason( @@ -112,7 +112,7 @@ def generate_text_table_sell_reason( profit_percent_tot, ] ) - return tabulate(tabular_data, headers=headers, tablefmt="pipe") + return tabulate(tabular_data, headers=headers, tablefmt="orgtbl", stralign="right") def generate_text_table_strategy(stake_currency: str, max_open_trades: str, @@ -146,7 +146,7 @@ def generate_text_table_strategy(stake_currency: str, max_open_trades: str, ]) # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore + floatfmt=floatfmt, tablefmt="orgtbl", stralign="right") # type: ignore def generate_edge_table(results: dict) -> str: @@ -172,4 +172,4 @@ def generate_edge_table(results: dict) -> str: # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, - floatfmt=floatfmt, tablefmt="pipe") # type: ignore + floatfmt=floatfmt, tablefmt="orgtbl", stralign="right") # type: ignore diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 57e928cca..285ecaa02 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -22,14 +22,14 @@ def test_generate_text_table(default_conf, mocker): ) result_str = ( - '| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC |' - ' Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' - '|:--------|-------:|---------------:|---------------:|-----------------:|' - '---------------:|:---------------|-------:|--------:|---------:|\n' + '| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC |' + ' Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|---------+--------+----------------+----------------+------------------+' + '----------------+----------------+--------+---------+----------|\n' '| ETH/BTC | 2 | 15.00 | 30.00 | 0.60000000 |' - ' 15.00 | 0:20:00 | 2 | 0 | 0 |\n' - '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 |' - ' 15.00 | 0:20:00 | 2 | 0 | 0 |' + ' 15.00 | 0:20:00 | 2 | 0 | 0 |\n' + '| TOTAL | 2 | 15.00 | 30.00 | 0.60000000 |' + ' 15.00 | 0:20:00 | 2 | 0 | 0 |' ) assert generate_text_table(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, @@ -52,13 +52,13 @@ def test_generate_text_table_sell_reason(default_conf, mocker): ) result_str = ( - '| Sell Reason | Sells | Wins | Draws | Losses |' + '| Sell Reason | Sells | Wins | Draws | Losses |' ' Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % |\n' - '|:--------------|--------:|-------:|--------:|---------:|' - '---------------:|---------------:|-----------------:|---------------:|\n' - '| roi | 2 | 2 | 0 | 0 |' + '|---------------+---------+--------+---------+----------+' + '----------------+----------------+------------------+----------------|\n' + '| roi | 2 | 2 | 0 | 0 |' ' 15 | 30 | 0.6 | 15 |\n' - '| stop_loss | 1 | 0 | 0 | 1 |' + '| stop_loss | 1 | 0 | 0 | 1 |' ' -10 | -10 | -0.2 | -5 |' ) assert generate_text_table_sell_reason( @@ -95,14 +95,14 @@ def test_generate_text_table_strategy(default_conf, mocker): ) result_str = ( - '| Strategy | Buys | Avg Profit % | Cum Profit % | Tot' - ' Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' - '|:--------------|-------:|---------------:|---------------:|------' - '-----------:|---------------:|:---------------|-------:|--------:|---------:|\n' - '| TestStrategy1 | 3 | 20.00 | 60.00 | ' - ' 1.10000000 | 30.00 | 0:17:00 | 3 | 0 | 0 |\n' - '| TestStrategy2 | 3 | 30.00 | 90.00 | ' - ' 1.30000000 | 45.00 | 0:20:00 | 3 | 0 | 0 |' + '| Strategy | Buys | Avg Profit % | Cum Profit % | Tot' + ' Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |\n' + '|---------------+--------+----------------+----------------+------------------+' + '----------------+----------------+--------+---------+----------|\n' + '| TestStrategy1 | 3 | 20.00 | 60.00 | 1.10000000 |' + ' 30.00 | 0:17:00 | 3 | 0 | 0 |\n' + '| TestStrategy2 | 3 | 30.00 | 90.00 | 1.30000000 |' + ' 45.00 | 0:20:00 | 3 | 0 | 0 |' ) assert generate_text_table_strategy('BTC', 2, all_results=results) == result_str @@ -111,8 +111,7 @@ def test_generate_edge_table(edge_conf, mocker): results = {} results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60) - - assert generate_edge_table(results).count(':|') == 7 + assert generate_edge_table(results).count('+') == 7 assert generate_edge_table(results).count('| ETH/BTC |') == 1 assert generate_edge_table(results).count( '| Risk Reward Ratio | Required Risk Reward | Expectancy |') == 1 From e5a9c81412b4a6846872fde59489203184244288 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Feb 2020 14:04:12 +0100 Subject: [PATCH 0642/1106] Add 0 entry to enhanced ROI example --- docs/strategy-customization.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index fd40a971e..4aacd3af6 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -257,11 +257,12 @@ from freqtrade.exchange import timeframe_to_minutes class AwesomeStrategy(IStrategy): - ticker_interval = '1d' + ticker_interval = "1d" ticker_interval_mins = timeframe_to_minutes(ticker_interval) minimal_roi = { - str(ticker_interval_mins * 3)): 0.02, # After 3 candles - str(ticker_interval_mins * 6)): 0.01, # After 6 candles + "0": 0.05, # 5% for the first 3 candles + str(ticker_interval_mins * 3)): 0.02, # 2% after 3 candles + str(ticker_interval_mins * 6)): 0.01, # 1% After 6 candles } ``` From 15e59654d9121bbbe8a1a20f4d1e0529906cc18d Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 27 Feb 2020 16:10:45 +0100 Subject: [PATCH 0643/1106] Minor change to standardize table style. This PR will target commands. --- freqtrade/commands/list_commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 49674b81a..327901dc0 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -58,7 +58,7 @@ def _print_objs_tabular(objs: List, print_colorized: bool) -> None: else yellow + "DUPLICATE NAME" + reset) } for s in objs] - print(tabulate(objss_to_print, headers='keys', tablefmt='pipe')) + print(tabulate(objss_to_print, headers='keys', tablefmt='psql', stralign='right')) def start_list_strategies(args: Dict[str, Any]) -> None: @@ -192,7 +192,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: else: # print data as a table, with the human-readable summary print(f"{summary_str}:") - print(tabulate(tabular_data, headers='keys', tablefmt='pipe')) + print(tabulate(tabular_data, headers='keys', tablefmt='psql', stralign='right')) elif not (args.get('print_one_column', False) or args.get('list_pairs_print_json', False) or args.get('print_csv', False)): From 5a02026f82decd18789f78440e4a71b51e24ff89 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Feb 2020 19:35:58 +0100 Subject: [PATCH 0644/1106] Add test validating behaviour --- tests/test_configuration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index a58e88ea0..1e9d6440d 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -319,6 +319,7 @@ def test_load_dry_run(default_conf, mocker, config_value, expected, arglist) -> validated_conf = configuration.load_config() assert validated_conf['dry_run'] is expected + assert validated_conf['runmode'] == (RunMode.DRY_RUN if expected else RunMode.LIVE) def test_load_custom_strategy(default_conf, mocker) -> None: From a55964a6221c1806ba195bf7be1dfe4167fd15f2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 27 Feb 2020 19:36:54 +0100 Subject: [PATCH 0645/1106] we Must parse --dry-run before setting run-mode --- freqtrade/configuration/configuration.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 035b091b3..6a0441957 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -167,10 +167,6 @@ class Configuration: if 'sd_notify' in self.args and self.args["sd_notify"]: config['internals'].update({'sd_notify': True}) - self._args_to_config(config, argname='dry_run', - logstring='Parameter --dry-run detected, ' - 'overriding dry_run to: {} ...') - def _process_datadir_options(self, config: Dict[str, Any]) -> None: """ Extract information for sys.argv and load directory configurations @@ -376,6 +372,10 @@ class Configuration: def _process_runmode(self, config: Dict[str, Any]) -> None: + self._args_to_config(config, argname='dry_run', + logstring='Parameter --dry-run detected, ' + 'overriding dry_run to: {} ...') + if not self.runmode: # Handle real mode, infer dry/live from config self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE From e411717de9397afe29b58c62a7aca5c3aa6f8f65 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 28 Feb 2020 12:36:39 +0300 Subject: [PATCH 0646/1106] No percent where ratio is to be used --- freqtrade/edge/edge_positioning.py | 12 ++++++------ freqtrade/freqtradebot.py | 12 ++++++------ freqtrade/persistence.py | 4 ++-- freqtrade/rpc/rpc.py | 20 ++++++++++---------- freqtrade/rpc/telegram.py | 2 +- freqtrade/strategy/interface.py | 7 ++++--- tests/edge/test_edge.py | 2 +- tests/rpc/test_rpc_telegram.py | 12 ++++++------ tests/test_freqtradebot.py | 8 ++++---- 9 files changed, 40 insertions(+), 39 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index ee5c3e95d..57a8f4a7c 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -246,7 +246,8 @@ class Edge: # we set stake amount to an arbitrary amount. # as it doesn't change the calculation. - # all returned values are relative. they are percentages. + # all returned values are relative. + # they are defined as ratios. stake = 0.015 fee = self.fee open_fee = fee / 2 @@ -269,8 +270,8 @@ class Edge: result['sell_fee'] = result['sell_sum'] * close_fee result['sell_take'] = result['sell_sum'] - result['sell_fee'] - # profit_percent - result['profit_percent'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend'] + # profit_ratio + result['profit_ratio'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend'] # Absolute profit result['profit_abs'] = result['sell_take'] - result['buy_spend'] @@ -399,9 +400,8 @@ class Edge: # trade opens in reality on the next candle open_trade_index += 1 - stop_price_percentage = stoploss + 1 open_price = ohlc_columns[open_trade_index, 0] - stop_price = (open_price * stop_price_percentage) + stop_price = (open_price * (stoploss + 1)) # Searching for the index where stoploss is hit stop_index = utf1st.find_1st( @@ -441,7 +441,7 @@ class Edge: trade = {'pair': pair, 'stoploss': stoploss, - 'profit_percent': '', + 'profit_ratio': '', 'profit_abs': '', 'open_time': date_column[open_trade_index], 'close_time': date_column[exit_index], diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index dffec940c..f50244dac 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1034,8 +1034,8 @@ class FreqtradeBot: profit_trade = trade.calc_profit(rate=profit_rate) # Use cached ticker here - it was updated seconds ago. current_rate = self.get_sell_rate(trade.pair, False) - profit_percent = trade.calc_profit_ratio(profit_rate) - gain = "profit" if profit_percent > 0 else "loss" + profit_ratio = trade.calc_profit_ratio(profit_rate) + gain = "profit" if profit_ratio > 0 else "loss" msg = { 'type': RPCMessageType.SELL_NOTIFICATION, @@ -1048,7 +1048,7 @@ class FreqtradeBot: 'open_rate': trade.open_rate, 'current_rate': current_rate, 'profit_amount': profit_trade, - 'profit_percent': profit_percent, + 'profit_ratio': profit_ratio, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, 'close_date': trade.close_date or datetime.utcnow(), @@ -1071,8 +1071,8 @@ class FreqtradeBot: profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) current_rate = self.get_sell_rate(trade.pair, False) - profit_percent = trade.calc_profit_ratio(profit_rate) - gain = "profit" if profit_percent > 0 else "loss" + profit_ratio = trade.calc_profit_ratio(profit_rate) + gain = "profit" if profit_ratio > 0 else "loss" msg = { 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, @@ -1085,7 +1085,7 @@ class FreqtradeBot: 'open_rate': trade.open_rate, 'current_rate': current_rate, 'profit_amount': profit_trade, - 'profit_percent': profit_percent, + 'profit_ratio': profit_ratio, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, 'close_date': trade.close_date, diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index fa041abc3..ac084d12e 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -405,8 +405,8 @@ class Trade(_DECL_BASE): rate=(rate or self.close_rate), fee=(fee or self.fee_close) ) - profit_percent = (close_trade_price / self.open_trade_price) - 1 - return float(f"{profit_percent:.8f}") + profit_ratio = (close_trade_price / self.open_trade_price) - 1 + return float(f"{profit_ratio:.8f}") @staticmethod def get_trades(trade_filter=None) -> Query: diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 1e4eaa3e0..9014c1874 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -155,9 +155,9 @@ class RPC: current_rate = self._freqtrade.get_sell_rate(trade.pair, False) except DependencyException: current_rate = NAN - trade_perc = (100 * trade.calc_profit_ratio(current_rate)) + trade_percent = (100 * trade.calc_profit_ratio(current_rate)) trade_profit = trade.calc_profit(current_rate) - profit_str = f'{trade_perc:.2f}%' + profit_str = f'{trade_percent:.2f}%' if self._fiat_converter: fiat_profit = self._fiat_converter.convert_amount( trade_profit, @@ -232,9 +232,9 @@ class RPC: trades = Trade.get_trades().order_by(Trade.id).all() profit_all_coin = [] - profit_all_perc = [] + profit_all_ratio = [] profit_closed_coin = [] - profit_closed_perc = [] + profit_closed_ratio = [] durations = [] for trade in trades: @@ -246,21 +246,21 @@ class RPC: durations.append((trade.close_date - trade.open_date).total_seconds()) if not trade.is_open: - profit_percent = trade.calc_profit_ratio() + profit_ratio = trade.calc_profit_ratio() profit_closed_coin.append(trade.calc_profit()) - profit_closed_perc.append(profit_percent) + profit_closed_ratio.append(profit_ratio) else: # Get current rate try: current_rate = self._freqtrade.get_sell_rate(trade.pair, False) except DependencyException: current_rate = NAN - profit_percent = trade.calc_profit_ratio(rate=current_rate) + profit_ratio = trade.calc_profit_ratio(rate=current_rate) profit_all_coin.append( trade.calc_profit(rate=trade.close_rate or current_rate) ) - profit_all_perc.append(profit_percent) + profit_all_ratio.append(profit_ratio) best_pair = Trade.get_best_pair() @@ -271,7 +271,7 @@ class RPC: # Prepare data to display profit_closed_coin_sum = round(sum(profit_closed_coin), 8) - profit_closed_percent = (round(mean(profit_closed_perc) * 100, 2) if profit_closed_perc + profit_closed_percent = (round(mean(profit_closed_ratio) * 100, 2) if profit_closed_ratio else 0.0) profit_closed_fiat = self._fiat_converter.convert_amount( profit_closed_coin_sum, @@ -280,7 +280,7 @@ class RPC: ) if self._fiat_converter else 0 profit_all_coin_sum = round(sum(profit_all_coin), 8) - profit_all_percent = round(mean(profit_all_perc) * 100, 2) if profit_all_perc else 0.0 + profit_all_percent = round(mean(profit_all_ratio) * 100, 2) if profit_all_ratio else 0.0 profit_all_fiat = self._fiat_converter.convert_amount( profit_all_coin_sum, stake_currency, diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index e3958b31a..ad01700ab 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -148,7 +148,7 @@ class Telegram(RPC): elif msg['type'] == RPCMessageType.SELL_NOTIFICATION: msg['amount'] = round(msg['amount'], 8) - msg['profit_percent'] = round(msg['profit_percent'] * 100, 2) + msg['profit_percent'] = round(msg['profit_ratio'] * 100, 2) msg['duration'] = msg['close_date'].replace( microsecond=0) - msg['open_date'].replace(microsecond=0) msg['duration_min'] = msg['duration'].total_seconds() / 60 diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index ae3dbd307..d23af3f6e 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -364,7 +364,7 @@ class IStrategy(ABC): """ Based on current profit of the trade and configured (trailing) stoploss, decides to sell or not - :param current_profit: current profit in percent + :param current_profit: current profit as ratio """ stop_loss_value = force_stoploss if force_stoploss else self.stoploss @@ -427,8 +427,9 @@ class IStrategy(ABC): def min_roi_reached(self, trade: Trade, current_profit: float, current_time: datetime) -> bool: """ - Based on trade duration, current price and ROI configuration, decides whether bot should - sell. Requires current_profit to be in percent!! + Based on trade duration, current profit of the trade and ROI configuration, + decides whether bot should sell. + :param current_profit: current profit as ratio :return: True if bot should sell at current rate """ # Check if time matches and current rate is above threshold diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index 6b86d9c1f..2a0d19128 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -158,7 +158,7 @@ def test_edge_results(edge_conf, mocker, caplog, data) -> None: assert len(trades) == len(data.trades) if not results.empty: - assert round(results["profit_percent"].sum(), 3) == round(data.profit_perc, 3) + assert round(results["profit_ratio"].sum(), 3) == round(data.profit_perc, 3) for c, trade in enumerate(data.trades): res = results.iloc[c] diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index a8b8e0c5a..1ac03f812 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -726,7 +726,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee, 'open_rate': 1.099e-05, 'current_rate': 1.172e-05, 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'profit_ratio': 0.0611052, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, @@ -785,7 +785,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, 'open_rate': 1.099e-05, 'current_rate': 1.044e-05, 'profit_amount': -5.492e-05, - 'profit_percent': -0.05478342, + 'profit_ratio': -0.05478342, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, @@ -833,7 +833,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None 'open_rate': 1.099e-05, 'current_rate': 1.098e-05, 'profit_amount': -5.91e-06, - 'profit_percent': -0.00589291, + 'profit_ratio': -0.00589291, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value, @@ -1253,7 +1253,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'open_rate': 7.5e-05, 'current_rate': 3.201e-05, 'profit_amount': -0.05746268, - 'profit_percent': -0.57405275, + 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, @@ -1282,7 +1282,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'open_rate': 7.5e-05, 'current_rate': 3.201e-05, 'profit_amount': -0.05746268, - 'profit_percent': -0.57405275, + 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', 'sell_reason': SellType.STOP_LOSS.value, 'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30), @@ -1448,7 +1448,7 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None: 'open_rate': 7.5e-05, 'current_rate': 3.201e-05, 'profit_amount': -0.05746268, - 'profit_percent': -0.57405275, + 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 852b6b990..61f69bd85 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2297,7 +2297,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N 'open_rate': 1.099e-05, 'current_rate': 1.172e-05, 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'profit_ratio': 0.0611052, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.ROI.value, @@ -2346,7 +2346,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) 'open_rate': 1.099e-05, 'current_rate': 1.044e-05, 'profit_amount': -5.492e-05, - 'profit_percent': -0.05478342, + 'profit_ratio': -0.05478342, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, @@ -2402,7 +2402,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe 'open_rate': 1.099e-05, 'current_rate': 1.044e-05, 'profit_amount': -1.498e-05, - 'profit_percent': -0.01493766, + 'profit_ratio': -0.01493766, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.STOP_LOSS.value, @@ -2602,7 +2602,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee, 'open_rate': 1.099e-05, 'current_rate': 1.172e-05, 'profit_amount': 6.126e-05, - 'profit_percent': 0.0611052, + 'profit_ratio': 0.0611052, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.ROI.value, From bee8e92f0287aec18b77e936a5a5d1771aa869a0 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 28 Feb 2020 23:50:25 +0300 Subject: [PATCH 0647/1106] Final changes, use sqrt i.o. statistics.pstdev --- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 0f81ffca5..16dc26142 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -5,7 +5,6 @@ This module defines the alternative HyperOptLoss class which can be used for Hyperoptimization. """ import math -import statistics from datetime import datetime from pandas import DataFrame, date_range @@ -56,7 +55,9 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): sum_daily['downside_returns'] = 0 sum_daily.loc[total_profit < 0, 'downside_returns'] = total_profit total_downside = sum_daily['downside_returns'] - down_stdev = statistics.pstdev(total_downside, 0) + # Here total_downside contains min(0, P - MAR) values, + # where P = sum_daily["profit_percent_after_slippage"] + down_stdev = math.sqrt((total_downside**2).sum() / len(total_downside)) if (down_stdev != 0.): sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year) From 349aa2f9574d04f7f20c9c04e6008767129a17e5 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Fri, 28 Feb 2020 21:54:04 +0100 Subject: [PATCH 0648/1106] Added dynamic print table function to hyperopt --- freqtrade/commands/hyperopt_commands.py | 2 +- freqtrade/optimize/hyperopt.py | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index ccaa59e54..72e5bf12f 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -51,7 +51,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: try: Hyperopt.print_result_table(config, trials, total_epochs, - not filteroptions['only_best'], print_colorized) + not filteroptions['only_best'], print_colorized, 0) except KeyboardInterrupt: print('User interrupted..') diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 66ea18bd1..84cd078a0 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -116,6 +116,7 @@ class Hyperopt: self.config['ask_strategy']['use_sell_signal'] = True self.print_all = self.config.get('print_all', False) + self.hyperopt_table_header = 0 self.print_colorized = self.config.get('print_colorized', False) self.print_json = self.config.get('print_json', False) @@ -272,8 +273,13 @@ class Hyperopt: if not self.print_all: # Separate the results explanation string from dots print("\n") - self.print_results_explanation(results, self.total_epochs, self.print_all, - self.print_colorized) + self.print_result_table(self.config, results, self.total_epochs, + self.print_all, self.print_colorized, + self.hyperopt_table_header) + if is_best: + self.hyperopt_table_header = 2 + else: + self.hyperopt_table_header = 3 @staticmethod def print_results_explanation(results, total_epochs, highlight_best: bool, @@ -299,7 +305,7 @@ class Hyperopt: @staticmethod def print_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool, - print_colorized: bool) -> None: + print_colorized: bool, remove_header: int) -> None: """ Log result table """ @@ -328,7 +334,7 @@ class Hyperopt: trials['Profit'] = trials['Profit'].apply( lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) trials['Total profit'] = trials['Total profit'].apply( - lambda x: '{: 11.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) + lambda x: '{:,.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) trials['Avg duration'] = trials['Avg duration'].apply( lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) if print_colorized: @@ -343,9 +349,11 @@ class Hyperopt: str(trials.loc[i][z]), Style.RESET_ALL) trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) - - print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql', - stralign="right")) + table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', + headers='keys', stralign="right") + if remove_header > 0: + table = table.split("\n", remove_header)[remove_header] + print(table) def has_space(self, space: str) -> bool: """ From 5277d71913566088747c6499740bcdc68ac51f27 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 14:56:04 +0100 Subject: [PATCH 0649/1106] Add test for empty stake-currency --- tests/exchange/test_exchange.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 179566bb0..6bec53d49 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -511,6 +511,22 @@ def test_validate_pairs_stakecompatibility(default_conf, mocker, caplog): Exchange(default_conf) +def test_validate_pairs_stakecompatibility_downloaddata(default_conf, mocker, caplog): + api_mock = MagicMock() + default_conf['stake_currency'] = '' + type(api_mock).markets = PropertyMock(return_value={ + 'ETH/BTC': {'quote': 'BTC'}, 'LTC/BTC': {'quote': 'BTC'}, + 'XRP/BTC': {'quote': 'BTC'}, 'NEO/BTC': {'quote': 'BTC'}, + 'HELLO-WORLD': {'quote': 'BTC'}, + }) + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange.validate_timeframes') + mocker.patch('freqtrade.exchange.Exchange._load_async_markets') + mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') + + Exchange(default_conf) + + def test_validate_pairs_stakecompatibility_fail(default_conf, mocker, caplog): default_conf['exchange']['pair_whitelist'].append('HELLO-WORLD') api_mock = MagicMock() From 60579485e52dd36d1bc20344766baf9850510b57 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 14:56:36 +0100 Subject: [PATCH 0650/1106] fix empty stake currency problem --- freqtrade/exchange/exchange.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 799ee2c37..f6b722c9a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -332,7 +332,8 @@ class Exchange: logger.warning(f"Pair {pair} is restricted for some users on this exchange." f"Please check if you are impacted by this restriction " f"on the exchange and eventually remove {pair} from your whitelist.") - if not self.get_pair_quote_currency(pair) == self._config['stake_currency']: + if (self._config['stake_currency'] and + not self.get_pair_quote_currency(pair) == self._config['stake_currency']): invalid_pairs.append(pair) if invalid_pairs: raise OperationalException( From 9336d8ee02d63e56513fe0a76c5bbef00aab9390 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 15:44:45 +0100 Subject: [PATCH 0651/1106] Try fix random testfailure --- tests/commands/test_commands.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 5f9bc0aa2..1877aaa43 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -447,11 +447,9 @@ def test_create_datadir_failed(caplog): def test_create_datadir(caplog, mocker): - # Ensure that caplog is empty before starting ... - # Should prevent random failures. - caplog.clear() - # Added assert here to analyze random test-failures ... - assert len(caplog.record_tuples) == 0 + + # Capture caplog length here trying to avoid random test failure + len_caplog_before = len(caplog.record_tuples) cud = mocker.patch("freqtrade.commands.deploy_commands.create_userdata_dir", MagicMock()) csf = mocker.patch("freqtrade.commands.deploy_commands.copy_sample_files", MagicMock()) @@ -464,7 +462,7 @@ def test_create_datadir(caplog, mocker): assert cud.call_count == 1 assert csf.call_count == 1 - assert len(caplog.record_tuples) == 0 + assert len(caplog.record_tuples) == len_caplog_before def test_start_new_strategy(mocker, caplog): From f25adf3b12096fab33dbcb098a8d679067334a17 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 15:48:36 +0100 Subject: [PATCH 0652/1106] improve and correct release documentation --- docs/developer.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/developer.md b/docs/developer.md index b128ffd2b..ef9232a59 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -234,7 +234,7 @@ git checkout -b new_release Determine if crucial bugfixes have been made between this commit and the current state, and eventually cherry-pick these. -* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7-1` should we need to do a second release that month. +* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi. * Commit this part * push that branch to the remote and create a PR against the master branch @@ -268,11 +268,6 @@ Once the PR against master is merged (best right after merging): * Use "master" as reference (this step comes after the above PR is merged). * Use the above changelog as release comment (as codeblock) -### After-release - -* Update version in develop by postfixing that with `-dev` (`2019.6 -> 2019.6-dev`). -* Create a PR against develop to update that branch. - ## Releases ### pypi From 848054d140243a18e2dfa8eb70077e6be15a4f94 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 15:53:54 +0100 Subject: [PATCH 0653/1106] Fix jupyter notebook example - generate_candlestick_graph() needs a filtered pairlist, not a list containing all pairs --- docs/strategy_analysis_example.md | 6 ++++-- freqtrade/templates/strategy_analysis_example.ipynb | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/strategy_analysis_example.md b/docs/strategy_analysis_example.md index 53b35ca09..d26d684ce 100644 --- a/docs/strategy_analysis_example.md +++ b/docs/strategy_analysis_example.md @@ -121,7 +121,6 @@ from freqtrade.data.btanalysis import analyze_trade_parallelism # Analyze the above parallel_trades = analyze_trade_parallelism(trades, '5m') - parallel_trades.plot() ``` @@ -134,11 +133,14 @@ Freqtrade offers interactive plotting capabilities based on plotly. from freqtrade.plot.plotting import generate_candlestick_graph # Limit graph period to keep plotly quick and reactive +# Filter trades to one pair +trades_red = trades.loc[trades['pair'] == pair] + data_red = data['2019-06-01':'2019-06-10'] # Generate candlestick graph graph = generate_candlestick_graph(pair=pair, data=data_red, - trades=trades, + trades=trades_red, indicators1=['sma20', 'ema50', 'ema55'], indicators2=['rsi', 'macd', 'macdsignal', 'macdhist'] ) diff --git a/freqtrade/templates/strategy_analysis_example.ipynb b/freqtrade/templates/strategy_analysis_example.ipynb index 399235cfe..dffa308ce 100644 --- a/freqtrade/templates/strategy_analysis_example.ipynb +++ b/freqtrade/templates/strategy_analysis_example.ipynb @@ -190,7 +190,6 @@ "# Analyze the above\n", "parallel_trades = analyze_trade_parallelism(trades, '5m')\n", "\n", - "\n", "parallel_trades.plot()" ] }, @@ -212,11 +211,14 @@ "from freqtrade.plot.plotting import generate_candlestick_graph\n", "# Limit graph period to keep plotly quick and reactive\n", "\n", + "# Filter trades to one pair\n", + "trades_red = trades.loc[trades['pair'] == pair]\n", + "\n", "data_red = data['2019-06-01':'2019-06-10']\n", "# Generate candlestick graph\n", "graph = generate_candlestick_graph(pair=pair,\n", " data=data_red,\n", - " trades=trades,\n", + " trades=trades_red,\n", " indicators1=['sma20', 'ema50', 'ema55'],\n", " indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']\n", " )\n", From 4c39f360844a5db0352914e190a7a933489adb4d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 16:36:33 +0100 Subject: [PATCH 0654/1106] Add note about InvalidNonce to documentation --- docs/exchanges.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/exchanges.md b/docs/exchanges.md index f615bc61a..70dae0aa5 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -62,6 +62,11 @@ res = [ f"{x['MarketCurrency']}/{x['BaseCurrency']}" for x in ct.publicGetMarket print(res) ``` +## All exchanges + +Should you experience constant errors with Nonce (like `InvalidNonce`), it is best to regenerate the API keys. Resetting Nonce is difficult and it's usually easier to regenerate the API keys. + + ## Random notes for other exchanges * The Ocean (exchange id: `theocean`) exchange uses Web3 functionality and requires `web3` python package to be installed: From d7373be55344f80883203fa493f766d542911882 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 16:58:22 +0100 Subject: [PATCH 0655/1106] Add official support for Kraken --- README.md | 3 ++- docs/configuration.md | 5 ++++- freqtrade/exchange/exchange.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 59799da84..88070d45e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ hesitate to read the source code and understand the mechanism of this bot. ## Exchange marketplaces supported - [X] [Bittrex](https://bittrex.com/) -- [X] [Binance](https://www.binance.com/) ([*Note for binance users](#a-note-on-binance)) +- [X] [Binance](https://www.binance.com/) ([*Note for binance users](docs/exchanges.md#blacklists)) +- [X] [Kraken](https://kraken.com/) - [ ] [113 others to tests](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_ ## Documentation diff --git a/docs/configuration.md b/docs/configuration.md index b05dab7c9..95af2c049 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -371,15 +371,18 @@ The possible values are: `gtc` (default), `fok` or `ioc`. Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports over 100 cryptocurrency exchange markets and trading APIs. The complete up-to-date list can be found in the [CCXT repo homepage](https://github.com/ccxt/ccxt/tree/master/python). However, the bot was tested -with only Bittrex and Binance. +with only Bittrex, Binance and Kraken. The bot was tested with the following exchanges: - [Bittrex](https://bittrex.com/): "bittrex" - [Binance](https://www.binance.com/): "binance" +- [Kraken](https://kraken.com/): "kraken" Feel free to test other exchanges and submit your PR to improve the bot. +Some exchanges require special configuration, which can be found on the [Exchange-specific Notes](exchanges.md) documentation page. + #### Sample exchange configuration A exchange configuration for "binance" would look as follows: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 799ee2c37..4f03bde80 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1023,7 +1023,7 @@ def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = Non def is_exchange_officially_supported(exchange_name: str) -> bool: - return exchange_name in ['bittrex', 'binance'] + return exchange_name in ['bittrex', 'binance', 'kraken'] def ccxt_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: From 18d724f7a18994ba4bf50b605218f9ee76e5750a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 19:22:36 +0100 Subject: [PATCH 0656/1106] Adjust wording of supported exchanges --- docs/configuration.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 95af2c049..b3f032bc6 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -370,10 +370,9 @@ The possible values are: `gtc` (default), `fok` or `ioc`. Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports over 100 cryptocurrency exchange markets and trading APIs. The complete up-to-date list can be found in the -[CCXT repo homepage](https://github.com/ccxt/ccxt/tree/master/python). However, the bot was tested -with only Bittrex, Binance and Kraken. - -The bot was tested with the following exchanges: +[CCXT repo homepage](https://github.com/ccxt/ccxt/tree/master/python). + However, the bot was tested by the development team with only Bittrex, Binance and Kraken, + so the these are the only officially supported exhanges: - [Bittrex](https://bittrex.com/): "bittrex" - [Binance](https://www.binance.com/): "binance" From 60f04cff4de955361b310295b702150e256b8789 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 29 Feb 2020 20:41:03 +0100 Subject: [PATCH 0657/1106] Simplify expression --- freqtrade/exchange/exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f6b722c9a..d1397a282 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -333,7 +333,7 @@ class Exchange: f"Please check if you are impacted by this restriction " f"on the exchange and eventually remove {pair} from your whitelist.") if (self._config['stake_currency'] and - not self.get_pair_quote_currency(pair) == self._config['stake_currency']): + self.get_pair_quote_currency(pair) != self._config['stake_currency']): invalid_pairs.append(pair) if invalid_pairs: raise OperationalException( From 23ae0653bd6a92ccdfc0a513dde1fa7f120ceb49 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 29 Feb 2020 23:24:08 +0100 Subject: [PATCH 0658/1106] Changed table output to match hyperopt-list command --- freqtrade/optimize/hyperopt.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 84cd078a0..700614453 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -276,10 +276,7 @@ class Hyperopt: self.print_result_table(self.config, results, self.total_epochs, self.print_all, self.print_colorized, self.hyperopt_table_header) - if is_best: - self.hyperopt_table_header = 2 - else: - self.hyperopt_table_header = 3 + self.hyperopt_table_header = 2 @staticmethod def print_results_explanation(results, total_epochs, highlight_best: bool, @@ -349,10 +346,17 @@ class Hyperopt: str(trials.loc[i][z]), Style.RESET_ALL) trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) - table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', - headers='keys', stralign="right") if remove_header > 0: + table = tabulate(trials.to_dict(orient='list'), tablefmt='orgtbl', + headers='keys', stralign="right") table = table.split("\n", remove_header)[remove_header] + elif remove_header < 0: + table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', + headers='keys', stralign="right") + table = "\n".join(table.split("\n")[0:remove_header]) + else: + table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', + headers='keys', stralign="right") print(table) def has_space(self, space: str) -> bool: @@ -541,7 +545,7 @@ class Hyperopt: def start(self) -> None: self.random_state = self._set_random_state(self.config.get('hyperopt_random_state', None)) logger.info(f"Using optimizer random state: {self.random_state}") - + self.hyperopt_table_header = -1 data, timerange = self.backtesting.load_bt_data() preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data) From 7a4edb1cd8f0c397bd16b19bcb67c4e0b7f40fd9 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 29 Feb 2020 23:41:59 +0100 Subject: [PATCH 0659/1106] Fix: When total epochs is less than cpu cores --- freqtrade/optimize/hyperopt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 66ea18bd1..ee3f4d2c4 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -557,6 +557,8 @@ class Hyperopt: cpus = cpu_count() logger.info(f"Found {cpus} CPU cores. Let's make them scream!") config_jobs = self.config.get('hyperopt_jobs', -1) + if self.total_epochs < cpus: + config_jobs = self.total_epochs logger.info(f'Number of parallel jobs set as: {config_jobs}') self.dimensions: List[Dimension] = self.hyperopt_space() From e89fd33229e0b8c6e9ebbd8e49920205fcf0a81c Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 29 Feb 2020 23:57:15 +0100 Subject: [PATCH 0660/1106] Fix for more arguments --- 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 ee3f4d2c4..6b334507a 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -557,7 +557,7 @@ class Hyperopt: cpus = cpu_count() logger.info(f"Found {cpus} CPU cores. Let's make them scream!") config_jobs = self.config.get('hyperopt_jobs', -1) - if self.total_epochs < cpus: + if self.total_epochs < cpus and (config_jobs > self.total_epochs or config_jobs < 0): config_jobs = self.total_epochs logger.info(f'Number of parallel jobs set as: {config_jobs}') From 267416ecedf34c4019cac403fe18f808c38a2b06 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 1 Mar 2020 03:11:00 +0100 Subject: [PATCH 0661/1106] Changed test for new table printing --- tests/optimize/test_hyperopt.py | 129 +++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index e3212e0cd..0fa5b9536 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -390,17 +390,30 @@ def test_onlyprofit_loss_prefers_higher_profits(default_conf, hyperopt_results) def test_log_results_if_loss_improves(hyperopt, capsys) -> None: hyperopt.current_best_loss = 2 hyperopt.total_epochs = 2 + hyperopt.print_results( { - 'is_best': True, 'loss': 1, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + }, + 'total_profit': 0, 'current_epoch': 2, # This starts from 1 (in a human-friendly manner) - 'results_explanation': 'foo.', - 'is_initial_point': False + 'is_initial_point': False, + 'is_best': True } ) out, err = capsys.readouterr() - assert ' 2/2: foo. Objective: 1.00000' in out + result_str = ( + '| Best | 2/2 | 1 | 0.10% | 0.00100000 BTC |' + ' 1.00% | 20.0m | 1 |' + ) + assert result_str in out def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: @@ -467,7 +480,16 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None: parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', - 'params': {'buy': {}, 'sell': {}, 'roi': {}, 'stoploss': 0.0}}]) + 'params': {'buy': {}, 'sell': {}, 'roi': {}, 'stoploss': 0.0}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + }, + }]) ) patch_exchange(mocker) # Co-test loading ticker-interval from strategy @@ -761,11 +783,23 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None: parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', 'params': {}, - 'params_details': {'buy': {'mfi-value': None}, - 'sell': {'sell-mfi-value': None}, - 'roi': {}, 'stoploss': {'stoploss': None}, - 'trailing': {'trailing_stop': None}}}]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', 'params': {}, + 'params_details': { + 'buy': {'mfi-value': None}, + 'sell': {'sell-mfi-value': None}, + 'roi': {}, 'stoploss': {'stoploss': None}, + 'trailing': {'trailing_stop': None} + }, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) @@ -787,7 +821,11 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None: parallel.assert_called_once() out, err = capsys.readouterr() - assert '{"params":{"mfi-value":null,"sell-mfi-value":null},"minimal_roi":{},"stoploss":null,"trailing_stop":null}' in out # noqa: E501 + result_str = ( + '{"params":{"mfi-value":null,"sell-mfi-value":null},"minimal_roi"' + ':{},"stoploss":null,"trailing_stop":null}' + ) + assert result_str in out # noqa: E501 assert dumper.called # Should be called twice, once for tickerdata, once to save evaluations assert dumper.call_count == 2 @@ -804,10 +842,22 @@ def test_print_json_spaces_default(mocker, default_conf, caplog, capsys) -> None parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', 'params': {}, - 'params_details': {'buy': {'mfi-value': None}, - 'sell': {'sell-mfi-value': None}, - 'roi': {}, 'stoploss': {'stoploss': None}}}]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', 'params': {}, + 'params_details': { + 'buy': {'mfi-value': None}, + 'sell': {'sell-mfi-value': None}, + 'roi': {}, 'stoploss': {'stoploss': None} + }, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) @@ -846,8 +896,18 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) -> parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', 'params': {}, - 'params_details': {'roi': {}, 'stoploss': {'stoploss': None}}}]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', 'params': {}, + 'params_details': {'roi': {}, 'stoploss': {'stoploss': None}}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) @@ -887,7 +947,16 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys) parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', MagicMock(return_value=[{ - 'loss': 1, 'results_explanation': 'foo result', 'params': {'stoploss': 0.0}}]) + 'loss': 1, 'results_explanation': 'foo result', 'params': {'stoploss': 0.0}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) @@ -965,7 +1034,17 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None: parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', 'params': {}}]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', 'params': {}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) @@ -1012,7 +1091,17 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', 'params': {}}]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', 'params': {}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + } + }]) ) patch_exchange(mocker) From 379275e2d6446f8f5950a61b0b233933c851f632 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 1 Mar 2020 03:24:04 +0100 Subject: [PATCH 0662/1106] Updated tests --- tests/optimize/test_hyperopt.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 0fa5b9536..5bd9e542f 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -479,17 +479,18 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None: parallel = mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', - MagicMock(return_value=[{'loss': 1, 'results_explanation': 'foo result', - 'params': {'buy': {}, 'sell': {}, 'roi': {}, 'stoploss': 0.0}, - 'results_metrics': - { - 'trade_count': 1, - 'avg_profit': 0.1, - 'total_profit': 0.001, - 'profit': 1.0, - 'duration': 20.0 - }, - }]) + MagicMock(return_value=[{ + 'loss': 1, 'results_explanation': 'foo result', + 'params': {'buy': {}, 'sell': {}, 'roi': {}, 'stoploss': 0.0}, + 'results_metrics': + { + 'trade_count': 1, + 'avg_profit': 0.1, + 'total_profit': 0.001, + 'profit': 1.0, + 'duration': 20.0 + }, + }]) ) patch_exchange(mocker) # Co-test loading ticker-interval from strategy From eda77aeec8555bf5c27e1a574f63497773e4d38c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:30:30 +0100 Subject: [PATCH 0663/1106] Add render_template fallback --- freqtrade/misc.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 96bac28d8..9eb309e13 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -148,3 +148,15 @@ def render_template(templatefile: str, arguments: dict = {}) -> str: ) template = env.get_template(templatefile) return template.render(**arguments) + + +def render_template_with_fallback(templatefile: str, templatefallbackfile: str, + arguments: dict = {}) -> str: + """ + Use templatefile if possible, otherwise fall back to templatefallbackfile + """ + from jinja2.exceptions import TemplateNotFound + try: + return render_template(templatefile, arguments) + except TemplateNotFound: + return render_template(templatefallbackfile, arguments) From 7736f8d0180f8e4ae86aed14867131443be9557a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:34:42 +0100 Subject: [PATCH 0664/1106] Add tests for fallkback --- tests/test_misc.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 83e008466..23775c85e 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -9,7 +9,8 @@ import pytest from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, file_load_json, format_ms_time, pair_to_filename, - plural, shorten_date) + plural, render_template, + render_template_with_fallback, shorten_date) def test_shorten_date() -> None: @@ -123,3 +124,17 @@ def test_plural() -> None: assert plural(1.5, "ox", "oxen") == "oxen" assert plural(-0.5, "ox", "oxen") == "oxen" assert plural(-1.5, "ox", "oxen") == "oxen" + + +def test_render_template_fallback(mocker): + from jinja2.exceptions import TemplateNotFound + with pytest.raises(TemplateNotFound): + val = render_template( + templatefile='subtemplates/indicators_does-not-exist.j2',) + + val = render_template_with_fallback( + templatefile='subtemplates/indicators_does-not-exist.j2', + templatefallbackfile='subtemplates/indicators_minimal.j2', + ) + assert isinstance(val, str) + assert 'if self.dp' in val From 791148176c90ce493952268c6401052c2b6f32ba Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:35:53 +0100 Subject: [PATCH 0665/1106] Add callback functions to new-strategy --template advanced --- freqtrade/commands/cli_options.py | 6 +-- freqtrade/commands/deploy_commands.py | 53 ++++++++++++++----- freqtrade/templates/base_strategy.py.j2 | 1 + .../subtemplates/strategy_methods_advanced.j2 | 36 +++++++++++++ .../subtemplates/strategy_methods_empty.j2 | 0 5 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 freqtrade/templates/subtemplates/strategy_methods_advanced.j2 create mode 100644 freqtrade/templates/subtemplates/strategy_methods_empty.j2 diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index a8d4bc198..2c49d7487 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -379,9 +379,9 @@ AVAILABLE_CLI_OPTIONS = { # Templating options "template": Arg( '--template', - help='Use a template which is either `minimal` or ' - '`full` (containing multiple sample indicators). Default: `%(default)s`.', - choices=['full', 'minimal'], + help='Use a template which is either `minimal`, ' + '`full` (containing multiple sample indicators) or `advanced`. Default: `%(default)s`.', + choices=['full', 'minimal', 'advanced'], default='full', ), # Plot dataframe diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index f5a68f748..a29ba346f 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -8,7 +8,7 @@ from freqtrade.configuration.directory_operations import (copy_sample_files, create_userdata_dir) from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES from freqtrade.exceptions import OperationalException -from freqtrade.misc import render_template +from freqtrade.misc import render_template, render_template_with_fallback from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -32,10 +32,27 @@ def deploy_new_strategy(strategy_name: str, strategy_path: Path, subtemplate: st """ Deploy new strategy from template to strategy_path """ - indicators = render_template(templatefile=f"subtemplates/indicators_{subtemplate}.j2",) - buy_trend = render_template(templatefile=f"subtemplates/buy_trend_{subtemplate}.j2",) - sell_trend = render_template(templatefile=f"subtemplates/sell_trend_{subtemplate}.j2",) - plot_config = render_template(templatefile=f"subtemplates/plot_config_{subtemplate}.j2",) + fallback = 'full' + indicators = render_template_with_fallback( + templatefile=f"subtemplates/indicators_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/indicators_{fallback}.j2", + ) + buy_trend = render_template_with_fallback( + templatefile=f"subtemplates/buy_trend_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/buy_trend_{fallback}.j2", + ) + sell_trend = render_template_with_fallback( + templatefile=f"subtemplates/sell_trend_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/sell_trend_{fallback}.j2", + ) + plot_config = render_template_with_fallback( + templatefile=f"subtemplates/plot_config_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/plot_config_{fallback}.j2", + ) + additional_methods = render_template_with_fallback( + templatefile=f"subtemplates/strategy_methods_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/strategy_methods_empty.j2", + ) strategy_text = render_template(templatefile='base_strategy.py.j2', arguments={"strategy": strategy_name, @@ -43,6 +60,7 @@ def deploy_new_strategy(strategy_name: str, strategy_path: Path, subtemplate: st "buy_trend": buy_trend, "sell_trend": sell_trend, "plot_config": plot_config, + "additional_methods": additional_methods, }) logger.info(f"Writing strategy to `{strategy_path}`.") @@ -73,14 +91,23 @@ def deploy_new_hyperopt(hyperopt_name: str, hyperopt_path: Path, subtemplate: st """ Deploys a new hyperopt template to hyperopt_path """ - buy_guards = render_template( - templatefile=f"subtemplates/hyperopt_buy_guards_{subtemplate}.j2",) - sell_guards = render_template( - templatefile=f"subtemplates/hyperopt_sell_guards_{subtemplate}.j2",) - buy_space = render_template( - templatefile=f"subtemplates/hyperopt_buy_space_{subtemplate}.j2",) - sell_space = render_template( - templatefile=f"subtemplates/hyperopt_sell_space_{subtemplate}.j2",) + fallback = 'full' + buy_guards = render_template_with_fallback( + templatefile=f"subtemplates/hyperopt_buy_guards_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/hyperopt_buy_guards_{fallback}.j2", + ) + sell_guards = render_template_with_fallback( + templatefile=f"subtemplates/hyperopt_sell_guards_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/hyperopt_sell_guards_{fallback}.j2", + ) + buy_space = render_template_with_fallback( + templatefile=f"subtemplates/hyperopt_buy_space_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/hyperopt_buy_space_{fallback}.j2", + ) + sell_space = render_template_with_fallback( + templatefile=f"subtemplates/hyperopt_sell_space_{subtemplate}.j2", + templatefallbackfile=f"subtemplates/hyperopt_sell_space_{fallback}.j2", + ) strategy_text = render_template(templatefile='base_hyperopt.py.j2', arguments={"hyperopt": hyperopt_name, diff --git a/freqtrade/templates/base_strategy.py.j2 b/freqtrade/templates/base_strategy.py.j2 index fbf083387..a1b9f7388 100644 --- a/freqtrade/templates/base_strategy.py.j2 +++ b/freqtrade/templates/base_strategy.py.j2 @@ -137,3 +137,4 @@ class {{ strategy }}(IStrategy): ), 'sell'] = 1 return dataframe + {{ additional_methods | indent(4) }} diff --git a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 new file mode 100644 index 000000000..05541d1c7 --- /dev/null +++ b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 @@ -0,0 +1,36 @@ + +def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + """ + Check buy timeout function callback. + This method can be used to override the buy-timeout. + It is called whenever a limit buy order has been created, + and is not yet fully filled. + Configuration options in `unfilledtimeout` will be verified before this, + so ensure to set these timeouts high enough. + + When not implemented by a strategy, this simply returns False. + :param pair: Pair the trade is for + :param trade: trade object. + :param order: Order dictionary as returned from CCXT. + :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. + :return bool: When True is returned, then the buy-order is cancelled. + """ + return False + +def check_sell_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + """ + Check sell timeout function callback. + This method can be used to override the sell-timeout. + It is called whenever a limit sell order has been created, + and is not yet fully filled. + Configuration options in `unfilledtimeout` will be verified before this, + so ensure to set these timeouts high enough. + + When not implemented by a strategy, this simply returns False. + :param pair: Pair the trade is for + :param trade: trade object. + :param order: Order dictionary as returned from CCXT. + :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. + :return bool: When True is returned, then the sell-order is cancelled. + """ + return False diff --git a/freqtrade/templates/subtemplates/strategy_methods_empty.j2 b/freqtrade/templates/subtemplates/strategy_methods_empty.j2 new file mode 100644 index 000000000..e69de29bb From cd54875f03ab8fb2444503bf50ec9bd8837a42fe Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:40:07 +0100 Subject: [PATCH 0666/1106] Add documentation link to advanced functions --- .../templates/subtemplates/strategy_methods_advanced.j2 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 index 05541d1c7..20144125c 100644 --- a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 +++ b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 @@ -1,5 +1,5 @@ -def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: +def check_buy_timeout(self, pair: str, trade: 'Trade', order: Dict, **kwargs) -> bool: """ Check buy timeout function callback. This method can be used to override the buy-timeout. @@ -8,6 +8,8 @@ def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> b Configuration options in `unfilledtimeout` will be verified before this, so ensure to set these timeouts high enough. + For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/ + When not implemented by a strategy, this simply returns False. :param pair: Pair the trade is for :param trade: trade object. @@ -17,7 +19,7 @@ def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> b """ return False -def check_sell_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: +def check_sell_timeout(self, pair: str, trade: 'Trade', order: Dict, **kwargs) -> bool: """ Check sell timeout function callback. This method can be used to override the sell-timeout. @@ -26,6 +28,8 @@ def check_sell_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> Configuration options in `unfilledtimeout` will be verified before this, so ensure to set these timeouts high enough. + For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/ + When not implemented by a strategy, this simply returns False. :param pair: Pair the trade is for :param trade: trade object. From 4d8430c687de23be59b7914374f5d5c5f72b92c6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:43:20 +0100 Subject: [PATCH 0667/1106] Use string typehints to avoid import errors --- docs/strategy-advanced.md | 4 ++-- freqtrade/strategy/interface.py | 4 ++-- freqtrade/templates/subtemplates/strategy_methods_advanced.j2 | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 8d241cc86..dcb8018f9 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -33,7 +33,7 @@ class Awesomestrategy(IStrategy): 'sell': 60 * 25 } - def check_buy_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + def check_buy_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool: if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5): return True elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3): @@ -43,7 +43,7 @@ class Awesomestrategy(IStrategy): return False - def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: + def check_sell_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool: if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5): return True elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3): diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 95dbbb99f..a5945ae1f 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -149,7 +149,7 @@ class IStrategy(ABC): :return: DataFrame with sell column """ - def check_buy_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + def check_buy_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: """ Check buy timeout function callback. This method can be used to override the buy-timeout. @@ -167,7 +167,7 @@ class IStrategy(ABC): """ return False - def check_sell_timeout(self, pair: str, trade: Trade, order: Dict, **kwargs) -> bool: + def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool: """ Check sell timeout function callback. This method can be used to override the sell-timeout. diff --git a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 index 20144125c..0ca35e117 100644 --- a/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 +++ b/freqtrade/templates/subtemplates/strategy_methods_advanced.j2 @@ -1,5 +1,5 @@ -def check_buy_timeout(self, pair: str, trade: 'Trade', order: Dict, **kwargs) -> bool: +def check_buy_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool: """ Check buy timeout function callback. This method can be used to override the buy-timeout. @@ -19,7 +19,7 @@ def check_buy_timeout(self, pair: str, trade: 'Trade', order: Dict, **kwargs) -> """ return False -def check_sell_timeout(self, pair: str, trade: 'Trade', order: Dict, **kwargs) -> bool: +def check_sell_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool: """ Check sell timeout function callback. This method can be used to override the sell-timeout. From 0f2d77163455ed1c163a26bee03592a5c8f3a2d6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 1 Mar 2020 09:46:12 +0100 Subject: [PATCH 0668/1106] update docs --- docs/utils.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index cdf0c31af..78185be38 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -77,7 +77,7 @@ Results will be located in `user_data/strategies/.py`. ``` output usage: freqtrade new-strategy [-h] [--userdir PATH] [-s NAME] - [--template {full,minimal}] + [--template {full,minimal,advanced}] optional arguments: -h, --help show this help message and exit @@ -86,10 +86,10 @@ optional arguments: -s NAME, --strategy NAME Specify strategy class name which will be used by the bot. - --template {full,minimal} - Use a template which is either `minimal` or `full` - (containing multiple sample indicators). Default: - `full`. + --template {full,minimal,advanced} + Use a template which is either `minimal`, `full` + (containing multiple sample indicators) or `advanced`. + Default: `full`. ``` @@ -105,6 +105,12 @@ With custom user directory freqtrade new-strategy --userdir ~/.freqtrade/ --strategy AwesomeStrategy ``` +Using the advanced template (populates all optional functions and methods) + +```bash +freqtrade new-strategy --strategy AwesomeStrategy --template advanced +``` + ## Create new hyperopt Creates a new hyperopt from a template similar to SampleHyperopt. @@ -114,7 +120,7 @@ Results will be located in `user_data/hyperopts/.py`. ``` output usage: freqtrade new-hyperopt [-h] [--userdir PATH] [--hyperopt NAME] - [--template {full,minimal}] + [--template {full,minimal,advanced}] optional arguments: -h, --help show this help message and exit @@ -122,10 +128,10 @@ optional arguments: Path to userdata directory. --hyperopt NAME Specify hyperopt class name which will be used by the bot. - --template {full,minimal} - Use a template which is either `minimal` or `full` - (containing multiple sample indicators). Default: - `full`. + --template {full,minimal,advanced} + Use a template which is either `minimal`, `full` + (containing multiple sample indicators) or `advanced`. + Default: `full`. ``` ### Sample usage of new-hyperopt From 75b4f1a442e29084c4a93bda81419fe4223cd33d Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 1 Mar 2020 14:12:27 +0100 Subject: [PATCH 0669/1106] Fix alignment of higher values --- 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 6b334507a..947aa78bf 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -9,6 +9,7 @@ import logging import random import sys import warnings +from math import ceil, floor from collections import OrderedDict from operator import itemgetter from pathlib import Path @@ -571,7 +572,7 @@ class Hyperopt: with Parallel(n_jobs=config_jobs) as parallel: jobs = parallel._effective_n_jobs() logger.info(f'Effective number of parallel workers used: {jobs}') - EVALS = max(self.total_epochs // jobs, 1) + EVALS = ceil(self.total_epochs / jobs) for i in range(EVALS): asked = self.opt.ask(n_points=jobs) f_val = self.run_optimizer_parallel(parallel, asked, i) @@ -580,6 +581,8 @@ class Hyperopt: for j in range(jobs): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 + if current > self.total_epochs: + continue val = f_val[j] val['current_epoch'] = current val['is_initial_point'] = current <= INITIAL_POINTS From f08c7eedf1b583a65e01d4ea5f30ead17f7bfad3 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 1 Mar 2020 14:35:13 +0100 Subject: [PATCH 0670/1106] Changed jobs to be dynamic for last loop --- freqtrade/optimize/hyperopt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 947aa78bf..91507c347 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -9,7 +9,7 @@ import logging import random import sys import warnings -from math import ceil, floor +from math import ceil from collections import OrderedDict from operator import itemgetter from pathlib import Path @@ -578,11 +578,13 @@ class Hyperopt: f_val = self.run_optimizer_parallel(parallel, asked, i) self.opt.tell(asked, [v['loss'] for v in f_val]) self.fix_optimizer_models_list() - for j in range(jobs): + if (i * jobs + jobs) > self.total_epochs: + current_jobs = jobs - ((i * jobs + jobs) - self.total_epochs) + else: + current_jobs = jobs + for j in range(current_jobs): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 - if current > self.total_epochs: - continue val = f_val[j] val['current_epoch'] = current val['is_initial_point'] = current <= INITIAL_POINTS From 77b7f95efb786c71e325cc662dea0bb6bc61d291 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Mon, 2 Mar 2020 00:14:01 +0100 Subject: [PATCH 0671/1106] simple code styling fixes --- freqtrade/commands/hyperopt_commands.py | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index ccaa59e54..e7f89a375 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -97,10 +97,10 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: if n > trials_epochs: raise OperationalException( - f"The index of the epoch to show should be less than {trials_epochs + 1}.") + f"The index of the epoch to show should be less than {trials_epochs + 1}.") if n < -trials_epochs: raise OperationalException( - f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") + f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") # Translate epoch index from human-readable format to pythonic if n > 0: @@ -122,52 +122,52 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: trials = [x for x in trials if x['results_metrics']['profit'] > 0] if filteroptions['filter_min_trades'] > 0: trials = [ - x for x in trials - if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades'] - ] + x for x in trials + if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades'] + ] if filteroptions['filter_max_trades'] > 0: trials = [ - x for x in trials - if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades'] - ] + x for x in trials + if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades'] + ] if filteroptions['filter_min_avg_time'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] - ] + x for x in trials + if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] + ] if filteroptions['filter_max_avg_time'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] - ] + x for x in trials + if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] + ] if filteroptions['filter_min_avg_profit'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['avg_profit'] - > filteroptions['filter_min_avg_profit'] - ] + x for x in trials + if x['results_metrics']['avg_profit'] + > filteroptions['filter_min_avg_profit'] + ] if filteroptions['filter_max_avg_profit'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['avg_profit'] - < filteroptions['filter_max_avg_profit'] - ] + x for x in trials + if x['results_metrics']['avg_profit'] + < filteroptions['filter_max_avg_profit'] + ] if filteroptions['filter_min_total_profit'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] - ] + x for x in trials + if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] + ] if filteroptions['filter_max_total_profit'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ - x for x in trials - if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit'] - ] + x for x in trials + if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit'] + ] logger.info(f"{len(trials)} " + ("best " if filteroptions['only_best'] else "") + From e204e3277bd277f3dbfcee58c764b559f105740b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2020 08:37:58 +0000 Subject: [PATCH 0672/1106] Bump ccxt from 1.22.95 to 1.23.30 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.95 to 1.23.30. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.22.95...1.23.30) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index bdb1f1127..10d567a96 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.22.95 +ccxt==1.23.30 SQLAlchemy==1.3.13 python-telegram-bot==12.4.2 arrow==0.15.5 From 485075b8f2e8cd4a5f19456388d6b482b404b413 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2020 08:38:36 +0000 Subject: [PATCH 0673/1106] Bump scikit-learn from 0.22.1 to 0.22.2 Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22.1 to 0.22.2. - [Release notes](https://github.com/scikit-learn/scikit-learn/releases) - [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22.1...0.22.2) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 2984229c1..c713317ec 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -3,7 +3,7 @@ # Required for hyperopt scipy==1.4.1 -scikit-learn==0.22.1 +scikit-learn==0.22.2 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 From a17f3fb8be7229fb064cb74f853a61b5428b3b0c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2020 08:39:25 +0000 Subject: [PATCH 0674/1106] Bump plotly from 4.5.1 to 4.5.2 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.1 to 4.5.2. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.5.1...v4.5.2) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 5e62a5e95..a70c3e0cf 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.5.1 +plotly==4.5.2 From 6e2290c4f0d142de4e924f7ee78b209d90ec3643 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 2 Mar 2020 20:05:54 +0100 Subject: [PATCH 0675/1106] Allow last to be empty - closes #3005 --- freqtrade/freqtradebot.py | 8 +++----- tests/test_freqtradebot.py | 8 ++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 53493ad4c..04e3dd72f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -257,12 +257,10 @@ class FreqtradeBot: else: logger.info(f"Using Last {bid_strategy['price_side'].capitalize()} / Last Price") ticker = self.exchange.fetch_ticker(pair) - rate = ticker[bid_strategy['price_side']] - if rate < ticker['last']: - ticker_rate = rate - else: + ticker_rate = ticker[bid_strategy['price_side']] + if ticker['last'] and ticker_rate > ticker['last']: balance = self.config['bid_strategy']['ask_last_balance'] - ticker_rate = rate + balance * (ticker['last'] - rate) + ticker_rate = ticker_rate + balance * (ticker['last'] - ticker_rate) used_rate = ticker_rate self._buy_rate_cache[pair] = used_rate diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 49000382f..a5506017c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -914,6 +914,10 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: ('ask', 20, 19, 10, 0.3, 17), # Between ask and last ('ask', 5, 6, 10, 1.0, 5), # last bigger than ask ('ask', 5, 6, 10, 0.5, 5), # last bigger than ask + ('ask', 10, 20, None, 0.5, 10), # last not available - uses ask + ('ask', 4, 5, None, 0.5, 4), # last not available - uses ask + ('ask', 4, 5, None, 1, 4), # last not available - uses ask + ('ask', 4, 5, None, 0, 4), # last not available - uses ask ('bid', 10, 20, 10, 0.0, 20), # Full bid side ('bid', 10, 20, 10, 1.0, 10), # Full last side ('bid', 10, 20, 10, 0.5, 15), # Between bid and last @@ -921,6 +925,10 @@ def test_process_informative_pairs_added(default_conf, ticker, mocker) -> None: ('bid', 10, 20, 10, 0.3, 17), # Between bid and last ('bid', 4, 5, 10, 1.0, 5), # last bigger than bid ('bid', 4, 5, 10, 0.5, 5), # last bigger than bid + ('bid', 10, 20, None, 0.5, 20), # last not available - uses bid + ('bid', 4, 5, None, 0.5, 5), # last not available - uses bid + ('bid', 4, 5, None, 1, 5), # last not available - uses bid + ('bid', 4, 5, None, 0, 5), # last not available - uses bid ]) def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid, last, last_ab, expected) -> None: From 7713cfeb7996b478f20c65afab9a1b49318b062b Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 2 Mar 2020 21:02:32 +0100 Subject: [PATCH 0676/1106] Corrected logic for -j + and - argument --- 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 91507c347..c500e71bf 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -558,7 +558,8 @@ class Hyperopt: cpus = cpu_count() logger.info(f"Found {cpus} CPU cores. Let's make them scream!") config_jobs = self.config.get('hyperopt_jobs', -1) - if self.total_epochs < cpus and (config_jobs > self.total_epochs or config_jobs < 0): + if (config_jobs < 0 and (cpus + config_jobs + 1) > self.total_epochs) \ + or (config_jobs > 0 and config_jobs > self.total_epochs): config_jobs = self.total_epochs logger.info(f'Number of parallel jobs set as: {config_jobs}') From 0e4862b0c8f8cc927675eb4e3fb098f479f1d0b9 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 2 Mar 2020 22:58:54 +0100 Subject: [PATCH 0677/1106] Added logging if argument is miss-configured --- freqtrade/optimize/hyperopt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index c500e71bf..98c19f15b 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -561,6 +561,7 @@ class Hyperopt: if (config_jobs < 0 and (cpus + config_jobs + 1) > self.total_epochs) \ or (config_jobs > 0 and config_jobs > self.total_epochs): config_jobs = self.total_epochs + logger.info("Job count invalid will correct") logger.info(f'Number of parallel jobs set as: {config_jobs}') self.dimensions: List[Dimension] = self.hyperopt_space() From 92425642da922740e319f9563c93a36873af946f Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 3 Mar 2020 01:00:24 +0300 Subject: [PATCH 0678/1106] Fix config_jobs --- freqtrade/optimize/hyperopt.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 98c19f15b..66ce94ae0 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -558,10 +558,6 @@ class Hyperopt: cpus = cpu_count() logger.info(f"Found {cpus} CPU cores. Let's make them scream!") config_jobs = self.config.get('hyperopt_jobs', -1) - if (config_jobs < 0 and (cpus + config_jobs + 1) > self.total_epochs) \ - or (config_jobs > 0 and config_jobs > self.total_epochs): - config_jobs = self.total_epochs - logger.info("Job count invalid will correct") logger.info(f'Number of parallel jobs set as: {config_jobs}') self.dimensions: List[Dimension] = self.hyperopt_space() From a7d4755859740a62cc87dc7f168eb2f7fbb54f81 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 3 Mar 2020 01:20:14 +0300 Subject: [PATCH 0679/1106] optimize calculation of current_jobs --- freqtrade/optimize/hyperopt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 66ce94ae0..27fb7bcdb 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -576,10 +576,12 @@ class Hyperopt: f_val = self.run_optimizer_parallel(parallel, asked, i) self.opt.tell(asked, [v['loss'] for v in f_val]) self.fix_optimizer_models_list() - if (i * jobs + jobs) > self.total_epochs: - current_jobs = jobs - ((i * jobs + jobs) - self.total_epochs) - else: - current_jobs = jobs + + # Correct the number of epochs to handled for the last + # iteration (should not exceed self.total_epochs) + n_rest = (i + 1) * jobs - self.total_epochs + current_jobs = jobs - n_rest if n_rest > 0 else jobs + for j in range(current_jobs): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 From 45c94967927609b556f3b5ec226cc5dc31d9a8a9 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 3 Mar 2020 01:33:11 +0300 Subject: [PATCH 0680/1106] Do not run optimizer for 'jobs' epochs for the last iteration --- freqtrade/optimize/hyperopt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 27fb7bcdb..41e2ce82b 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -572,16 +572,16 @@ class Hyperopt: logger.info(f'Effective number of parallel workers used: {jobs}') EVALS = ceil(self.total_epochs / jobs) for i in range(EVALS): - asked = self.opt.ask(n_points=jobs) + # Correct the number of epochs to be processed for the last + # iteration (should not exceed self.total_epochs in total) + 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) f_val = self.run_optimizer_parallel(parallel, asked, i) self.opt.tell(asked, [v['loss'] for v in f_val]) self.fix_optimizer_models_list() - # Correct the number of epochs to handled for the last - # iteration (should not exceed self.total_epochs) - n_rest = (i + 1) * jobs - self.total_epochs - current_jobs = jobs - n_rest if n_rest > 0 else jobs - for j in range(current_jobs): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 From 52cd5f912789d7b151702ba6c0a7caf3e4414846 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 3 Mar 2020 01:42:25 +0300 Subject: [PATCH 0681/1106] Better use enumerate: more correct and more pythonic --- freqtrade/optimize/hyperopt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 41e2ce82b..b3be3f160 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -582,10 +582,9 @@ class Hyperopt: self.opt.tell(asked, [v['loss'] for v in f_val]) self.fix_optimizer_models_list() - for j in range(current_jobs): + for j, val in enumerate(f_val): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 - val = f_val[j] val['current_epoch'] = current val['is_initial_point'] = current <= INITIAL_POINTS logger.debug(f"Optimizer epoch evaluated: {val}") From 399c419163cd8acf867f16b9702b9936a1d05c7d Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 3 Mar 2020 01:14:56 +0100 Subject: [PATCH 0682/1106] Changed table formating. Adding some code to align hyperopt table generation. WIP --- freqtrade/optimize/hyperopt.py | 15 ++++++++++----- tests/optimize/test_hyperopt.py | 4 +++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 700614453..ac272128e 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -325,15 +325,20 @@ class Hyperopt: trials['Trades'] = trials['Trades'].astype(str) trials['Epoch'] = trials['Epoch'].apply( - lambda x: "{}/{}".format(x, total_epochs)) + lambda x: '{}/{}'.format(str(x).rjust(len(str(total_epochs)), ' '), total_epochs)) trials['Avg profit'] = trials['Avg profit'].apply( - lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + lambda x: ('{:,.2f}%'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ')) trials['Profit'] = trials['Profit'].apply( - lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "--") trials['Total profit'] = trials['Total profit'].apply( - lambda x: '{:,.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) + lambda x: ('{:,.8f} '.format(x)) + config['stake_currency'] if not isna(x) else "--") trials['Avg duration'] = trials['Avg duration'].apply( - lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) + lambda x: ('{:,.1f}m'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ')) + trials['Objective'] = trials['Objective'].apply( + lambda x: str(x).rjust(10, ' ') if str(x) != str(100000) else "N/A".rjust(10, ' ')) + trials['Profit'] = trials['Total profit'] + " (" + trials['Profit'] + ")" + trials = trials.drop(columns=['Total profit']) + if print_colorized: for i in range(len(trials)): if trials.loc[i]['is_profit']: diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 5bd9e542f..8de812d2d 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -413,7 +413,9 @@ def test_log_results_if_loss_improves(hyperopt, capsys) -> None: '| Best | 2/2 | 1 | 0.10% | 0.00100000 BTC |' ' 1.00% | 20.0m | 1 |' ) - assert result_str in out + # assert result_str in out + assert all(x in out + for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC", "1.00%", "20.0m"]) def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: From 4aca8d7fcc2e217652572325aa72a61a70d8ec98 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 3 Mar 2020 01:35:18 +0100 Subject: [PATCH 0683/1106] PEP8 fix --- tests/optimize/test_hyperopt.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 8de812d2d..6c7e1e16f 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -409,11 +409,6 @@ def test_log_results_if_loss_improves(hyperopt, capsys) -> None: } ) out, err = capsys.readouterr() - result_str = ( - '| Best | 2/2 | 1 | 0.10% | 0.00100000 BTC |' - ' 1.00% | 20.0m | 1 |' - ) - # assert result_str in out assert all(x in out for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC", "1.00%", "20.0m"]) From 3479f7d986a044de4db94c6d1c9f3ac02b4544f6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 07:13:11 +0100 Subject: [PATCH 0684/1106] Add max_drawdown function --- freqtrade/data/btanalysis.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index c28e462ba..9407a3139 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -3,7 +3,7 @@ Helpers when analyzing backtest data """ import logging from pathlib import Path -from typing import Dict, Union +from typing import Dict, Union, Tuple import numpy as np import pandas as pd @@ -188,3 +188,23 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str, # FFill to get continuous df[col_name] = df[col_name].ffill() return df + + +def calculate_max_drawdown(trades: pd.DataFrame) -> Tuple[float, pd.Timestamp, pd.Timestamp]: + """ + Calculate max drawdown and the corresponding close dates + :param trades: DataFrame containing trades (requires columns close_time and profitperc) + :return: Tuple (float, highdate, lowdate) with absolute max drawdown, high and low time + :raise: ValueError if trade-dataframe was found empty. + """ + if len(trades) == 0: + raise ValueError("Trade dataframe empty") + profit_results = trades.sort_values('close_time') + max_drawdown_df = pd.DataFrame() + max_drawdown_df['cumulative'] = profit_results['profitperc'].cumsum() + max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax() + max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value'] + high_date = profit_results.loc[max_drawdown_df['high_value'].idxmax(), 'close_time'] + low_date = profit_results.loc[max_drawdown_df['drawdown'].idxmin(), 'close_time'] + + return abs(min(max_drawdown_df['drawdown'])), high_date, low_date From e050511ddcd295841590cfd99c4897e97dc678e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 07:20:41 +0100 Subject: [PATCH 0685/1106] Add test for max_drawdown calculation --- freqtrade/data/btanalysis.py | 2 +- tests/data/test_btanalysis.py | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 9407a3139..799f15011 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -198,7 +198,7 @@ def calculate_max_drawdown(trades: pd.DataFrame) -> Tuple[float, pd.Timestamp, p :raise: ValueError if trade-dataframe was found empty. """ if len(trades) == 0: - raise ValueError("Trade dataframe empty") + raise ValueError("Trade dataframe empty.") profit_results = trades.sort_values('close_time') max_drawdown_df = pd.DataFrame() max_drawdown_df['cumulative'] = profit_results['profitperc'].cumsum() diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 60d9c3ea5..7e3c1f077 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -2,15 +2,17 @@ from unittest.mock import MagicMock import pytest from arrow import Arrow -from pandas import DataFrame, DateOffset, to_datetime +from pandas import DataFrame, DateOffset, to_datetime, Timestamp from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, + analyze_trade_parallelism, + calculate_max_drawdown, combine_tickers_with_mean, create_cum_profit, extract_trades_of_period, load_backtest_data, load_trades, - load_trades_from_db, analyze_trade_parallelism) + load_trades_from_db) from freqtrade.data.history import load_data, load_pair_history from tests.test_persistence import create_mock_trades @@ -163,3 +165,17 @@ def test_create_cum_profit1(testdatadir): assert "cum_profits" in cum_profits.columns assert cum_profits.iloc[0]['cum_profits'] == 0 assert cum_profits.iloc[-1]['cum_profits'] == 0.0798005 + + +def test_calculate_max_drawdown(testdatadir): + filename = testdatadir / "backtest-result_test.json" + bt_data = load_backtest_data(filename) + drawdown, h, low = calculate_max_drawdown(bt_data) + assert isinstance(drawdown, float) + assert pytest.approx(drawdown) == 0.21142322 + assert isinstance(h, Timestamp) + assert isinstance(low, Timestamp) + assert h == Timestamp('2018-01-24 14:25:00', tz='UTC') + assert low == Timestamp('2018-01-30 04:45:00', tz='UTC') + with pytest.raises(ValueError, match='Trade dataframe empty.'): + drawdown, h, low = calculate_max_drawdown(DataFrame()) From 88e7cab5b99873d3f5af59ca61333013d8e2234b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 07:21:14 +0100 Subject: [PATCH 0686/1106] Add max_drawdown to profit plot --- freqtrade/plot/plotting.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 4a892792a..2ce4f1501 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -5,7 +5,8 @@ from typing import Any, Dict, List import pandas as pd from freqtrade.configuration import TimeRange -from freqtrade.data.btanalysis import (combine_tickers_with_mean, +from freqtrade.data.btanalysis import (calculate_max_drawdown, + combine_tickers_with_mean, create_cum_profit, extract_trades_of_period, load_trades) from freqtrade.data.converter import trim_dataframe @@ -111,6 +112,36 @@ def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_sub return fig +def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> make_subplots: + """ + Add scatter points indicating max drawdown + """ + try: + max_drawdown, highdate, lowdate = calculate_max_drawdown(trades) + + drawdown = go.Scatter( + x=[highdate, lowdate], + y=[ + df_comb.loc[highdate, 'cum_profit'], + df_comb.loc[lowdate, 'cum_profit'], + ], + mode='markers', + name='Max Drawdown', + text=f"Max drawdown {max_drawdown}", + marker=dict( + symbol='square-open', + size=9, + line=dict(width=2), + color='green' + + ) + ) + fig.add_trace(drawdown, row, 1) + except ValueError: + logger.warning("No trades found - not plotting max drawdown.") + return fig + + def plot_trades(fig, trades: pd.DataFrame) -> make_subplots: """ Add trades to "fig" @@ -364,6 +395,7 @@ def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame], fig.add_trace(avgclose, 1, 1) fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit') + fig = add_max_drawdown(fig, 2, trades, df_comb) for pair in pairs: profit_col = f'cum_profit_{pair}' From 33a63562cbacdeb858a29b09c4a11b9d3f31ae7b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 07:23:38 +0100 Subject: [PATCH 0687/1106] make drawdown function less restrictive --- freqtrade/data/btanalysis.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 799f15011..394c40112 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -190,21 +190,26 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str, return df -def calculate_max_drawdown(trades: pd.DataFrame) -> Tuple[float, pd.Timestamp, pd.Timestamp]: +def calculate_max_drawdown(trades: pd.DataFrame, date_col: str = 'close_time', + value_col: str = 'profitperc' + ) -> Tuple[float, pd.Timestamp, pd.Timestamp]: """ Calculate max drawdown and the corresponding close dates :param trades: DataFrame containing trades (requires columns close_time and profitperc) + :param date_col: Column in DataFrame to use for dates (defaults to 'close_time') + :param value_col: Column in DataFrame to use for values (defaults to 'profitperc') :return: Tuple (float, highdate, lowdate) with absolute max drawdown, high and low time :raise: ValueError if trade-dataframe was found empty. """ if len(trades) == 0: raise ValueError("Trade dataframe empty.") - profit_results = trades.sort_values('close_time') + profit_results = trades.sort_values(date_col) max_drawdown_df = pd.DataFrame() - max_drawdown_df['cumulative'] = profit_results['profitperc'].cumsum() + max_drawdown_df['cumulative'] = profit_results[value_col].cumsum() max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax() max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value'] - high_date = profit_results.loc[max_drawdown_df['high_value'].idxmax(), 'close_time'] - low_date = profit_results.loc[max_drawdown_df['drawdown'].idxmin(), 'close_time'] + + high_date = profit_results.loc[max_drawdown_df['high_value'].idxmax(), date_col] + low_date = profit_results.loc[max_drawdown_df['drawdown'].idxmin(), date_col] return abs(min(max_drawdown_df['drawdown'])), high_date, low_date From d9e83cc4e2892bb9210c166dbd0857fc7b9e87b9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 09:33:08 +0100 Subject: [PATCH 0688/1106] Run CI on windows python 3.8 --- .github/workflows/ci.yml | 5 ++--- .../TA_Lib-0.4.17-cp38-cp38-win_amd64.whl | Bin 0 -> 662134 bytes build_helpers/install_windows.ps1 | 10 +++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc3d324a1..42668e46f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,7 +115,7 @@ jobs: strategy: matrix: os: [ windows-latest ] - python-version: [3.7] + python-version: [3.7, 3.8] steps: - uses: actions/checkout@v2 @@ -130,8 +130,7 @@ jobs: if: startsWith(runner.os, 'Windows') with: path: ~\AppData\Local\pip\Cache - key: ${{ runner.os }}-pip - restore-keys: ${{ runner.os }}-pip + key: ${{ matrix.os }}-${{ matrix.python-version }}-pip - name: Installation run: | diff --git a/build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl b/build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl new file mode 100644 index 0000000000000000000000000000000000000000..90626b183a42e55d12ddabf57d3d257aea29fbf5 GIT binary patch literal 662134 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

$U6w?tKT@c&g@Lvze-5=` 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�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

O_G_btw< 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 c-u=Va$x49#GO+I{BZxql@8(eq1LnQ Date: Tue, 3 Mar 2020 09:36:04 +0100 Subject: [PATCH 0689/1106] Remove flucky test assert --- tests/commands/test_commands.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 1877aaa43..3e1c0a581 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -448,9 +448,6 @@ def test_create_datadir_failed(caplog): def test_create_datadir(caplog, mocker): - # Capture caplog length here trying to avoid random test failure - len_caplog_before = len(caplog.record_tuples) - cud = mocker.patch("freqtrade.commands.deploy_commands.create_userdata_dir", MagicMock()) csf = mocker.patch("freqtrade.commands.deploy_commands.copy_sample_files", MagicMock()) args = [ @@ -462,7 +459,6 @@ def test_create_datadir(caplog, mocker): assert cud.call_count == 1 assert csf.call_count == 1 - assert len(caplog.record_tuples) == len_caplog_before def test_start_new_strategy(mocker, caplog): From 9bebc9ba7699426a86271f711f98e080142531a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 09:40:41 +0100 Subject: [PATCH 0690/1106] Fix powershell comparison --- build_helpers/install_windows.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_helpers/install_windows.ps1 b/build_helpers/install_windows.ps1 index af1768d18..7dbdd77dd 100644 --- a/build_helpers/install_windows.ps1 +++ b/build_helpers/install_windows.ps1 @@ -6,10 +6,10 @@ python -m pip install --upgrade pip $pyv = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" -if ($pyv == '3.7') { +if ($pyv -eq '3.7') { pip install build_helpers\TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl } -if ($pyv == '3.8') { +if ($pyv -eq '3.8') { pip install build_helpers\TA_Lib-0.4.17-cp38-cp38-win_amd64.whl } From 53dcb5d5ed1dd1dc741e9cf3f6d0b49f90e55029 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 19:36:03 +0100 Subject: [PATCH 0691/1106] Fix logging expression --- freqtrade/freqtradebot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 04e3dd72f..920c9203e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -685,7 +685,8 @@ class FreqtradeBot: order_book_max=order_book_max) for i in range(order_book_min, order_book_max + 1): sell_rate = next(order_book) - logger.debug(' order book asks top %s: %0.8f', i, sell_rate) + logger.debug(f" order book {config_ask_strategy['price_side']} top {i}: " + f"{sell_rate:0.8f}") if self._check_and_execute_sell(trade, sell_rate, buy, sell): return True From 9d8970a76bdff307482bdf82dffe2279af3fa731 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 3 Mar 2020 20:18:38 +0100 Subject: [PATCH 0692/1106] Add test and formatting to drawdown --- docs/plotting.md | 1 + freqtrade/data/btanalysis.py | 2 +- freqtrade/plot/plotting.py | 4 ++-- tests/test_plotting.py | 8 ++++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index ecd5e1603..3eef8f8e7 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -196,6 +196,7 @@ The first graph is good to get a grip of how the overall market progresses. The second graph will show if your algorithm works or doesn't. Perhaps you want an algorithm that steadily makes small profits, or one that acts less often, but makes big swings. +This graph will also highlight the start (and end) of the Max drawdown period. The third graph can be useful to spot outliers, events in pairs that cause profit spikes. diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 394c40112..7972c6333 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -190,7 +190,7 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str, return df -def calculate_max_drawdown(trades: pd.DataFrame, date_col: str = 'close_time', +def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time', value_col: str = 'profitperc' ) -> Tuple[float, pd.Timestamp, pd.Timestamp]: """ diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 2ce4f1501..d979a40e0 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -126,8 +126,8 @@ def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> m df_comb.loc[lowdate, 'cum_profit'], ], mode='markers', - name='Max Drawdown', - text=f"Max drawdown {max_drawdown}", + name=f"Max drawdown {max_drawdown:.2f}%", + text=f"Max drawdown {max_drawdown:.2f}%", marker=dict( symbol='square-open', size=9, diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 34d1f2b0c..dd04035b7 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -3,15 +3,16 @@ from copy import deepcopy from pathlib import Path from unittest.mock import MagicMock +import pandas as pd import plotly.graph_objects as go import pytest from plotly.subplots import make_subplots +from freqtrade.commands import start_plot_dataframe, start_plot_profit from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data from freqtrade.exceptions import OperationalException -from freqtrade.commands import start_plot_dataframe, start_plot_profit from freqtrade.plot.plotting import (add_indicators, add_profit, create_plotconfig, generate_candlestick_graph, @@ -266,6 +267,7 @@ def test_generate_profit_graph(testdatadir): trades = load_backtest_data(filename) timerange = TimeRange.parse_timerange("20180110-20180112") pairs = ["TRX/BTC", "ADA/BTC"] + trades = trades[trades['close_time'] < pd.Timestamp('2018-01-12', tz='UTC')] tickers = history.load_data(datadir=testdatadir, pairs=pairs, @@ -283,13 +285,15 @@ def test_generate_profit_graph(testdatadir): assert fig.layout.yaxis3.title.text == "Profit" figure = fig.layout.figure - assert len(figure.data) == 4 + assert len(figure.data) == 5 avgclose = find_trace_in_fig_data(figure.data, "Avg close price") assert isinstance(avgclose, go.Scatter) profit = find_trace_in_fig_data(figure.data, "Profit") assert isinstance(profit, go.Scatter) + profit = find_trace_in_fig_data(figure.data, "Max drawdown 0.00%") + assert isinstance(profit, go.Scatter) for pair in pairs: profit_pair = find_trace_in_fig_data(figure.data, f"Profit {pair}") From 7652a2bb95451ad907aec48ff4a8cc133901ae40 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 4 Mar 2020 00:10:47 +0100 Subject: [PATCH 0693/1106] Updated table layout and aligning better for hyperopt --- freqtrade/optimize/hyperopt.py | 50 ++++++++++++++++++++------------- tests/optimize/test_hyperopt.py | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ac272128e..7937ad611 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -21,7 +21,7 @@ from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna -from tabulate import tabulate +import tabulate from freqtrade.data.converter import trim_dataframe from freqtrade.data.history import get_timerange @@ -309,6 +309,8 @@ class Hyperopt: if not results: return + tabulate.PRESERVE_WHITESPACE = True + trials = json_normalize(results, max_level=1) trials['Best'] = '' trials = trials[['Best', 'current_epoch', 'results_metrics.trade_count', @@ -325,43 +327,51 @@ class Hyperopt: trials['Trades'] = trials['Trades'].astype(str) trials['Epoch'] = trials['Epoch'].apply( - lambda x: '{}/{}'.format(str(x).rjust(len(str(total_epochs)), ' '), total_epochs)) + lambda x: '{}/{}'.format(str(x).rjust(len(str(total_epochs)), ' '), total_epochs) + ) trials['Avg profit'] = trials['Avg profit'].apply( - lambda x: ('{:,.2f}%'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ')) - trials['Profit'] = trials['Profit'].apply( - lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "--") - trials['Total profit'] = trials['Total profit'].apply( - lambda x: ('{:,.8f} '.format(x)) + config['stake_currency'] if not isna(x) else "--") + lambda x: ('{:,.2f}%'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') + ) trials['Avg duration'] = trials['Avg duration'].apply( - lambda x: ('{:,.1f}m'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ')) + lambda x: ('{:,.1f} m'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') + ) trials['Objective'] = trials['Objective'].apply( - lambda x: str(x).rjust(10, ' ') if str(x) != str(100000) else "N/A".rjust(10, ' ')) - trials['Profit'] = trials['Total profit'] + " (" + trials['Profit'] + ")" + lambda x: str(x).rjust(10, ' ') if str(x) != str(100000) else "N/A".rjust(10, ' ') + ) + + trials['Profit'] = trials.apply( + lambda x: '{:,.8f} {} ({:,.2f}%)'.format( + x['Total profit'], config['stake_currency'], + x['Profit']).rjust(24+len(config['stake_currency'])) + if x['Total profit'] != 0.0 else '--'.rjust(24+len(config['stake_currency'])), + axis=1 + ) trials = trials.drop(columns=['Total profit']) if print_colorized: for i in range(len(trials)): if trials.loc[i]['is_profit']: for z in range(len(trials.loc[i])-3): - trials.iat[i, z] = "{}{}{}".format(Fore.GREEN, - str(trials.loc[i][z]), Fore.RESET) + trials.iat[i, z] = "{}{}{}".format( + Fore.GREEN, str(trials.loc[i][z]), Fore.RESET) if trials.loc[i]['is_best'] and highlight_best: for z in range(len(trials.loc[i])-3): - trials.iat[i, z] = "{}{}{}".format(Style.BRIGHT, - str(trials.loc[i][z]), Style.RESET_ALL) + trials.iat[i, z] = "{}{}{}".format( + Style.BRIGHT, str(trials.loc[i][z]), Style.RESET_ALL) trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) if remove_header > 0: - table = tabulate(trials.to_dict(orient='list'), tablefmt='orgtbl', - headers='keys', stralign="right") + table = tabulate.tabulate( + trials.to_dict(orient='list'), tablefmt='orgtbl', headers='keys', stralign="right") + # print(table) table = table.split("\n", remove_header)[remove_header] elif remove_header < 0: - table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', - headers='keys', stralign="right") + table = tabulate.tabulate( + trials.to_dict(orient='list'), tablefmt='psql', headers='keys', stralign="right") table = "\n".join(table.split("\n")[0:remove_header]) else: - table = tabulate(trials.to_dict(orient='list'), tablefmt='psql', - headers='keys', stralign="right") + table = tabulate.tabulate( + trials.to_dict(orient='list'), tablefmt='psql', headers='keys', stralign="right") print(table) def has_space(self, space: str) -> bool: diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 6c7e1e16f..5820cc9f9 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -410,7 +410,7 @@ def test_log_results_if_loss_improves(hyperopt, capsys) -> None: ) out, err = capsys.readouterr() assert all(x in out - for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC", "1.00%", "20.0m"]) + for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC (1.00%)", "20.0 m"]) def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: From 8de35e1c83becae0f226deb1f55fd7277510cf41 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Mar 2020 06:40:19 +0100 Subject: [PATCH 0694/1106] Documentation suggestions from Review Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index c70f3425c..c2c144541 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -465,7 +465,7 @@ Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) s #### Buy price side -The configuration option `bid_strategy.price_side` defines the side of the spread the bot looks for when buying. +The configuration setting `bid_strategy.price_side` defines the side of the spread the bot looks for when buying. The following displays an orderbook. @@ -503,7 +503,7 @@ The `bid_strategy.ask_last_balance` configuration parameter controls this. A val #### Sell price side -The configuration option `ask_strategy.price_side` defines the side of the spread the bot looks for when selling. +The configuration setting `ask_strategy.price_side` defines the side of the spread the bot looks for when selling. The following displays an orderbook: @@ -524,7 +524,7 @@ In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot #### Sell price with Orderbook enabled -When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration and the sell order is placed at the first profitable spot. +When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration (`minimal_roi` conditions) and the sell order is placed at the first profitable spot. !!! Note Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`. From 2f54aff0ce25d04edf25f9663c62c9138cabf622 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Mar 2020 06:44:47 +0100 Subject: [PATCH 0695/1106] Improve documentation wording for price sides --- docs/configuration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index c2c144541..7e33f1528 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -485,7 +485,8 @@ If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buyi In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price. Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary. - +Taker fees instead of maker fees will most likely apply even when using limit buy orders. +Also, prices at the "ask" side of the spread are higher than prices at the "bid" side in the orderbook, so the order behaves similar to a market order (however with a maximum price). #### Buy price with Orderbook enabled From 090d1e8a709d9c0abcbd1cff667207f4e22d25dd Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 4 Mar 2020 20:51:09 +0100 Subject: [PATCH 0696/1106] Alignment and cleanups --- freqtrade/optimize/hyperopt.py | 38 +++++++++++++++++++-------------- tests/optimize/test_hyperopt.py | 4 +--- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 7937ad611..bc0a0d58f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -154,7 +154,7 @@ class Hyperopt: """ num_trials = len(self.trials) if num_trials > self.num_trials_saved: - logger.info(f"Saving {num_trials} {plural(num_trials, 'epoch')}.") + logger.debug(f"Saving {num_trials} {plural(num_trials, 'epoch')}.") dump(self.trials, self.trials_file) self.num_trials_saved = num_trials if final: @@ -322,7 +322,6 @@ class Hyperopt: trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' trials.loc[trials['is_best'], 'Best'] = 'Best' - trials['Objective'] = trials['Objective'].astype(str) trials.loc[trials['Total profit'] > 0, 'is_profit'] = True trials['Trades'] = trials['Trades'].astype(str) @@ -336,14 +335,15 @@ class Hyperopt: lambda x: ('{:,.1f} m'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') ) trials['Objective'] = trials['Objective'].apply( - lambda x: str(x).rjust(10, ' ') if str(x) != str(100000) else "N/A".rjust(10, ' ') + lambda x: '{:,.5f}'.format(x).rjust(8, ' ') if x != 100000 else "N/A".rjust(8, ' ') ) trials['Profit'] = trials.apply( - lambda x: '{:,.8f} {} ({:,.2f}%)'.format( + lambda x: '{:,.8f} {} {}'.format( x['Total profit'], config['stake_currency'], - x['Profit']).rjust(24+len(config['stake_currency'])) - if x['Total profit'] != 0.0 else '--'.rjust(24+len(config['stake_currency'])), + '({:,.2f}%)'.format(x['Profit']).rjust(10, ' ') + ).rjust(25+len(config['stake_currency'])) + if x['Total profit'] != 0.0 else '--'.rjust(25+len(config['stake_currency'])), axis=1 ) trials = trials.drop(columns=['Total profit']) @@ -351,27 +351,33 @@ class Hyperopt: if print_colorized: for i in range(len(trials)): if trials.loc[i]['is_profit']: - for z in range(len(trials.loc[i])-3): - trials.iat[i, z] = "{}{}{}".format( - Fore.GREEN, str(trials.loc[i][z]), Fore.RESET) + for j in range(len(trials.loc[i])-3): + trials.iat[i, j] = "{}{}{}".format(Fore.GREEN, + str(trials.loc[i][j]), Fore.RESET) if trials.loc[i]['is_best'] and highlight_best: - for z in range(len(trials.loc[i])-3): - trials.iat[i, z] = "{}{}{}".format( - Style.BRIGHT, str(trials.loc[i][z]), Style.RESET_ALL) + for j in range(len(trials.loc[i])-3): + trials.iat[i, j] = "{}{}{}".format(Style.BRIGHT, + str(trials.loc[i][j]), Style.RESET_ALL) trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) if remove_header > 0: table = tabulate.tabulate( - trials.to_dict(orient='list'), tablefmt='orgtbl', headers='keys', stralign="right") - # print(table) + trials.to_dict(orient='list'), tablefmt='orgtbl', + headers='keys', stralign="right" + ) + table = table.split("\n", remove_header)[remove_header] elif remove_header < 0: table = tabulate.tabulate( - trials.to_dict(orient='list'), tablefmt='psql', headers='keys', stralign="right") + trials.to_dict(orient='list'), tablefmt='psql', + headers='keys', stralign="right" + ) table = "\n".join(table.split("\n")[0:remove_header]) else: table = tabulate.tabulate( - trials.to_dict(orient='list'), tablefmt='psql', headers='keys', stralign="right") + trials.to_dict(orient='list'), tablefmt='psql', + headers='keys', stralign="right" + ) print(table) def has_space(self, space: str) -> bool: diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 5820cc9f9..0e35ff827 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -410,7 +410,7 @@ def test_log_results_if_loss_improves(hyperopt, capsys) -> None: ) out, err = capsys.readouterr() assert all(x in out - for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC (1.00%)", "20.0 m"]) + for x in ["Best", "2/2", " 1", "0.10%", "0.00100000 BTC (1.00%)", "20.0 m"]) def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: @@ -432,13 +432,11 @@ def test_save_trials_saves_trials(mocker, hyperopt, testdatadir, caplog) -> None hyperopt.trials = trials hyperopt.save_trials(final=True) - assert log_has("Saving 1 epoch.", caplog) assert log_has(f"1 epoch saved to '{trials_file}'.", caplog) mock_dump.assert_called_once() hyperopt.trials = trials + trials hyperopt.save_trials(final=True) - assert log_has("Saving 2 epochs.", caplog) assert log_has(f"2 epochs saved to '{trials_file}'.", caplog) From 7606d814fa3158f7383ecca47e60ebb9c8be9595 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 5 Mar 2020 01:58:33 +0100 Subject: [PATCH 0697/1106] Initial work on csv-file export. Missing docs and tests --- freqtrade/commands/arguments.py | 3 +- freqtrade/commands/cli_options.py | 6 +++ freqtrade/commands/hyperopt_commands.py | 12 +++++ freqtrade/configuration/configuration.py | 3 ++ freqtrade/optimize/hyperopt.py | 58 ++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 73e77d69d..8a8b06782 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -69,7 +69,8 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", - "print_colorized", "print_json", "hyperopt_list_no_details"] + "print_colorized", "print_json", "hyperopt_list_no_details", + "export_csv"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index ef674c5c2..77fba8eef 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -221,6 +221,12 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), + "export_csv": Arg( + '--export-csv', + help='Export to CSV-File. Put + in front of filename to overwrite.' + 'Example: --export-csv +hyperopt.csv', + metavar='FILE', + ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 4803f6885..f4f119351 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -21,6 +21,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) + export_csv = config.get('export_csv', None) no_details = config.get('hyperopt_list_no_details', False) no_header = False @@ -59,6 +60,17 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: sorted_trials = sorted(trials, key=itemgetter('loss')) results = sorted_trials[0] Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) + print(export_csv) + if trials and export_csv: + overwrite_csv = False + if export_csv[0] == '+': + overwrite_csv = True + export_csv = export_csv[1:] + + Hyperopt.export_csv_file( + config, trials, total_epochs, + not filteroptions['only_best'], export_csv, overwrite_csv + ) def start_hyperopt_show(args: Dict[str, Any]) -> None: diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 6a0441957..0645d72be 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -282,6 +282,9 @@ class Configuration: self._args_to_config(config, argname='print_json', logstring='Parameter --print-json detected ...') + self._args_to_config(config, argname='export_csv', + logstring='Parameter --export-csv detected: {}') + self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index e9ab469f4..d397c720c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -23,6 +23,8 @@ from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna import tabulate +from os import path +import io from freqtrade.data.converter import trim_dataframe from freqtrade.data.history import get_timerange @@ -381,6 +383,62 @@ class Hyperopt: ) print(table) + @staticmethod + def export_csv_file(config: dict, results: list, total_epochs: int, highlight_best: bool, + csv_file: str, overwrite: bool) -> None: + """ + Log result to csv-file + """ + if not results: + return + + # Verification for owerwrite + if not overwrite and path.isfile(csv_file): + logging.error("CSV-File already exists and no overwrite specified!") + return + + try: + io.open(csv_file, 'w+').close() + except IOError: + logging.error("Filed to create/overwrite CSV-File!") + return + + trials = json_normalize(results, max_level=1) + trials['Best'] = '' + trials['Stake currency'] = config['stake_currency'] + trials = trials[['Best', 'current_epoch', 'results_metrics.trade_count', + 'results_metrics.avg_profit', 'results_metrics.total_profit', + 'Stake currency', 'results_metrics.profit', 'results_metrics.duration', + 'loss', 'is_initial_point', 'is_best']] + trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Stake currency', + 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] + trials['is_profit'] = False + trials.loc[trials['is_initial_point'], 'Best'] = '*' + trials.loc[trials['is_best'], 'Best'] = 'Best' + trials.loc[trials['Total profit'] > 0, 'is_profit'] = True + trials['Epoch'] = trials['Epoch'].astype(str) + trials['Trades'] = trials['Trades'].astype(str) + + trials['Total profit'] = trials['Total profit'].apply( + lambda x: '{:,.8f}'.format(x) if x != 0.0 else "--" + ) + trials['Profit'] = trials['Profit'].apply( + lambda x: '{:,.2f}'.format(x) if not isna(x) else "--" + ) + trials['Avg profit'] = trials['Avg profit'].apply( + lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "--" + ) + trials['Avg duration'] = trials['Avg duration'].apply( + lambda x: ('{:,.1f} m'.format(x)) if not isna(x) else "--" + ) + trials['Objective'] = trials['Objective'].apply( + lambda x: '{:,.5f}'.format(x) if x != 100000 else "N/A" + ) + + trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) + trials.to_csv(csv_file, index=False, header=True, mode='w', encoding='UTF-8') + print("CSV-File created!") + def has_space(self, space: str) -> bool: """ Tell if the space value is contained in the configuration From 97b194a45485310199b76abadba46446f31ab42f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 5 Mar 2020 06:20:36 +0100 Subject: [PATCH 0698/1106] Throttle may take longer than .10s on slow machines This made this test fluky on windows CI ... --- tests/test_worker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_worker.py b/tests/test_worker.py index 7b446ac6a..839f7cdac 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -60,7 +60,7 @@ def test_throttle(mocker, default_conf, caplog) -> None: assert result == 42 assert end - start > 0.1 - assert log_has_re(r"Throttling with 'throttled_func\(\)': sleep for 0\.10 s.*", caplog) + assert log_has_re(r"Throttling with 'throttled_func\(\)': sleep for \d\.\d{2} s.*", caplog) result = worker._throttle(throttled_func, throttle_secs=-1) assert result == 42 From 7a3660cd6b0abca9dc42017f0c2303c602e05a67 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 5 Mar 2020 17:44:21 +0300 Subject: [PATCH 0699/1106] Adjust webhook tests --- tests/rpc/test_rpc_webhook.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/rpc/test_rpc_webhook.py b/tests/rpc/test_rpc_webhook.py index 3f3f36766..1ced62746 100644 --- a/tests/rpc/test_rpc_webhook.py +++ b/tests/rpc/test_rpc_webhook.py @@ -28,12 +28,12 @@ def get_webhook_dict() -> dict: "webhooksell": { "value1": "Selling {pair}", "value2": "limit {limit:8f}", - "value3": "profit: {profit_amount:8f} {stake_currency}" + "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" }, "webhooksellcancel": { "value1": "Cancelling Open Sell Order for {pair}", "value2": "limit {limit:8f}", - "value3": "profit: {profit_amount:8f} {stake_currency}" + "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" }, "webhookstatus": { "value1": "Status: {status}", @@ -110,7 +110,7 @@ def test_send_msg(default_conf, mocker): 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, - 'profit_percent': 0.20, + 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': SellType.STOP_LOSS.value } @@ -136,7 +136,7 @@ def test_send_msg(default_conf, mocker): 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, - 'profit_percent': 0.20, + 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': SellType.STOP_LOSS.value } From eee5727426fd0001ec8ddfdbf529dac435d503c4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 5 Mar 2020 17:44:38 +0300 Subject: [PATCH 0700/1106] Adjust webhook docs --- docs/webhook-config.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/webhook-config.md b/docs/webhook-config.md index e53aa8af5..70a41dd46 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -23,12 +23,12 @@ Sample configuration (tested using IFTTT). "webhooksell": { "value1": "Selling {pair}", "value2": "limit {limit:8f}", - "value3": "profit: {profit_amount:8f} {stake_currency}" + "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" }, "webhooksellcancel": { "value1": "Cancelling Open Sell Order for {pair}", "value2": "limit {limit:8f}", - "value3": "profit: {profit_amount:8f} {stake_currency}" + "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" }, "webhookstatus": { "value1": "Status: {status}", @@ -87,7 +87,7 @@ Possible parameters are: * `open_rate` * `current_rate` * `profit_amount` -* `profit_percent` +* `profit_ratio` * `stake_currency` * `fiat_currency` * `sell_reason` @@ -108,7 +108,7 @@ Possible parameters are: * `open_rate` * `current_rate` * `profit_amount` -* `profit_percent` +* `profit_ratio` * `stake_currency` * `fiat_currency` * `sell_reason` From 91db75a7073763d8c00c1057b5485d50e5103e46 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 5 Mar 2020 19:43:43 +0100 Subject: [PATCH 0701/1106] Added tests and updated doc --- docs/utils.md | 3 +++ freqtrade/commands/cli_options.py | 3 ++- freqtrade/commands/hyperopt_commands.py | 13 +++++++------ tests/commands/test_commands.py | 16 +++++++++++++++- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index cdf0c31af..dd7a9dfe3 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -450,6 +450,9 @@ optional arguments: useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. --no-details Do not print best epoch details. + --export-csv FILE Export to CSV-File. Put + in front of filename to + overwrite. This will disable table print. Example: + --export-csv +hyperopt.csv Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 77fba8eef..b782c2fb9 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -224,7 +224,8 @@ AVAILABLE_CLI_OPTIONS = { "export_csv": Arg( '--export-csv', help='Export to CSV-File. Put + in front of filename to overwrite.' - 'Example: --export-csv +hyperopt.csv', + ' This will disable table print.' + ' Example: --export-csv +hyperopt.csv', metavar='FILE', ), "hyperopt_jobs": Arg( diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index f4f119351..efc9aba88 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -50,17 +50,18 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: if print_colorized: colorama_init(autoreset=True) - try: - Hyperopt.print_result_table(config, trials, total_epochs, - not filteroptions['only_best'], print_colorized, 0) - except KeyboardInterrupt: - print('User interrupted..') + if not export_csv: + try: + Hyperopt.print_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized, 0) + except KeyboardInterrupt: + print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) results = sorted_trials[0] Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) - print(export_csv) + if trials and export_csv: overwrite_csv = False if export_csv[0] == '+': diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 3e1c0a581..58e97fd49 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -902,7 +902,21 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) - + args = [ + "hyperopt-list", + "--no-details", + "--export-csv", "+test_file.csv" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in ["CSV-File created!"]) + f = Path("test_file.csv") + assert 'Best,1,2,-1.25%,-0.00125625,,-2.51,"3,930.0 m",0.43662' in f.read_text() + assert f.is_file() + f.unlink() def test_hyperopt_show(mocker, capsys, hyperopt_results): mocker.patch( From f0d56e23a340e77dac0c6cd64ea3de2eeaedc1c4 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 5 Mar 2020 19:58:01 +0100 Subject: [PATCH 0702/1106] PEP8 fix --- tests/commands/test_commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 58e97fd49..f404a4671 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -918,6 +918,7 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert f.is_file() f.unlink() + def test_hyperopt_show(mocker, capsys, hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.load_previous_results', From 4474482307cb280bd3119dc7a34b96cb3582339b Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Thu, 5 Mar 2020 20:44:29 +0100 Subject: [PATCH 0703/1106] unifying get_sell_rate with get_buy_rate --- freqtrade/freqtradebot.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4cbacdb1e..c800e4f7f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -246,7 +246,7 @@ class FreqtradeBot: if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False): logger.info( f"Getting price from order book {bid_strategy['price_side'].capitalize()} side." - ) + ) order_book_top = bid_strategy.get('order_book_top', 1) order_book = self.exchange.get_order_book(pair, order_book_top) logger.debug('order_book %s', order_book) @@ -643,14 +643,16 @@ class FreqtradeBot: logger.info(f"Using cached sell rate for {pair}.") return rate - config_ask_strategy = self.config.get('ask_strategy', {}) - if config_ask_strategy.get('use_order_book', False): + ask_strategy = self.config.get('ask_strategy', {}) + if ask_strategy.get('use_order_book', False): # This code is only used for notifications, selling uses the generator directly - logger.debug('Using order book to get sell rate') - rate = next(self._order_book_gen(pair, f"{config_ask_strategy['price_side']}s")) + logger.info( + f"Getting price from order book {ask_strategy['price_side'].capitalize()} side." + ) + rate = next(self._order_book_gen(pair, f"{ask_strategy['price_side']}s")) else: - rate = self.exchange.fetch_ticker(pair)[config_ask_strategy['price_side']] + rate = self.exchange.fetch_ticker(pair)[ask_strategy['price_side']] self._sell_rate_cache[pair] = rate return rate From 0587256733a1f9df8deb4ac4c6f63a2ded10e274 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Thu, 5 Mar 2020 21:57:01 +0100 Subject: [PATCH 0704/1106] minor create_trade() optimization --- freqtrade/freqtradebot.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4cbacdb1e..e5ae9043a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -246,7 +246,7 @@ class FreqtradeBot: if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False): logger.info( f"Getting price from order book {bid_strategy['price_side'].capitalize()} side." - ) + ) order_book_top = bid_strategy.get('order_book_top', 1) order_book = self.exchange.get_order_book(pair, order_book_top) logger.debug('order_book %s', order_book) @@ -394,21 +394,21 @@ class FreqtradeBot: logger.info(f"Pair {pair} is currently locked.") return False + if not self.get_free_open_trades(): + logger.debug(f"Can't open a new trade for {pair}: max number of trades is reached.") + return False + + stake_amount = self.get_trade_stake_amount(pair) + if not stake_amount: + logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.") + return False + # running get_signal on historical data fetched (buy, sell) = self.strategy.get_signal( pair, self.strategy.ticker_interval, self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) if buy and not sell: - if not self.get_free_open_trades(): - logger.debug("Can't open a new trade: max number of trades is reached.") - return False - - stake_amount = self.get_trade_stake_amount(pair) - if not stake_amount: - logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.") - return False - logger.info(f"Buy signal found: about create a new trade with stake_amount: " f"{stake_amount} ...") From b8d05d87511c6f29971a1d422b7d57eef9cda5a5 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Thu, 5 Mar 2020 22:14:05 +0100 Subject: [PATCH 0705/1106] found instance of config get without default --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4cbacdb1e..4d4ad14fc 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -246,7 +246,7 @@ class FreqtradeBot: if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False): logger.info( f"Getting price from order book {bid_strategy['price_side'].capitalize()} side." - ) + ) order_book_top = bid_strategy.get('order_book_top', 1) order_book = self.exchange.get_order_book(pair, order_book_top) logger.debug('order_book %s', order_book) @@ -669,7 +669,7 @@ class FreqtradeBot: config_ask_strategy = self.config.get('ask_strategy', {}) if (config_ask_strategy.get('use_sell_signal', True) or - config_ask_strategy.get('ignore_roi_if_buy_signal')): + config_ask_strategy.get('ignore_roi_if_buy_signal', False)): (buy, sell) = self.strategy.get_signal( trade.pair, self.strategy.ticker_interval, self.dataprovider.ohlcv(trade.pair, self.strategy.ticker_interval)) From 78908e24965405a13755f62cf25659d26c55cd51 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 6 Mar 2020 15:47:16 +0100 Subject: [PATCH 0706/1106] Fix travis build failure --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec688a1f4..0cb76b78b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: true os: - linux dist: xenial @@ -11,10 +10,10 @@ env: global: - IMAGE_NAME=freqtradeorg/freqtrade install: -- cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd .. +- cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies; cd .. - export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH - export TA_LIBRARY_PATH=${HOME}/dependencies/lib -- export TA_INCLUDE_PATH=${HOME}/dependencies/lib/include +- export TA_INCLUDE_PATH=${HOME}/dependencies/include - pip install -r requirements-dev.txt - pip install -e . jobs: From 93fc14d72653caae85bc7ae5139418c0ac0b3b3a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 11:52:02 +0100 Subject: [PATCH 0707/1106] Exchange dependencies to coingekko --- requirements-common.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-common.txt b/requirements-common.txt index 10d567a96..a844e81bc 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -11,7 +11,7 @@ wrapt==1.12.0 jsonschema==3.2.0 TA-Lib==0.4.17 tabulate==0.8.6 -coinmarketcap==5.0.3 +pycoingecko==1.2.0 jinja2==2.11.1 # find first, C search in arrays diff --git a/setup.py b/setup.py index 63a595f32..7890f862e 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,7 @@ setup(name='freqtrade', 'jsonschema', 'TA-Lib', 'tabulate', - 'coinmarketcap', + 'pycoingecko', 'py_find_1st', 'python-rapidjson', 'sdnotify', From df5adb6ca59358aa2df47039b66deb89f900dda0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 11:52:26 +0100 Subject: [PATCH 0708/1106] Exchange coingekko for coinmarketcap --- freqtrade/rpc/fiat_convert.py | 52 ++++++++++++++++---------------- tests/conftest.py | 24 +++++++-------- tests/rpc/test_fiat_convert.py | 54 +++++++++++++++++----------------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/freqtrade/rpc/fiat_convert.py b/freqtrade/rpc/fiat_convert.py index d40f9221e..99d06dde0 100644 --- a/freqtrade/rpc/fiat_convert.py +++ b/freqtrade/rpc/fiat_convert.py @@ -7,7 +7,7 @@ import logging import time from typing import Dict, List -from coinmarketcap import Market +from pycoingecko import CoinGeckoAPI from freqtrade.constants import SUPPORTED_FIAT @@ -38,8 +38,8 @@ class CryptoFiat: # Private attributes self._expiration = 0.0 - self.crypto_symbol = crypto_symbol.upper() - self.fiat_symbol = fiat_symbol.upper() + self.crypto_symbol = crypto_symbol.lower() + self.fiat_symbol = fiat_symbol.lower() self.set_price(price=price) def set_price(self, price: float) -> None: @@ -67,17 +67,20 @@ class CryptoToFiatConverter: This object is also a Singleton """ __instance = None - _coinmarketcap: Market = None + _coingekko: CoinGeckoAPI = None _cryptomap: Dict = {} def __new__(cls): + """ + This class is a singleton - should not be instanciated twice. + """ if CryptoToFiatConverter.__instance is None: CryptoToFiatConverter.__instance = object.__new__(cls) try: - CryptoToFiatConverter._coinmarketcap = Market() + CryptoToFiatConverter._coingekko = CoinGeckoAPI() except BaseException: - CryptoToFiatConverter._coinmarketcap = None + CryptoToFiatConverter._coingekko = None return CryptoToFiatConverter.__instance def __init__(self) -> None: @@ -86,14 +89,12 @@ class CryptoToFiatConverter: def _load_cryptomap(self) -> None: try: - coinlistings = self._coinmarketcap.listings() - self._cryptomap = dict(map(lambda coin: (coin["symbol"], str(coin["id"])), - coinlistings["data"])) - except (BaseException) as exception: + coinlistings = self._coingekko.get_coins_list() + # Create mapping table from synbol to coingekko_id + self._cryptomap = {x['symbol']: x['id'] for x in coinlistings} + except (Exception) as exception: logger.error( - "Could not load FIAT Cryptocurrency map for the following problem: %s", - type(exception).__name__ - ) + f"Could not load FIAT Cryptocurrency map for the following problem: {exception}") def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float: """ @@ -115,8 +116,8 @@ class CryptoToFiatConverter: :param fiat_symbol: FIAT currency you want to convert to (e.g USD) :return: Price in FIAT """ - crypto_symbol = crypto_symbol.upper() - fiat_symbol = fiat_symbol.upper() + crypto_symbol = crypto_symbol.lower() + fiat_symbol = fiat_symbol.lower() # Check if the fiat convertion you want is supported if not self._is_supported_fiat(fiat=fiat_symbol): @@ -170,15 +171,13 @@ class CryptoToFiatConverter: :return: bool, True supported, False not supported """ - fiat = fiat.upper() - - return fiat in SUPPORTED_FIAT + return fiat.upper() in SUPPORTED_FIAT def _find_price(self, crypto_symbol: str, fiat_symbol: str) -> float: """ - Call CoinMarketCap API to retrieve the price in the FIAT - :param crypto_symbol: Crypto-currency you want to convert (e.g BTC) - :param fiat_symbol: FIAT currency you want to convert to (e.g USD) + Call CoinGekko API to retrieve the price in the FIAT + :param crypto_symbol: Crypto-currency you want to convert (e.g btc) + :param fiat_symbol: FIAT currency you want to convert to (e.g usd) :return: float, price of the crypto-currency in Fiat """ # Check if the fiat convertion you want is supported @@ -195,12 +194,13 @@ class CryptoToFiatConverter: return 0.0 try: + _gekko_id = self._cryptomap[crypto_symbol] return float( - self._coinmarketcap.ticker( - currency=self._cryptomap[crypto_symbol], - convert=fiat_symbol - )['data']['quotes'][fiat_symbol.upper()]['price'] + self._coingekko.get_price( + ids=_gekko_id, + vs_currencies=fiat_symbol + )[_gekko_id][fiat_symbol] ) - except BaseException as exception: + except Exception as exception: logger.error("Error in _find_price: %s", exception) return 0.0 diff --git a/tests/conftest.py b/tests/conftest.py index 000f62868..e8e3fe9e3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -167,23 +167,23 @@ def patch_get_signal(freqtrade: FreqtradeBot, value=(True, False)) -> None: @pytest.fixture(autouse=True) -def patch_coinmarketcap(mocker) -> None: +def patch_coingekko(mocker) -> None: """ - Mocker to coinmarketcap to speed up tests - :param mocker: mocker to patch coinmarketcap class + Mocker to coingekko to speed up tests + :param mocker: mocker to patch coingekko class :return: None """ - tickermock = MagicMock(return_value={'price_usd': 12345.0}) - listmock = MagicMock(return_value={'data': [{'id': 1, 'name': 'Bitcoin', 'symbol': 'BTC', - 'website_slug': 'bitcoin'}, - {'id': 1027, 'name': 'Ethereum', 'symbol': 'ETH', - 'website_slug': 'ethereum'} - ]}) + tickermock = MagicMock(return_value={'bitcoin': {'usd': 12345.0}, 'ethereum': {'usd': 12345.0}}) + listmock = MagicMock(return_value=[{'id': 'bitcoin', 'name': 'Bitcoin', 'symbol': 'btc', + 'website_slug': 'bitcoin'}, + {'id': 'ethereum', 'name': 'Ethereum', 'symbol': 'eth', + 'website_slug': 'ethereum'} + ]) mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=tickermock, - listings=listmock, + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=tickermock, + get_coins_list=listmock, ) diff --git a/tests/rpc/test_fiat_convert.py b/tests/rpc/test_fiat_convert.py index 05760ce25..ed21bc516 100644 --- a/tests/rpc/test_fiat_convert.py +++ b/tests/rpc/test_fiat_convert.py @@ -8,7 +8,7 @@ import pytest from requests.exceptions import RequestException from freqtrade.rpc.fiat_convert import CryptoFiat, CryptoToFiatConverter -from tests.conftest import log_has +from tests.conftest import log_has, log_has_re def test_pair_convertion_object(): @@ -22,8 +22,8 @@ def test_pair_convertion_object(): assert pair_convertion.CACHE_DURATION == 6 * 60 * 60 # Check a regular usage - assert pair_convertion.crypto_symbol == 'BTC' - assert pair_convertion.fiat_symbol == 'USD' + assert pair_convertion.crypto_symbol == 'btc' + assert pair_convertion.fiat_symbol == 'usd' assert pair_convertion.price == 12345.0 assert pair_convertion.is_expired() is False @@ -57,15 +57,15 @@ def test_fiat_convert_add_pair(mocker): fiat_convert._add_pair(crypto_symbol='btc', fiat_symbol='usd', price=12345.0) pair_len = len(fiat_convert._pairs) assert pair_len == 1 - assert fiat_convert._pairs[0].crypto_symbol == 'BTC' - assert fiat_convert._pairs[0].fiat_symbol == 'USD' + assert fiat_convert._pairs[0].crypto_symbol == 'btc' + assert fiat_convert._pairs[0].fiat_symbol == 'usd' assert fiat_convert._pairs[0].price == 12345.0 fiat_convert._add_pair(crypto_symbol='btc', fiat_symbol='Eur', price=13000.2) pair_len = len(fiat_convert._pairs) assert pair_len == 2 - assert fiat_convert._pairs[1].crypto_symbol == 'BTC' - assert fiat_convert._pairs[1].fiat_symbol == 'EUR' + assert fiat_convert._pairs[1].crypto_symbol == 'btc' + assert fiat_convert._pairs[1].fiat_symbol == 'eur' assert fiat_convert._pairs[1].price == 13000.2 @@ -100,15 +100,15 @@ def test_fiat_convert_get_price(mocker): fiat_convert = CryptoToFiatConverter() - with pytest.raises(ValueError, match=r'The fiat US DOLLAR is not supported.'): - fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='US Dollar') + with pytest.raises(ValueError, match=r'The fiat us dollar is not supported.'): + fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='US Dollar') # Check the value return by the method pair_len = len(fiat_convert._pairs) assert pair_len == 0 - assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='USD') == 28000.0 - assert fiat_convert._pairs[0].crypto_symbol == 'BTC' - assert fiat_convert._pairs[0].fiat_symbol == 'USD' + assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 28000.0 + assert fiat_convert._pairs[0].crypto_symbol == 'btc' + assert fiat_convert._pairs[0].fiat_symbol == 'usd' assert fiat_convert._pairs[0].price == 28000.0 assert fiat_convert._pairs[0]._expiration != 0 assert len(fiat_convert._pairs) == 1 @@ -116,13 +116,13 @@ def test_fiat_convert_get_price(mocker): # Verify the cached is used fiat_convert._pairs[0].price = 9867.543 expiration = fiat_convert._pairs[0]._expiration - assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='USD') == 9867.543 + assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 9867.543 assert fiat_convert._pairs[0]._expiration == expiration # Verify the cache expiration expiration = time.time() - 2 * 60 * 60 fiat_convert._pairs[0]._expiration = expiration - assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='USD') == 28000.0 + assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 28000.0 assert fiat_convert._pairs[0]._expiration is not expiration @@ -143,15 +143,15 @@ def test_loadcryptomap(mocker): fiat_convert = CryptoToFiatConverter() assert len(fiat_convert._cryptomap) == 2 - assert fiat_convert._cryptomap["BTC"] == "1" + assert fiat_convert._cryptomap["btc"] == "bitcoin" def test_fiat_init_network_exception(mocker): # Because CryptoToFiatConverter is a Singleton we reset the listings listmock = MagicMock(side_effect=RequestException) mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - listings=listmock, + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_coins_list=listmock, ) # with pytest.raises(RequestEsxception): fiat_convert = CryptoToFiatConverter() @@ -163,24 +163,24 @@ def test_fiat_init_network_exception(mocker): def test_fiat_convert_without_network(mocker): - # Because CryptoToFiatConverter is a Singleton we reset the value of _coinmarketcap + # Because CryptoToFiatConverter is a Singleton we reset the value of _coingekko fiat_convert = CryptoToFiatConverter() - cmc_temp = CryptoToFiatConverter._coinmarketcap - CryptoToFiatConverter._coinmarketcap = None + cmc_temp = CryptoToFiatConverter._coingekko + CryptoToFiatConverter._coingekko = None - assert fiat_convert._coinmarketcap is None - assert fiat_convert._find_price(crypto_symbol='BTC', fiat_symbol='USD') == 0.0 - CryptoToFiatConverter._coinmarketcap = cmc_temp + assert fiat_convert._coingekko is None + assert fiat_convert._find_price(crypto_symbol='btc', fiat_symbol='usd') == 0.0 + CryptoToFiatConverter._coingekko = cmc_temp def test_fiat_invalid_response(mocker, caplog): # Because CryptoToFiatConverter is a Singleton we reset the listings listmock = MagicMock(return_value="{'novalidjson':DEADBEEFf}") mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - listings=listmock, + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_coins_list=listmock, ) # with pytest.raises(RequestEsxception): fiat_convert = CryptoToFiatConverter() @@ -189,8 +189,8 @@ def test_fiat_invalid_response(mocker, caplog): length_cryptomap = len(fiat_convert._cryptomap) assert length_cryptomap == 0 - assert log_has('Could not load FIAT Cryptocurrency map for the following problem: TypeError', - caplog) + assert log_has_re('Could not load FIAT Cryptocurrency map for the following problem: .*', + caplog) def test_convert_amount(mocker): From acea49beaf364bc9890a4d08e0897fe45fd8ff0e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 13:01:26 +0100 Subject: [PATCH 0709/1106] Fix tests / test mocks --- tests/rpc/test_rpc.py | 22 +++++++++++----------- tests/rpc/test_rpc_telegram.py | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 6319ab9e6..47ffb771b 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -95,8 +95,8 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=MagicMock(return_value={'price_usd': 15000.0}), + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), ) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) @@ -178,7 +178,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, day[1] == '0.00006217 BTC') assert (day[2] == '0.000 USD' or - day[2] == '0.933 USD') + day[2] == '0.767 USD') # ensure first day is current date assert str(days[0][0]) == str(datetime.utcnow().date()) @@ -190,8 +190,8 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, limit_buy_order, limit_sell_order, mocker) -> None: mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=MagicMock(return_value={'price_usd': 15000.0}), + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), ) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) @@ -273,8 +273,8 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, ticker_sell_up, limit_buy_order, limit_sell_order): mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=MagicMock(return_value={'price_usd': 15000.0}), + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), ) mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) @@ -341,8 +341,8 @@ def test_rpc_balance_handle_error(default_conf, mocker): # ETH will be skipped due to mocked Error below mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=MagicMock(return_value={'price_usd': 15000.0}), + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), ) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) @@ -380,8 +380,8 @@ def test_rpc_balance_handle(default_conf, mocker, tickers): } mocker.patch.multiple( - 'freqtrade.rpc.fiat_convert.Market', - ticker=MagicMock(return_value={'price_usd': 15000.0}), + 'freqtrade.rpc.fiat_convert.CoinGeckoAPI', + get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}), ) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index cea863ac8..d769016c4 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -1210,7 +1210,7 @@ def test_send_msg_buy_notification(default_conf, mocker) -> None: '*Amount:* `1333.33333333`\n' \ '*Open Rate:* `0.00001099`\n' \ '*Current Rate:* `0.00001099`\n' \ - '*Total:* `(0.001000 BTC, 0.000 USD)`' + '*Total:* `(0.001000 BTC, 12.345 USD)`' def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None: From 1b3038390a5298e3774047e5aac46e6d6d9711bb Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 13:05:46 +0100 Subject: [PATCH 0710/1106] Update comment --- freqtrade/rpc/fiat_convert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/fiat_convert.py b/freqtrade/rpc/fiat_convert.py index 99d06dde0..4e26432d4 100644 --- a/freqtrade/rpc/fiat_convert.py +++ b/freqtrade/rpc/fiat_convert.py @@ -73,7 +73,7 @@ class CryptoToFiatConverter: def __new__(cls): """ - This class is a singleton - should not be instanciated twice. + This class is a singleton - cannot be instantiated twice. """ if CryptoToFiatConverter.__instance is None: CryptoToFiatConverter.__instance = object.__new__(cls) From d51bb9acfb27d090272f9a2b67fbd61cc3d3f898 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 13:11:36 +0100 Subject: [PATCH 0711/1106] Update conda environment file --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 4e8c1efcc..86ea03519 100644 --- a/environment.yml +++ b/environment.yml @@ -45,7 +45,7 @@ dependencies: - pip: # Required for app - cython - - coinmarketcap + - pycoingecko - ccxt - TA-Lib - py_find_1st From 281cf577d1b63601265361c739fc04b1f404fa37 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 7 Mar 2020 17:03:31 +0100 Subject: [PATCH 0712/1106] Remove unsupported FIAT --- freqtrade/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index ac1a8a6a9..54f620631 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -43,7 +43,7 @@ SUPPORTED_FIAT = [ "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD", - "BTC", "XBT", "ETH", "XRP", "LTC", "BCH", "USDT" + "BTC", "ETH", "XRP", "LTC", "BCH" ] MINIMAL_CONFIG = { From 3208faf7ede6be0898951b8d0bffd2966071f1b7 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 8 Mar 2020 13:35:31 +0300 Subject: [PATCH 0713/1106] Do not use ticker where it's not a ticker --- docs/backtesting.md | 12 +-- docs/configuration.md | 8 +- docs/data-download.md | 12 +-- docs/developer.md | 6 +- docs/edge.md | 2 +- docs/exchanges.md | 4 +- docs/hyperopt.md | 17 ++-- docs/strategy-customization.md | 17 ++-- docs/utils.md | 6 +- freqtrade/commands/arguments.py | 4 +- freqtrade/commands/build_config_commands.py | 2 +- freqtrade/commands/cli_options.py | 2 +- freqtrade/configuration/timerange.py | 2 +- freqtrade/data/btanalysis.py | 10 +- freqtrade/data/converter.py | 55 +++++------ freqtrade/data/dataprovider.py | 14 +-- freqtrade/data/history/history_utils.py | 22 ++--- freqtrade/data/history/idatahandler.py | 25 +++-- freqtrade/data/history/jsondatahandler.py | 4 +- freqtrade/edge/edge_positioning.py | 16 +-- freqtrade/exchange/exchange.py | 79 +++++++-------- freqtrade/freqtradebot.py | 8 +- freqtrade/misc.py | 12 +-- freqtrade/optimize/backtesting.py | 48 ++++----- freqtrade/optimize/hyperopt.py | 12 +-- freqtrade/plot/plotting.py | 24 ++--- freqtrade/strategy/interface.py | 30 +++--- freqtrade/templates/base_strategy.py.j2 | 2 +- freqtrade/templates/sample_strategy.py | 2 +- tests/conftest.py | 23 ++--- tests/data/test_btanalysis.py | 11 +-- tests/data/test_converter.py | 28 +++--- tests/data/test_dataprovider.py | 36 +++---- tests/data/test_history.py | 48 ++++----- tests/edge/test_edge.py | 26 ++--- tests/exchange/test_exchange.py | 102 ++++++++++---------- tests/optimize/__init__.py | 10 +- tests/optimize/test_backtesting.py | 44 ++++----- tests/optimize/test_hyperopt.py | 44 ++++----- tests/strategy/strats/default_strategy.py | 2 +- tests/strategy/test_interface.py | 52 +++++----- tests/test_misc.py | 8 +- tests/test_plotting.py | 20 ++-- 43 files changed, 459 insertions(+), 452 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 79bfa2350..3d08d5332 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -11,8 +11,8 @@ Now you have good Buy and Sell strategies and some historic data, you want to te real data. This is what we call [backtesting](https://en.wikipedia.org/wiki/Backtesting). -Backtesting will use the crypto-currencies (pairs) from your config file and load ticker data from `user_data/data/` by default. -If no data is available for the exchange / pair / ticker interval combination, backtesting will ask you to download them first using `freqtrade download-data`. +Backtesting will use the crypto-currencies (pairs) from your config file and load historical candle (OHCLV) data from `user_data/data/` by default. +If no data is available for the exchange / pair / timeframe (ticker interval) combination, backtesting will ask you to download them first using `freqtrade download-data`. For details on downloading, please refer to the [Data Downloading](data-download.md) section in the documentation. The result of backtesting will confirm if your bot has better odds of making a profit than a loss. @@ -22,19 +22,19 @@ The result of backtesting will confirm if your bot has better odds of making a p ### Run a backtesting against the currencies listed in your config file -#### With 5 min tickers (Per default) +#### With 5 min candle (OHLCV) data (per default) ```bash freqtrade backtesting ``` -#### With 1 min tickers +#### With 1 min candle (OHLCV) data ```bash freqtrade backtesting --ticker-interval 1m ``` -#### Using a different on-disk ticker-data source +#### Using a different on-disk historical candle (OHLCV) data source Assume you downloaded the history data from the Bittrex exchange and kept it in the `user_data/data/bittrex-20180101` directory. You can then use this data for backtesting as follows: @@ -223,7 +223,7 @@ You can then load the trades to perform further analysis as shown in our [data a To compare multiple strategies, a list of Strategies can be provided to backtesting. -This is limited to 1 ticker-interval per run, however, data is only loaded once from disk so if you have multiple +This is limited to 1 timeframe (ticker interval) value per run. However, data is only loaded once from disk so if you have multiple strategies you'd like to compare, this will give a nice runtime boost. All listed Strategies need to be in the same directory. diff --git a/docs/configuration.md b/docs/configuration.md index 5580b9c68..42018a499 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -47,7 +47,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
**Datatype:** Boolean | `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
**Datatype:** Float (as ratio) | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
**Datatype:** Positive Float as ratio. -| `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String +| `ticker_interval` | The timeframe (ticker interval) to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
**Datatype:** String | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
*Defaults to `true`.*
**Datatype:** Boolean | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
*Defaults to `1000`.*
**Datatype:** Float @@ -113,8 +113,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
**Datatype:** Boolean | `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file.
**Datatype:** String | `user_data_dir` | Directory containing user data.
*Defaults to `./user_data/`*.
**Datatype:** String -| `dataformat_ohlcv` | Data format to use to store OHLCV historic data.
*Defaults to `json`*.
**Datatype:** String -| `dataformat_trades` | Data format to use to store trades historic data.
*Defaults to `jsongz`*.
**Datatype:** String +| `dataformat_ohlcv` | Data format to use to store historical candle (OHLCV) data.
*Defaults to `json`*.
**Datatype:** String +| `dataformat_trades` | Data format to use to store historical trades data.
*Defaults to `jsongz`*.
**Datatype:** String ### Parameters in the strategy @@ -413,7 +413,7 @@ Advanced options can be configured using the `_ft_has_params` setting, which wil Available options are listed in the exchange-class as `_ft_has_default`. -For example, to test the order type `FOK` with Kraken, and modify candle_limit to 200 (so you only get 200 candles per call): +For example, to test the order type `FOK` with Kraken, and modify candle limit to 200 (so you only get 200 candles per API call): ```json "exchange": { diff --git a/docs/data-download.md b/docs/data-download.md index 76e22f4ea..903d62854 100644 --- a/docs/data-download.md +++ b/docs/data-download.md @@ -33,7 +33,7 @@ optional arguments: Specify which tickers to download. Space-separated list. Default: `1m 5m`. --erase Clean all existing data for the selected exchange/pairs/timeframes. --data-format-ohlcv {json,jsongz} - Storage format for downloaded ohlcv data. (default: `json`). + Storage format for downloaded candle (OHLCV) data. (default: `json`). --data-format-trades {json,jsongz} Storage format for downloaded trades data. (default: `jsongz`). @@ -105,7 +105,7 @@ Common arguments: ##### Example converting data -The following command will convert all ohlcv (candle) data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process. +The following command will convert all candle (OHLCV) data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process. It'll also remove original json data files (`--erase` parameter). ``` bash @@ -192,15 +192,15 @@ Then run: freqtrade download-data --exchange binance ``` -This will download ticker data for all the currency pairs you defined in `pairs.json`. +This will download historical candle (OHLCV) data for all the currency pairs you defined in `pairs.json`. ### Other Notes - To use a different directory than the exchange specific default, use `--datadir user_data/data/some_directory`. -- To change the exchange used to download the tickers, please use a different configuration file (you'll probably need to adjust ratelimits etc.) +- To change the exchange used to download the historical data from, please use a different configuration file (you'll probably need to adjust ratelimits etc.) - To use `pairs.json` from some other directory, use `--pairs-file some_other_dir/pairs.json`. -- To download ticker data for only 10 days, use `--days 10` (defaults to 30 days). -- Use `--timeframes` to specify which tickers to download. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute tickers. +- To download historical candle (OHLCV) data for only 10 days, use `--days 10` (defaults to 30 days). +- Use `--timeframes` to specify what timeframe download the historical candle (OHLCV) data for. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute data. - To use exchange, timeframe and list of pairs as defined in your configuration file, use the `-c/--config` option. With this, the script uses the whitelist defined in the config as the list of currency pairs to download data for and does not require the pairs.json file. You can combine `-c/--config` with most other options. ### Trades (tick) data diff --git a/docs/developer.md b/docs/developer.md index ef9232a59..34b2f1ba5 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -165,7 +165,7 @@ Since CCXT does not provide unification for Stoploss On Exchange yet, we'll need ### Incomplete candles -While fetching OHLCV data, we're may end up getting incomplete candles (Depending on the exchange). +While fetching candle (OHLCV) data, we may end up getting incomplete candles (depending on the exchange). To demonstrate this, we'll use daily candles (`"1d"`) to keep things simple. We query the api (`ct.fetch_ohlcv()`) for the timeframe and look at the date of the last entry. If this entry changes or shows the date of a "incomplete" candle, then we should drop this since having incomplete candles is problematic because indicators assume that only complete candles are passed to them, and will generate a lot of false buy signals. By default, we're therefore removing the last candle assuming it's incomplete. @@ -174,14 +174,14 @@ To check how the new exchange behaves, you can use the following snippet: ``` python import ccxt from datetime import datetime -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe ct = ccxt.binance() timeframe = "1d" pair = "XLM/BTC" # Make sure to use a pair that exists on that exchange! raw = ct.fetch_ohlcv(pair, timeframe=timeframe) # convert to dataframe -df1 = parse_ticker_dataframe(raw, timeframe, pair=pair, drop_incomplete=False) +df1 = ohlcv_to_dataframe(raw, timeframe, pair=pair, drop_incomplete=False) print(df1.tail(1)) print(datetime.utcnow()) diff --git a/docs/edge.md b/docs/edge.md index 6a301b044..721f570c7 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -156,7 +156,7 @@ Edge module has following configuration options: | `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate.
This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio.
*Defaults to `0.60`.*
**Datatype:** Float | `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number.
Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return.
*Defaults to `0.20`.*
**Datatype:** Float | `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable.
Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something.
*Defaults to `10` (it is highly recommended not to decrease this number).*
**Datatype:** Integer -| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
*Defaults to `1440` (one day).*
**Datatype:** Integer +| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your timeframe (ticker interval). As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
*Defaults to `1440` (one day).*
**Datatype:** Integer | `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.
*Defaults to `false`.*
**Datatype:** Boolean ## Running Edge independently diff --git a/docs/exchanges.md b/docs/exchanges.md index 70dae0aa5..66a0e96da 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -76,8 +76,8 @@ $ pip3 install web3 ### Send incomplete candles to the strategy -Most exchanges return incomplete candles via their ohlcv / klines interface. -By default, Freqtrade assumes that incomplete candles are returned and removes the last candle assuming it's an incomplete candle. +Most exchanges return current incomplete candle via their OHLCV/klines API interface. +By default, Freqtrade assumes that incomplete candle is fetched from the exchange and removes the last candle assuming it's the incomplete candle. Whether your exchange returns incomplete candles or not can be checked using [the helper script](developer.md#Incomplete-candles) from the Contributor documentation. diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 9bc5888ce..abd7aa7ce 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -103,9 +103,10 @@ Place the corresponding settings into the following methods The configuration and rules are the same than for buy signals. To avoid naming collisions in the search-space, please prefix all sell-spaces with `sell-`. -#### Using ticker-interval as part of the Strategy +#### Using timeframe as a part of the Strategy -The Strategy exposes the ticker-interval as `self.ticker_interval`. The same value is available as class-attribute `HyperoptName.ticker_interval`. +The Strategy class exposes the timeframe (ticker interval) value as the `self.ticker_interval` attribute. +The same value is available as class-attribute `HyperoptName.ticker_interval`. In the case of the linked sample-value this would be `SampleHyperOpt.ticker_interval`. ## Solving a Mystery @@ -222,11 +223,11 @@ The `--spaces all` option determines that all possible parameters should be opti !!! Warning When switching parameters or changing configuration options, make sure to not use the argument `--continue` so temporary results can be removed. -### Execute Hyperopt with Different Ticker-Data Source +### Execute Hyperopt with different historical data source -If you would like to hyperopt parameters using an alternate ticker data that -you have on-disk, use the `--datadir PATH` option. Default hyperopt will -use data from directory `user_data/data`. +If you would like to hyperopt parameters using an alternate historical data set that +you have on-disk, use the `--datadir PATH` option. By default, hyperopt +uses data from directory `user_data/data`. ### Running Hyperopt with Smaller Testset @@ -380,7 +381,7 @@ As stated in the comment, you can also use it as the value of the `minimal_roi` #### Default ROI Search Space -If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps). Hyperopt implements adaptive ranges for ROI tables with ranges for values in the ROI steps that depend on the ticker_interval used. By default the values vary in the following ranges (for some of the most used ticker intervals, values are rounded to 5 digits after the decimal point): +If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps). Hyperopt implements adaptive ranges for ROI tables with ranges for values in the ROI steps that depend on the ticker_interval used. By default the values vary in the following ranges (for some of the most used timeframes, values are rounded to 5 digits after the decimal point): | # step | 1m | | 5m | | 1h | | 1d | | | ------ | ------ | ----------------- | -------- | ----------- | ---------- | ----------------- | ------------ | ----------------- | @@ -389,7 +390,7 @@ If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace f | 3 | 4...20 | 0.00387...0.01547 | 20...100 | 0.01...0.04 | 240...1200 | 0.02294...0.09177 | 5760...28800 | 0.04059...0.16237 | | 4 | 6...44 | 0.0 | 30...220 | 0.0 | 360...2640 | 0.0 | 8640...63360 | 0.0 | -These ranges should be sufficient in most cases. The minutes in the steps (ROI dict keys) are scaled linearly depending on the ticker interval used. The ROI values in the steps (ROI dict values) are scaled logarithmically depending on the ticker interval used. +These ranges should be sufficient in most cases. The minutes in the steps (ROI dict keys) are scaled linearly depending on the timeframe (ticker interval) used. The ROI values in the steps (ROI dict values) are scaled logarithmically depending on the timeframe used. If you have the `generate_roi_table()` and `roi_space()` methods in your custom hyperopt file, remove them in order to utilize these adaptive ROI tables and the ROI hyperoptimization space generated by Freqtrade by default. diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 4aacd3af6..7793ea148 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -84,7 +84,7 @@ def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> 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: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ @@ -284,13 +284,14 @@ If your exchange supports it, it's recommended to also set `"stoploss_on_exchang For more information on order_types please look [here](configuration.md#understand-order_types). -### Ticker interval +### Timeframe (ticker interval) This is the set of candles the bot should download and use for the analysis. Common values are `"1m"`, `"5m"`, `"15m"`, `"1h"`, however all values supported by your exchange should work. -Please note that the same buy/sell signals may work with one interval, but not the other. -This setting is accessible within the strategy by using `self.ticker_interval`. +Please note that the same buy/sell signals may work well with one timeframe, but not with the others. + +This setting is accessible within the strategy methods as the `self.ticker_interval` attribute. ### Metadata dict @@ -335,14 +336,14 @@ Please always check the mode of operation to select the correct method to get da #### Possible options for DataProvider - `available_pairs` - Property with tuples listing cached pairs with their intervals (pair, interval). -- `ohlcv(pair, timeframe)` - Currently cached ticker data for the pair, returns DataFrame or empty DataFrame. +- `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame. - `historic_ohlcv(pair, timeframe)` - Returns historical data stored on disk. - `get_pair_dataframe(pair, timeframe)` - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes). - `orderbook(pair, maximum)` - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries. - `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on Market data structure. - `runmode` - Property containing the current runmode. -#### Example: fetch live ohlcv / historic data for the first informative pair +#### Example: fetch live / historical candle (OHLCV) data for the first informative pair ``` python if self.dp: @@ -377,8 +378,8 @@ if self.dp: ``` python if self.dp: - for pair, ticker in self.dp.available_pairs: - print(f"available {pair}, {ticker}") + for pair, timeframe in self.dp.available_pairs: + print(f"available {pair}, {timeframe}") ``` #### Get data for non-tradeable pairs diff --git a/docs/utils.md b/docs/utils.md index cdf0c31af..ec9ceeac9 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -61,8 +61,8 @@ $ freqtrade new-config --config config_binance.json ? Do you want to enable Dry-run (simulated trades)? Yes ? Please insert your stake currency: BTC ? Please insert your stake amount: 0.05 -? Please insert max_open_trades (Integer or 'unlimited'): 5 -? Please insert your ticker interval: 15m +? Please insert max_open_trades (Integer or 'unlimited'): 3 +? Please insert your timeframe (ticker interval): 5m ? Please insert your display Currency (for reporting): USD ? Select exchange binance ? Do you want to enable Telegram? No @@ -258,7 +258,7 @@ All exchanges supported by the ccxt library: _1btcxe, acx, adara, allcoin, anxpr ## List Timeframes -Use the `list-timeframes` subcommand to see the list of ticker intervals (timeframes) available for the exchange. +Use the `list-timeframes` subcommand to see the list of timeframes (ticker intervals) available for the exchange. ``` usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1] diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 73e77d69d..06acea69e 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -296,7 +296,7 @@ class Arguments: # Add convert-data subcommand convert_data_cmd = subparsers.add_parser( 'convert-data', - help='Convert OHLCV data from one format to another.', + help='Convert candle (OHLCV) data from one format to another.', parents=[_common_parser], ) convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=True)) @@ -305,7 +305,7 @@ class Arguments: # Add convert-trade-data subcommand convert_trade_data_cmd = subparsers.add_parser( 'convert-trade-data', - help='Convert trade-data from one format to another.', + help='Convert trade data from one format to another.', parents=[_common_parser], ) convert_trade_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False)) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 1598fa2ae..58ac6ec27 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -76,7 +76,7 @@ def ask_user_config() -> Dict[str, Any]: { "type": "text", "name": "ticker_interval", - "message": "Please insert your ticker interval:", + "message": "Please insert your timeframe (ticker interval):", "default": "5m", }, { diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index ef674c5c2..e92acef30 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -348,7 +348,7 @@ AVAILABLE_CLI_OPTIONS = { ), "dataformat_ohlcv": Arg( '--data-format-ohlcv', - help='Storage format for downloaded ohlcv data. (default: `%(default)s`).', + help='Storage format for downloaded candle (OHLCV) data. (default: `%(default)s`).', choices=constants.AVAILABLE_DATAHANDLERS, default='json' ), diff --git a/freqtrade/configuration/timerange.py b/freqtrade/configuration/timerange.py index 3db5f6217..151003999 100644 --- a/freqtrade/configuration/timerange.py +++ b/freqtrade/configuration/timerange.py @@ -45,7 +45,7 @@ class TimeRange: """ Adjust startts by candles. Applies only if no startup-candles have been available. - :param timeframe_secs: Ticker timeframe in seconds e.g. `timeframe_to_seconds('5m')` + :param timeframe_secs: Timeframe in seconds e.g. `timeframe_to_seconds('5m')` :param startup_candles: Number of candles to move start-date forward :param min_date: Minimum data date loaded. Key kriterium to decide if start-time has to be moved diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 7972c6333..681bf6734 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -151,17 +151,17 @@ def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> p return trades -def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], - column: str = "close") -> pd.DataFrame: +def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame], + column: str = "close") -> pd.DataFrame: """ Combine multiple dataframes "column" - :param tickers: Dict of Dataframes, dict key should be pair. + :param data: Dict of Dataframes, dict key should be pair. :param column: Column in the original dataframes to use :return: DataFrame with the column renamed to the dict key, and a column named mean, containing the mean of all pairs. """ - df_comb = pd.concat([tickers[pair].set_index('date').rename( - {column: pair}, axis=1)[pair] for pair in tickers], axis=1) + df_comb = pd.concat([data[pair].set_index('date').rename( + {column: pair}, axis=1)[pair] for pair in data], axis=1) df_comb['mean'] = df_comb.mean(axis=1) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 49a2a25bc..77371bf27 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -13,12 +13,12 @@ from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS logger = logging.getLogger(__name__) -def parse_ticker_dataframe(ticker: list, timeframe: str, pair: str, *, - fill_missing: bool = True, - drop_incomplete: bool = True) -> DataFrame: +def ohlcv_to_dataframe(ohlcv: list, timeframe: str, pair: str, *, + fill_missing: bool = True, drop_incomplete: bool = True) -> DataFrame: """ - Converts a ticker-list (format ccxt.fetch_ohlcv) to a Dataframe - :param ticker: ticker list, as returned by exchange.async_get_candle_history + Converts a list with candle (OHLCV) data (in format returned by ccxt.fetch_ohlcv) + to a Dataframe + :param ohlcv: list with candle (OHLCV) data, as returned by exchange.async_get_candle_history :param timeframe: timeframe (e.g. 5m). Used to fill up eventual missing data :param pair: Pair this data is for (used to warn if fillup was necessary) :param fill_missing: fill up missing candles with 0 candles @@ -26,21 +26,18 @@ def parse_ticker_dataframe(ticker: list, timeframe: str, pair: str, *, :param drop_incomplete: Drop the last candle of the dataframe, assuming it's incomplete :return: DataFrame """ - logger.debug("Parsing tickerlist to dataframe") + logger.debug(f"Converting candle (OHLCV) data to dataframe for pair {pair}.") cols = DEFAULT_DATAFRAME_COLUMNS - frame = DataFrame(ticker, columns=cols) + df = DataFrame(ohlcv, columns=cols) - frame['date'] = to_datetime(frame['date'], - unit='ms', - utc=True, - infer_datetime_format=True) + df['date'] = to_datetime(df['date'], unit='ms', utc=True, infer_datetime_format=True) - # Some exchanges return int values for volume and even for ohlc. + # Some exchanges return int values for Volume and even for OHLC. # Convert them since TA-LIB indicators used in the strategy assume floats # and fail with exception... - frame = frame.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float', - 'volume': 'float'}) - return clean_ohlcv_dataframe(frame, timeframe, pair, + df = df.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float', + 'volume': 'float'}) + return clean_ohlcv_dataframe(df, timeframe, pair, fill_missing=fill_missing, drop_incomplete=drop_incomplete) @@ -49,11 +46,11 @@ def clean_ohlcv_dataframe(data: DataFrame, timeframe: str, pair: str, *, fill_missing: bool = True, drop_incomplete: bool = True) -> DataFrame: """ - Clense a ohlcv dataframe by + Clense a OHLCV dataframe by * Grouping it by date (removes duplicate tics) * dropping last candles if requested * Filling up missing data (if requested) - :param data: DataFrame containing ohlcv data. + :param data: DataFrame containing candle (OHLCV) data. :param timeframe: timeframe (e.g. 5m). Used to fill up eventual missing data :param pair: Pair this data is for (used to warn if fillup was necessary) :param fill_missing: fill up missing candles with 0 candles @@ -88,16 +85,16 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) """ from freqtrade.exchange import timeframe_to_minutes - ohlc_dict = { + ohlcv_dict = { 'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last', 'volume': 'sum' } - ticker_minutes = timeframe_to_minutes(timeframe) + timeframe_minutes = timeframe_to_minutes(timeframe) # Resample to create "NAN" values - df = dataframe.resample(f'{ticker_minutes}min', on='date').agg(ohlc_dict) + df = dataframe.resample(f'{timeframe_minutes}min', on='date').agg(ohlcv_dict) # Forwardfill close for missing columns df['close'] = df['close'].fillna(method='ffill') @@ -159,20 +156,20 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: """ - Converts trades list to ohlcv list + Converts trades list to OHLCV list TODO: This should get a dedicated test :param trades: List of trades, as returned by ccxt.fetch_trades. - :param timeframe: Ticker timeframe to resample data to - :return: ohlcv Dataframe. + :param timeframe: Timeframe to resample data to + :return: OHLCV Dataframe. """ from freqtrade.exchange import timeframe_to_minutes - ticker_minutes = timeframe_to_minutes(timeframe) + timeframe_minutes = timeframe_to_minutes(timeframe) df = pd.DataFrame(trades) df['datetime'] = pd.to_datetime(df['datetime']) df = df.set_index('datetime') - df_new = df['price'].resample(f'{ticker_minutes}min').ohlc() - df_new['volume'] = df['amount'].resample(f'{ticker_minutes}min').sum() + df_new = df['price'].resample(f'{timeframe_minutes}min').ohlc() + df_new['volume'] = df['amount'].resample(f'{timeframe_minutes}min').sum() df_new['date'] = df_new.index # Drop 0 volume rows df_new = df_new.dropna() @@ -206,7 +203,7 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool): """ - Convert ohlcv from one format to another format. + Convert OHLCV from one format to another :param config: Config dictionary :param convert_from: Source format :param convert_to: Target format @@ -216,7 +213,7 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: src = get_datahandler(config['datadir'], convert_from) trg = get_datahandler(config['datadir'], convert_to) timeframes = config.get('timeframes', [config.get('ticker_interval')]) - logger.info(f"Converting OHLCV for timeframe {timeframes}") + logger.info(f"Converting candle (OHLCV) for timeframe {timeframes}") if 'pairs' not in config: config['pairs'] = [] @@ -224,7 +221,7 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: for timeframe in timeframes: config['pairs'].extend(src.ohlcv_get_pairs(config['datadir'], timeframe)) - logger.info(f"Converting OHLCV for {config['pairs']}") + logger.info(f"Converting candle (OHLCV) data for {config['pairs']}") for timeframe in timeframes: for pair in config['pairs']: diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 2964d1cb7..1df710152 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -1,7 +1,7 @@ """ Dataprovider Responsible to provide data to the bot -including Klines, tickers, historic data +including ticker and orderbook data, live and historical candle (OHLCV) data Common Interface for bot and strategy to access data. """ import logging @@ -43,10 +43,10 @@ class DataProvider: def ohlcv(self, pair: str, timeframe: str = None, copy: bool = True) -> DataFrame: """ - Get ohlcv data for the given pair as DataFrame + Get candle (OHLCV) data for the given pair as DataFrame Please use the `available_pairs` method to verify which pairs are currently cached. :param pair: pair to get the data for - :param timeframe: Ticker timeframe to get data for + :param timeframe: Timeframe to get data for :param copy: copy dataframe before returning if True. Use False only for read-only operations (where the dataframe is not modified) """ @@ -58,7 +58,7 @@ class DataProvider: def historic_ohlcv(self, pair: str, timeframe: str = None) -> DataFrame: """ - Get stored historic ohlcv data + Get stored historical candle (OHLCV) data :param pair: pair to get the data for :param timeframe: timeframe to get data for """ @@ -69,17 +69,17 @@ class DataProvider: def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame: """ - Return pair ohlcv data, either live or cached historical -- depending + Return pair candle (OHLCV) data, either live or cached historical -- depending on the runmode. :param pair: pair to get the data for :param timeframe: timeframe to get data for :return: Dataframe for this pair """ if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE): - # Get live ohlcv data. + # Get live OHLCV data. data = self.ohlcv(pair=pair, timeframe=timeframe) else: - # Get historic ohlcv data (cached on disk). + # Get historical OHLCV data (cached on disk). data = self.historic_ohlcv(pair=pair, timeframe=timeframe) if len(data) == 0: logger.warning(f"No data found for ({pair}, {timeframe}).") diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 5f9a7da20..89d29d33b 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -9,7 +9,7 @@ from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS -from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv +from freqtrade.data.converter import ohlcv_to_dataframe, trades_to_ohlcv from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange @@ -28,10 +28,10 @@ def load_pair_history(pair: str, data_handler: IDataHandler = None, ) -> DataFrame: """ - Load cached ticker history for the given pair. + Load cached ohlcv history for the given pair. :param pair: Pair to load data for - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param datadir: Path to the data storage location. :param data_format: Format of the data. Ignored if data_handler is set. :param timerange: Limit data to be loaded to this timerange @@ -63,10 +63,10 @@ def load_data(datadir: Path, data_format: str = 'json', ) -> Dict[str, DataFrame]: """ - Load ticker history data for a list of pairs. + Load ohlcv history data for a list of pairs. :param datadir: Path to the data storage location. - :param timeframe: Ticker Timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param pairs: List of pairs to load :param timerange: Limit data to be loaded to this timerange :param fill_up_missing: Fill missing values with "No action"-candles @@ -104,10 +104,10 @@ def refresh_data(datadir: Path, timerange: Optional[TimeRange] = None, ) -> None: """ - Refresh ticker history data for a list of pairs. + Refresh ohlcv history data for a list of pairs. :param datadir: Path to the data storage location. - :param timeframe: Ticker Timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param pairs: List of pairs to load :param exchange: Exchange object :param timerange: Limit data to be loaded to this timerange @@ -165,7 +165,7 @@ def _download_pair_history(datadir: Path, Based on @Rybolov work: https://github.com/rybolov/freqtrade-data :param pair: pair to download - :param timeframe: Ticker Timeframe (e.g 5m) + :param timeframe: Timeframe (e.g "5m") :param timerange: range of time to download :return: bool with success state """ @@ -194,8 +194,8 @@ def _download_pair_history(datadir: Path, days=-30).float_timestamp) * 1000 ) # TODO: Maybe move parsing to exchange class (?) - new_dataframe = parse_ticker_dataframe(new_data, timeframe, pair, - fill_missing=False, drop_incomplete=True) + new_dataframe = ohlcv_to_dataframe(new_data, timeframe, pair, + fill_missing=False, drop_incomplete=True) if data.empty: data = new_dataframe else: @@ -362,7 +362,7 @@ def validate_backtest_data(data: DataFrame, pair: str, min_date: datetime, :param pair: pair used for log output. :param min_date: start-date of the data :param max_date: end-date of the data - :param timeframe_min: ticker Timeframe in minutes + :param timeframe_min: Timeframe in minutes """ # total difference in minutes / timeframe-minutes expected_frames = int((max_date - min_date).total_seconds() // 60 // timeframe_min) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index df03e7713..b08292604 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -55,7 +55,7 @@ class IDataHandler(ABC): Implements the loading and conversion to a Pandas dataframe. Timerange trimming and dataframe validation happens outside of this method. :param pair: Pair to load data - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange. Optionally implemented by subclasses to avoid loading all data where possible. @@ -67,7 +67,7 @@ class IDataHandler(ABC): """ Remove data for this pair :param pair: Delete data for this pair. - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :return: True when deleted, false if file did not exist. """ @@ -129,10 +129,10 @@ class IDataHandler(ABC): warn_no_data: bool = True ) -> DataFrame: """ - Load cached ticker history for the given pair. + Load cached candle (OHLCV) data for the given pair. :param pair: Pair to load data for - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange :param fill_missing: Fill missing values with "No action"-candles :param drop_incomplete: Drop last candle assuming it may be incomplete. @@ -145,28 +145,27 @@ class IDataHandler(ABC): if startup_candles > 0 and timerange_startup: timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles) - pairdf = self._ohlcv_load(pair, timeframe, - timerange=timerange_startup) - if pairdf.empty: + df = self._ohlcv_load(pair, timeframe, timerange=timerange_startup) + if df.empty: if warn_no_data: logger.warning( f'No history data for pair: "{pair}", timeframe: {timeframe}. ' 'Use `freqtrade download-data` to download the data' ) - return pairdf + return df else: - enddate = pairdf.iloc[-1]['date'] + enddate = df.iloc[-1]['date'] if timerange_startup: - self._validate_pairdata(pair, pairdf, timerange_startup) - pairdf = trim_dataframe(pairdf, timerange_startup) + self._validate_pairdata(pair, df, timerange_startup) + df = trim_dataframe(df, timerange_startup) # incomplete candles should only be dropped if we didn't trim the end beforehand. - return clean_ohlcv_dataframe(pairdf, timeframe, + return clean_ohlcv_dataframe(df, timeframe, pair=pair, fill_missing=fill_missing, drop_incomplete=(drop_incomplete and - enddate == pairdf.iloc[-1]['date'])) + enddate == df.iloc[-1]['date'])) def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange): """ diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 2b738a94a..363b03958 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -60,7 +60,7 @@ class JsonDataHandler(IDataHandler): Implements the loading and conversion to a Pandas dataframe. Timerange trimming and dataframe validation happens outside of this method. :param pair: Pair to load data - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :param timerange: Limit data to be loaded to this timerange. Optionally implemented by subclasses to avoid loading all data where possible. @@ -83,7 +83,7 @@ class JsonDataHandler(IDataHandler): """ Remove data for this pair :param pair: Delete data for this pair. - :param timeframe: Ticker timeframe (e.g. "5m") + :param timeframe: Timeframe (e.g. "5m") :return: True when deleted, false if file did not exist. """ filename = self._pair_data_filename(self._datadir, pair, timeframe) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index 57a8f4a7c..a24e29efb 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -119,7 +119,7 @@ class Edge: logger.critical("No data found. Edge is stopped ...") return False - preprocessed = self.strategy.tickerdata_to_dataframe(data) + preprocessed = self.strategy.ohlcvdata_to_dataframe(data) # Print timeframe min_date, max_date = history.get_timerange(preprocessed) @@ -137,10 +137,10 @@ class Edge: pair_data = pair_data.sort_values(by=['date']) pair_data = pair_data.reset_index(drop=True) - ticker_data = self.strategy.advise_sell( + dataframe = self.strategy.advise_sell( self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() - trades += self._find_trades_for_stoploss_range(ticker_data, pair, self._stoploss_range) + trades += self._find_trades_for_stoploss_range(dataframe, pair, self._stoploss_range) # If no trade found then exit if len(trades) == 0: @@ -359,11 +359,11 @@ class Edge: # Returning a list of pairs in order of "expectancy" return final - def _find_trades_for_stoploss_range(self, ticker_data, pair, stoploss_range): - buy_column = ticker_data['buy'].values - sell_column = ticker_data['sell'].values - date_column = ticker_data['date'].values - ohlc_columns = ticker_data[['open', 'high', 'low', 'close']].values + def _find_trades_for_stoploss_range(self, dataframe, pair, stoploss_range): + buy_column = dataframe['buy'].values + sell_column = dataframe['sell'].values + date_column = dataframe['date'].values + ohlc_columns = dataframe[['open', 'high', 'low', 'close']].values result: list = [] for stoploss in stoploss_range: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 522b4e40e..f4c94a1ca 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -18,7 +18,7 @@ from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, TRUNCATE, decimal_to_precision) from pandas import DataFrame -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.exceptions import (DependencyException, InvalidOrderException, OperationalException, TemporaryError) from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async @@ -351,7 +351,7 @@ class Exchange: def validate_timeframes(self, timeframe: Optional[str]) -> None: """ - Checks if ticker interval from config is a supported timeframe on the exchange + Check if timeframe from config is a supported timeframe on the exchange """ if not hasattr(self._api, "timeframes") or self._api.timeframes is None: # If timeframes attribute is missing (or is None), the exchange probably @@ -364,7 +364,7 @@ class Exchange: if timeframe and (timeframe not in self.timeframes): raise OperationalException( - f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}") + f"Invalid timeframe '{timeframe}'. This exchange supports: {self.timeframes}") if timeframe and timeframe_to_minutes(timeframe) < 1: raise OperationalException( @@ -599,7 +599,7 @@ class Exchange: return self._api.fetch_tickers() except ccxt.NotSupported as e: raise OperationalException( - f'Exchange {self._api.name} does not support fetching tickers in batch.' + f'Exchange {self._api.name} does not support fetching tickers in batch. ' f'Message: {e}') from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( @@ -623,13 +623,13 @@ class Exchange: def get_historic_ohlcv(self, pair: str, timeframe: str, since_ms: int) -> List: """ - Gets candle history using asyncio and returns the list of candles. - Handles all async doing. - Async over one pair, assuming we get `_ohlcv_candle_limit` candles per call. + Get candle history using asyncio and returns the list of candles. + Handles all async work for this. + Async over one pair, assuming we get `self._ohlcv_candle_limit` candles per call. :param pair: Pair to download - :param timeframe: Ticker Timeframe to get + :param timeframe: Timeframe to get data for :param since_ms: Timestamp in milliseconds to get history from - :returns List of tickers + :returns List with candle (OHLCV) data """ return asyncio.get_event_loop().run_until_complete( self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe, @@ -649,26 +649,27 @@ class Exchange: pair, timeframe, since) for since in range(since_ms, arrow.utcnow().timestamp * 1000, one_call)] - tickers = await asyncio.gather(*input_coroutines, return_exceptions=True) + results = await asyncio.gather(*input_coroutines, return_exceptions=True) - # Combine tickers + # Combine gathered results data: List = [] - for p, timeframe, ticker in tickers: + for p, timeframe, res in results: if p == pair: - data.extend(ticker) + data.extend(res) # Sort data again after extending the result - above calls return in "async order" data = sorted(data, key=lambda x: x[0]) - logger.info("downloaded %s with length %s.", pair, len(data)) + logger.info("Downloaded data for %s with length %s.", pair, len(data)) return data def refresh_latest_ohlcv(self, pair_list: List[Tuple[str, str]]) -> List[Tuple[str, List]]: """ - Refresh in-memory ohlcv asynchronously and set `_klines` with the result + Refresh in-memory OHLCV asynchronously and set `_klines` with the result Loops asynchronously over pair_list and downloads all pairs async (semi-parallel). + Only used in the dataprovider.refresh() method. :param pair_list: List of 2 element tuples containing pair, interval to refresh - :return: Returns a List of ticker-dataframes. + :return: TODO: return value is only used in the tests, get rid of it """ - logger.debug("Refreshing ohlcv data for %d pairs", len(pair_list)) + logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list)) input_coroutines = [] @@ -679,15 +680,15 @@ class Exchange: input_coroutines.append(self._async_get_candle_history(pair, timeframe)) else: logger.debug( - "Using cached ohlcv data for pair %s, timeframe %s ...", + "Using cached candle (OHLCV) data for pair %s, timeframe %s ...", pair, timeframe ) - tickers = asyncio.get_event_loop().run_until_complete( + results = asyncio.get_event_loop().run_until_complete( asyncio.gather(*input_coroutines, return_exceptions=True)) # handle caching - for res in tickers: + for res in results: if isinstance(res, Exception): logger.warning("Async code raised an exception: %s", res.__class__.__name__) continue @@ -698,13 +699,14 @@ class Exchange: if ticks: self._pairs_last_refresh_time[(pair, timeframe)] = ticks[-1][0] // 1000 # keeping parsed dataframe in cache - self._klines[(pair, timeframe)] = parse_ticker_dataframe( + self._klines[(pair, timeframe)] = ohlcv_to_dataframe( ticks, timeframe, pair=pair, fill_missing=True, drop_incomplete=self._ohlcv_partial_candle) - return tickers + + return results def _now_is_time_to_refresh(self, pair: str, timeframe: str) -> bool: - # Calculating ticker interval in seconds + # Timeframe in seconds interval_in_sec = timeframe_to_seconds(timeframe) return not ((self._pairs_last_refresh_time.get((pair, timeframe), 0) @@ -714,11 +716,11 @@ class Exchange: async def _async_get_candle_history(self, pair: str, timeframe: str, since_ms: Optional[int] = None) -> Tuple[str, str, List]: """ - Asynchronously gets candle histories using fetch_ohlcv + Asynchronously get candle history data using fetch_ohlcv returns tuple: (pair, timeframe, ohlcv_list) """ try: - # fetch ohlcv asynchronously + # Fetch OHLCV asynchronously s = '(' + arrow.get(since_ms // 1000).isoformat() + ') ' if since_ms is not None else '' logger.debug( "Fetching pair %s, interval %s, since %s %s...", @@ -728,9 +730,9 @@ class Exchange: data = await self._api_async.fetch_ohlcv(pair, timeframe=timeframe, since=since_ms) - # Because some exchange sort Tickers ASC and other DESC. - # Ex: Bittrex returns a list of tickers ASC (oldest first, newest last) - # when GDAX returns a list of tickers DESC (newest first, oldest last) + # Some exchanges sort OHLCV in ASC order and others in DESC. + # Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last) + # while GDAX returns the list of OHLCV in DESC order (newest first, oldest last) # Only sort if necessary to save computing time try: if data and data[0][0] > data[-1][0]: @@ -743,14 +745,15 @@ class Exchange: except ccxt.NotSupported as e: raise OperationalException( - f'Exchange {self._api.name} does not support fetching historical candlestick data.' - f'Message: {e}') from e + f'Exchange {self._api.name} does not support fetching historical ' + f'candle (OHLCV) data. Message: {e}') from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: - raise TemporaryError(f'Could not load ticker history for pair {pair} due to ' - f'{e.__class__.__name__}. Message: {e}') from e + raise TemporaryError(f'Could not fetch historical candle (OHLCV) data ' + f'for pair {pair} due to {e.__class__.__name__}. ' + f'Message: {e}') from e except ccxt.BaseError as e: - raise OperationalException(f'Could not fetch ticker data for pair {pair}. ' - f'Msg: {e}') from e + raise OperationalException(f'Could not fetch historical candle (OHLCV) data ' + f'for pair {pair}. Message: {e}') from e @retrier_async async def _async_fetch_trades(self, pair: str, @@ -883,14 +886,14 @@ class Exchange: until: Optional[int] = None, from_id: Optional[str] = None) -> Tuple[str, List]: """ - Gets candle history using asyncio and returns the list of candles. - Handles all async doing. - Async over one pair, assuming we get `_ohlcv_candle_limit` candles per call. + Get trade history data using asyncio. + Handles all async work and returns the list of candles. + Async over one pair, assuming we get `self._ohlcv_candle_limit` candles per call. :param pair: Pair to download :param since: Timestamp in milliseconds to get history from :param until: Timestamp in milliseconds. Defaults to current timestamp if not defined. :param from_id: Download data starting with ID (if id is known) - :returns List of tickers + :returns List of trade data """ if not self.exchange_has("fetchTrades"): raise OperationalException("This exchange does not suport downloading Trades.") diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 914b8d9cd..9897b39b4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -172,8 +172,8 @@ class FreqtradeBot: _whitelist = self.edge.adjust(_whitelist) if trades: - # Extend active-pair whitelist with pairs from open trades - # It ensures that tickers are downloaded for open trades + # Extend active-pair whitelist with pairs of open trades + # It ensures that candle (OHLCV) data are downloaded for open trades as well _whitelist.extend([trade.pair for trade in trades if trade.pair not in _whitelist]) return _whitelist @@ -628,7 +628,7 @@ class FreqtradeBot: def get_sell_rate(self, pair: str, refresh: bool) -> float: """ - Get sell rate - either using get-ticker bid or first bid based on orderbook + Get sell rate - either using ticker bid or first bid based on orderbook The orderbook portion is only used for rpc messaging, which would otherwise fail for BitMex (has no bid/ask in fetch_ticker) or remain static in any other case since it's not updating. @@ -1043,7 +1043,7 @@ class FreqtradeBot: """ profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) - # Use cached ticker here - it was updated seconds ago. + # Use cached rates here - it was updated seconds ago. current_rate = self.get_sell_rate(trade.pair, False) profit_ratio = trade.calc_profit_ratio(profit_rate) gain = "profit" if profit_ratio > 0 else "loss" diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 96bac28d8..1f52b75ec 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -81,13 +81,13 @@ def file_load_json(file): gzipfile = file # Try gzip file first, otherwise regular json file. if gzipfile.is_file(): - logger.debug('Loading ticker data from file %s', gzipfile) - with gzip.open(gzipfile) as tickerdata: - pairdata = json_load(tickerdata) + logger.debug(f"Loading historical data from file {gzipfile}") + with gzip.open(gzipfile) as datafile: + pairdata = json_load(datafile) elif file.is_file(): - logger.debug('Loading ticker data from file %s', file) - with open(file) as tickerdata: - pairdata = json_load(tickerdata) + logger.debug(f"Loading historical data from file {file}") + with open(file) as datafile: + pairdata = json_load(datafile) else: return None return pairdata diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 94441ce24..949c072c5 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -88,8 +88,8 @@ class Backtesting: validate_config_consistency(self.config) if "ticker_interval" not in self.config: - raise OperationalException("Ticker-interval needs to be set in either configuration " - "or as cli argument `--ticker-interval 5m`") + raise OperationalException("Timeframe (ticker interval) needs to be set in either " + "configuration or as cli argument `--ticker-interval 5m`") self.timeframe = str(self.config.get('ticker_interval')) self.timeframe_min = timeframe_to_minutes(self.timeframe) @@ -151,32 +151,33 @@ class Backtesting: logger.info(f'Dumping backtest results to {recordfilename}') file_dump_json(recordfilename, records) - def _get_ticker_list(self, processed: Dict) -> Dict[str, DataFrame]: + def _get_ohlcv_as_lists(self, processed: Dict) -> Dict[str, DataFrame]: """ - Helper function to convert a processed tickerlist into a list for performance reasons. + Helper function to convert a processed dataframes into lists for performance reasons. Used by backtest() - so keep this optimized for performance. """ headers = ['date', 'buy', 'open', 'close', 'sell', 'low', 'high'] - ticker: Dict = {} - # Create ticker dict + data: Dict = {} + # Create dict with data for pair, pair_data in processed.items(): pair_data.loc[:, 'buy'] = 0 # cleanup from previous run pair_data.loc[:, 'sell'] = 0 # cleanup from previous run - ticker_data = self.strategy.advise_sell( + dataframe = self.strategy.advise_sell( self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() - # to avoid using data from future, we buy/sell with signal from previous candle - ticker_data.loc[:, 'buy'] = ticker_data['buy'].shift(1) - ticker_data.loc[:, 'sell'] = ticker_data['sell'].shift(1) + # To avoid using data from future, we use buy/sell signals shifted + # from the previous candle + dataframe.loc[:, 'buy'] = dataframe['buy'].shift(1) + dataframe.loc[:, 'sell'] = dataframe['sell'].shift(1) - ticker_data.drop(ticker_data.head(1).index, inplace=True) + dataframe.drop(dataframe.head(1).index, inplace=True) # Convert from Pandas to list for performance reasons # (Looping Pandas is slow.) - ticker[pair] = [x for x in ticker_data.itertuples()] - return ticker + data[pair] = [x for x in dataframe.itertuples()] + return data def _get_close_rate(self, sell_row, trade: Trade, sell: SellCheckTuple, trade_dur: int) -> float: @@ -220,7 +221,7 @@ class Backtesting: def _get_sell_trade_entry( self, pair: str, buy_row: DataFrame, - partial_ticker: List, trade_count_lock: Dict, + partial_ohlcv: List, trade_count_lock: Dict, stake_amount: float, max_open_trades: int) -> Optional[BacktestResult]: trade = Trade( @@ -235,7 +236,7 @@ class Backtesting: ) logger.debug(f"{pair} - Backtesting emulates creation of new trade: {trade}.") # calculate win/lose forwards from buy point - for sell_row in partial_ticker: + for sell_row in partial_ohlcv: if max_open_trades > 0: # Increase trade_count_lock for every iteration trade_count_lock[sell_row.date] = trade_count_lock.get(sell_row.date, 0) + 1 @@ -259,9 +260,9 @@ class Backtesting: close_rate=closerate, sell_reason=sell.sell_type ) - if partial_ticker: + if partial_ohlcv: # no sell condition found - trade stil open at end of backtest period - sell_row = partial_ticker[-1] + sell_row = partial_ohlcv[-1] bt_res = BacktestResult(pair=pair, profit_percent=trade.calc_profit_ratio(rate=sell_row.open), profit_abs=trade.calc_profit(rate=sell_row.open), @@ -308,8 +309,9 @@ class Backtesting: trades = [] trade_count_lock: Dict = {} - # Dict of ticker-lists for performance (looping lists is a lot faster than dataframes) - ticker: Dict = self._get_ticker_list(processed) + # Use dict of lists with data for performance + # (looping lists is a lot faster than pandas DataFrames) + data: Dict = self._get_ohlcv_as_lists(processed) lock_pair_until: Dict = {} # Indexes per pair, so some pairs are allowed to have a missing start. @@ -319,12 +321,12 @@ class Backtesting: # Loop timerange and get candle for each pair at that point in time while tmp < end_date: - for i, pair in enumerate(ticker): + for i, pair in enumerate(data): if pair not in indexes: indexes[pair] = 0 try: - row = ticker[pair][indexes[pair]] + row = data[pair][indexes[pair]] except IndexError: # missing Data for one pair at the end. # Warnings for this are shown during data loading @@ -352,7 +354,7 @@ class Backtesting: # since indexes has been incremented before, we need to go one step back to # also check the buying candle for sell conditions. - trade_entry = self._get_sell_trade_entry(pair, row, ticker[pair][indexes[pair]-1:], + trade_entry = self._get_sell_trade_entry(pair, row, data[pair][indexes[pair]-1:], trade_count_lock, stake_amount, max_open_trades) @@ -395,7 +397,7 @@ class Backtesting: self._set_strategy(strat) # need to reprocess data every time to populate signals - preprocessed = self.strategy.tickerdata_to_dataframe(data) + preprocessed = self.strategy.ohlcvdata_to_dataframe(data) # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index e9ab469f4..ed58db977 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -75,8 +75,8 @@ class Hyperopt: self.trials_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') - self.tickerdata_pickle = (self.config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_tickerdata.pkl') + self.data_pickle_file = (self.config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_data.pkl') self.total_epochs = config.get('epochs', 0) self.current_best_loss = 100 @@ -130,7 +130,7 @@ class Hyperopt: """ Remove hyperopt pickle files to restart hyperopt. """ - for f in [self.tickerdata_pickle, self.trials_file]: + for f in [self.data_pickle_file, self.trials_file]: p = Path(f) if p.is_file(): logger.info(f"Removing `{p}`.") @@ -454,7 +454,7 @@ class Hyperopt: self.backtesting.strategy.trailing_only_offset_is_reached = \ d['trailing_only_offset_is_reached'] - processed = load(self.tickerdata_pickle) + processed = load(self.data_pickle_file) min_date, max_date = get_timerange(processed) @@ -570,7 +570,7 @@ class Hyperopt: self.hyperopt_table_header = -1 data, timerange = self.backtesting.load_bt_data() - preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data) + preprocessed = self.backtesting.strategy.ohlcvdata_to_dataframe(data) # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): @@ -581,7 +581,7 @@ class Hyperopt: 'Hyperopting with data from %s up to %s (%s days)..', min_date.isoformat(), max_date.isoformat(), (max_date - min_date).days ) - dump(preprocessed, self.tickerdata_pickle) + dump(preprocessed, self.data_pickle_file) # We don't need exchange instance anymore while running hyperopt self.backtesting.exchange = None # type: ignore diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index d979a40e0..cfbda6714 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -6,7 +6,7 @@ import pandas as pd from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (calculate_max_drawdown, - combine_tickers_with_mean, + combine_dataframes_with_mean, create_cum_profit, extract_trades_of_period, load_trades) from freqtrade.data.converter import trim_dataframe @@ -29,7 +29,7 @@ except ImportError: def init_plotscript(config): """ Initialize objects needed for plotting - :return: Dict with tickers, trades and pairs + :return: Dict with candle (OHLCV) data, trades and pairs """ if "pairs" in config: @@ -40,7 +40,7 @@ def init_plotscript(config): # Set timerange to use timerange = TimeRange.parse_timerange(config.get("timerange")) - tickers = load_data( + data = load_data( datadir=config.get("datadir"), pairs=pairs, timeframe=config.get('ticker_interval', '5m'), @@ -53,7 +53,7 @@ def init_plotscript(config): exportfilename=config.get('exportfilename'), ) trades = trim_dataframe(trades, timerange, 'open_time') - return {"tickers": tickers, + return {"ohlcv": data, "trades": trades, "pairs": pairs, } @@ -368,10 +368,10 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra return fig -def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame], +def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], trades: pd.DataFrame, timeframe: str) -> go.Figure: # Combine close-values for all pairs, rename columns to "pair" - df_comb = combine_tickers_with_mean(tickers, "close") + df_comb = combine_dataframes_with_mean(data, "close") # Add combined cumulative profit df_comb = create_cum_profit(df_comb, trades, 'cum_profit', timeframe) @@ -439,7 +439,7 @@ def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided - Initializes plot-script - - Get tickers data + - Get candle (OHLCV) data - Generate Dafaframes populated with indicators and signals based on configured strategy - Load trades excecuted during the selected period - Generate Plotly plot objects @@ -451,13 +451,13 @@ def load_and_plot_trades(config: Dict[str, Any]): plot_elements = init_plotscript(config) trades = plot_elements['trades'] pair_counter = 0 - for pair, data in plot_elements["tickers"].items(): + for pair, data in plot_elements["ohlcv"].items(): pair_counter += 1 logger.info("analyse pair %s", pair) - tickers = {} - tickers[pair] = data + ohlcv = {} + ohlcv[pair] = data - dataframe = strategy.analyze_ticker(tickers[pair], {'pair': pair}) + dataframe = strategy.analyze_ticker(ohlcv[pair], {'pair': pair}) trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) @@ -494,7 +494,7 @@ def plot_profit(config: Dict[str, Any]) -> None: # Create an average close price of all the pairs that were involved. # this could be useful to gauge the overall market trend - fig = generate_profit_graph(plot_elements["pairs"], plot_elements["tickers"], + fig = generate_profit_graph(plot_elements["pairs"], plot_elements["ohlcv"], trades, config.get('ticker_interval', '5m')) store_plot_file(fig, filename='freqtrade-profit-plot.html', directory=config['user_data_dir'] / "plot", auto_open=True) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index d23af3f6e..696d2b2d2 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -59,7 +59,7 @@ class IStrategy(ABC): Attributes you can use: minimal_roi -> Dict: Minimal ROI designed for the strategy stoploss -> float: optimal stoploss designed for the strategy - ticker_interval -> str: value of the ticker interval to use for the strategy + ticker_interval -> str: value of the timeframe (ticker interval) to use with the strategy """ # Strategy interface version # Default to version 2 @@ -125,7 +125,7 @@ class IStrategy(ABC): def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Populate indicators that will be used in the Buy and Sell strategy - :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ @@ -200,11 +200,11 @@ class IStrategy(ABC): def analyze_ticker(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ - Parses the given ticker history and returns a populated DataFrame + Parses the given candle (OHLCV) data and returns a populated DataFrame add several TA indicators and buy signal to it - :param dataframe: Dataframe containing ticker data + :param dataframe: Dataframe containing data from exchange :param metadata: Metadata dictionary with additional data (e.g. 'pair') - :return: DataFrame with ticker data and indicator data + :return: DataFrame of candle (OHLCV) data with indicator data and signals added """ logger.debug("TA Analysis Launched") dataframe = self.advise_indicators(dataframe, metadata) @@ -214,12 +214,12 @@ class IStrategy(ABC): def _analyze_ticker_internal(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ - Parses the given ticker history and returns a populated DataFrame + Parses the given candle (OHLCV) data and returns a populated DataFrame add several TA indicators and buy signal to it WARNING: Used internally only, may skip analysis if `process_only_new_candles` is set. - :param dataframe: Dataframe containing ticker data + :param dataframe: Dataframe containing data from exchange :param metadata: Metadata dictionary with additional data (e.g. 'pair') - :return: DataFrame with ticker data and indicator data + :return: DataFrame of candle (OHLCV) data with indicator data and signals added """ pair = str(metadata.get('pair')) @@ -251,21 +251,21 @@ class IStrategy(ABC): :return: (Buy, Sell) A bool-tuple indicating buy/sell signal """ if not isinstance(dataframe, DataFrame) or dataframe.empty: - logger.warning('Empty ticker history for pair %s', pair) + logger.warning('Empty candle (OHLCV) data for pair %s', pair) return False, False try: dataframe = self._analyze_ticker_internal(dataframe, {'pair': pair}) except ValueError as error: logger.warning( - 'Unable to analyze ticker for pair %s: %s', + 'Unable to analyze candle (OHLCV) data for pair %s: %s', pair, str(error) ) return False, False except Exception as error: logger.exception( - 'Unexpected error when analyzing ticker for pair %s: %s', + 'Unexpected error when analyzing candle (OHLCV) data for pair %s: %s', pair, str(error) ) @@ -440,19 +440,19 @@ class IStrategy(ABC): else: return current_profit > roi - def tickerdata_to_dataframe(self, tickerdata: Dict[str, DataFrame]) -> Dict[str, DataFrame]: + def ohlcvdata_to_dataframe(self, data: Dict[str, DataFrame]) -> Dict[str, DataFrame]: """ - Creates a dataframe and populates indicators for given ticker data + Creates a dataframe and populates indicators for given candle (OHLCV) data Used by optimize operations only, not during dry / live runs. """ return {pair: self.advise_indicators(pair_data, {'pair': pair}) - for pair, pair_data in tickerdata.items()} + for pair, pair_data in data.items()} def advise_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Populate indicators that will be used in the Buy and Sell strategy This method should not be overridden. - :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ diff --git a/freqtrade/templates/base_strategy.py.j2 b/freqtrade/templates/base_strategy.py.j2 index fbf083387..97a189ff4 100644 --- a/freqtrade/templates/base_strategy.py.j2 +++ b/freqtrade/templates/base_strategy.py.j2 @@ -99,7 +99,7 @@ class {{ strategy }}(IStrategy): 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: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ diff --git a/freqtrade/templates/sample_strategy.py b/freqtrade/templates/sample_strategy.py index 17372e1e0..f78489173 100644 --- a/freqtrade/templates/sample_strategy.py +++ b/freqtrade/templates/sample_strategy.py @@ -116,7 +116,7 @@ class SampleStrategy(IStrategy): 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: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ diff --git a/tests/conftest.py b/tests/conftest.py index e8e3fe9e3..64d0cd5ee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,7 @@ from telegram import Chat, Message, Update from freqtrade import constants, persistence from freqtrade.commands import Arguments -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.edge import Edge, PairInfo from freqtrade.exchange import Exchange from freqtrade.freqtradebot import FreqtradeBot @@ -849,15 +849,15 @@ def order_book_l2(): @pytest.fixture -def ticker_history_list(): +def ohlcv_history_list(): return [ [ 1511686200000, # unix timestamp ms - 8.794e-05, # open - 8.948e-05, # high - 8.794e-05, # low - 8.88e-05, # close - 0.0877869, # volume (in quote currency) + 8.794e-05, # open + 8.948e-05, # high + 8.794e-05, # low + 8.88e-05, # close + 0.0877869, # volume (in quote currency) ], [ 1511686500000, @@ -879,8 +879,9 @@ def ticker_history_list(): @pytest.fixture -def ticker_history(ticker_history_list): - return parse_ticker_dataframe(ticker_history_list, "5m", pair="UNITTEST/BTC", fill_missing=True) +def ohlcv_history(ohlcv_history_list): + return ohlcv_to_dataframe(ohlcv_history_list, "5m", pair="UNITTEST/BTC", + fill_missing=True) @pytest.fixture @@ -1195,8 +1196,8 @@ def tickers(): @pytest.fixture def result(testdatadir): with (testdatadir / 'UNITTEST_BTC-1m.json').open('r') as data_file: - return parse_ticker_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC", - fill_missing=True) + return ohlcv_to_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC", + fill_missing=True) @pytest.fixture(scope="function") diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 7e3c1f077..da5d225b9 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -8,7 +8,7 @@ from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, analyze_trade_parallelism, calculate_max_drawdown, - combine_tickers_with_mean, + combine_dataframes_with_mean, create_cum_profit, extract_trades_of_period, load_backtest_data, load_trades, @@ -120,13 +120,10 @@ def test_load_trades(default_conf, mocker): assert bt_mock.call_count == 1 -def test_combine_tickers_with_mean(testdatadir): +def test_combine_dataframes_with_mean(testdatadir): pairs = ["ETH/BTC", "ADA/BTC"] - tickers = load_data(datadir=testdatadir, - pairs=pairs, - timeframe='5m' - ) - df = combine_tickers_with_mean(tickers) + data = load_data(datadir=testdatadir, pairs=pairs, timeframe='5m') + df = combine_dataframes_with_mean(data) assert isinstance(df, DataFrame) assert "ETH/BTC" in df.columns assert "ADA/BTC" in df.columns diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index a0ec2f46f..7dff520e0 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -5,9 +5,12 @@ from freqtrade.configuration.timerange import TimeRange from freqtrade.data.converter import (convert_ohlcv_format, convert_trades_format, ohlcv_fill_up_missing_data, - parse_ticker_dataframe, trim_dataframe) -from freqtrade.data.history import (get_timerange, load_data, - load_pair_history, validate_backtest_data) + ohlcv_to_dataframe, + trim_dataframe) +from freqtrade.data.history import (get_timerange, + load_data, + load_pair_history, + validate_backtest_data) from tests.conftest import log_has from tests.data.test_history import _backup_file, _clean_test_file @@ -16,15 +19,15 @@ def test_dataframe_correct_columns(result): assert result.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume'] -def test_parse_ticker_dataframe(ticker_history_list, caplog): +def test_ohlcv_to_dataframe(ohlcv_history_list, caplog): columns = ['date', 'open', 'high', 'low', 'close', 'volume'] caplog.set_level(logging.DEBUG) # Test file with BV data - dataframe = parse_ticker_dataframe(ticker_history_list, '5m', - pair="UNITTEST/BTC", fill_missing=True) + dataframe = ohlcv_to_dataframe(ohlcv_history_list, '5m', pair="UNITTEST/BTC", + fill_missing=True) assert dataframe.columns.tolist() == columns - assert log_has('Parsing tickerlist to dataframe', caplog) + assert log_has('Converting candle (OHLCV) data to dataframe for pair UNITTEST/BTC.', caplog) def test_ohlcv_fill_up_missing_data(testdatadir, caplog): @@ -84,7 +87,8 @@ def test_ohlcv_fill_up_missing_data2(caplog): ] # Generate test-data without filling missing - data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC", fill_missing=False) + data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC", + fill_missing=False) assert len(data) == 3 caplog.set_level(logging.DEBUG) data2 = ohlcv_fill_up_missing_data(data, timeframe, "UNITTEST/BTC") @@ -140,14 +144,14 @@ def test_ohlcv_drop_incomplete(caplog): ] ] caplog.set_level(logging.DEBUG) - data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC", - fill_missing=False, drop_incomplete=False) + data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC", + fill_missing=False, drop_incomplete=False) assert len(data) == 4 assert not log_has("Dropping last candle", caplog) # Drop last candle - data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC", - fill_missing=False, drop_incomplete=True) + data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC", + fill_missing=False, drop_incomplete=True) assert len(data) == 3 assert log_has("Dropping last candle", caplog) diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 1dbe20936..2b3dda188 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -7,19 +7,19 @@ from freqtrade.state import RunMode from tests.conftest import get_patched_exchange -def test_ohlcv(mocker, default_conf, ticker_history): +def test_ohlcv(mocker, default_conf, ohlcv_history): default_conf["runmode"] = RunMode.DRY_RUN timeframe = default_conf["ticker_interval"] exchange = get_patched_exchange(mocker, default_conf) - exchange._klines[("XRP/BTC", timeframe)] = ticker_history - exchange._klines[("UNITTEST/BTC", timeframe)] = ticker_history + exchange._klines[("XRP/BTC", timeframe)] = ohlcv_history + exchange._klines[("UNITTEST/BTC", timeframe)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.DRY_RUN - assert ticker_history.equals(dp.ohlcv("UNITTEST/BTC", timeframe)) + assert ohlcv_history.equals(dp.ohlcv("UNITTEST/BTC", timeframe)) assert isinstance(dp.ohlcv("UNITTEST/BTC", timeframe), DataFrame) - assert dp.ohlcv("UNITTEST/BTC", timeframe) is not ticker_history - assert dp.ohlcv("UNITTEST/BTC", timeframe, copy=False) is ticker_history + assert dp.ohlcv("UNITTEST/BTC", timeframe) is not ohlcv_history + assert dp.ohlcv("UNITTEST/BTC", timeframe, copy=False) is ohlcv_history assert not dp.ohlcv("UNITTEST/BTC", timeframe).empty assert dp.ohlcv("NONESENSE/AAA", timeframe).empty @@ -37,8 +37,8 @@ def test_ohlcv(mocker, default_conf, ticker_history): assert dp.ohlcv("UNITTEST/BTC", timeframe).empty -def test_historic_ohlcv(mocker, default_conf, ticker_history): - historymock = MagicMock(return_value=ticker_history) +def test_historic_ohlcv(mocker, default_conf, ohlcv_history): + historymock = MagicMock(return_value=ohlcv_history) mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock) dp = DataProvider(default_conf, None) @@ -48,18 +48,18 @@ def test_historic_ohlcv(mocker, default_conf, ticker_history): assert historymock.call_args_list[0][1]["timeframe"] == "5m" -def test_get_pair_dataframe(mocker, default_conf, ticker_history): +def test_get_pair_dataframe(mocker, default_conf, ohlcv_history): default_conf["runmode"] = RunMode.DRY_RUN ticker_interval = default_conf["ticker_interval"] exchange = get_patched_exchange(mocker, default_conf) - exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history - exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history + exchange._klines[("XRP/BTC", ticker_interval)] = ohlcv_history + exchange._klines[("UNITTEST/BTC", ticker_interval)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.DRY_RUN - assert ticker_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval)) + assert ohlcv_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval)) assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame) - assert dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval) is not ticker_history + assert dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval) is not ohlcv_history assert not dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval).empty assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty @@ -73,7 +73,7 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history): assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame) assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty - historymock = MagicMock(return_value=ticker_history) + historymock = MagicMock(return_value=ohlcv_history) mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock) default_conf["runmode"] = RunMode.BACKTEST dp = DataProvider(default_conf, exchange) @@ -82,11 +82,11 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history): # assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty -def test_available_pairs(mocker, default_conf, ticker_history): +def test_available_pairs(mocker, default_conf, ohlcv_history): exchange = get_patched_exchange(mocker, default_conf) ticker_interval = default_conf["ticker_interval"] - exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history - exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history + exchange._klines[("XRP/BTC", ticker_interval)] = ohlcv_history + exchange._klines[("UNITTEST/BTC", ticker_interval)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert len(dp.available_pairs) == 2 @@ -96,7 +96,7 @@ def test_available_pairs(mocker, default_conf, ticker_history): ] -def test_refresh(mocker, default_conf, ticker_history): +def test_refresh(mocker, default_conf, ohlcv_history): refresh_mock = MagicMock() mocker.patch("freqtrade.exchange.Exchange.refresh_latest_ohlcv", refresh_mock) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 9c9af9acd..12390538a 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -12,7 +12,7 @@ from pandas import DataFrame from pandas.testing import assert_frame_equal from freqtrade.configuration import TimeRange -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.data.history.history_utils import ( _download_pair_history, _download_trades_history, _load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange, @@ -63,7 +63,7 @@ def _clean_test_file(file: Path) -> None: file_swp.rename(file) -def test_load_data_30min_ticker(mocker, caplog, default_conf, testdatadir) -> None: +def test_load_data_30min_timeframe(mocker, caplog, default_conf, testdatadir) -> None: ld = load_pair_history(pair='UNITTEST/BTC', timeframe='30m', datadir=testdatadir) assert isinstance(ld, DataFrame) assert not log_has( @@ -72,7 +72,7 @@ def test_load_data_30min_ticker(mocker, caplog, default_conf, testdatadir) -> No ) -def test_load_data_7min_ticker(mocker, caplog, default_conf, testdatadir) -> None: +def test_load_data_7min_timeframe(mocker, caplog, default_conf, testdatadir) -> None: ld = load_pair_history(pair='UNITTEST/BTC', timeframe='7m', datadir=testdatadir) assert isinstance(ld, DataFrame) assert ld.empty @@ -82,8 +82,8 @@ def test_load_data_7min_ticker(mocker, caplog, default_conf, testdatadir) -> Non ) -def test_load_data_1min_ticker(ticker_history, mocker, caplog, testdatadir) -> None: - mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history) +def test_load_data_1min_timeframe(ohlcv_history, mocker, caplog, testdatadir) -> None: + mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history) file = testdatadir / 'UNITTEST_BTC-1m.json' _backup_file(file, copy_file=True) load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC']) @@ -110,12 +110,12 @@ def test_load_data_startup_candles(mocker, caplog, default_conf, testdatadir) -> assert ltfmock.call_args_list[0][1]['timerange'].startts == timerange.startts - 20 * 60 -def test_load_data_with_new_pair_1min(ticker_history_list, mocker, caplog, +def test_load_data_with_new_pair_1min(ohlcv_history_list, mocker, caplog, default_conf, testdatadir) -> None: """ - Test load_pair_history() with 1 min ticker + Test load_pair_history() with 1 min timeframe """ - mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list) + mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list) exchange = get_patched_exchange(mocker, default_conf) file = testdatadir / 'MEME_BTC-1m.json' @@ -188,8 +188,8 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None: with open(test_filename, "rt") as file: test_data = json.load(file) - test_data_df = parse_ticker_dataframe(test_data, '1m', 'UNITTEST/BTC', - fill_missing=False, drop_incomplete=False) + test_data_df = ohlcv_to_dataframe(test_data, '1m', 'UNITTEST/BTC', + fill_missing=False, drop_incomplete=False) # now = last cached item + 1 hour now_ts = test_data[-1][0] / 1000 + 60 * 60 mocker.patch('arrow.utcnow', return_value=arrow.get(now_ts)) @@ -230,8 +230,8 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None: assert start_ts is None -def test_download_pair_history(ticker_history_list, mocker, default_conf, testdatadir) -> None: - mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list) +def test_download_pair_history(ohlcv_history_list, mocker, default_conf, testdatadir) -> None: + mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list) exchange = get_patched_exchange(mocker, default_conf) file1_1 = testdatadir / 'MEME_BTC-1m.json' file1_5 = testdatadir / 'MEME_BTC-5m.json' @@ -293,7 +293,7 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None: assert json_dump_mock.call_count == 2 -def test_download_backtesting_data_exception(ticker_history, mocker, caplog, +def test_download_backtesting_data_exception(ohlcv_history, mocker, caplog, default_conf, testdatadir) -> None: mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', side_effect=Exception('File Error')) @@ -321,15 +321,15 @@ def test_load_partial_missing(testdatadir, caplog) -> None: # Make sure we start fresh - test missing data at start start = arrow.get('2018-01-01T00:00:00') end = arrow.get('2018-01-11T00:00:00') - tickerdata = load_data(testdatadir, '5m', ['UNITTEST/BTC'], startup_candles=20, - timerange=TimeRange('date', 'date', start.timestamp, end.timestamp)) + data = load_data(testdatadir, '5m', ['UNITTEST/BTC'], startup_candles=20, + timerange=TimeRange('date', 'date', start.timestamp, end.timestamp)) assert log_has( 'Using indicator startup period: 20 ...', caplog ) # timedifference in 5 minutes td = ((end - start).total_seconds() // 60 // 5) + 1 - assert td != len(tickerdata['UNITTEST/BTC']) - start_real = tickerdata['UNITTEST/BTC'].iloc[0, 0] + assert td != len(data['UNITTEST/BTC']) + start_real = data['UNITTEST/BTC'].iloc[0, 0] assert log_has(f'Missing data at start for pair ' f'UNITTEST/BTC, data starts at {start_real.strftime("%Y-%m-%d %H:%M:%S")}', caplog) @@ -337,14 +337,14 @@ def test_load_partial_missing(testdatadir, caplog) -> None: caplog.clear() start = arrow.get('2018-01-10T00:00:00') end = arrow.get('2018-02-20T00:00:00') - tickerdata = load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'], - timerange=TimeRange('date', 'date', start.timestamp, end.timestamp)) + data = load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'], + timerange=TimeRange('date', 'date', start.timestamp, end.timestamp)) # timedifference in 5 minutes td = ((end - start).total_seconds() // 60 // 5) + 1 - assert td != len(tickerdata['UNITTEST/BTC']) + assert td != len(data['UNITTEST/BTC']) # Shift endtime with +5 - as last candle is dropped (partial candle) - end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5) + end_real = arrow.get(data['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5) assert log_has(f'Missing data at end for pair ' f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}', caplog) @@ -403,7 +403,7 @@ def test_get_timerange(default_conf, mocker, testdatadir) -> None: default_conf.update({'strategy': 'DefaultStrategy'}) strategy = StrategyResolver.load_strategy(default_conf) - data = strategy.tickerdata_to_dataframe( + data = strategy.ohlcvdata_to_dataframe( load_data( datadir=testdatadir, timeframe='1m', @@ -421,7 +421,7 @@ def test_validate_backtest_data_warn(default_conf, mocker, caplog, testdatadir) default_conf.update({'strategy': 'DefaultStrategy'}) strategy = StrategyResolver.load_strategy(default_conf) - data = strategy.tickerdata_to_dataframe( + data = strategy.ohlcvdata_to_dataframe( load_data( datadir=testdatadir, timeframe='1m', @@ -446,7 +446,7 @@ def test_validate_backtest_data(default_conf, mocker, caplog, testdatadir) -> No strategy = StrategyResolver.load_strategy(default_conf) timerange = TimeRange('index', 'index', 200, 250) - data = strategy.tickerdata_to_dataframe( + data = strategy.ohlcvdata_to_dataframe( load_data( datadir=testdatadir, timeframe='5m', diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index 2a0d19128..c68ac477c 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -11,7 +11,7 @@ import pytest from pandas import DataFrame, to_datetime from freqtrade.exceptions import OperationalException -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.edge import Edge, PairInfo from freqtrade.strategy.interface import SellType from tests.conftest import get_patched_freqtradebot, log_has @@ -26,7 +26,7 @@ from tests.optimize import (BTContainer, BTrade, _build_backtest_dataframe, # 5) Stoploss and sell are hit. should sell on stoploss #################################################################### -ticker_start_time = arrow.get(2018, 10, 3) +tests_start_time = arrow.get(2018, 10, 3) ticker_interval_in_minute = 60 _ohlc = {'date': 0, 'buy': 1, 'open': 2, 'high': 3, 'low': 4, 'close': 5, 'sell': 6, 'volume': 7} @@ -43,10 +43,10 @@ def _validate_ohlc(buy_ohlc_sell_matrice): def _build_dataframe(buy_ohlc_sell_matrice): _validate_ohlc(buy_ohlc_sell_matrice) - tickers = [] + data = [] for ohlc in buy_ohlc_sell_matrice: - ticker = { - 'date': ticker_start_time.shift( + d = { + 'date': tests_start_time.shift( minutes=( ohlc[0] * ticker_interval_in_minute)).timestamp * @@ -57,9 +57,9 @@ def _build_dataframe(buy_ohlc_sell_matrice): 'low': ohlc[4], 'close': ohlc[5], 'sell': ohlc[6]} - tickers.append(ticker) + data.append(d) - frame = DataFrame(tickers) + frame = DataFrame(data) frame['date'] = to_datetime(frame['date'], unit='ms', utc=True, @@ -69,7 +69,7 @@ def _build_dataframe(buy_ohlc_sell_matrice): def _time_on_candle(number): - return np.datetime64(ticker_start_time.shift( + return np.datetime64(tests_start_time.shift( minutes=(number * ticker_interval_in_minute)).timestamp * 1000, 'ms') @@ -262,7 +262,7 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m', NEOBTC = [ [ - ticker_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000, + tests_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000, math.sin(x * hz) / 1000 + base, math.sin(x * hz) / 1000 + base + 0.0001, math.sin(x * hz) / 1000 + base - 0.0001, @@ -274,7 +274,7 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m', base = 0.002 LTCBTC = [ [ - ticker_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000, + tests_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000, math.sin(x * hz) / 1000 + base, math.sin(x * hz) / 1000 + base + 0.0001, math.sin(x * hz) / 1000 + base - 0.0001, @@ -282,8 +282,10 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m', 123.45 ] for x in range(0, 500)] - pairdata = {'NEO/BTC': parse_ticker_dataframe(NEOBTC, '1h', pair="NEO/BTC", fill_missing=True), - 'LTC/BTC': parse_ticker_dataframe(LTCBTC, '1h', pair="LTC/BTC", fill_missing=True)} + pairdata = {'NEO/BTC': ohlcv_to_dataframe(NEOBTC, '1h', pair="NEO/BTC", + fill_missing=True), + 'LTC/BTC': ohlcv_to_dataframe(LTCBTC, '1h', pair="LTC/BTC", + fill_missing=True)} return pairdata diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 6bec53d49..8d8930f66 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -581,7 +581,7 @@ def test_validate_timeframes_failed(default_conf, mocker): mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) with pytest.raises(OperationalException, - match=r"Invalid ticker interval '3m'. This exchange supports.*"): + match=r"Invalid timeframe '3m'. This exchange supports.*"): Exchange(default_conf) default_conf["ticker_interval"] = "15s" @@ -1211,7 +1211,7 @@ def test_fetch_ticker(default_conf, mocker, exchange_name): @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name): exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) - tick = [ + ohlcv = [ [ arrow.utcnow().timestamp * 1000, # unix timestamp ms 1, # open @@ -1224,7 +1224,7 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name): pair = 'ETH/BTC' async def mock_candle_hist(pair, timeframe, since_ms): - return pair, timeframe, tick + return pair, timeframe, ohlcv exchange._async_get_candle_history = Mock(wraps=mock_candle_hist) # one_call calculation * 1.8 should do 2 calls @@ -1232,12 +1232,12 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name): ret = exchange.get_historic_ohlcv(pair, "5m", int((arrow.utcnow().timestamp - since) * 1000)) assert exchange._async_get_candle_history.call_count == 2 - # Returns twice the above tick + # Returns twice the above OHLCV data assert len(ret) == 2 def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None: - tick = [ + ohlcv = [ [ (arrow.utcnow().timestamp - 1) * 1000, # unix timestamp ms 1, # open @@ -1258,14 +1258,14 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None: caplog.set_level(logging.DEBUG) exchange = get_patched_exchange(mocker, default_conf) - exchange._api_async.fetch_ohlcv = get_mock_coro(tick) + exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv) pairs = [('IOTA/ETH', '5m'), ('XRP/ETH', '5m')] # empty dicts assert not exchange._klines exchange.refresh_latest_ohlcv(pairs) - assert log_has(f'Refreshing ohlcv data for {len(pairs)} pairs', caplog) + assert log_has(f'Refreshing candle (OHLCV) data for {len(pairs)} pairs', caplog) assert exchange._klines assert exchange._api_async.fetch_ohlcv.call_count == 2 for pair in pairs: @@ -1283,14 +1283,15 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None: exchange.refresh_latest_ohlcv([('IOTA/ETH', '5m'), ('XRP/ETH', '5m')]) assert exchange._api_async.fetch_ohlcv.call_count == 2 - assert log_has(f"Using cached ohlcv data for pair {pairs[0][0]}, timeframe {pairs[0][1]} ...", + assert log_has(f"Using cached candle (OHLCV) data for pair {pairs[0][0]}, " + f"timeframe {pairs[0][1]} ...", caplog) @pytest.mark.asyncio @pytest.mark.parametrize("exchange_name", EXCHANGES) async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_name): - tick = [ + ohlcv = [ [ arrow.utcnow().timestamp * 1000, # unix timestamp ms 1, # open @@ -1304,7 +1305,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_ caplog.set_level(logging.DEBUG) exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) # Monkey-patch async function - exchange._api_async.fetch_ohlcv = get_mock_coro(tick) + exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv) pair = 'ETH/BTC' res = await exchange._async_get_candle_history(pair, "5m") @@ -1312,9 +1313,9 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_ assert len(res) == 3 assert res[0] == pair assert res[1] == "5m" - assert res[2] == tick + assert res[2] == ohlcv assert exchange._api_async.fetch_ohlcv.call_count == 1 - assert not log_has(f"Using cached ohlcv data for {pair} ...", caplog) + assert not log_has(f"Using cached candle (OHLCV) data for {pair} ...", caplog) # exchange = Exchange(default_conf) await async_ccxt_exception(mocker, default_conf, MagicMock(), @@ -1322,14 +1323,15 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_ pair='ABCD/BTC', timeframe=default_conf['ticker_interval']) api_mock = MagicMock() - with pytest.raises(OperationalException, match=r'Could not fetch ticker data*'): + with pytest.raises(OperationalException, + match=r'Could not fetch historical candle \(OHLCV\) data.*'): api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError("Unknown error")) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) await exchange._async_get_candle_history(pair, "5m", (arrow.utcnow().timestamp - 2000) * 1000) with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching ' - r'historical candlestick data\..*'): + r'historical candle \(OHLCV\) data\..*'): api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NotSupported("Not supported")) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) await exchange._async_get_candle_history(pair, "5m", @@ -1339,7 +1341,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_ @pytest.mark.asyncio async def test__async_get_candle_history_empty(default_conf, mocker, caplog): """ Test empty exchange result """ - tick = [] + ohlcv = [] caplog.set_level(logging.DEBUG) exchange = get_patched_exchange(mocker, default_conf) @@ -1353,7 +1355,7 @@ async def test__async_get_candle_history_empty(default_conf, mocker, caplog): assert len(res) == 3 assert res[0] == pair assert res[1] == "5m" - assert res[2] == tick + assert res[2] == ohlcv assert exchange._api_async.fetch_ohlcv.call_count == 1 @@ -1431,8 +1433,8 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na return sorted(data, key=key) # GDAX use-case (real data from GDAX) - # This ticker history is ordered DESC (newest first, oldest last) - tick = [ + # This OHLCV data is ordered DESC (newest first, oldest last) + ohlcv = [ [1527833100000, 0.07666, 0.07671, 0.07666, 0.07668, 16.65244264], [1527832800000, 0.07662, 0.07666, 0.07662, 0.07666, 1.30051526], [1527832500000, 0.07656, 0.07661, 0.07656, 0.07661, 12.034778840000001], @@ -1445,31 +1447,31 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na [1527830400000, 0.07649, 0.07651, 0.07649, 0.07651, 2.5734867] ] exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) - exchange._api_async.fetch_ohlcv = get_mock_coro(tick) + exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv) sort_mock = mocker.patch('freqtrade.exchange.exchange.sorted', MagicMock(side_effect=sort_data)) - # Test the ticker history sort + # Test the OHLCV data sort res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval']) assert res[0] == 'ETH/BTC' - ticks = res[2] + res_ohlcv = res[2] assert sort_mock.call_count == 1 - assert ticks[0][0] == 1527830400000 - assert ticks[0][1] == 0.07649 - assert ticks[0][2] == 0.07651 - assert ticks[0][3] == 0.07649 - assert ticks[0][4] == 0.07651 - assert ticks[0][5] == 2.5734867 + assert res_ohlcv[0][0] == 1527830400000 + assert res_ohlcv[0][1] == 0.07649 + assert res_ohlcv[0][2] == 0.07651 + assert res_ohlcv[0][3] == 0.07649 + assert res_ohlcv[0][4] == 0.07651 + assert res_ohlcv[0][5] == 2.5734867 - assert ticks[9][0] == 1527833100000 - assert ticks[9][1] == 0.07666 - assert ticks[9][2] == 0.07671 - assert ticks[9][3] == 0.07666 - assert ticks[9][4] == 0.07668 - assert ticks[9][5] == 16.65244264 + assert res_ohlcv[9][0] == 1527833100000 + assert res_ohlcv[9][1] == 0.07666 + assert res_ohlcv[9][2] == 0.07671 + assert res_ohlcv[9][3] == 0.07666 + assert res_ohlcv[9][4] == 0.07668 + assert res_ohlcv[9][5] == 16.65244264 # Bittrex use-case (real data from Bittrex) - # This ticker history is ordered ASC (oldest first, newest last) - tick = [ + # This OHLCV data is ordered ASC (oldest first, newest last) + ohlcv = [ [1527827700000, 0.07659999, 0.0766, 0.07627, 0.07657998, 1.85216924], [1527828000000, 0.07657995, 0.07657995, 0.0763, 0.0763, 26.04051037], [1527828300000, 0.0763, 0.07659998, 0.0763, 0.0764, 10.36434124], @@ -1481,29 +1483,29 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na [1527830100000, 0.076695, 0.07671, 0.07624171, 0.07671, 1.80689244], [1527830400000, 0.07671, 0.07674399, 0.07629216, 0.07655213, 2.31452783] ] - exchange._api_async.fetch_ohlcv = get_mock_coro(tick) + exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv) # Reset sort mock sort_mock = mocker.patch('freqtrade.exchange.sorted', MagicMock(side_effect=sort_data)) - # Test the ticker history sort + # Test the OHLCV data sort res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval']) assert res[0] == 'ETH/BTC' assert res[1] == default_conf['ticker_interval'] - ticks = res[2] + res_ohlcv = res[2] # Sorted not called again - data is already in order assert sort_mock.call_count == 0 - assert ticks[0][0] == 1527827700000 - assert ticks[0][1] == 0.07659999 - assert ticks[0][2] == 0.0766 - assert ticks[0][3] == 0.07627 - assert ticks[0][4] == 0.07657998 - assert ticks[0][5] == 1.85216924 + assert res_ohlcv[0][0] == 1527827700000 + assert res_ohlcv[0][1] == 0.07659999 + assert res_ohlcv[0][2] == 0.0766 + assert res_ohlcv[0][3] == 0.07627 + assert res_ohlcv[0][4] == 0.07657998 + assert res_ohlcv[0][5] == 1.85216924 - assert ticks[9][0] == 1527830400000 - assert ticks[9][1] == 0.07671 - assert ticks[9][2] == 0.07674399 - assert ticks[9][3] == 0.07629216 - assert ticks[9][4] == 0.07655213 - assert ticks[9][5] == 2.31452783 + assert res_ohlcv[9][0] == 1527830400000 + assert res_ohlcv[9][1] == 0.07671 + assert res_ohlcv[9][2] == 0.07674399 + assert res_ohlcv[9][3] == 0.07629216 + assert res_ohlcv[9][4] == 0.07655213 + assert res_ohlcv[9][5] == 2.31452783 @pytest.mark.asyncio diff --git a/tests/optimize/__init__.py b/tests/optimize/__init__.py index 13605a38c..8bc66f02c 100644 --- a/tests/optimize/__init__.py +++ b/tests/optimize/__init__.py @@ -6,7 +6,7 @@ from pandas import DataFrame from freqtrade.exchange import timeframe_to_minutes from freqtrade.strategy.interface import SellType -ticker_start_time = arrow.get(2018, 10, 3) +tests_start_time = arrow.get(2018, 10, 3) tests_timeframe = '1h' @@ -36,14 +36,14 @@ class BTContainer(NamedTuple): def _get_frame_time_from_offset(offset): - return ticker_start_time.shift(minutes=(offset * timeframe_to_minutes(tests_timeframe)) - ).datetime + minutes = offset * timeframe_to_minutes(tests_timeframe) + return tests_start_time.shift(minutes=minutes).datetime -def _build_backtest_dataframe(ticker_with_signals): +def _build_backtest_dataframe(data): columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'buy', 'sell'] - frame = DataFrame.from_records(ticker_with_signals, columns=columns) + frame = DataFrame.from_records(data, columns=columns) frame['date'] = frame['date'].apply(_get_frame_time_from_offset) # Ensure floats are in place for column in ['open', 'high', 'low', 'close', 'volume']: diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 96855dc9d..1b6e23ffa 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -84,7 +84,7 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None: backtesting = Backtesting(config) data = load_data_test(contour, testdatadir) - processed = backtesting.strategy.tickerdata_to_dataframe(data) + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) min_date, max_date = get_timerange(processed) assert isinstance(processed, dict) results = backtesting.backtest( @@ -105,7 +105,7 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'): data = trim_dictlist(data, -201) patch_exchange(mocker) backtesting = Backtesting(conf) - processed = backtesting.strategy.tickerdata_to_dataframe(data) + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) min_date, max_date = get_timerange(processed) return { 'processed': processed, @@ -275,7 +275,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None: backtesting = Backtesting(default_conf) assert backtesting.config == default_conf assert backtesting.timeframe == '5m' - assert callable(backtesting.strategy.tickerdata_to_dataframe) + assert callable(backtesting.strategy.ohlcvdata_to_dataframe) assert callable(backtesting.strategy.advise_buy) assert callable(backtesting.strategy.advise_sell) assert isinstance(backtesting.strategy.dp, DataProvider) @@ -297,7 +297,7 @@ def test_backtesting_init_no_ticker_interval(mocker, default_conf, caplog) -> No "or as cli argument `--ticker-interval 5m`", caplog) -def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None: +def test_data_with_fee(default_conf, mocker, testdatadir) -> None: patch_exchange(mocker) default_conf['fee'] = 0.1234 @@ -307,21 +307,21 @@ def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None: assert fee_mock.call_count == 0 -def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: +def test_data_to_dataframe_bt(default_conf, mocker, testdatadir) -> None: patch_exchange(mocker) timerange = TimeRange.parse_timerange('1510694220-1510700340') - tickerlist = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, - fill_up_missing=True) + data = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) backtesting = Backtesting(default_conf) - data = backtesting.strategy.tickerdata_to_dataframe(tickerlist) - assert len(data['UNITTEST/BTC']) == 102 + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) + assert len(processed['UNITTEST/BTC']) == 102 # Load strategy to compare the result between Backtesting function and strategy are the same default_conf.update({'strategy': 'DefaultStrategy'}) strategy = StrategyResolver.load_strategy(default_conf) - data2 = strategy.tickerdata_to_dataframe(tickerlist) - assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC']) + processed2 = strategy.ohlcvdata_to_dataframe(data) + assert processed['UNITTEST/BTC'].equals(processed2['UNITTEST/BTC']) def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: @@ -329,7 +329,6 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) - mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) @@ -360,7 +359,6 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> mocker.patch('freqtrade.data.history.history_utils.load_pair_history', MagicMock(return_value=pd.DataFrame())) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) - mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock()) patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) @@ -385,10 +383,10 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None: timerange = TimeRange('date', None, 1517227800, 0) data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'], timerange=timerange) - data_processed = backtesting.strategy.tickerdata_to_dataframe(data) - min_date, max_date = get_timerange(data_processed) + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) + min_date, max_date = get_timerange(processed) results = backtesting.backtest( - processed=data_processed, + processed=processed, stake_amount=default_conf['stake_amount'], start_date=min_date, end_date=max_date, @@ -416,7 +414,7 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None: 'sell_reason': [SellType.ROI, SellType.ROI] }) pd.testing.assert_frame_equal(results, expected) - data_pair = data_processed[pair] + data_pair = processed[pair] for _, t in results.iterrows(): ln = data_pair.loc[data_pair["date"] == t["open_time"]] # Check open trade rate alignes to open rate @@ -439,7 +437,7 @@ def test_backtest_1min_ticker_interval(default_conf, fee, mocker, testdatadir) - timerange = TimeRange.parse_timerange('1510688220-1510700340') data = history.load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC'], timerange=timerange) - processed = backtesting.strategy.tickerdata_to_dataframe(data) + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) min_date, max_date = get_timerange(processed) results = backtesting.backtest( processed=processed, @@ -458,7 +456,7 @@ def test_processed(default_conf, mocker, testdatadir) -> None: backtesting = Backtesting(default_conf) dict_of_tickerrows = load_data_test('raise', testdatadir) - dataframes = backtesting.strategy.tickerdata_to_dataframe(dict_of_tickerrows) + dataframes = backtesting.strategy.ohlcvdata_to_dataframe(dict_of_tickerrows) dataframe = dataframes['UNITTEST/BTC'] cols = dataframe.columns # assert the dataframe got some of the indicator columns @@ -557,10 +555,10 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) backtesting.strategy.advise_buy = _trend_alternate_hold # Override backtesting.strategy.advise_sell = _trend_alternate_hold # Override - data_processed = backtesting.strategy.tickerdata_to_dataframe(data) - min_date, max_date = get_timerange(data_processed) + processed = backtesting.strategy.ohlcvdata_to_dataframe(data) + min_date, max_date = get_timerange(processed) backtest_conf = { - 'processed': data_processed, + 'processed': processed, 'stake_amount': default_conf['stake_amount'], 'start_date': min_date, 'end_date': max_date, @@ -576,7 +574,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) assert len(evaluate_result_multi(results, '5m', 3)) == 0 backtest_conf = { - 'processed': data_processed, + 'processed': processed, 'stake_amount': default_conf['stake_amount'], 'start_date': min_date, 'end_date': max_date, diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 0406157f6..eefc6b28a 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -524,7 +524,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None: }]) ) patch_exchange(mocker) - # Co-test loading ticker-interval from strategy + # Co-test loading timeframe from strategy del default_conf['ticker_interval'] default_conf.update({'config': 'config.json.example', 'hyperopt': 'DefaultHyperOpt', @@ -534,7 +534,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None: 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.start() @@ -544,7 +544,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None: out, err = capsys.readouterr() assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 assert hasattr(hyperopt.backtesting.strategy, "advise_sell") assert hasattr(hyperopt.backtesting.strategy, "advise_buy") @@ -630,8 +630,8 @@ def test_has_space(hyperopt, spaces, expected_results): def test_populate_indicators(hyperopt, testdatadir) -> None: - tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) - dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist) + data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) + dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data) dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'}) @@ -642,8 +642,8 @@ def test_populate_indicators(hyperopt, testdatadir) -> None: def test_buy_strategy_generator(hyperopt, testdatadir) -> None: - tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) - dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist) + data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True) + dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data) dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'}) @@ -783,7 +783,7 @@ def test_clean_hyperopt(mocker, default_conf, caplog): h = Hyperopt(default_conf) assert unlinkmock.call_count == 2 - assert log_has(f"Removing `{h.tickerdata_pickle}`.", caplog) + assert log_has(f"Removing `{h.data_pickle_file}`.", caplog) def test_continue_hyperopt(mocker, default_conf, caplog): @@ -845,7 +845,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None: }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.start() @@ -859,7 +859,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None: ) assert result_str in out # noqa: E501 assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 @@ -903,7 +903,7 @@ def test_print_json_spaces_default(mocker, default_conf, caplog, capsys) -> None }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.start() @@ -913,7 +913,7 @@ def test_print_json_spaces_default(mocker, default_conf, caplog, capsys) -> None out, err = capsys.readouterr() assert '{"params":{"mfi-value":null,"sell-mfi-value":null},"minimal_roi":{},"stoploss":null}' in out # noqa: E501 assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 @@ -953,7 +953,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) -> }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.start() @@ -963,7 +963,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) -> out, err = capsys.readouterr() assert '{"minimal_roi":{},"stoploss":null}' in out assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 @@ -1000,7 +1000,7 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys) 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) del hyperopt.custom_hyperopt.__class__.buy_strategy_generator @@ -1015,7 +1015,7 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys) out, err = capsys.readouterr() assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 assert hasattr(hyperopt.backtesting.strategy, "advise_sell") assert hasattr(hyperopt.backtesting.strategy, "advise_buy") @@ -1043,7 +1043,7 @@ def test_simplified_interface_all_failed(mocker, default_conf, caplog, capsys) - 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) del hyperopt.custom_hyperopt.__class__.buy_strategy_generator @@ -1088,7 +1088,7 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None: 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) # TODO: sell_strategy_generator() is actually not called because @@ -1103,7 +1103,7 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None: out, err = capsys.readouterr() assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 assert hasattr(hyperopt.backtesting.strategy, "advise_sell") assert hasattr(hyperopt.backtesting.strategy, "advise_buy") @@ -1145,7 +1145,7 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) # TODO: buy_strategy_generator() is actually not called because @@ -1160,7 +1160,7 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None out, err = capsys.readouterr() assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out assert dumper.called - # Should be called twice, once for tickerdata, once to save evaluations + # Should be called twice, once for historical candle data, once to save evaluations assert dumper.call_count == 2 assert hasattr(hyperopt.backtesting.strategy, "advise_sell") assert hasattr(hyperopt.backtesting.strategy, "advise_buy") @@ -1194,7 +1194,7 @@ def test_simplified_interface_failed(mocker, default_conf, caplog, capsys, metho 'hyperopt_jobs': 1, }) hyperopt = Hyperopt(default_conf) - hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock() + hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock() hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) delattr(hyperopt.custom_hyperopt.__class__, method) diff --git a/tests/strategy/strats/default_strategy.py b/tests/strategy/strats/default_strategy.py index 6c343b477..7ea55d3f9 100644 --- a/tests/strategy/strats/default_strategy.py +++ b/tests/strategy/strats/default_strategy.py @@ -68,7 +68,7 @@ class DefaultStrategy(IStrategy): 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: Raw data from the exchange and parsed by parse_ticker_dataframe() + :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 """ diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 86d0738c6..949dda4a0 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -17,69 +17,69 @@ from tests.conftest import get_patched_exchange, log_has _STRATEGY = DefaultStrategy(config={}) -def test_returns_latest_buy_signal(mocker, default_conf, ticker_history): +def test_returns_latest_buy_signal(mocker, default_conf, ohlcv_history): mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([{'buy': 1, 'sell': 0, 'date': arrow.utcnow()}]) ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (True, False) + assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False) mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([{'buy': 0, 'sell': 1, 'date': arrow.utcnow()}]) ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (False, True) + assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True) -def test_returns_latest_sell_signal(mocker, default_conf, ticker_history): +def test_returns_latest_sell_signal(mocker, default_conf, ohlcv_history): mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([{'sell': 1, 'buy': 0, 'date': arrow.utcnow()}]) ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (False, True) + assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True) mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([{'sell': 0, 'buy': 1, 'date': arrow.utcnow()}]) ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (True, False) + assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False) def test_get_signal_empty(default_conf, mocker, caplog): assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'], DataFrame()) - assert log_has('Empty ticker history for pair foo', caplog) + assert log_has('Empty candle (OHLCV) data for pair foo', caplog) caplog.clear() assert (False, False) == _STRATEGY.get_signal('bar', default_conf['ticker_interval'], []) - assert log_has('Empty ticker history for pair bar', caplog) + assert log_has('Empty candle (OHLCV) data for pair bar', caplog) -def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_history): +def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ohlcv_history): caplog.set_level(logging.INFO) mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', side_effect=ValueError('xyz') ) assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'], - ticker_history) - assert log_has('Unable to analyze ticker for pair foo: xyz', caplog) + ohlcv_history) + assert log_has('Unable to analyze candle (OHLCV) data for pair foo: xyz', caplog) -def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history): +def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ohlcv_history): caplog.set_level(logging.INFO) mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([]) ) assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], - ticker_history) + ohlcv_history) assert log_has('Empty dataframe for pair xyz', caplog) -def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history): +def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): caplog.set_level(logging.INFO) # default_conf defines a 5m interval. we check interval * 2 + 5m # this is necessary as the last candle is removed (partial candles) by default @@ -90,7 +90,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history): return_value=DataFrame(ticks) ) assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], - ticker_history) + ohlcv_history) assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog) @@ -103,15 +103,15 @@ def test_get_signal_handles_exceptions(mocker, default_conf): assert _STRATEGY.get_signal(exchange, 'ETH/BTC', '5m') == (False, False) -def test_tickerdata_to_dataframe(default_conf, testdatadir) -> None: +def test_ohlcvdata_to_dataframe(default_conf, testdatadir) -> None: default_conf.update({'strategy': 'DefaultStrategy'}) strategy = StrategyResolver.load_strategy(default_conf) timerange = TimeRange.parse_timerange('1510694220-1510700340') - tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, - fill_up_missing=True) - data = strategy.tickerdata_to_dataframe(tickerlist) - assert len(data['UNITTEST/BTC']) == 102 # partial candle was removed + data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) + processed = strategy.ohlcvdata_to_dataframe(data) + assert len(processed['UNITTEST/BTC']) == 102 # partial candle was removed def test_min_roi_reached(default_conf, fee) -> None: @@ -222,7 +222,7 @@ def test_min_roi_reached3(default_conf, fee) -> None: assert strategy.min_roi_reached(trade, 0.31, arrow.utcnow().shift(minutes=-2).datetime) -def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None: +def test_analyze_ticker_default(ohlcv_history, mocker, caplog) -> None: caplog.set_level(logging.DEBUG) ind_mock = MagicMock(side_effect=lambda x, meta: x) buy_mock = MagicMock(side_effect=lambda x, meta: x) @@ -235,7 +235,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None: ) strategy = DefaultStrategy({}) - strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'}) + strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'}) assert ind_mock.call_count == 1 assert buy_mock.call_count == 1 assert buy_mock.call_count == 1 @@ -244,7 +244,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None: assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) caplog.clear() - strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'}) + strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'}) # No analysis happens as process_only_new_candles is true assert ind_mock.call_count == 2 assert buy_mock.call_count == 2 @@ -253,7 +253,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None: assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) -def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -> None: +def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) -> None: caplog.set_level(logging.DEBUG) ind_mock = MagicMock(side_effect=lambda x, meta: x) buy_mock = MagicMock(side_effect=lambda x, meta: x) @@ -268,7 +268,7 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) - strategy = DefaultStrategy({}) strategy.process_only_new_candles = True - ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'}) + ret = strategy._analyze_ticker_internal(ohlcv_history, {'pair': 'ETH/BTC'}) assert 'high' in ret.columns assert 'low' in ret.columns assert 'close' in ret.columns @@ -280,7 +280,7 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) - assert not log_has('Skipping TA Analysis for already analyzed candle', caplog) caplog.clear() - ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'}) + ret = strategy._analyze_ticker_internal(ohlcv_history, {'pair': 'ETH/BTC'}) # No analysis happens as process_only_new_candles is true assert ind_mock.call_count == 1 assert buy_mock.call_count == 1 diff --git a/tests/test_misc.py b/tests/test_misc.py index 83e008466..c1e23926b 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -6,7 +6,7 @@ from unittest.mock import MagicMock import pytest -from freqtrade.data.converter import parse_ticker_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, file_load_json, format_ms_time, pair_to_filename, plural, shorten_date) @@ -18,9 +18,9 @@ def test_shorten_date() -> None: assert shorten_date(str_data) == str_shorten_data -def test_datesarray_to_datetimearray(ticker_history_list): - dataframes = parse_ticker_dataframe(ticker_history_list, "5m", pair="UNITTEST/BTC", - fill_missing=True) +def test_datesarray_to_datetimearray(ohlcv_history_list): + dataframes = ohlcv_to_dataframe(ohlcv_history_list, "5m", pair="UNITTEST/BTC", + fill_missing=True) dates = datesarray_to_datetimearray(dataframes['date']) assert isinstance(dates[0], datetime.datetime) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index dd04035b7..42010ad0d 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -51,15 +51,15 @@ def test_init_plotscript(default_conf, mocker, testdatadir): default_conf["datadir"] = testdatadir default_conf['exportfilename'] = str(testdatadir / "backtest-result_test.json") ret = init_plotscript(default_conf) - assert "tickers" in ret + assert "ohlcv" in ret assert "trades" in ret assert "pairs" in ret default_conf['pairs'] = ["TRX/BTC", "ADA/BTC"] ret = init_plotscript(default_conf) - assert "tickers" in ret - assert "TRX/BTC" in ret["tickers"] - assert "ADA/BTC" in ret["tickers"] + assert "ohlcv" in ret + assert "TRX/BTC" in ret["ohlcv"] + assert "ADA/BTC" in ret["ohlcv"] def test_add_indicators(default_conf, testdatadir, caplog): @@ -269,14 +269,14 @@ def test_generate_profit_graph(testdatadir): pairs = ["TRX/BTC", "ADA/BTC"] trades = trades[trades['close_time'] < pd.Timestamp('2018-01-12', tz='UTC')] - tickers = history.load_data(datadir=testdatadir, - pairs=pairs, - timeframe='5m', - timerange=timerange - ) + data = history.load_data(datadir=testdatadir, + pairs=pairs, + timeframe='5m', + timerange=timerange) + trades = trades[trades['pair'].isin(pairs)] - fig = generate_profit_graph(pairs, tickers, trades, timeframe="5m") + fig = generate_profit_graph(pairs, data, trades, timeframe="5m") assert isinstance(fig, go.Figure) assert fig.layout.title.text == "Freqtrade Profit plot" From 4ad93ed6bbe2f9f5b653552d05f7d9b73fb9a30c Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 8 Mar 2020 22:41:05 +0100 Subject: [PATCH 0714/1106] Changed output for null columns --- freqtrade/optimize/hyperopt.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index d397c720c..f0c992760 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -420,19 +420,19 @@ class Hyperopt: trials['Trades'] = trials['Trades'].astype(str) trials['Total profit'] = trials['Total profit'].apply( - lambda x: '{:,.8f}'.format(x) if x != 0.0 else "--" + lambda x: '{:,.8f}'.format(x) if x != 0.0 else "" ) trials['Profit'] = trials['Profit'].apply( - lambda x: '{:,.2f}'.format(x) if not isna(x) else "--" + lambda x: '{:,.2f}'.format(x) if not isna(x) else "" ) trials['Avg profit'] = trials['Avg profit'].apply( - lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "--" + lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "" ) trials['Avg duration'] = trials['Avg duration'].apply( - lambda x: ('{:,.1f} m'.format(x)) if not isna(x) else "--" + lambda x: ('{:,.1f} m'.format(x)) if not isna(x) else "" ) trials['Objective'] = trials['Objective'].apply( - lambda x: '{:,.5f}'.format(x) if x != 100000 else "N/A" + lambda x: '{:,.5f}'.format(x) if x != 100000 else "" ) trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) From cb419614cd10ae7e4fb063e4bc2b28c795a0ce31 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 8 Mar 2020 23:00:21 +0100 Subject: [PATCH 0715/1106] Spelling miss --- 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 f0c992760..d12e9cd45 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -392,7 +392,7 @@ class Hyperopt: if not results: return - # Verification for owerwrite + # Verification for overwrite if not overwrite and path.isfile(csv_file): logging.error("CSV-File already exists and no overwrite specified!") return From c7b2f173ebcade7092be49f4d2aa87ec19745768 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2020 08:32:42 +0000 Subject: [PATCH 0716/1106] Bump wrapt from 1.12.0 to 1.12.1 Bumps [wrapt](https://github.com/GrahamDumpleton/wrapt) from 1.12.0 to 1.12.1. - [Release notes](https://github.com/GrahamDumpleton/wrapt/releases) - [Changelog](https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst) - [Commits](https://github.com/GrahamDumpleton/wrapt/compare/1.12.0...1.12.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a844e81bc..e44881041 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -7,7 +7,7 @@ arrow==0.15.5 cachetools==4.0.0 requests==2.23.0 urllib3==1.25.8 -wrapt==1.12.0 +wrapt==1.12.1 jsonschema==3.2.0 TA-Lib==0.4.17 tabulate==0.8.6 From 09c25faa51a68ab7c0e42795bc809b0da135782a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2020 08:33:37 +0000 Subject: [PATCH 0717/1106] Bump ccxt from 1.23.30 to 1.23.81 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.23.30 to 1.23.81. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md) - [Commits](https://github.com/ccxt/ccxt/compare/1.23.30...1.23.81) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a844e81bc..f64644db9 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.23.30 +ccxt==1.23.81 SQLAlchemy==1.3.13 python-telegram-bot==12.4.2 arrow==0.15.5 From 46763e148b6ccec222d849467f0cabb60f900f7e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2020 08:33:59 +0000 Subject: [PATCH 0718/1106] Bump prompt-toolkit from 3.0.3 to 3.0.4 Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases) - [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG) - [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.3...3.0.4) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a844e81bc..ec12f1c65 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -30,4 +30,4 @@ flask==1.1.1 colorama==0.4.3 # Building config files interactively questionary==1.5.1 -prompt-toolkit==3.0.3 +prompt-toolkit==3.0.4 From 23127b8da08ab45641a955dc94b58bfec582d38d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2020 08:34:33 +0000 Subject: [PATCH 0719/1106] Bump scikit-learn from 0.22.2 to 0.22.2.post1 Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22.2 to 0.22.2.post1. - [Release notes](https://github.com/scikit-learn/scikit-learn/releases) - [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22.2...0.22.2.post1) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index c713317ec..c7e586a33 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -3,7 +3,7 @@ # Required for hyperopt scipy==1.4.1 -scikit-learn==0.22.2 +scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 From 4cc0d3dbc42600136a7539e7f523a31f375683c9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2020 08:35:16 +0000 Subject: [PATCH 0720/1106] Bump plotly from 4.5.2 to 4.5.3 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.2 to 4.5.3. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.5.2...v4.5.3) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index a70c3e0cf..381334a66 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.5.2 +plotly==4.5.3 From 5cbf325fda4f0a3d9bb6032122aa56d085118d83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 11:30:13 +0100 Subject: [PATCH 0721/1106] Allow different loglevels for message --- freqtrade/pairlist/IPairList.py | 24 ++++++++++++++++++++---- freqtrade/pairlist/VolumePairList.py | 2 +- freqtrade/pairlist/pairlistmanager.py | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index d45a329dd..f591fa8da 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -67,21 +67,37 @@ class IPairList(ABC): """ @staticmethod - def verify_blacklist(pairlist: List[str], blacklist: List[str]) -> List[str]: + def verify_blacklist(pairlist: List[str], blacklist: List[str], + aswarning: bool) -> List[str]: """ Verify and remove items from pairlist - returning a filtered pairlist. + Logs a warning or info depending on `aswarning`. + Pairlists explicitly using this method shall use `aswarning=False`! + :param pairlist: Pairlist to validate + :param blacklist: Blacklist to validate pairlist against + :param aswarning: Log message as Warning or info + :return: pairlist - blacklisted pairs """ for pair in deepcopy(pairlist): if pair in blacklist: - logger.warning(f"Pair {pair} in your blacklist. Removing it from whitelist...") + if aswarning: + logger.warning(f"Pair {pair} in your blacklist. Removing it from whitelist...") + else: + logger.info(f"Pair {pair} in your blacklist. Removing it from whitelist...") pairlist.remove(pair) return pairlist - def _verify_blacklist(self, pairlist: List[str]) -> List[str]: + def _verify_blacklist(self, pairlist: List[str], aswarning: bool = True) -> List[str]: """ Proxy method to verify_blacklist for easy access for child classes. + Logs a warning or info depending on `aswarning`. + Pairlists explicitly using this method shall use aswarning=False! + :param pairlist: Pairlist to validate + :param aswarning: Log message as Warning or info. + :return: pairlist - blacklisted pairs """ - return IPairList.verify_blacklist(pairlist, self._pairlistmanager.blacklist) + return IPairList.verify_blacklist(pairlist, self._pairlistmanager.blacklist, + aswarning=aswarning) def _whitelist_for_active_markets(self, pairlist: List[str]) -> List[str]: """ diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index d067d5e8a..9ce2adc9e 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -106,7 +106,7 @@ class VolumePairList(IPairList): # Validate whitelist to only have active market pairs pairs = self._whitelist_for_active_markets([s['symbol'] for s in sorted_tickers]) - pairs = self._verify_blacklist(pairs) + pairs = self._verify_blacklist(pairs, aswarning=False) # Limit to X number of pairs pairs = pairs[:self._number_pairs] logger.info(f"Searching {self._number_pairs} pairs: {pairs}") diff --git a/freqtrade/pairlist/pairlistmanager.py b/freqtrade/pairlist/pairlistmanager.py index 55828c6ef..5b4c5b602 100644 --- a/freqtrade/pairlist/pairlistmanager.py +++ b/freqtrade/pairlist/pairlistmanager.py @@ -91,6 +91,6 @@ class PairListManager(): pairlist = pl.filter_pairlist(pairlist, tickers) # Validation against blacklist happens after the pairlists to ensure blacklist is respected. - pairlist = IPairList.verify_blacklist(pairlist, self.blacklist) + pairlist = IPairList.verify_blacklist(pairlist, self.blacklist, True) self._whitelist = pairlist From c049651784491f82807a07cbc2b3d3d6a8f57e22 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 11:30:28 +0100 Subject: [PATCH 0722/1106] whitelist_for_active_markets should not remove blacklisted items --- freqtrade/pairlist/IPairList.py | 1 - tests/pairlist/test_pairlist.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index f591fa8da..35844a99e 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -129,6 +129,5 @@ class IPairList(ABC): if pair not in sanitized_whitelist: sanitized_whitelist.append(pair) - sanitized_whitelist = self._verify_blacklist(sanitized_whitelist) # We need to remove pairs that are unknown return sanitized_whitelist diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index b8a4be037..1ce1151b7 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -240,8 +240,6 @@ def test_pairlist_class(mocker, whitelist_conf, markets, pairlist): (['ETH/BTC', 'TKN/BTC', 'ETH/USDT'], "is not compatible with your stake currency"), # BCH/BTC not available (['ETH/BTC', 'TKN/BTC', 'BCH/BTC'], "is not compatible with exchange"), - # BLK/BTC in blacklist - (['ETH/BTC', 'TKN/BTC', 'BLK/BTC'], "in your blacklist. Removing "), # BTT/BTC is inactive (['ETH/BTC', 'TKN/BTC', 'BTT/BTC'], "Market is not active") ]) From 856ba203d959716d40a5f0bab3569e63b807d76d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 15:04:28 +0100 Subject: [PATCH 0723/1106] Update hyperopt samples docstring --- freqtrade/templates/base_hyperopt.py.j2 | 15 +++++++++------ freqtrade/templates/sample_hyperopt.py | 19 ++++++++++++------- .../templates/sample_hyperopt_advanced.py | 7 ++++--- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/freqtrade/templates/base_hyperopt.py.j2 b/freqtrade/templates/base_hyperopt.py.j2 index 05ba08b81..08178da4b 100644 --- a/freqtrade/templates/base_hyperopt.py.j2 +++ b/freqtrade/templates/base_hyperopt.py.j2 @@ -21,7 +21,7 @@ class {{ hyperopt }}(IHyperOpt): """ This is a Hyperopt template to get you started. - More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ You should: - Add any lib you need to build your hyperopt. @@ -29,11 +29,14 @@ class {{ hyperopt }}(IHyperOpt): You must keep: - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. - The roi_space, generate_roi_table, stoploss_space methods are no longer required to be - copied in every custom hyperopt. However, you may override them if you need the - 'roi' and the 'stoploss' spaces that differ from the defaults offered by Freqtrade. - Sample implementation of these methods can be found in - https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_advanced.py + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. """ @staticmethod diff --git a/freqtrade/templates/sample_hyperopt.py b/freqtrade/templates/sample_hyperopt.py index f1dcb404a..0baa00442 100644 --- a/freqtrade/templates/sample_hyperopt.py +++ b/freqtrade/templates/sample_hyperopt.py @@ -20,23 +20,28 @@ import freqtrade.vendor.qtpylib.indicators as qtpylib class SampleHyperOpt(IHyperOpt): """ This is a sample Hyperopt to inspire you. - Feel free to customize it. - More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ You should: - Rename the class name to some unique name. - Add any methods you want to build your hyperopt. - Add any lib you need to build your hyperopt. + An easier way to get a new hyperopt file is by using + `freqtrade new-hyperopt --hyperopt MyCoolHyperopt`. + You must keep: - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. - The roi_space, generate_roi_table, stoploss_space methods are no longer required to be - copied in every custom hyperopt. However, you may override them if you need the - 'roi' and the 'stoploss' spaces that differ from the defaults offered by Freqtrade. - Sample implementation of these methods can be found in - https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_advanced.py + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need 'roi' and 'stoploss' spaces that + differ from the defaults offered by Freqtrade. + Sample implementation of these methods will be copied to `user_data/hyperopts` when + creating the user-data directory using `freqtrade create-userdir --userdir user_data`, + or is available online under the following URL: + https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py. """ @staticmethod diff --git a/freqtrade/templates/sample_hyperopt_advanced.py b/freqtrade/templates/sample_hyperopt_advanced.py index e66ef948b..c8067ad28 100644 --- a/freqtrade/templates/sample_hyperopt_advanced.py +++ b/freqtrade/templates/sample_hyperopt_advanced.py @@ -22,7 +22,7 @@ class AdvancedSampleHyperOpt(IHyperOpt): This is a sample hyperopt to inspire you. Feel free to customize it. - More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md + More information in the documentation: https://www.freqtrade.io/en/latest/hyperopt/ You should: - Rename the class name to some unique name. @@ -32,8 +32,9 @@ class AdvancedSampleHyperOpt(IHyperOpt): You must keep: - The prototypes for the methods: populate_indicators, indicator_space, buy_strategy_generator. - The roi_space, generate_roi_table, stoploss_space methods are no longer required to be - copied in every custom hyperopt. However, you may override them if you need the + The methods roi_space, generate_roi_table and stoploss_space are not required + and are provided by default. + However, you may override them if you need the 'roi' and the 'stoploss' spaces that differ from the defaults offered by Freqtrade. This sample illustrates how to override these methods. From 5da63d399be30908273ce7b2db7178e380a54dad Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 17:38:25 +0100 Subject: [PATCH 0724/1106] Reduce default order_book_max to 1 --- config.json.example | 2 +- config_binance.json.example | 2 +- config_full.json.example | 2 +- config_kraken.json.example | 2 +- freqtrade/templates/base_config.json.j2 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config.json.example b/config.json.example index 46441e72d..8ebb092e1 100644 --- a/config.json.example +++ b/config.json.example @@ -23,7 +23,7 @@ "ask_strategy":{ "use_order_book": false, "order_book_min": 1, - "order_book_max": 9, + "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, "ignore_roi_if_buy_signal": false diff --git a/config_binance.json.example b/config_binance.json.example index e2c9879b0..d324ce883 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -23,7 +23,7 @@ "ask_strategy":{ "use_order_book": false, "order_book_min": 1, - "order_book_max": 9, + "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, "ignore_roi_if_buy_signal": false diff --git a/config_full.json.example b/config_full.json.example index f0414bd0d..181740b9a 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -38,7 +38,7 @@ "price_side": "ask", "use_order_book": false, "order_book_min": 1, - "order_book_max": 9, + "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, "ignore_roi_if_buy_signal": false diff --git a/config_kraken.json.example b/config_kraken.json.example index 4f74d0b7d..dcf4c552a 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -23,7 +23,7 @@ "ask_strategy":{ "use_order_book": false, "order_book_min": 1, - "order_book_max": 9, + "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, "ignore_roi_if_buy_signal": false diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index 0049d59a0..134719273 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -24,7 +24,7 @@ "price_side": "ask", "use_order_book": false, "order_book_min": 1, - "order_book_max": 9, + "order_book_max": 1, "use_sell_signal": true, "sell_profit_only": false, "ignore_roi_if_buy_signal": false From 74a17c7b7b45cac99238bcb684e7089c5b92c735 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 17:38:35 +0100 Subject: [PATCH 0725/1106] Clarify warning in the documentation --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 5580b9c68..aedd3e043 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -537,7 +537,7 @@ The idea here is to place the sell order early, to be ahead in the queue. A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. !!! Warning "Orderbook and stoploss_on_exchange" - Using `ask_strategy.order_book_max` higher than 1 may increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. + Using `ask_strategy.order_book_max` higher than 1 will increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (even without stoploss on exchange). #### Sell price without Orderbook enabled From e0afbcd4af8e2b1e51a5eaca2b7e5ecd457f9f53 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 9 Mar 2020 17:41:44 +0100 Subject: [PATCH 0726/1106] Additional warning about order_book-max --- docs/configuration.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index aedd3e043..a9487a0ed 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -536,8 +536,14 @@ The idea here is to place the sell order early, to be ahead in the queue. A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. -!!! Warning "Orderbook and stoploss_on_exchange" - Using `ask_strategy.order_book_max` higher than 1 will increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (even without stoploss on exchange). +!!! Warning "Order_book_max > 1 - increased Risk!" + Using `ask_strategy.order_book_max` higher than 1 will increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. + Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss_on_exchange). + +!!! Warning "Order_book_max > 1 in dry-run" + Using `ask_strategy.order_book_max` higher than 1 will result in improved dry-run results, since dry-run assumes orders to be filled almost instantly. + It is therefore advised to not use this setting for dry-runs. + #### Sell price without Orderbook enabled From 3eaae4661d3256ca27c92329b60661734c3ed716 Mon Sep 17 00:00:00 2001 From: orehunt Date: Mon, 9 Mar 2020 07:39:23 +0100 Subject: [PATCH 0727/1106] check again for emptiness after trimming dataframe --- freqtrade/data/history/idatahandler.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index df03e7713..87810c95f 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -160,6 +160,13 @@ class IDataHandler(ABC): if timerange_startup: self._validate_pairdata(pair, pairdf, timerange_startup) pairdf = trim_dataframe(pairdf, timerange_startup) + if pairdf.empty: + if warn_no_data: + logger.warning( + f'No history data for pair: "{pair}", timeframe: {timeframe}. ' + 'Use `freqtrade download-data` to download the data' + ) + return pairdf # incomplete candles should only be dropped if we didn't trim the end beforehand. return clean_ohlcv_dataframe(pairdf, timeframe, From 2f5fc731bba51239a3195cbd0fb79e9e58a20d33 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 9 Mar 2020 18:53:30 +0100 Subject: [PATCH 0728/1106] Removed overwrite option --- docs/utils.md | 13 +++++++------ freqtrade/commands/cli_options.py | 4 ++-- freqtrade/commands/hyperopt_commands.py | 8 +------- freqtrade/optimize/hyperopt.py | 6 +++--- tests/commands/test_commands.py | 2 +- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index dd7a9dfe3..eb71c509c 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -429,6 +429,7 @@ usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] [--min-total-profit FLOAT] [--max-total-profit FLOAT] [--no-color] [--print-json] [--no-details] + [--export-csv FILE] optional arguments: -h, --help show this help message and exit @@ -450,9 +451,8 @@ optional arguments: useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. --no-details Do not print best epoch details. - --export-csv FILE Export to CSV-File. Put + in front of filename to - overwrite. This will disable table print. Example: - --export-csv +hyperopt.csv + --export-csv FILE Export to CSV-File. This will disable table print. + Example: --export-csv hyperopt.csv Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). @@ -461,9 +461,10 @@ Common arguments: details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). - Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index b782c2fb9..8548bd887 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -223,9 +223,9 @@ AVAILABLE_CLI_OPTIONS = { ), "export_csv": Arg( '--export-csv', - help='Export to CSV-File. Put + in front of filename to overwrite.' + help='Export to CSV-File.' ' This will disable table print.' - ' Example: --export-csv +hyperopt.csv', + ' Example: --export-csv hyperopt.csv', metavar='FILE', ), "hyperopt_jobs": Arg( diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index efc9aba88..5b2388252 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -63,14 +63,8 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) if trials and export_csv: - overwrite_csv = False - if export_csv[0] == '+': - overwrite_csv = True - export_csv = export_csv[1:] - Hyperopt.export_csv_file( - config, trials, total_epochs, - not filteroptions['only_best'], export_csv, overwrite_csv + config, trials, total_epochs, not filteroptions['only_best'], export_csv ) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index d12e9cd45..8e0eba4d7 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -385,7 +385,7 @@ class Hyperopt: @staticmethod def export_csv_file(config: dict, results: list, total_epochs: int, highlight_best: bool, - csv_file: str, overwrite: bool) -> None: + csv_file: str) -> None: """ Log result to csv-file """ @@ -393,8 +393,8 @@ class Hyperopt: return # Verification for overwrite - if not overwrite and path.isfile(csv_file): - logging.error("CSV-File already exists and no overwrite specified!") + if path.isfile(csv_file): + logging.error("CSV-File already exists!") return try: diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index f404a4671..4530cd03d 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -905,7 +905,7 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): args = [ "hyperopt-list", "--no-details", - "--export-csv", "+test_file.csv" + "--export-csv", "test_file.csv" ] pargs = get_args(args) pargs['config'] = None From bd158eefd29a3cdec29887e7f54895935a379179 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 10 Mar 2020 03:02:52 +0100 Subject: [PATCH 0729/1106] Fixed loggin --- freqtrade/optimize/hyperopt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 8e0eba4d7..1b6343208 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -394,13 +394,13 @@ class Hyperopt: # Verification for overwrite if path.isfile(csv_file): - logging.error("CSV-File already exists!") + logger.error("CSV-File already exists!") return try: io.open(csv_file, 'w+').close() except IOError: - logging.error("Filed to create/overwrite CSV-File!") + logger.error("Filed to create CSV-File!") return trials = json_normalize(results, max_level=1) From 42038da7f1f47d5e34cc10af04f9b42c5f6e4533 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 10 Mar 2020 07:57:25 +0100 Subject: [PATCH 0730/1106] Update docs/configuration.md Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index a9487a0ed..1fca61fdb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -541,7 +541,7 @@ A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss_on_exchange). !!! Warning "Order_book_max > 1 in dry-run" - Using `ask_strategy.order_book_max` higher than 1 will result in improved dry-run results, since dry-run assumes orders to be filled almost instantly. + Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly. It is therefore advised to not use this setting for dry-runs. From f148b5f73450861d8f416f0e3b03d355c568ec6e Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Tue, 10 Mar 2020 10:38:37 +0300 Subject: [PATCH 0731/1106] cosmetics in lambdas --- freqtrade/optimize/hyperopt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 1b6343208..4c32a0543 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -332,10 +332,10 @@ class Hyperopt: lambda x: '{}/{}'.format(str(x).rjust(len(str(total_epochs)), ' '), total_epochs) ) trials['Avg profit'] = trials['Avg profit'].apply( - lambda x: ('{:,.2f}%'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') + lambda x: '{:,.2f}%'.format(x).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') ) trials['Avg duration'] = trials['Avg duration'].apply( - lambda x: ('{:,.1f} m'.format(x)).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') + lambda x: '{:,.1f} m'.format(x).rjust(7, ' ') if not isna(x) else "--".rjust(7, ' ') ) trials['Objective'] = trials['Objective'].apply( lambda x: '{:,.5f}'.format(x).rjust(8, ' ') if x != 100000 else "N/A".rjust(8, ' ') @@ -426,10 +426,10 @@ class Hyperopt: lambda x: '{:,.2f}'.format(x) if not isna(x) else "" ) trials['Avg profit'] = trials['Avg profit'].apply( - lambda x: ('{:,.2f}%'.format(x)) if not isna(x) else "" + lambda x: '{:,.2f}%'.format(x) if not isna(x) else "" ) trials['Avg duration'] = trials['Avg duration'].apply( - lambda x: ('{:,.1f} m'.format(x)) if not isna(x) else "" + lambda x: '{:,.1f} m'.format(x) if not isna(x) else "" ) trials['Objective'] = trials['Objective'].apply( lambda x: '{:,.5f}'.format(x) if x != 100000 else "" From a046c4829c01ad2934337c59a304b181cb4f2a23 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 10 Mar 2020 09:03:44 +0100 Subject: [PATCH 0732/1106] Apply suggestions from code review Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 1fca61fdb..76df5bd08 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -536,9 +536,9 @@ The idea here is to place the sell order early, to be ahead in the queue. A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number. -!!! Warning "Order_book_max > 1 - increased Risk!" - Using `ask_strategy.order_book_max` higher than 1 will increase the risk, since an eventual [stoploss on exchange](#understand-order_types) will be needed to be cancelled as soon as the order is placed. - Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss_on_exchange). +!!! Warning "Order_book_max > 1 - increased risks for stoplosses!" + Using `ask_strategy.order_book_max` higher than 1 will increase the risk the stoploss on exchange is cancelled too early, since an eventual [stoploss on exchange](#understand-order_types) will be cancelled as soon as the order is placed. + Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss on exchange). !!! Warning "Order_book_max > 1 in dry-run" Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly. From f7ad6c20c7276ca6f76721d8195034ec2993bb87 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 10 Mar 2020 12:02:23 +0300 Subject: [PATCH 0733/1106] Do not allow unlimited stake_amount for hyperopt --- freqtrade/commands/optimize_commands.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/optimize_commands.py b/freqtrade/commands/optimize_commands.py index a2d1b4601..2fc605926 100644 --- a/freqtrade/commands/optimize_commands.py +++ b/freqtrade/commands/optimize_commands.py @@ -17,10 +17,15 @@ def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[ """ config = setup_utils_configuration(args, method) - if method == RunMode.BACKTEST: - if config['stake_amount'] == constants.UNLIMITED_STAKE_AMOUNT: - raise DependencyException('stake amount could not be "%s" for backtesting' % - constants.UNLIMITED_STAKE_AMOUNT) + no_unlimited_runmodes = { + RunMode.BACKTEST: 'backtesting', + RunMode.HYPEROPT: 'hyperoptimization', + } + if (method in no_unlimited_runmodes.keys() and + config['stake_amount'] == constants.UNLIMITED_STAKE_AMOUNT): + raise DependencyException( + f'The value of `stake_amount` cannot be set as "{constants.UNLIMITED_STAKE_AMOUNT}" ' + f'for {no_unlimited_runmodes[method]}') return config From 81b6a950ac58e231e7e29bd1429b34b40b40c1ff Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 10 Mar 2020 12:42:11 +0300 Subject: [PATCH 0734/1106] Adjust test for backtesting --- tests/optimize/test_backtesting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 96855dc9d..702337463 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -241,7 +241,7 @@ def test_setup_optimize_configuration_unlimited_stake_amount(mocker, default_con '--strategy', 'DefaultStrategy', ] - with pytest.raises(DependencyException, match=r'.*stake amount.*'): + with pytest.raises(DependencyException, match=r'.`stake_amount`.*'): setup_optimize_configuration(get_args(args), RunMode.BACKTEST) From 1b6e77649a437a75f4eae10d78d3fc0bc7dd7ba7 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 10 Mar 2020 12:42:31 +0300 Subject: [PATCH 0735/1106] Add test for hyperopt --- tests/optimize/test_hyperopt.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index 0406157f6..c0bddd085 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -10,10 +10,11 @@ import pytest from arrow import Arrow from filelock import Timeout +from freqtrade import constants from freqtrade.commands.optimize_commands import (setup_optimize_configuration, start_hyperopt) from freqtrade.data.history import load_data -from freqtrade.exceptions import OperationalException +from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.optimize.default_hyperopt import DefaultHyperOpt from freqtrade.optimize.default_hyperopt_loss import DefaultHyperOptLoss from freqtrade.optimize.hyperopt import Hyperopt @@ -158,6 +159,21 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo assert log_has('Parameter --print-all detected ...', caplog) +def test_setup_hyperopt_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None: + default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT + + patched_configuration_load_config_file(mocker, default_conf) + + args = [ + 'hyperopt', + '--config', 'config.json', + '--hyperopt', 'DefaultHyperOpt', + ] + + with pytest.raises(DependencyException, match=r'.`stake_amount`.*'): + setup_optimize_configuration(get_args(args), RunMode.HYPEROPT) + + def test_hyperoptresolver(mocker, default_conf, caplog) -> None: patched_configuration_load_config_file(mocker, default_conf) From 73c19da4b988e13db70ec6f434baf773aa71faba Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 10 Mar 2020 13:44:16 +0300 Subject: [PATCH 0736/1106] Adjust handling of zero stdev in loss functions --- freqtrade/optimize/hyperopt_loss_sharpe.py | 2 +- freqtrade/optimize/hyperopt_loss_sharpe_daily.py | 2 +- freqtrade/optimize/hyperopt_loss_sortino.py | 2 +- freqtrade/optimize/hyperopt_loss_sortino_daily.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt_loss_sharpe.py b/freqtrade/optimize/hyperopt_loss_sharpe.py index a4ec6f90a..29377bdd5 100644 --- a/freqtrade/optimize/hyperopt_loss_sharpe.py +++ b/freqtrade/optimize/hyperopt_loss_sharpe.py @@ -36,7 +36,7 @@ class SharpeHyperOptLoss(IHyperOptLoss): expected_returns_mean = total_profit.sum() / days_period up_stdev = np.std(total_profit) - if (np.std(total_profit) != 0.): + if up_stdev != 0: sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365) else: # Define high (negative) sharpe ratio to be clear that this is NOT optimal. diff --git a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py index 5a8ebaa11..e4cd1d749 100644 --- a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py @@ -51,7 +51,7 @@ class SharpeHyperOptLossDaily(IHyperOptLoss): expected_returns_mean = total_profit.mean() up_stdev = total_profit.std() - if (up_stdev != 0.): + if up_stdev != 0: sharp_ratio = expected_returns_mean / up_stdev * math.sqrt(days_in_year) else: # Define high (negative) sharpe ratio to be clear that this is NOT optimal. diff --git a/freqtrade/optimize/hyperopt_loss_sortino.py b/freqtrade/optimize/hyperopt_loss_sortino.py index 83f644a43..d470a9977 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino.py +++ b/freqtrade/optimize/hyperopt_loss_sortino.py @@ -39,7 +39,7 @@ class SortinoHyperOptLoss(IHyperOptLoss): results.loc[total_profit < 0, 'downside_returns'] = results['profit_percent'] down_stdev = np.std(results['downside_returns']) - if np.std(total_profit) != 0.0: + if down_stdev != 0: sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365) else: # Define high (negative) sortino ratio to be clear that this is NOT optimal. diff --git a/freqtrade/optimize/hyperopt_loss_sortino_daily.py b/freqtrade/optimize/hyperopt_loss_sortino_daily.py index 16dc26142..cd6a8bcc2 100644 --- a/freqtrade/optimize/hyperopt_loss_sortino_daily.py +++ b/freqtrade/optimize/hyperopt_loss_sortino_daily.py @@ -59,7 +59,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss): # where P = sum_daily["profit_percent_after_slippage"] down_stdev = math.sqrt((total_downside**2).sum() / len(total_downside)) - if (down_stdev != 0.): + if down_stdev != 0: sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year) else: # Define high (negative) sortino ratio to be clear that this is NOT optimal. From 2b1c146940633b50dc0d9a9d225f44cc893bb088 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 10 Mar 2020 16:05:33 +0100 Subject: [PATCH 0737/1106] Add default volume > 0 filter --- docs/hyperopt.md | 3 +++ freqtrade/templates/base_hyperopt.py.j2 | 6 ++++++ freqtrade/templates/sample_hyperopt.py | 6 ++++++ freqtrade/templates/sample_hyperopt_advanced.py | 6 ++++++ 4 files changed, 21 insertions(+) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 9bc5888ce..1293c7ab4 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -159,6 +159,9 @@ So let's write the buy strategy using these values: dataframe['macd'], dataframe['macdsignal'] )) + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), diff --git a/freqtrade/templates/base_hyperopt.py.j2 b/freqtrade/templates/base_hyperopt.py.j2 index 08178da4b..ec787cbb6 100644 --- a/freqtrade/templates/base_hyperopt.py.j2 +++ b/freqtrade/templates/base_hyperopt.py.j2 @@ -66,6 +66,9 @@ class {{ hyperopt }}(IHyperOpt): dataframe['close'], dataframe['sar'] )) + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), @@ -111,6 +114,9 @@ class {{ hyperopt }}(IHyperOpt): dataframe['sar'], dataframe['close'] )) + # Check that the candle had volume + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), diff --git a/freqtrade/templates/sample_hyperopt.py b/freqtrade/templates/sample_hyperopt.py index 0baa00442..0b6d030db 100644 --- a/freqtrade/templates/sample_hyperopt.py +++ b/freqtrade/templates/sample_hyperopt.py @@ -78,6 +78,9 @@ class SampleHyperOpt(IHyperOpt): dataframe['close'], dataframe['sar'] )) + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), @@ -138,6 +141,9 @@ class SampleHyperOpt(IHyperOpt): dataframe['sar'], dataframe['close'] )) + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), diff --git a/freqtrade/templates/sample_hyperopt_advanced.py b/freqtrade/templates/sample_hyperopt_advanced.py index c8067ad28..7f05c4430 100644 --- a/freqtrade/templates/sample_hyperopt_advanced.py +++ b/freqtrade/templates/sample_hyperopt_advanced.py @@ -93,6 +93,9 @@ class AdvancedSampleHyperOpt(IHyperOpt): dataframe['close'], dataframe['sar'] )) + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), @@ -153,6 +156,9 @@ class AdvancedSampleHyperOpt(IHyperOpt): dataframe['sar'], dataframe['close'] )) + # Check that volume is not 0 + conditions.append(dataframe['volume'] > 0) + if conditions: dataframe.loc[ reduce(lambda x, y: x & y, conditions), From 3a8b68c0fd721094c606286b4dce6a86d89442d9 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 10 Mar 2020 20:30:36 +0100 Subject: [PATCH 0738/1106] Initial work on progressbar --- freqtrade/loggers.py | 9 ++++++--- freqtrade/optimize/hyperopt.py | 34 ++++++++++++++++++++++++++++++---- requirements-hyperopt.txt | 1 + 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/freqtrade/loggers.py b/freqtrade/loggers.py index c69388430..609604ff2 100644 --- a/freqtrade/loggers.py +++ b/freqtrade/loggers.py @@ -4,6 +4,7 @@ import sys from logging import Formatter from logging.handlers import RotatingFileHandler, SysLogHandler from typing import Any, Dict, List +import progressbar from freqtrade.exceptions import OperationalException @@ -18,13 +19,13 @@ def _set_loggers(verbosity: int = 0) -> None: """ logging.getLogger('requests').setLevel( - logging.INFO if verbosity <= 1 else logging.DEBUG + logging.INFO if verbosity <= 1 else logging.DEBUG ) logging.getLogger("urllib3").setLevel( - logging.INFO if verbosity <= 1 else logging.DEBUG + logging.INFO if verbosity <= 1 else logging.DEBUG ) logging.getLogger('ccxt.base.exchange').setLevel( - logging.INFO if verbosity <= 2 else logging.DEBUG + logging.INFO if verbosity <= 2 else logging.DEBUG ) logging.getLogger('telegram').setLevel(logging.INFO) @@ -36,6 +37,8 @@ def setup_logging(config: Dict[str, Any]) -> None: # Log level verbosity = config['verbosity'] + progressbar.streams.wrap_stderr() + # Log to stderr log_handlers: List[logging.Handler] = [logging.StreamHandler(sys.stderr)] diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 4c32a0543..93fc3c558 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -7,7 +7,6 @@ This module contains the hyperopt logic import locale import logging import random -import sys import warnings from math import ceil from collections import OrderedDict @@ -22,8 +21,9 @@ from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna +import progressbar import tabulate -from os import path +from os import path, popen import io from freqtrade.data.converter import trim_dataframe @@ -270,7 +270,6 @@ class Hyperopt: # Print '\n' after each 100th epoch to separate dots from the log messages. # Otherwise output is messy on a terminal. print('.', end='' if results['current_epoch'] % 100 != 0 else None) # type: ignore - sys.stdout.flush() if self.print_all or is_best: if not self.print_all: @@ -622,6 +621,10 @@ class Hyperopt: def _set_random_state(self, random_state: Optional[int]) -> int: return random_state or random.randint(1, 2**16 - 1) + def _get_height(self) -> int: + rows = int((popen('stty size', 'r').read().split())[0]) + return rows + def start(self) -> None: self.random_state = self._set_random_state(self.config.get('hyperopt_random_state', None)) logger.info(f"Using optimizer random state: {self.random_state}") @@ -629,7 +632,6 @@ class Hyperopt: data, timerange = self.backtesting.load_bt_data() preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data) - # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): preprocessed[pair] = trim_dataframe(df, timerange) @@ -659,6 +661,14 @@ class Hyperopt: try: with Parallel(n_jobs=config_jobs) as parallel: + self.progress_bar = progressbar.ProgressBar( + min_value=0, + max_value=self.total_epochs, + initial_value=0, + line_breaks=True, + enable_colors=self.print_colorized + ) + self.progress_bar.start() jobs = parallel._effective_n_jobs() logger.info(f'Effective number of parallel workers used: {jobs}') EVALS = ceil(self.total_epochs / jobs) @@ -673,6 +683,9 @@ class Hyperopt: self.opt.tell(asked, [v['loss'] for v in f_val]) self.fix_optimizer_models_list() + # Calculate progressbar outputs + pbar_line = ceil(self._get_height() / 2) + for j, val in enumerate(f_val): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 @@ -689,12 +702,19 @@ class Hyperopt: self.print_results(val) + if pbar_line <= current: + self.progress_bar.update(current) + pbar_line = current + ceil(self._get_height() / 2) + if is_best: self.current_best_loss = val['loss'] self.trials.append(val) # Save results after each best epoch and every 100 epochs if is_best or current % 100 == 0: self.save_trials() + self.progress_bar.finish() + + # self.progress_bar.update(current) except KeyboardInterrupt: print('User interrupted..') @@ -708,3 +728,9 @@ 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 __getstate__(self): + state = self.__dict__.copy() + del state['trials'] + del state['progress_bar'] + return state diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index c7e586a33..3c500839e 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -7,3 +7,4 @@ scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 +progressbar2==3.50.0 From 129a88d5da1879e1cae93e1771a995da6d5f0bfc Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 11 Mar 2020 19:53:28 +0100 Subject: [PATCH 0739/1106] Extract emptyness check to it's own method --- freqtrade/data/history/idatahandler.py | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index 87810c95f..bde9612f2 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -147,12 +147,7 @@ class IDataHandler(ABC): pairdf = self._ohlcv_load(pair, timeframe, timerange=timerange_startup) - if pairdf.empty: - if warn_no_data: - logger.warning( - f'No history data for pair: "{pair}", timeframe: {timeframe}. ' - 'Use `freqtrade download-data` to download the data' - ) + if self._check_empty_df(pairdf, pair, timeframe, warn_no_data): return pairdf else: enddate = pairdf.iloc[-1]['date'] @@ -160,12 +155,7 @@ class IDataHandler(ABC): if timerange_startup: self._validate_pairdata(pair, pairdf, timerange_startup) pairdf = trim_dataframe(pairdf, timerange_startup) - if pairdf.empty: - if warn_no_data: - logger.warning( - f'No history data for pair: "{pair}", timeframe: {timeframe}. ' - 'Use `freqtrade download-data` to download the data' - ) + if self._check_empty_df(pairdf, pair, timeframe, warn_no_data): return pairdf # incomplete candles should only be dropped if we didn't trim the end beforehand. @@ -175,6 +165,19 @@ class IDataHandler(ABC): drop_incomplete=(drop_incomplete and enddate == pairdf.iloc[-1]['date'])) + def _check_empty_df(self, pairdf: DataFrame, pair: str, timeframe: str, warn_no_data: bool): + """ + Warn on empty dataframe + """ + if pairdf.empty: + if warn_no_data: + logger.warning( + f'No history data for pair: "{pair}", timeframe: {timeframe}. ' + 'Use `freqtrade download-data` to download the data' + ) + return True + return False + def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange): """ Validates pairdata for missing data at start end end and logs warnings. From 81cbb925568dbae6260caf88ced5c90f7abc1a3b Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 11 Mar 2020 22:30:36 +0100 Subject: [PATCH 0740/1106] Switch to TQDM --- freqtrade/commands/hyperopt_commands.py | 4 +- freqtrade/optimize/hyperopt.py | 71 +++++++++++++++++++------ 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 5b2388252..3f61ea66c 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -52,8 +52,8 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: if not export_csv: try: - Hyperopt.print_result_table(config, trials, total_epochs, - not filteroptions['only_best'], print_colorized, 0) + print(Hyperopt.get_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized, 0)) except KeyboardInterrupt: print('User interrupted..') diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 93fc3c558..e110f7e9c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -21,7 +21,7 @@ from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna -import progressbar +from tqdm import tqdm import tabulate from os import path, popen import io @@ -275,11 +275,37 @@ class Hyperopt: if not self.print_all: # Separate the results explanation string from dots print("\n") - self.print_result_table(self.config, results, self.total_epochs, - self.print_all, self.print_colorized, - self.hyperopt_table_header) + print(self.get_result_table( + self.config, results, self.total_epochs, + self.print_all, self.print_colorized, + self.hyperopt_table_header + ) + ) self.hyperopt_table_header = 2 + def get_results(self, results) -> str: + """ + Log results if it is better than any previous evaluation + """ + output = '' + is_best = results['is_best'] + # if not self.print_all: + # Print '\n' after each 100th epoch to separate dots from the log messages. + # Otherwise output is messy on a terminal. + # return '.', end='' if results['current_epoch'] % 100 != 0 else None # type: ignore + + if self.print_all or is_best: + # if not self.print_all: + # Separate the results explanation string from dots + # print("\n") + output = self.get_result_table( + self.config, results, self.total_epochs, + self.print_all, self.print_colorized, + self.hyperopt_table_header + ) + self.hyperopt_table_header = 2 + return output + @staticmethod def print_results_explanation(results, total_epochs, highlight_best: bool, print_colorized: bool) -> None: @@ -303,13 +329,13 @@ class Hyperopt: f"Objective: {results['loss']:.5f}") @staticmethod - def print_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool, - print_colorized: bool, remove_header: int) -> None: + def get_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool, + print_colorized: bool, remove_header: int) -> str: """ Log result table """ if not results: - return + return '' tabulate.PRESERVE_WHITESPACE = True @@ -380,7 +406,7 @@ class Hyperopt: trials.to_dict(orient='list'), tablefmt='psql', headers='keys', stralign="right" ) - print(table) + return table @staticmethod def export_csv_file(config: dict, results: list, total_epochs: int, highlight_best: bool, @@ -661,6 +687,7 @@ class Hyperopt: try: with Parallel(n_jobs=config_jobs) as parallel: + """ self.progress_bar = progressbar.ProgressBar( min_value=0, max_value=self.total_epochs, @@ -668,9 +695,17 @@ class Hyperopt: line_breaks=True, enable_colors=self.print_colorized ) - self.progress_bar.start() + """ jobs = parallel._effective_n_jobs() logger.info(f'Effective number of parallel workers used: {jobs}') + + # Define progressbar + self.progress_bar = tqdm( + total=self.total_epochs, ncols=108, unit=' Epoch', + bar_format='Epoch {n_fmt}/{total_fmt} ({percentage:3.0f}%)|{bar}|' + ' [{elapsed}<{remaining} {rate_fmt}{postfix}]' + ) + EVALS = ceil(self.total_epochs / jobs) for i in range(EVALS): # Correct the number of epochs to be processed for the last @@ -684,8 +719,7 @@ class Hyperopt: self.fix_optimizer_models_list() # Calculate progressbar outputs - pbar_line = ceil(self._get_height() / 2) - + # pbar_line = ceil(self._get_height() / 2) for j, val in enumerate(f_val): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 @@ -699,20 +733,25 @@ class Hyperopt: # evaluations can take different time. Here they are aligned in the # order they will be shown to the user. val['is_best'] = is_best - - self.print_results(val) - + # print(current) + output = self.get_results(val) + self.progress_bar.write(output) + # self.progress_bar.write(str(len(output.split('\n')[0]))) + self.progress_bar.ncols = len(output.split('\n')[0]) + self.progress_bar.update(1) + """ if pbar_line <= current: self.progress_bar.update(current) pbar_line = current + ceil(self._get_height() / 2) - + """ if is_best: self.current_best_loss = val['loss'] self.trials.append(val) # Save results after each best epoch and every 100 epochs if is_best or current % 100 == 0: self.save_trials() - self.progress_bar.finish() + self.progress_bar.ncols = 108 + self.progress_bar.close() # self.progress_bar.update(current) except KeyboardInterrupt: From 755763ec42b51370c7326e4e90f5c35921ba2125 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 11 Mar 2020 22:43:27 +0100 Subject: [PATCH 0741/1106] Update requirements --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 3c500839e..7469674cd 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -7,4 +7,4 @@ scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 -progressbar2==3.50.0 +tqdm==4.43.0 From 40a413c524b9eb2b2d13e222ac1e81173a1d5b1e Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 11 Mar 2020 22:50:23 +0100 Subject: [PATCH 0742/1106] More remove of progressbar2 --- freqtrade/loggers.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/freqtrade/loggers.py b/freqtrade/loggers.py index 609604ff2..153ce8c80 100644 --- a/freqtrade/loggers.py +++ b/freqtrade/loggers.py @@ -4,7 +4,6 @@ import sys from logging import Formatter from logging.handlers import RotatingFileHandler, SysLogHandler from typing import Any, Dict, List -import progressbar from freqtrade.exceptions import OperationalException @@ -37,8 +36,6 @@ def setup_logging(config: Dict[str, Any]) -> None: # Log level verbosity = config['verbosity'] - progressbar.streams.wrap_stderr() - # Log to stderr log_handlers: List[logging.Handler] = [logging.StreamHandler(sys.stderr)] From 9387ed923c97a2dffebfa1ca57662745d97a0f44 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 12 Mar 2020 02:07:50 +0100 Subject: [PATCH 0743/1106] fix for empty lines --- freqtrade/optimize/hyperopt.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index e110f7e9c..48a89e1d6 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -289,15 +289,8 @@ class Hyperopt: """ output = '' is_best = results['is_best'] - # if not self.print_all: - # Print '\n' after each 100th epoch to separate dots from the log messages. - # Otherwise output is messy on a terminal. - # return '.', end='' if results['current_epoch'] % 100 != 0 else None # type: ignore if self.print_all or is_best: - # if not self.print_all: - # Separate the results explanation string from dots - # print("\n") output = self.get_result_table( self.config, results, self.total_epochs, self.print_all, self.print_colorized, @@ -735,9 +728,10 @@ class Hyperopt: val['is_best'] = is_best # print(current) output = self.get_results(val) - self.progress_bar.write(output) + if output: + self.progress_bar.write(output) # self.progress_bar.write(str(len(output.split('\n')[0]))) - self.progress_bar.ncols = len(output.split('\n')[0]) + self.progress_bar.ncols = 108 self.progress_bar.update(1) """ if pbar_line <= current: From df1ae565dc09c93b046b2ba79cb5a1ce647c1d09 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 12 Mar 2020 02:26:41 +0100 Subject: [PATCH 0744/1106] clean-up --- freqtrade/optimize/hyperopt.py | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 48a89e1d6..a6da8c4b8 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -23,7 +23,7 @@ from joblib import (Parallel, cpu_count, delayed, dump, load, from pandas import DataFrame, json_normalize, isna from tqdm import tqdm import tabulate -from os import path, popen +from os import path import io from freqtrade.data.converter import trim_dataframe @@ -640,10 +640,6 @@ class Hyperopt: def _set_random_state(self, random_state: Optional[int]) -> int: return random_state or random.randint(1, 2**16 - 1) - def _get_height(self) -> int: - rows = int((popen('stty size', 'r').read().split())[0]) - return rows - def start(self) -> None: self.random_state = self._set_random_state(self.config.get('hyperopt_random_state', None)) logger.info(f"Using optimizer random state: {self.random_state}") @@ -680,15 +676,6 @@ class Hyperopt: try: with Parallel(n_jobs=config_jobs) as parallel: - """ - self.progress_bar = progressbar.ProgressBar( - min_value=0, - max_value=self.total_epochs, - initial_value=0, - line_breaks=True, - enable_colors=self.print_colorized - ) - """ jobs = parallel._effective_n_jobs() logger.info(f'Effective number of parallel workers used: {jobs}') @@ -712,7 +699,6 @@ class Hyperopt: self.fix_optimizer_models_list() # Calculate progressbar outputs - # pbar_line = ceil(self._get_height() / 2) for j, val in enumerate(f_val): # Use human-friendly indexes here (starting from 1) current = i * jobs + j + 1 @@ -726,18 +712,12 @@ class Hyperopt: # evaluations can take different time. Here they are aligned in the # order they will be shown to the user. val['is_best'] = is_best - # print(current) output = self.get_results(val) if output: self.progress_bar.write(output) - # self.progress_bar.write(str(len(output.split('\n')[0]))) self.progress_bar.ncols = 108 self.progress_bar.update(1) - """ - if pbar_line <= current: - self.progress_bar.update(current) - pbar_line = current + ceil(self._get_height() / 2) - """ + if is_best: self.current_best_loss = val['loss'] self.trials.append(val) @@ -747,8 +727,8 @@ class Hyperopt: self.progress_bar.ncols = 108 self.progress_bar.close() - # self.progress_bar.update(current) except KeyboardInterrupt: + self.progress_bar.close() print('User interrupted..') self.save_trials(final=True) @@ -761,9 +741,3 @@ 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 __getstate__(self): - state = self.__dict__.copy() - del state['trials'] - del state['progress_bar'] - return state From 1a59fc11be8312c19cd5723f641ac66128b05117 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 12 Mar 2020 02:36:18 +0100 Subject: [PATCH 0745/1106] doh --- freqtrade/optimize/hyperopt.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a6da8c4b8..9ff4a1ead 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -741,3 +741,9 @@ 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 __getstate__(self): + state = self.__dict__.copy() + del state['trials'] + del state['progress_bar'] + return state From 5737139979351eab8482cbe230b111310e11981b Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 12 Mar 2020 16:47:09 +0100 Subject: [PATCH 0746/1106] Small fix --- freqtrade/optimize/hyperopt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 9ff4a1ead..a5921703f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -7,6 +7,7 @@ This module contains the hyperopt logic import locale import logging import random +import sys import warnings from math import ceil from collections import OrderedDict @@ -270,6 +271,7 @@ class Hyperopt: # Print '\n' after each 100th epoch to separate dots from the log messages. # Otherwise output is messy on a terminal. print('.', end='' if results['current_epoch'] % 100 != 0 else None) # type: ignore + sys.stdout.flush() if self.print_all or is_best: if not self.print_all: From 6f67b8d9b900961afb93508214d981925261d3ec Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 12 Mar 2020 19:50:46 +0100 Subject: [PATCH 0747/1106] iCheck after clean_dataframe, too --- freqtrade/data/history/idatahandler.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index bde9612f2..b0a6a97dc 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -159,11 +159,13 @@ class IDataHandler(ABC): return pairdf # incomplete candles should only be dropped if we didn't trim the end beforehand. - return clean_ohlcv_dataframe(pairdf, timeframe, - pair=pair, - fill_missing=fill_missing, - drop_incomplete=(drop_incomplete and - enddate == pairdf.iloc[-1]['date'])) + pairdf = clean_ohlcv_dataframe(pairdf, timeframe, + pair=pair, + fill_missing=fill_missing, + drop_incomplete=(drop_incomplete and + enddate == pairdf.iloc[-1]['date'])) + self._check_empty_df(pairdf, pair, timeframe, warn_no_data) + return pairdf def _check_empty_df(self, pairdf: DataFrame, pair: str, timeframe: str, warn_no_data: bool): """ From ebb0187f4040aa7f23ed54cacd8faa9919640994 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 13 Mar 2020 03:54:56 +0300 Subject: [PATCH 0748/1106] dataframe -> df_analyzed in backtesting and edge --- freqtrade/edge/edge_positioning.py | 14 +++++++------- freqtrade/optimize/backtesting.py | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index a24e29efb..256b67383 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -137,10 +137,10 @@ class Edge: pair_data = pair_data.sort_values(by=['date']) pair_data = pair_data.reset_index(drop=True) - dataframe = self.strategy.advise_sell( + df_analyzed = self.strategy.advise_sell( self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() - trades += self._find_trades_for_stoploss_range(dataframe, pair, self._stoploss_range) + trades += self._find_trades_for_stoploss_range(df_analyzed, pair, self._stoploss_range) # If no trade found then exit if len(trades) == 0: @@ -359,11 +359,11 @@ class Edge: # Returning a list of pairs in order of "expectancy" return final - def _find_trades_for_stoploss_range(self, dataframe, pair, stoploss_range): - buy_column = dataframe['buy'].values - sell_column = dataframe['sell'].values - date_column = dataframe['date'].values - ohlc_columns = dataframe[['open', 'high', 'low', 'close']].values + def _find_trades_for_stoploss_range(self, df, pair, stoploss_range): + buy_column = df['buy'].values + sell_column = df['sell'].values + date_column = df['date'].values + ohlc_columns = df[['open', 'high', 'low', 'close']].values result: list = [] for stoploss in stoploss_range: diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 949c072c5..210fe3c66 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -164,19 +164,19 @@ class Backtesting: pair_data.loc[:, 'buy'] = 0 # cleanup from previous run pair_data.loc[:, 'sell'] = 0 # cleanup from previous run - dataframe = self.strategy.advise_sell( + df_analyzed = self.strategy.advise_sell( self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() # To avoid using data from future, we use buy/sell signals shifted # from the previous candle - dataframe.loc[:, 'buy'] = dataframe['buy'].shift(1) - dataframe.loc[:, 'sell'] = dataframe['sell'].shift(1) + df_analyzed.loc[:, 'buy'] = df_analyzed['buy'].shift(1) + df_analyzed.loc[:, 'sell'] = df_analyzed['sell'].shift(1) - dataframe.drop(dataframe.head(1).index, inplace=True) + df_analyzed.drop(df_analyzed.head(1).index, inplace=True) # Convert from Pandas to list for performance reasons # (Looping Pandas is slow.) - data[pair] = [x for x in dataframe.itertuples()] + data[pair] = [x for x in df_analyzed.itertuples()] return data def _get_close_rate(self, sell_row, trade: Trade, sell: SellCheckTuple, From b2952cd42ad22ecb0e623909524c07ac273803f3 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 13 Mar 2020 03:58:16 +0300 Subject: [PATCH 0749/1106] remove redundant dict --- freqtrade/plot/plotting.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index cfbda6714..220056d2d 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -454,10 +454,8 @@ def load_and_plot_trades(config: Dict[str, Any]): for pair, data in plot_elements["ohlcv"].items(): pair_counter += 1 logger.info("analyse pair %s", pair) - ohlcv = {} - ohlcv[pair] = data - dataframe = strategy.analyze_ticker(ohlcv[pair], {'pair': pair}) + dataframe = strategy.analyze_ticker(data, {'pair': pair}) trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) From ddfe5b5f1cb4788936699afbc36c1f19e85d2fc4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 13 Mar 2020 04:00:24 +0300 Subject: [PATCH 0750/1106] dataframe -> df_analyzed in plotting --- freqtrade/plot/plotting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 220056d2d..be7be2de0 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -455,13 +455,13 @@ def load_and_plot_trades(config: Dict[str, Any]): pair_counter += 1 logger.info("analyse pair %s", pair) - dataframe = strategy.analyze_ticker(data, {'pair': pair}) + df_analyzed = strategy.analyze_ticker(data, {'pair': pair}) trades_pair = trades.loc[trades['pair'] == pair] - trades_pair = extract_trades_of_period(dataframe, trades_pair) + trades_pair = extract_trades_of_period(df_analyzed, trades_pair) fig = generate_candlestick_graph( pair=pair, - data=dataframe, + data=df_analyzed, trades=trades_pair, indicators1=config.get("indicators1", []), indicators2=config.get("indicators2", []), From a7ed51c6424202dccb27f44a847721dbbf4eecde Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 13 Mar 2020 04:04:23 +0300 Subject: [PATCH 0751/1106] return back the name of the hyperopt data file --- 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 ed58db977..a6b13f93f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -76,7 +76,7 @@ class Hyperopt: self.trials_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') self.data_pickle_file = (self.config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_data.pkl') + 'hyperopt_results' / 'hyperopt_tickerdata.pkl') self.total_epochs = config.get('epochs', 0) self.current_best_loss = 100 From 59fadabb5ba01bc113c0d87cced31a7e7074df66 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 13 Mar 2020 20:26:14 +0300 Subject: [PATCH 0752/1106] Fix merging --- freqtrade/data/history/idatahandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index ae050103b..1bb4d5971 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -150,7 +150,7 @@ class IDataHandler(ABC): if self._check_empty_df(pairdf, pair, timeframe, warn_no_data): return pairdf else: - enddate = df.iloc[-1]['date'] + enddate = pairdf.iloc[-1]['date'] if timerange_startup: self._validate_pairdata(pair, pairdf, timerange_startup) From c56cbc21b1658102d912435fa00316ae3da51443 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 14 Mar 2020 10:42:01 +0100 Subject: [PATCH 0753/1106] Remove indexing warning in edge --- freqtrade/edge/edge_positioning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index 256b67383..d196ab4b3 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -317,7 +317,7 @@ class Edge: } # Group by (pair and stoploss) by applying above aggregator - df = results.groupby(['pair', 'stoploss'])['profit_abs', 'trade_duration'].agg( + df = results.groupby(['pair', 'stoploss'])[['profit_abs', 'trade_duration']].agg( groupby_aggregator).reset_index(col_level=1) # Dropping level 0 as we don't need it From 308d8fe2a9daf78fd58642c884dd6a9c4bd9a119 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 14 Mar 2020 10:44:46 +0100 Subject: [PATCH 0754/1106] Remove deprecation warnings due to date conversion --- tests/edge/test_edge.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index c68ac477c..3bebeee65 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -163,8 +163,8 @@ def test_edge_results(edge_conf, mocker, caplog, data) -> None: for c, trade in enumerate(data.trades): res = results.iloc[c] assert res.exit_type == trade.sell_reason - assert res.open_time == np.datetime64(_get_frame_time_from_offset(trade.open_tick)) - assert res.close_time == np.datetime64(_get_frame_time_from_offset(trade.close_tick)) + assert res.open_time == _get_frame_time_from_offset(trade.open_tick).replace(tzinfo=None) + assert res.close_time == _get_frame_time_from_offset(trade.close_tick).replace(tzinfo=None) def test_adjust(mocker, edge_conf): From 27faf12fdeef84f404aa7bf32f27e7591cc1a910 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 14 Mar 2020 22:15:03 +0100 Subject: [PATCH 0755/1106] Fix if no file exists --- freqtrade/commands/arguments.py | 2 +- freqtrade/commands/cli_options.py | 5 +++++ freqtrade/data/btanalysis.py | 8 ++++++-- freqtrade/plot/plotting.py | 19 +++++++++++++++---- tests/data/test_btanalysis.py | 5 ++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 1a8cca72b..66fa0b038 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -59,7 +59,7 @@ ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchang ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", "db_url", "trade_source", "export", "exportfilename", - "timerange", "ticker_interval"] + "timerange", "ticker_interval", "skip_trades"] ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 42c697d56..187e0a424 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -413,6 +413,11 @@ AVAILABLE_CLI_OPTIONS = { metavar='INT', default=750, ), + "skip_trades": Arg( + '--skip-trades', + help='Skip using trades file from backtesting and DB.', + action='store_true', + ), "trade_source": Arg( '--trade-source', help='Specify the source for trades (Can be DB or file (backtest file)) ' diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 681bf6734..fc938ad7e 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -111,7 +111,7 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: t.calc_profit(), t.calc_profit_ratio(), t.open_rate, t.close_rate, t.amount, (round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2) - if t.close_date else None), + if t.close_date else None), t.sell_reason, t.fee_open, t.fee_close, t.open_rate_requested, @@ -129,12 +129,16 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: return trades -def load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame: +def load_trades(source: str, db_url: str, exportfilename: str, skip_trades: bool) -> pd.DataFrame: """ Based on configuration option "trade_source": * loads data from DB (using `db_url`) * loads data from backtestfile (using `exportfilename`) """ + if skip_trades: + df = pd.DataFrame(columns=BT_DATA_COLUMNS) + return df + if source == "DB": return load_trades_from_db(db_url) elif source == "file": diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index be7be2de0..cb2686878 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -3,6 +3,7 @@ from pathlib import Path from typing import Any, Dict, List import pandas as pd +from os.path import isfile from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (calculate_max_drawdown, @@ -48,11 +49,21 @@ def init_plotscript(config): data_format=config.get('dataformat_ohlcv', 'json'), ) - trades = load_trades(config['trade_source'], - db_url=config.get('db_url'), - exportfilename=config.get('exportfilename'), - ) + skip_trades = False + if not isfile(config.get('exportfilename')) and config['trade_source'] == 'file': + logger.info("Backtest file is missing skipping trades.") + skip_trades = True + elif config.get('skip_trades', False): + skip_trades = True + + trades = load_trades( + config['trade_source'], + db_url=config.get('db_url'), + exportfilename=config.get('exportfilename'), + skip_trades=skip_trades + ) trades = trim_dataframe(trades, timerange, 'open_time') + return {"ohlcv": data, "trades": trades, "pairs": pairs, diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index da5d225b9..44e9c1072 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -104,6 +104,7 @@ def test_load_trades(default_conf, mocker): load_trades("DB", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'), + skip_trades=False ) assert db_mock.call_count == 1 @@ -114,7 +115,9 @@ def test_load_trades(default_conf, mocker): default_conf['exportfilename'] = "testfile.json" load_trades("file", db_url=default_conf.get('db_url'), - exportfilename=default_conf.get('exportfilename'),) + exportfilename=default_conf.get('exportfilename'), + skip_trades=False + ) assert db_mock.call_count == 0 assert bt_mock.call_count == 1 From cf7e80f45d5d664c1dcb1cc92335cffb67186d12 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 14 Mar 2020 23:55:13 +0100 Subject: [PATCH 0756/1106] Docs and logging --- docs/plotting.md | 62 +++++++++++++++++++++++++------------- freqtrade/plot/plotting.py | 2 +- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index 3eef8f8e7..ef28f0fe3 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -23,44 +23,64 @@ The `freqtrade plot-dataframe` subcommand shows an interactive graph with three Possible arguments: ``` -usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-s NAME] - [--strategy-path PATH] [-p PAIRS [PAIRS ...]] [--indicators1 INDICATORS1 [INDICATORS1 ...]] - [--indicators2 INDICATORS2 [INDICATORS2 ...]] [--plot-limit INT] [--db-url PATH] - [--trade-source {DB,file}] [--export EXPORT] [--export-filename PATH] [--timerange TIMERANGE] - [-i TICKER_INTERVAL] +usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [-s NAME] + [--strategy-path PATH] [-p PAIRS [PAIRS ...]] + [--indicators1 INDICATORS1 [INDICATORS1 ...]] + [--indicators2 INDICATORS2 [INDICATORS2 ...]] + [--plot-limit INT] [--db-url PATH] + [--trade-source {DB,file}] [--export EXPORT] + [--export-filename PATH] + [--timerange TIMERANGE] [-i TICKER_INTERVAL] + [--skip-trades] optional arguments: -h, --help show this help message and exit -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] - Show profits for only these pairs. Pairs are space-separated. + Show profits for only these pairs. Pairs are space- + separated. --indicators1 INDICATORS1 [INDICATORS1 ...] - Set indicators from your strategy you want in the first row of the graph. Space-separated list. Example: + Set indicators from your strategy you want in the + first row of the graph. Space-separated list. Example: `ema3 ema5`. Default: `['sma', 'ema3', 'ema5']`. --indicators2 INDICATORS2 [INDICATORS2 ...] - Set indicators from your strategy you want in the third row of the graph. Space-separated list. Example: + Set indicators from your strategy you want in the + third row of the graph. Space-separated list. Example: `fastd fastk`. Default: `['macd', 'macdsignal']`. - --plot-limit INT Specify tick limit for plotting. Notice: too high values cause huge files. Default: 750. - --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` - for Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for Dry Run). + --plot-limit INT Specify tick limit for plotting. Notice: too high + values cause huge files. Default: 750. + --db-url PATH Override trades database URL, this is useful in custom + deployments (default: `sqlite:///tradesv3.sqlite` for + Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for + Dry Run). --trade-source {DB,file} - Specify the source for trades (Can be DB or file (backtest file)) Default: file - --export EXPORT Export backtest results, argument are: trades. Example: `--export=trades` + Specify the source for trades (Can be DB or file + (backtest file)) Default: file + --export EXPORT Export backtest results, argument are: trades. + Example: `--export=trades` --export-filename PATH - Save backtest results to the file with this filename. Requires `--export` to be set as well. Example: - `--export-filename=user_data/backtest_results/backtest_today.json` + Save backtest results to the file with this filename. + Requires `--export` to be set as well. Example: + `--export-filename=user_data/backtest_results/backtest + _today.json` --timerange TIMERANGE Specify what timerange of data to use. -i TICKER_INTERVAL, --ticker-interval TICKER_INTERVAL - Specify ticker interval (`1m`, `5m`, `30m`, `1h`, `1d`). + Specify ticker interval (`1m`, `5m`, `30m`, `1h`, + `1d`). + --skip-trades Skip using trades file from backtesting and DB. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). - --logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more details. -V, --version show program's version number and exit -c PATH, --config PATH - Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to - `-` to read config from stdin. + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. -d PATH, --datadir PATH Path to directory with historical backtesting data. --userdir PATH, --user-data-dir PATH @@ -68,9 +88,9 @@ Common arguments: Strategy arguments: -s NAME, --strategy NAME - Specify strategy class name which will be used by the bot. + Specify strategy class name which will be used by the + bot. --strategy-path PATH Specify additional strategy lookup path. - ``` Example: diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index cb2686878..8da61597f 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -51,7 +51,7 @@ def init_plotscript(config): skip_trades = False if not isfile(config.get('exportfilename')) and config['trade_source'] == 'file': - logger.info("Backtest file is missing skipping trades.") + logger.warning("Backtest file is missing skipping trades.") skip_trades = True elif config.get('skip_trades', False): skip_trades = True From 2c0980aa3ab2af40e46411819f2e53b76eae6fa4 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 15 Mar 2020 00:09:08 +0100 Subject: [PATCH 0757/1106] Tests --- tests/data/test_btanalysis.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 44e9c1072..95f371d7f 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -122,6 +122,18 @@ def test_load_trades(default_conf, mocker): assert db_mock.call_count == 0 assert bt_mock.call_count == 1 + db_mock.reset_mock() + bt_mock.reset_mock() + default_conf['exportfilename'] = "testfile.json" + load_trades("file", + db_url=default_conf.get('db_url'), + exportfilename=default_conf.get('exportfilename'), + skip_trades=True + ) + + assert db_mock.call_count == 0 + assert bt_mock.call_count == 0 + def test_combine_dataframes_with_mean(testdatadir): pairs = ["ETH/BTC", "ADA/BTC"] From 0f1640bed4691cc0d27ed1d665e77c8d2dd85944 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 09:39:45 +0100 Subject: [PATCH 0758/1106] convert exportfilename to Path when config parsing --- freqtrade/configuration/configuration.py | 1 + freqtrade/data/btanalysis.py | 8 ++++++-- freqtrade/optimize/backtesting.py | 2 +- tests/data/test_btanalysis.py | 5 +++-- tests/optimize/test_backtesting.py | 1 + tests/test_plotting.py | 6 +++--- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 0645d72be..ce2101441 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -196,6 +196,7 @@ class Configuration: if self.args.get('exportfilename'): self._args_to_config(config, argname='exportfilename', logstring='Storing backtest results to {} ...') + config['exportfilename'] = Path(config['exportfilename']) else: config['exportfilename'] = (config['user_data_dir'] / 'backtest_results/backtest-result.json') diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 681bf6734..e8ec03fea 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -129,16 +129,20 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: return trades -def load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame: +def load_trades(source: str, db_url: str, exportfilename: Path) -> pd.DataFrame: """ Based on configuration option "trade_source": * loads data from DB (using `db_url`) * loads data from backtestfile (using `exportfilename`) + :param source: "DB" or "file" - specify source to load from + :param db_url: sqlalchemy formatted url to a database + :param exportfilename: Json file generated by backtesting + :return: DataFrame containing trades """ if source == "DB": return load_trades_from_db(db_url) elif source == "file": - return load_backtest_data(Path(exportfilename)) + return load_backtest_data(exportfilename) def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame: diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 210fe3c66..40e6590f7 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -421,7 +421,7 @@ class Backtesting: for strategy, results in all_results.items(): if self.config.get('export', False): - self._store_backtest_result(Path(self.config['exportfilename']), results, + self._store_backtest_result(self.config['exportfilename'], results, strategy if len(self.strategylist) > 1 else None) print(f"Result for strategy {strategy}") diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index da5d225b9..7513991ea 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -1,8 +1,9 @@ +from pathlib import Path from unittest.mock import MagicMock import pytest from arrow import Arrow -from pandas import DataFrame, DateOffset, to_datetime, Timestamp +from pandas import DataFrame, DateOffset, Timestamp, to_datetime from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, @@ -111,7 +112,7 @@ def test_load_trades(default_conf, mocker): db_mock.reset_mock() bt_mock.reset_mock() - default_conf['exportfilename'] = "testfile.json" + default_conf['exportfilename'] = Path("testfile.json") load_trades("file", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'),) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index f78b44704..da23a9af4 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -224,6 +224,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> assert 'export' in config assert log_has('Parameter --export detected: {} ...'.format(config['export']), caplog) assert 'exportfilename' in config + assert isinstance(config['exportfilename'], Path) assert log_has('Storing backtest results to {} ...'.format(config['exportfilename']), caplog) assert 'fee' in config diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 42010ad0d..a5c965429 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -49,7 +49,7 @@ def test_init_plotscript(default_conf, mocker, testdatadir): default_conf['trade_source'] = "file" default_conf['ticker_interval'] = "5m" default_conf["datadir"] = testdatadir - default_conf['exportfilename'] = str(testdatadir / "backtest-result_test.json") + default_conf['exportfilename'] = testdatadir / "backtest-result_test.json" ret = init_plotscript(default_conf) assert "ohlcv" in ret assert "trades" in ret @@ -318,7 +318,7 @@ def test_start_plot_dataframe(mocker): def test_load_and_plot_trades(default_conf, mocker, caplog, testdatadir): default_conf['trade_source'] = 'file' default_conf["datadir"] = testdatadir - default_conf['exportfilename'] = str(testdatadir / "backtest-result_test.json") + default_conf['exportfilename'] = testdatadir / "backtest-result_test.json" default_conf['indicators1'] = ["sma5", "ema10"] default_conf['indicators2'] = ["macd"] default_conf['pairs'] = ["ETH/BTC", "LTC/BTC"] @@ -374,7 +374,7 @@ def test_start_plot_profit_error(mocker): def test_plot_profit(default_conf, mocker, testdatadir, caplog): default_conf['trade_source'] = 'file' default_conf["datadir"] = testdatadir - default_conf['exportfilename'] = str(testdatadir / "backtest-result_test.json") + default_conf['exportfilename'] = testdatadir / "backtest-result_test.json" default_conf['pairs'] = ["ETH/BTC", "LTC/BTC"] profit_mock = MagicMock() From 328dbd3930981103d2646e27e53156f104e59745 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:04:48 +0100 Subject: [PATCH 0759/1106] Remove unnecessary parameter to generate_text_table_sell_reason --- freqtrade/optimize/backtesting.py | 7 +++---- freqtrade/optimize/optimize_reports.py | 8 ++++---- tests/optimize/test_optimize_reports.py | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 40e6590f7..5ee5a058f 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -7,7 +7,7 @@ import logging from copy import deepcopy from datetime import datetime, timedelta from pathlib import Path -from typing import Any, Dict, List, NamedTuple, Optional +from typing import Any, Dict, List, NamedTuple, Optional, Tuple import arrow from pandas import DataFrame @@ -108,7 +108,7 @@ class Backtesting: # And the regular "stoploss" function would not apply to that case self.strategy.order_types['stoploss_on_exchange'] = False - def load_bt_data(self): + def load_bt_data(self) -> Tuple[Dict[str, DataFrame], TimeRange]: timerange = TimeRange.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) @@ -432,8 +432,7 @@ class Backtesting: print(' BACKTESTING REPORT '.center(len(table.splitlines()[0]), '=')) print(table) - table = generate_text_table_sell_reason(data, - stake_currency=self.config['stake_currency'], + table = generate_text_table_sell_reason(stake_currency=self.config['stake_currency'], max_open_trades=self.config['max_open_trades'], results=results) if isinstance(table, str): diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 39bde50a8..ee29aa283 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -69,12 +69,12 @@ def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_tra floatfmt=floatfmt, tablefmt="orgtbl", stralign="right") # type: ignore -def generate_text_table_sell_reason( - data: Dict[str, Dict], stake_currency: str, max_open_trades: int, results: DataFrame -) -> str: +def generate_text_table_sell_reason(stake_currency: str, max_open_trades: int, + results: DataFrame) -> str: """ Generate small table outlining Backtest results - :param data: Dict of containing data that was used during backtesting. + :param stake_currency: Stakecurrency used + :param max_open_trades: Max_open_trades parameter :param results: Dataframe containing the backtest results :return: pretty printed table with tabulate as string """ diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 285ecaa02..5e68a5ef8 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -61,10 +61,8 @@ def test_generate_text_table_sell_reason(default_conf, mocker): '| stop_loss | 1 | 0 | 0 | 1 |' ' -10 | -10 | -0.2 | -5 |' ) - assert generate_text_table_sell_reason( - data={'ETH/BTC': {}}, - stake_currency='BTC', max_open_trades=2, - results=results) == result_str + assert generate_text_table_sell_reason(stake_currency='BTC', max_open_trades=2, + results=results) == result_str def test_generate_text_table_strategy(default_conf, mocker): From 6106d59e1a0122863849e03e671db698f02c5c96 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:17:35 +0100 Subject: [PATCH 0760/1106] Move store_backtest_results to optimize_reports --- freqtrade/optimize/backtesting.py | 18 ------------------ freqtrade/optimize/optimize_reports.py | 26 +++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 5ee5a058f..9dd1b8429 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -6,7 +6,6 @@ This module contains the backtesting logic import logging from copy import deepcopy from datetime import datetime, timedelta -from pathlib import Path from typing import Any, Dict, List, NamedTuple, Optional, Tuple import arrow @@ -134,23 +133,6 @@ class Backtesting: return data, timerange - def _store_backtest_result(self, recordfilename: Path, results: DataFrame, - strategyname: Optional[str] = None) -> None: - - records = [(t.pair, t.profit_percent, t.open_time.timestamp(), - t.close_time.timestamp(), t.open_index - 1, t.trade_duration, - t.open_rate, t.close_rate, t.open_at_end, t.sell_reason.value) - for index, t in results.iterrows()] - - if records: - if strategyname: - # Inject strategyname to filename - recordfilename = Path.joinpath( - recordfilename.parent, - f'{recordfilename.stem}-{strategyname}').with_suffix(recordfilename.suffix) - logger.info(f'Dumping backtest results to {recordfilename}') - file_dump_json(recordfilename, records) - def _get_ohlcv_as_lists(self, processed: Dict) -> Dict[str, DataFrame]: """ Helper function to convert a processed dataframes into lists for performance reasons. diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index ee29aa283..fb407f681 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -1,9 +1,33 @@ +import logging from datetime import timedelta -from typing import Dict +from pathlib import Path +from typing import Dict, Optional from pandas import DataFrame from tabulate import tabulate +from freqtrade.misc import file_dump_json + +logger = logging.getLogger(__name__) + + +def store_backtest_result(recordfilename: Path, results: DataFrame, + strategyname: Optional[str] = None) -> None: + + records = [(t.pair, t.profit_percent, t.open_time.timestamp(), + t.close_time.timestamp(), t.open_index - 1, t.trade_duration, + t.open_rate, t.close_rate, t.open_at_end, t.sell_reason.value) + for index, t in results.iterrows()] + + if records: + if strategyname: + # Inject strategyname to filename + recordfilename = Path.joinpath( + recordfilename.parent, + f'{recordfilename.stem}-{strategyname}').with_suffix(recordfilename.suffix) + logger.info(f'Dumping backtest results to {recordfilename}') + file_dump_json(recordfilename, records) + def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, results: DataFrame, skip_nan: bool = False) -> str: From a13d581658173fb764c110ae9966767f17c85e7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:17:53 +0100 Subject: [PATCH 0761/1106] Move backtest-result visualization out of backtesting class --- freqtrade/optimize/backtesting.py | 48 ++------------------------ freqtrade/optimize/optimize_reports.py | 44 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 9dd1b8429..323331bc6 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -18,10 +18,7 @@ from freqtrade.data.converter import trim_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds -from freqtrade.misc import file_dump_json -from freqtrade.optimize.optimize_reports import ( - generate_text_table, generate_text_table_sell_reason, - generate_text_table_strategy) +from freqtrade.optimize.optimize_reports import show_backtest_results from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode @@ -399,44 +396,5 @@ class Backtesting: max_open_trades=max_open_trades, position_stacking=position_stacking, ) - - for strategy, results in all_results.items(): - - if self.config.get('export', False): - self._store_backtest_result(self.config['exportfilename'], results, - strategy if len(self.strategylist) > 1 else None) - - print(f"Result for strategy {strategy}") - table = generate_text_table(data, stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results) - if isinstance(table, str): - print(' BACKTESTING REPORT '.center(len(table.splitlines()[0]), '=')) - print(table) - - table = generate_text_table_sell_reason(stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results) - if isinstance(table, str): - print(' SELL REASON STATS '.center(len(table.splitlines()[0]), '=')) - print(table) - - table = generate_text_table(data, - stake_currency=self.config['stake_currency'], - max_open_trades=self.config['max_open_trades'], - results=results.loc[results.open_at_end], skip_nan=True) - if isinstance(table, str): - print(' LEFT OPEN TRADES REPORT '.center(len(table.splitlines()[0]), '=')) - print(table) - if isinstance(table, str): - print('=' * len(table.splitlines()[0])) - print() - if len(all_results) > 1: - # Print Strategy summary table - table = generate_text_table_strategy(self.config['stake_currency'], - self.config['max_open_trades'], - all_results=all_results) - print(' STRATEGY SUMMARY '.center(len(table.splitlines()[0]), '=')) - print(table) - print('=' * len(table.splitlines()[0])) - print('\nFor more details, please look at the detail tables above') + # Show backtest results + show_backtest_results(self.config, data, all_results) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index fb407f681..fef0accb0 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -197,3 +197,47 @@ def generate_edge_table(results: dict) -> str: # Ignore type as floatfmt does allow tuples but mypy does not know that return tabulate(tabular_data, headers=headers, floatfmt=floatfmt, tablefmt="orgtbl", stralign="right") # type: ignore + + +def show_backtest_results(config: Dict, btdata: Dict[str, DataFrame], + all_results: Dict[str, DataFrame]): + for strategy, results in all_results.items(): + + if config.get('export', False): + store_backtest_result(config['exportfilename'], results, + strategy if len(all_results) > 1 else None) + + print(f"Result for strategy {strategy}") + table = generate_text_table(btdata, stake_currency=config['stake_currency'], + max_open_trades=config['max_open_trades'], + results=results) + if isinstance(table, str): + print(' BACKTESTING REPORT '.center(len(table.splitlines()[0]), '=')) + print(table) + + table = generate_text_table_sell_reason(stake_currency=config['stake_currency'], + max_open_trades=config['max_open_trades'], + results=results) + if isinstance(table, str): + print(' SELL REASON STATS '.center(len(table.splitlines()[0]), '=')) + print(table) + + table = generate_text_table(btdata, + stake_currency=config['stake_currency'], + max_open_trades=config['max_open_trades'], + results=results.loc[results.open_at_end], skip_nan=True) + if isinstance(table, str): + print(' LEFT OPEN TRADES REPORT '.center(len(table.splitlines()[0]), '=')) + print(table) + if isinstance(table, str): + print('=' * len(table.splitlines()[0])) + print() + if len(all_results) > 1: + # Print Strategy summary table + table = generate_text_table_strategy(config['stake_currency'], + config['max_open_trades'], + all_results=all_results) + print(' STRATEGY SUMMARY '.center(len(table.splitlines()[0]), '=')) + print(table) + print('=' * len(table.splitlines()[0])) + print('\nFor more details, please look at the detail tables above') From e95665cecaeec2337dee47660674401535b406a7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:36:23 +0100 Subject: [PATCH 0762/1106] Make backtestresult storing independent from printing --- freqtrade/optimize/backtesting.py | 6 ++++- freqtrade/optimize/optimize_reports.py | 36 ++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 323331bc6..1725a7d13 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -18,7 +18,8 @@ from freqtrade.data.converter import trim_dataframe from freqtrade.data.dataprovider import DataProvider from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds -from freqtrade.optimize.optimize_reports import show_backtest_results +from freqtrade.optimize.optimize_reports import (show_backtest_results, + store_backtest_result) from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode @@ -396,5 +397,8 @@ class Backtesting: max_open_trades=max_open_trades, position_stacking=position_stacking, ) + + if self.config.get('export', False): + store_backtest_result(self.config['exportfilename'], all_results) # Show backtest results show_backtest_results(self.config, data, all_results) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index fef0accb0..701432071 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -11,22 +11,22 @@ from freqtrade.misc import file_dump_json logger = logging.getLogger(__name__) -def store_backtest_result(recordfilename: Path, results: DataFrame, - strategyname: Optional[str] = None) -> None: +def store_backtest_result(recordfilename: Path, all_results: Dict[str, DataFrame]) -> None: - records = [(t.pair, t.profit_percent, t.open_time.timestamp(), - t.close_time.timestamp(), t.open_index - 1, t.trade_duration, - t.open_rate, t.close_rate, t.open_at_end, t.sell_reason.value) - for index, t in results.iterrows()] + for strategy, results in all_results.items(): + records = [(t.pair, t.profit_percent, t.open_time.timestamp(), + t.close_time.timestamp(), t.open_index - 1, t.trade_duration, + t.open_rate, t.close_rate, t.open_at_end, t.sell_reason.value) + for index, t in results.iterrows()] - if records: - if strategyname: - # Inject strategyname to filename - recordfilename = Path.joinpath( - recordfilename.parent, - f'{recordfilename.stem}-{strategyname}').with_suffix(recordfilename.suffix) - logger.info(f'Dumping backtest results to {recordfilename}') - file_dump_json(recordfilename, records) + if records: + if len(all_results) > 1: + # Inject strategy to filename + recordfilename = Path.joinpath( + recordfilename.parent, + f'{recordfilename.stem}-{strategy}').with_suffix(recordfilename.suffix) + logger.info(f'Dumping backtest results to {recordfilename}') + file_dump_json(recordfilename, records) def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, @@ -203,10 +203,6 @@ def show_backtest_results(config: Dict, btdata: Dict[str, DataFrame], all_results: Dict[str, DataFrame]): for strategy, results in all_results.items(): - if config.get('export', False): - store_backtest_result(config['exportfilename'], results, - strategy if len(all_results) > 1 else None) - print(f"Result for strategy {strategy}") table = generate_text_table(btdata, stake_currency=config['stake_currency'], max_open_trades=config['max_open_trades'], @@ -235,8 +231,8 @@ def show_backtest_results(config: Dict, btdata: Dict[str, DataFrame], if len(all_results) > 1: # Print Strategy summary table table = generate_text_table_strategy(config['stake_currency'], - config['max_open_trades'], - all_results=all_results) + config['max_open_trades'], + all_results=all_results) print(' STRATEGY SUMMARY '.center(len(table.splitlines()[0]), '=')) print(table) print('=' * len(table.splitlines()[0])) From fe50a0f3a13e0d0f92084314af081ce1230acaac Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:36:53 +0100 Subject: [PATCH 0763/1106] Move test for store_bt_results to optimize_reports --- tests/optimize/test_backtesting.py | 89 +++---------------------- tests/optimize/test_optimize_reports.py | 76 ++++++++++++++++++++- 2 files changed, 83 insertions(+), 82 deletions(-) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index da23a9af4..1c4d3b16a 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -331,8 +331,8 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: mocker.patch('freqtrade.data.history.get_timerange', get_timerange) patch_exchange(mocker) - mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) - mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) + mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') + mocker.patch('freqtrade.optimize.backtesting.show_backtest_results') default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = '1m' @@ -361,8 +361,8 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> MagicMock(return_value=pd.DataFrame())) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) patch_exchange(mocker) - mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) - mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1)) + mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') + mocker.patch('freqtrade.optimize.backtesting.show_backtest_results') default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = "1m" @@ -507,7 +507,6 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir): def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir): mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) - mocker.patch('freqtrade.optimize.backtesting.file_dump_json', MagicMock()) backtest_conf = _make_backtest_conf(mocker, conf=default_conf, pair='UNITTEST/BTC', datadir=testdatadir) default_conf['ticker_interval'] = '1m' @@ -515,7 +514,6 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir): backtesting.strategy.advise_buy = _trend_alternate # Override backtesting.strategy.advise_sell = _trend_alternate # Override results = backtesting.backtest(**backtest_conf) - backtesting._store_backtest_result("test_.json", results) # 200 candles in backtest data # won't buy on first (shifted by 1) # 100 buys signals @@ -586,84 +584,12 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) assert len(evaluate_result_multi(results, '5m', 1)) == 0 -def test_backtest_record(default_conf, fee, mocker): - names = [] - records = [] - patch_exchange(mocker) - mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) - mocker.patch( - 'freqtrade.optimize.backtesting.file_dump_json', - new=lambda n, r: (names.append(n), records.append(r)) - ) - - backtesting = Backtesting(default_conf) - results = pd.DataFrame({"pair": ["UNITTEST/BTC", "UNITTEST/BTC", - "UNITTEST/BTC", "UNITTEST/BTC"], - "profit_percent": [0.003312, 0.010801, 0.013803, 0.002780], - "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], - "open_time": [Arrow(2017, 11, 14, 19, 32, 00).datetime, - Arrow(2017, 11, 14, 21, 36, 00).datetime, - Arrow(2017, 11, 14, 22, 12, 00).datetime, - Arrow(2017, 11, 14, 22, 44, 00).datetime], - "close_time": [Arrow(2017, 11, 14, 21, 35, 00).datetime, - Arrow(2017, 11, 14, 22, 10, 00).datetime, - Arrow(2017, 11, 14, 22, 43, 00).datetime, - Arrow(2017, 11, 14, 22, 58, 00).datetime], - "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], - "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], - "open_index": [1, 119, 153, 185], - "close_index": [118, 151, 184, 199], - "trade_duration": [123, 34, 31, 14], - "open_at_end": [False, False, False, True], - "sell_reason": [SellType.ROI, SellType.STOP_LOSS, - SellType.ROI, SellType.FORCE_SELL] - }) - backtesting._store_backtest_result("backtest-result.json", results) - assert len(results) == 4 - # Assert file_dump_json was only called once - assert names == ['backtest-result.json'] - records = records[0] - # Ensure records are of correct type - assert len(records) == 4 - - # reset test to test with strategy name - names = [] - records = [] - backtesting._store_backtest_result(Path("backtest-result.json"), results, "DefStrat") - assert len(results) == 4 - # Assert file_dump_json was only called once - assert names == [Path('backtest-result-DefStrat.json')] - records = records[0] - # Ensure records are of correct type - assert len(records) == 4 - - # ('UNITTEST/BTC', 0.00331158, '1510684320', '1510691700', 0, 117) - # Below follows just a typecheck of the schema/type of trade-records - oix = None - for (pair, profit, date_buy, date_sell, buy_index, dur, - openr, closer, open_at_end, sell_reason) in records: - assert pair == 'UNITTEST/BTC' - assert isinstance(profit, float) - # FIX: buy/sell should be converted to ints - assert isinstance(date_buy, float) - assert isinstance(date_sell, float) - assert isinstance(openr, float) - assert isinstance(closer, float) - assert isinstance(open_at_end, bool) - assert isinstance(sell_reason, str) - isinstance(buy_index, pd._libs.tslib.Timestamp) - if oix: - assert buy_index > oix - oix = buy_index - assert dur > 0 - - def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) - mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock()) + mocker.patch('freqtrade.optimize.backtesting.show_backtest_results', MagicMock()) patched_configuration_load_config_file(mocker, default_conf) @@ -705,9 +631,10 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): backtestmock = MagicMock() mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) gen_table_mock = MagicMock() - mocker.patch('freqtrade.optimize.backtesting.generate_text_table', gen_table_mock) + mocker.patch('freqtrade.optimize.optimize_reports.generate_text_table', gen_table_mock) gen_strattable_mock = MagicMock() - mocker.patch('freqtrade.optimize.backtesting.generate_text_table_strategy', gen_strattable_mock) + mocker.patch('freqtrade.optimize.optimize_reports.generate_text_table_strategy', + gen_strattable_mock) patched_configuration_load_config_file(mocker, default_conf) args = [ diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 5e68a5ef8..36c9a93b3 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -1,10 +1,14 @@ +from pathlib import Path + import pandas as pd +from arrow import Arrow from freqtrade.edge import PairInfo from freqtrade.optimize.optimize_reports import ( generate_edge_table, generate_text_table, generate_text_table_sell_reason, - generate_text_table_strategy) + generate_text_table_strategy, store_backtest_result) from freqtrade.strategy.interface import SellType +from tests.conftest import patch_exchange def test_generate_text_table(default_conf, mocker): @@ -113,3 +117,73 @@ def test_generate_edge_table(edge_conf, mocker): assert generate_edge_table(results).count('| ETH/BTC |') == 1 assert generate_edge_table(results).count( '| Risk Reward Ratio | Required Risk Reward | Expectancy |') == 1 + + +def test_backtest_record(default_conf, fee, mocker): + names = [] + records = [] + patch_exchange(mocker) + mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) + mocker.patch( + 'freqtrade.optimize.optimize_reports.file_dump_json', + new=lambda n, r: (names.append(n), records.append(r)) + ) + + results = {'DefStrat': pd.DataFrame({"pair": ["UNITTEST/BTC", "UNITTEST/BTC", + "UNITTEST/BTC", "UNITTEST/BTC"], + "profit_percent": [0.003312, 0.010801, 0.013803, 0.002780], + "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], + "open_time": [Arrow(2017, 11, 14, 19, 32, 00).datetime, + Arrow(2017, 11, 14, 21, 36, 00).datetime, + Arrow(2017, 11, 14, 22, 12, 00).datetime, + Arrow(2017, 11, 14, 22, 44, 00).datetime], + "close_time": [Arrow(2017, 11, 14, 21, 35, 00).datetime, + Arrow(2017, 11, 14, 22, 10, 00).datetime, + Arrow(2017, 11, 14, 22, 43, 00).datetime, + Arrow(2017, 11, 14, 22, 58, 00).datetime], + "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], + "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], + "open_index": [1, 119, 153, 185], + "close_index": [118, 151, 184, 199], + "trade_duration": [123, 34, 31, 14], + "open_at_end": [False, False, False, True], + "sell_reason": [SellType.ROI, SellType.STOP_LOSS, + SellType.ROI, SellType.FORCE_SELL] + })} + store_backtest_result(Path("backtest-result.json"), results) + # Assert file_dump_json was only called once + assert names == [Path('backtest-result.json')] + records = records[0] + # Ensure records are of correct type + assert len(records) == 4 + + # reset test to test with strategy name + names = [] + records = [] + results['Strat'] = pd.DataFrame() + store_backtest_result(Path("backtest-result.json"), results) + # Assert file_dump_json was only called once + assert names == [Path('backtest-result-DefStrat.json')] + records = records[0] + # Ensure records are of correct type + assert len(records) == 4 + + # ('UNITTEST/BTC', 0.00331158, '1510684320', '1510691700', 0, 117) + # Below follows just a typecheck of the schema/type of trade-records + oix = None + for (pair, profit, date_buy, date_sell, buy_index, dur, + openr, closer, open_at_end, sell_reason) in records: + assert pair == 'UNITTEST/BTC' + assert isinstance(profit, float) + # FIX: buy/sell should be converted to ints + assert isinstance(date_buy, float) + assert isinstance(date_sell, float) + assert isinstance(openr, float) + assert isinstance(closer, float) + assert isinstance(open_at_end, bool) + assert isinstance(sell_reason, str) + isinstance(buy_index, pd._libs.tslib.Timestamp) + if oix: + assert buy_index > oix + oix = buy_index + assert dur > 0 From e1b08ad76caf8482ee712d782bad482c643b0307 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:38:26 +0100 Subject: [PATCH 0764/1106] Add docstring to store_backtest_result --- freqtrade/optimize/optimize_reports.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 701432071..abfbaf1d8 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -12,7 +12,11 @@ logger = logging.getLogger(__name__) def store_backtest_result(recordfilename: Path, all_results: Dict[str, DataFrame]) -> None: - + """ + Stores backtest results to file (one file per strategy) + :param recordfilename: Destination filename + :param all_results: Dict of Dataframes, one results dataframe per strategy + """ for strategy, results in all_results.items(): records = [(t.pair, t.profit_percent, t.open_time.timestamp(), t.close_time.timestamp(), t.open_index - 1, t.trade_duration, From 3d4664c2a6da70027189d73a04b75bdd1821f79e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 15 Mar 2020 15:40:12 +0100 Subject: [PATCH 0765/1106] Remove unnecessary import --- freqtrade/optimize/optimize_reports.py | 2 +- tests/optimize/test_optimize_reports.py | 40 ++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index abfbaf1d8..251da9159 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -1,7 +1,7 @@ import logging from datetime import timedelta from pathlib import Path -from typing import Dict, Optional +from typing import Dict from pandas import DataFrame from tabulate import tabulate diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 36c9a93b3..f19668459 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -130,26 +130,26 @@ def test_backtest_record(default_conf, fee, mocker): ) results = {'DefStrat': pd.DataFrame({"pair": ["UNITTEST/BTC", "UNITTEST/BTC", - "UNITTEST/BTC", "UNITTEST/BTC"], - "profit_percent": [0.003312, 0.010801, 0.013803, 0.002780], - "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], - "open_time": [Arrow(2017, 11, 14, 19, 32, 00).datetime, - Arrow(2017, 11, 14, 21, 36, 00).datetime, - Arrow(2017, 11, 14, 22, 12, 00).datetime, - Arrow(2017, 11, 14, 22, 44, 00).datetime], - "close_time": [Arrow(2017, 11, 14, 21, 35, 00).datetime, - Arrow(2017, 11, 14, 22, 10, 00).datetime, - Arrow(2017, 11, 14, 22, 43, 00).datetime, - Arrow(2017, 11, 14, 22, 58, 00).datetime], - "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], - "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], - "open_index": [1, 119, 153, 185], - "close_index": [118, 151, 184, 199], - "trade_duration": [123, 34, 31, 14], - "open_at_end": [False, False, False, True], - "sell_reason": [SellType.ROI, SellType.STOP_LOSS, - SellType.ROI, SellType.FORCE_SELL] - })} + "UNITTEST/BTC", "UNITTEST/BTC"], + "profit_percent": [0.003312, 0.010801, 0.013803, 0.002780], + "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003], + "open_time": [Arrow(2017, 11, 14, 19, 32, 00).datetime, + Arrow(2017, 11, 14, 21, 36, 00).datetime, + Arrow(2017, 11, 14, 22, 12, 00).datetime, + Arrow(2017, 11, 14, 22, 44, 00).datetime], + "close_time": [Arrow(2017, 11, 14, 21, 35, 00).datetime, + Arrow(2017, 11, 14, 22, 10, 00).datetime, + Arrow(2017, 11, 14, 22, 43, 00).datetime, + Arrow(2017, 11, 14, 22, 58, 00).datetime], + "open_rate": [0.002543, 0.003003, 0.003089, 0.003214], + "close_rate": [0.002546, 0.003014, 0.003103, 0.003217], + "open_index": [1, 119, 153, 185], + "close_index": [118, 151, 184, 199], + "trade_duration": [123, 34, 31, 14], + "open_at_end": [False, False, False, True], + "sell_reason": [SellType.ROI, SellType.STOP_LOSS, + SellType.ROI, SellType.FORCE_SELL] + })} store_backtest_result(Path("backtest-result.json"), results) # Assert file_dump_json was only called once assert names == [Path('backtest-result.json')] From 8c33e07dc660853eee0eee0d10109063f52d11cf Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 15 Mar 2020 21:20:32 +0100 Subject: [PATCH 0766/1106] Update based on comments --- docs/plotting.md | 2 +- freqtrade/commands/arguments.py | 2 +- freqtrade/commands/cli_options.py | 6 +++--- freqtrade/data/btanalysis.py | 6 +++--- freqtrade/plot/plotting.py | 13 ++++++------- tests/data/test_btanalysis.py | 6 +++--- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/docs/plotting.md b/docs/plotting.md index ef28f0fe3..56906ebec 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -68,7 +68,7 @@ optional arguments: -i TICKER_INTERVAL, --ticker-interval TICKER_INTERVAL Specify ticker interval (`1m`, `5m`, `30m`, `1h`, `1d`). - --skip-trades Skip using trades file from backtesting and DB. + --no-trades Skip using trades from backtesting file and DB. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 66fa0b038..8c64c5857 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -59,7 +59,7 @@ ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchang ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", "db_url", "trade_source", "export", "exportfilename", - "timerange", "ticker_interval", "skip_trades"] + "timerange", "ticker_interval", "no_trades"] ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 187e0a424..5cf1b7fce 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -413,9 +413,9 @@ AVAILABLE_CLI_OPTIONS = { metavar='INT', default=750, ), - "skip_trades": Arg( - '--skip-trades', - help='Skip using trades file from backtesting and DB.', + "no_trades": Arg( + '--no-trades', + help='Skip using trades from backtesting file and DB.', action='store_true', ), "trade_source": Arg( diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 8670f30c6..17b243f56 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -129,7 +129,7 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: return trades -def load_trades(source: str, db_url: str, exportfilename: Path, skip_trades: bool) -> pd.DataFrame: +def load_trades(source: str, db_url: str, exportfilename: Path, no_trades: bool) -> pd.DataFrame: """ Based on configuration option "trade_source": * loads data from DB (using `db_url`) @@ -137,10 +137,10 @@ def load_trades(source: str, db_url: str, exportfilename: Path, skip_trades: boo :param source: "DB" or "file" - specify source to load from :param db_url: sqlalchemy formatted url to a database :param exportfilename: Json file generated by backtesting - :param skip_trades: Skip using trades, only return backtesting data columns + :param no_trades: Skip using trades, only return backtesting data columns :return: DataFrame containing trades """ - if skip_trades: + if no_trades: df = pd.DataFrame(columns=BT_DATA_COLUMNS) return df diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 8da61597f..fc8f25612 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -3,7 +3,6 @@ from pathlib import Path from typing import Any, Dict, List import pandas as pd -from os.path import isfile from freqtrade.configuration import TimeRange from freqtrade.data.btanalysis import (calculate_max_drawdown, @@ -49,18 +48,18 @@ def init_plotscript(config): data_format=config.get('dataformat_ohlcv', 'json'), ) - skip_trades = False - if not isfile(config.get('exportfilename')) and config['trade_source'] == 'file': + no_trades = False + if config.get('no_trades', False): + no_trades = True + elif not config['exportfilename'].is_file() and config['trade_source'] == 'file': logger.warning("Backtest file is missing skipping trades.") - skip_trades = True - elif config.get('skip_trades', False): - skip_trades = True + no_trades = True trades = load_trades( config['trade_source'], db_url=config.get('db_url'), exportfilename=config.get('exportfilename'), - skip_trades=skip_trades + no_trades=no_trades ) trades = trim_dataframe(trades, timerange, 'open_time') diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 8561f2b84..4b47faeee 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -105,7 +105,7 @@ def test_load_trades(default_conf, mocker): load_trades("DB", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'), - skip_trades=False + no_trades=False ) assert db_mock.call_count == 1 @@ -117,7 +117,7 @@ def test_load_trades(default_conf, mocker): load_trades("file", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'), - skip_trades=False + no_trades=False ) assert db_mock.call_count == 0 @@ -129,7 +129,7 @@ def test_load_trades(default_conf, mocker): load_trades("file", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'), - skip_trades=True + no_trades=True ) assert db_mock.call_count == 0 From 06198c00283eeaef44f0dda391a3cc769acce6ae Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sun, 15 Mar 2020 21:27:45 +0100 Subject: [PATCH 0767/1106] Missed configuration.py --- freqtrade/configuration/configuration.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index ce2101441..e5515670d 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -359,6 +359,9 @@ class Configuration: self._args_to_config(config, argname='erase', logstring='Erase detected. Deleting existing data.') + self._args_to_config(config, argname='no_trades', + logstring='Parameter --no-trades detected.') + self._args_to_config(config, argname='timeframes', logstring='timeframes --timeframes: {}') From e8a92cb3136971bbcd96257e4dc036e7b701da26 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:17:21 +0000 Subject: [PATCH 0768/1106] Bump pandas from 1.0.1 to 1.0.2 Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md) - [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.1...v1.0.2) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 68024f587..12d7336aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ -r requirements-common.txt numpy==1.18.1 -pandas==1.0.1 +pandas==1.0.2 From 0b341757525c23f1242e7e9b189d97b76f5b54b2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:17:53 +0000 Subject: [PATCH 0769/1106] Bump ccxt from 1.23.81 to 1.24.31 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.23.81 to 1.24.31. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.23.81...1.24.31) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 784eef93c..f3f7d8a07 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.23.81 +ccxt==1.24.31 SQLAlchemy==1.3.13 python-telegram-bot==12.4.2 arrow==0.15.5 From 8cfff40fcfb2ba7145c12b165f75e34debcedae6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:18:07 +0000 Subject: [PATCH 0770/1106] Bump plotly from 4.5.3 to 4.5.4 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.3 to 4.5.4. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.5.3...v4.5.4) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 381334a66..7a5b21e2d 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.5.3 +plotly==4.5.4 From 3eee0c43a727fe91bad3481e1dab0551793afa4e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:18:33 +0000 Subject: [PATCH 0771/1106] Bump pytest from 5.3.5 to 5.4.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.5 to 5.4.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.3.5...5.4.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1e58ae6e0..f2801c15b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 mypy==0.761 -pytest==5.3.5 +pytest==5.4.1 pytest-asyncio==0.10.0 pytest-cov==2.8.1 pytest-mock==2.0.0 From 7a7530d57d4ef7d39ff715ccee7cf9ddf2a820a0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:53:20 +0000 Subject: [PATCH 0772/1106] Bump sqlalchemy from 1.3.13 to 1.3.15 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.13 to 1.3.15. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index f3f7d8a07..7c2ad4283 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,7 +1,7 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs ccxt==1.24.31 -SQLAlchemy==1.3.13 +SQLAlchemy==1.3.15 python-telegram-bot==12.4.2 arrow==0.15.5 cachetools==4.0.0 From 62d449251cc8a02182a46015bc2a36e71d549c85 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:54:12 +0000 Subject: [PATCH 0773/1106] Bump mypy from 0.761 to 0.770 Bumps [mypy](https://github.com/python/mypy) from 0.761 to 0.770. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.761...v0.770) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index f2801c15b..a4d83eb4f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ coveralls==1.11.1 flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.0.0 -mypy==0.761 +mypy==0.770 pytest==5.4.1 pytest-asyncio==0.10.0 pytest-cov==2.8.1 From 4f46fb9bf5cb0ae22e3b365e552f62da712bd99f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 17 Mar 2020 19:33:18 +0100 Subject: [PATCH 0774/1106] Add template and jupyter files to release --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 7529152a0..c67f5258f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,4 @@ include LICENSE include README.md include config.json.example recursive-include freqtrade *.py +recursive-include freqtrade/templates/ *.j2 *.ipynb From 05250ba6611278b794677780a2e00febdb14f476 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 18 Mar 2020 11:00:33 +0100 Subject: [PATCH 0775/1106] Update docs/plotting.md Co-Authored-By: Matthias --- docs/plotting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plotting.md b/docs/plotting.md index 56906ebec..be83065a6 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -32,7 +32,7 @@ usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] [--trade-source {DB,file}] [--export EXPORT] [--export-filename PATH] [--timerange TIMERANGE] [-i TICKER_INTERVAL] - [--skip-trades] + [--no-trades] optional arguments: -h, --help show this help message and exit From 0920d6fce4d35ebd3f99ed321131764fde628206 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Wed, 18 Mar 2020 11:01:09 +0100 Subject: [PATCH 0776/1106] Update freqtrade/data/btanalysis.py Co-Authored-By: Matthias --- freqtrade/data/btanalysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 17b243f56..898072748 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -129,7 +129,7 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: return trades -def load_trades(source: str, db_url: str, exportfilename: Path, no_trades: bool) -> pd.DataFrame: +def load_trades(source: str, db_url: str, exportfilename: Path, no_trades: bool = False) -> pd.DataFrame: """ Based on configuration option "trade_source": * loads data from DB (using `db_url`) From 3e1bef888ab1344f8763e130cdef835b0b030d6b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 18 Mar 2020 11:42:42 +0100 Subject: [PATCH 0777/1106] Fix flake8 error --- freqtrade/data/btanalysis.py | 3 ++- tests/data/test_btanalysis.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 898072748..23a9f720c 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -129,7 +129,8 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame: return trades -def load_trades(source: str, db_url: str, exportfilename: Path, no_trades: bool = False) -> pd.DataFrame: +def load_trades(source: str, db_url: str, exportfilename: Path, + no_trades: bool = False) -> pd.DataFrame: """ Based on configuration option "trade_source": * loads data from DB (using `db_url`) diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 4b47faeee..463e5ae36 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -117,7 +117,6 @@ def test_load_trades(default_conf, mocker): load_trades("file", db_url=default_conf.get('db_url'), exportfilename=default_conf.get('exportfilename'), - no_trades=False ) assert db_mock.call_count == 0 From ecf3a3e07076e3101e804e5216ec38ff236a1686 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Mar 2020 19:42:51 +0100 Subject: [PATCH 0778/1106] Add test validating different return values --- tests/test_freqtradebot.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 9f6e5ef0c..e37270bd3 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2228,10 +2228,16 @@ def test_handle_timedout_limit_buy(mocker, default_conf, limit_buy_order) -> Non assert cancel_order_mock.call_count == 1 -def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_order) -> None: +@pytest.mark.parametrize('cancelorder', [ + {}, + 'String Return value', + 123 +]) +def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_order, + cancelorder) -> None: patch_RPCManager(mocker) patch_exchange(mocker) - cancel_order_mock = MagicMock(return_value={}) + cancel_order_mock = MagicMock(return_value=cancelorder) mocker.patch.multiple( 'freqtrade.exchange.Exchange', cancel_order=cancel_order_mock From 5e702f6891c76a066aae85833026780cc01ebee5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 Mar 2020 19:43:19 +0100 Subject: [PATCH 0779/1106] Verify cancel_order returnvalue is a dictionary --- freqtrade/freqtradebot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9897b39b4..bc3078a5c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -891,6 +891,9 @@ class FreqtradeBot: if order['status'] != 'canceled': reason = "cancelled due to timeout" corder = self.exchange.cancel_order(trade.open_order_id, trade.pair) + # Some exchanges don't return a dict here. + if not isinstance(corder, dict): + corder = {} logger.info('Buy order %s for %s.', reason, trade) else: # Order was cancelled already, so we can reuse the existing dict From 5f9479b39fe4c31ac0171501c28186ef0b1065b9 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 20 Mar 2020 02:10:44 +0300 Subject: [PATCH 0780/1106] Edge import cosmetics --- freqtrade/edge/edge_positioning.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index d196ab4b3..5305e23cf 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -8,10 +8,10 @@ import numpy as np import utils_find_1st as utf1st from pandas import DataFrame -from freqtrade import constants from freqtrade.configuration import TimeRange -from freqtrade.data import history +from freqtrade.constants import UNLIMITED_STAKE_AMOUNT from freqtrade.exceptions import OperationalException +from freqtrade.data.history import get_timerange, load_data, refresh_data from freqtrade.strategy.interface import SellType logger = logging.getLogger(__name__) @@ -54,7 +54,7 @@ class Edge: if self.config['max_open_trades'] != float('inf'): logger.critical('max_open_trades should be -1 in config !') - if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: + if self.config['stake_amount'] != UNLIMITED_STAKE_AMOUNT: raise OperationalException('Edge works only with unlimited stake amount') # Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future. @@ -96,7 +96,7 @@ class Edge: logger.info('Using local backtesting data (using whitelist in given config) ...') if self._refresh_pairs: - history.refresh_data( + refresh_data( datadir=self.config['datadir'], pairs=pairs, exchange=self.exchange, @@ -104,7 +104,7 @@ class Edge: timerange=self._timerange, ) - data = history.load_data( + data = load_data( datadir=self.config['datadir'], pairs=pairs, timeframe=self.strategy.ticker_interval, @@ -122,7 +122,7 @@ class Edge: preprocessed = self.strategy.ohlcvdata_to_dataframe(data) # Print timeframe - min_date, max_date = history.get_timerange(preprocessed) + min_date, max_date = get_timerange(preprocessed) logger.info( 'Measuring data from %s up to %s (%s days) ...', min_date.isoformat(), From 3e0ffdce75aa6795caa830bfeb4c614a1750c207 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 20 Mar 2020 04:21:17 +0300 Subject: [PATCH 0781/1106] Adjust tests --- tests/edge/test_edge.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index 3bebeee65..2304c53c2 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -292,8 +292,8 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m', def test_edge_process_downloaded_data(mocker, edge_conf): freqtrade = get_patched_freqtradebot(mocker, edge_conf) mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001)) - mocker.patch('freqtrade.data.history.refresh_data', MagicMock()) - mocker.patch('freqtrade.data.history.load_data', mocked_load_data) + mocker.patch('freqtrade.edge.edge_positioning.refresh_data', MagicMock()) + mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data) edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy) assert edge.calculate() @@ -304,8 +304,8 @@ def test_edge_process_downloaded_data(mocker, edge_conf): def test_edge_process_no_data(mocker, edge_conf, caplog): freqtrade = get_patched_freqtradebot(mocker, edge_conf) mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001)) - mocker.patch('freqtrade.data.history.refresh_data', MagicMock()) - mocker.patch('freqtrade.data.history.load_data', MagicMock(return_value={})) + mocker.patch('freqtrade.edge.edge_positioning.refresh_data', MagicMock()) + mocker.patch('freqtrade.edge.edge_positioning.load_data', MagicMock(return_value={})) edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy) assert not edge.calculate() @@ -317,8 +317,8 @@ def test_edge_process_no_data(mocker, edge_conf, caplog): def test_edge_process_no_trades(mocker, edge_conf, caplog): freqtrade = get_patched_freqtradebot(mocker, edge_conf) mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001)) - mocker.patch('freqtrade.data.history.refresh_data', MagicMock()) - mocker.patch('freqtrade.data.history.load_data', mocked_load_data) + mocker.patch('freqtrade.edge.edge_positioning.refresh_data', MagicMock()) + mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data) # Return empty mocker.patch('freqtrade.edge.Edge._find_trades_for_stoploss_range', MagicMock(return_value=[])) edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy) From 942792f1233f35eba31d51d96ecbc92163376af1 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 20 Mar 2020 05:48:53 +0100 Subject: [PATCH 0782/1106] updated as suggested --- freqtrade/freqtradebot.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e5ae9043a..378252c29 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -394,21 +394,23 @@ class FreqtradeBot: logger.info(f"Pair {pair} is currently locked.") return False + # get_free_open_trades is checked before create_trade is called + # but it is still used here to prevent opening too many trades within one iteration if not self.get_free_open_trades(): logger.debug(f"Can't open a new trade for {pair}: max number of trades is reached.") return False - stake_amount = self.get_trade_stake_amount(pair) - if not stake_amount: - logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.") - return False - # running get_signal on historical data fetched (buy, sell) = self.strategy.get_signal( pair, self.strategy.ticker_interval, self.dataprovider.ohlcv(pair, self.strategy.ticker_interval)) if buy and not sell: + stake_amount = self.get_trade_stake_amount(pair) + if not stake_amount: + logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.") + return False + logger.info(f"Buy signal found: about create a new trade with stake_amount: " f"{stake_amount} ...") From e30faf8c8c371de43b0e1c35b5eae89489e01ab9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 21 Mar 2020 20:04:05 +0100 Subject: [PATCH 0783/1106] Remove partial candle documentation It wasn't working 100% correctly - see #2993 --- docs/exchanges.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index 66a0e96da..c600077ce 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -74,23 +74,13 @@ Should you experience constant errors with Nonce (like `InvalidNonce`), it is be $ pip3 install web3 ``` -### Send incomplete candles to the strategy +### Getting latest price / Incomplete candles Most exchanges return current incomplete candle via their OHLCV/klines API interface. By default, Freqtrade assumes that incomplete candle is fetched from the exchange and removes the last candle assuming it's the incomplete candle. Whether your exchange returns incomplete candles or not can be checked using [the helper script](developer.md#Incomplete-candles) from the Contributor documentation. -If the exchange does return incomplete candles and you would like to have incomplete candles in your strategy, you can set the following parameter in the configuration file. +Due to the danger of repainting, Freqtrade does not allow you to use this incomplete candle. -``` json -{ - - "exchange": { - "_ft_has_params": {"ohlcv_partial_candle": false} - } -} -``` - -!!! Warning "Danger of repainting" - Changing this parameter makes the strategy responsible to avoid repainting and handle this accordingly. Doing this is therefore not recommended, and should only be performed by experienced users who are fully aware of the impact this setting has. +However, usually, this requirement is based on the need for the latest price - which can be aquired using the [data provider](strategy-customization.md#possible-options-for-dataprovider) from within the strategy. From 2c434e9b116fdfb71c2da4f57db4e25683ce7d39 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 11:16:09 +0100 Subject: [PATCH 0784/1106] Add close_proit_abs column --- freqtrade/freqtradebot.py | 1 + freqtrade/persistence.py | 11 ++++++++--- tests/test_persistence.py | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index db632693a..570f8bea8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -954,6 +954,7 @@ class FreqtradeBot: trade.close_rate = None trade.close_profit = None + trade.close_profit_abs = None trade.close_date = None trade.is_open = True trade.open_order_id = None diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index ac084d12e..0d668596c 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -86,7 +86,7 @@ def check_migrate(engine) -> None: logger.debug(f'trying {table_back_name}') # Check for latest column - if not has_column(cols, 'open_trade_price'): + if not has_column(cols, 'close_profit_abs'): logger.info(f'Running database migration - backup available as {table_back_name}') fee_open = get_column_def(cols, 'fee_open', 'fee') @@ -106,6 +106,9 @@ def check_migrate(engine) -> None: ticker_interval = get_column_def(cols, 'ticker_interval', 'null') open_trade_price = get_column_def(cols, 'open_trade_price', f'amount * open_rate * (1 + {fee_open})') + close_profit_abs = get_column_def( + cols, 'close_profit_abs', + f"(amount * close_rate * (1 - {fee_close})) - {open_trade_price}") # Schema migration necessary engine.execute(f"alter table trades rename to {table_back_name}") @@ -123,7 +126,7 @@ def check_migrate(engine) -> None: stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct, stoploss_order_id, stoploss_last_update, max_rate, min_rate, sell_reason, strategy, - ticker_interval, open_trade_price + ticker_interval, open_trade_price, close_profit_abs ) select id, lower(exchange), case @@ -143,7 +146,7 @@ def check_migrate(engine) -> None: {stoploss_order_id} stoploss_order_id, {stoploss_last_update} stoploss_last_update, {max_rate} max_rate, {min_rate} min_rate, {sell_reason} sell_reason, {strategy} strategy, {ticker_interval} ticker_interval, - {open_trade_price} open_trade_price + {open_trade_price} open_trade_price, {close_profit_abs} close_profit_abs from {table_back_name} """) @@ -190,6 +193,7 @@ class Trade(_DECL_BASE): close_rate = Column(Float) close_rate_requested = Column(Float) close_profit = Column(Float) + close_profit_abs = Column(Float) stake_amount = Column(Float, nullable=False) amount = Column(Float) open_date = Column(DateTime, nullable=False, default=datetime.utcnow) @@ -334,6 +338,7 @@ class Trade(_DECL_BASE): """ self.close_rate = Decimal(rate) self.close_profit = self.calc_profit_ratio() + self.close_profit_abs = self.calc_profit() self.close_date = datetime.utcnow() self.is_open = False self.open_order_id = None diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 6bd7971a7..991922cba 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -476,12 +476,22 @@ def test_migrate_old(mocker, default_conf, fee): stake=default_conf.get("stake_amount"), amount=amount ) + insert_table_old2 = """INSERT INTO trades (exchange, pair, is_open, fee, + open_rate, close_rate, stake_amount, amount, open_date) + VALUES ('BITTREX', 'BTC_ETC', 0, {fee}, + 0.00258580, 0.00268580, {stake}, {amount}, + '2017-11-28 12:44:24.000000') + """.format(fee=fee.return_value, + stake=default_conf.get("stake_amount"), + amount=amount + ) engine = create_engine('sqlite://') mocker.patch('freqtrade.persistence.create_engine', lambda *args, **kwargs: engine) # Create table using the old format engine.execute(create_table_old) engine.execute(insert_table_old) + engine.execute(insert_table_old2) # Run init to test migration init(default_conf['db_url'], default_conf['dry_run']) @@ -500,6 +510,15 @@ def test_migrate_old(mocker, default_conf, fee): assert trade.stop_loss == 0.0 assert trade.initial_stop_loss == 0.0 assert trade.open_trade_price == trade._calc_open_trade_price() + assert trade.close_profit_abs is None + + trade = Trade.query.filter(Trade.id == 2).first() + assert trade.close_rate is not None + assert trade.is_open == 0 + assert trade.open_rate_requested is None + assert trade.close_rate_requested is None + assert trade.close_rate is not None + assert pytest.approx(trade.close_profit_abs) == trade.calc_profit() def test_migrate_new(mocker, default_conf, fee, caplog): @@ -583,6 +602,7 @@ def test_migrate_new(mocker, default_conf, fee, caplog): assert log_has("trying trades_bak2", caplog) assert log_has("Running database migration - backup available as trades_bak2", caplog) assert trade.open_trade_price == trade._calc_open_trade_price() + assert trade.close_profit_abs is None def test_migrate_mid_state(mocker, default_conf, fee, caplog): From efd94c84debab78c00bc141b6108f43b366c2e07 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 11:22:49 +0100 Subject: [PATCH 0785/1106] Add example notebook to gitignore again --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9ac2c9d5d..f206fce66 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ user_data/* !user_data/strategy/sample_strategy.py !user_data/notebooks user_data/notebooks/* -!user_data/notebooks/*example.ipynb freqtrade-plot.html freqtrade-profit-plot.html From f14c496ce9ffca5186d4479a611c37c76c0a35ce Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 11:28:18 +0100 Subject: [PATCH 0786/1106] Remove calc_close_profit from RPC This is now possible - but only for closed trades, so certain occurances need to remain. --- freqtrade/rpc/rpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 9014c1874..a0f50b070 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -197,7 +197,7 @@ class RPC: Trade.close_date >= profitday, Trade.close_date < (profitday + timedelta(days=1)) ]).order_by(Trade.close_date).all() - curdayprofit = sum(trade.calc_profit() for trade in trades) + curdayprofit = sum(trade.close_profit_abs for trade in trades) profit_days[profitday] = { 'amount': f'{curdayprofit:.8f}', 'trades': len(trades) @@ -246,8 +246,8 @@ class RPC: durations.append((trade.close_date - trade.open_date).total_seconds()) if not trade.is_open: - profit_ratio = trade.calc_profit_ratio() - profit_closed_coin.append(trade.calc_profit()) + profit_ratio = trade.close_profit + profit_closed_coin.append(trade.close_profit_abs) profit_closed_ratio.append(profit_ratio) else: # Get current rate From acd402187a179e1f040fc42fe1dba22b2519a2e9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 19:39:36 +0100 Subject: [PATCH 0787/1106] Update max_open_trades documentation --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index b0f4c7554..78c643868 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,7 +40,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. +| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the lenght of your whitelist another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Positive float or `"unlimited"`. | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
**Datatype:** Positive float between `0.1` and `1.0`. From 45aaa8c09d2a704e49b56ef47b360425f305b7b5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 20:09:01 +0100 Subject: [PATCH 0788/1106] Parse and show relevant configuration section --- freqtrade/configuration/load_config.py | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/freqtrade/configuration/load_config.py b/freqtrade/configuration/load_config.py index 19179c6c3..0d2dc0955 100644 --- a/freqtrade/configuration/load_config.py +++ b/freqtrade/configuration/load_config.py @@ -1,13 +1,15 @@ """ This module contain functions to load the configuration file """ -import rapidjson import logging +import re import sys +from pathlib import Path from typing import Any, Dict -from freqtrade.exceptions import OperationalException +import rapidjson +from freqtrade.exceptions import OperationalException logger = logging.getLogger(__name__) @@ -15,6 +17,22 @@ logger = logging.getLogger(__name__) CONFIG_PARSE_MODE = rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS +def log_config_error_range(path: str, errmsg: str) -> str: + """ + Parses configuration file and prints range around error + """ + if path != '-': + offsetlist = re.findall(r'(?<=Parse\serror\sat\soffset\s)\d+', errmsg) + if offsetlist: + offset = int(offsetlist[0]) + text = Path(path).read_text() + # Fetch an offset of 80 characters around the error line + subtext = text[offset-min(80, offset):offset+80] + segments = subtext.split('\n') + # Remove first and last lines, to avoid odd truncations + return '\n'.join(segments[1:-1]) + + def load_config_file(path: str) -> Dict[str, Any]: """ Loads a config file from the given path @@ -29,5 +47,11 @@ def load_config_file(path: str) -> Dict[str, Any]: raise OperationalException( f'Config file "{path}" not found!' ' Please create a config file or check whether it exists.') + except rapidjson.JSONDecodeError as e: + err_range = log_config_error_range(path, str(e)) + raise OperationalException( + f'{e}\n' + f'Please verify the following segment of your configuration:\n{err_range}' + ) return config From 6c55b40fe04f4cea4b92841212b150d69f5d200a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 22 Mar 2020 20:15:33 +0100 Subject: [PATCH 0789/1106] Add test verifying config printing --- tests/test_configuration.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 1e9d6440d..ec6753feb 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -66,6 +66,17 @@ def test_load_config_file(default_conf, mocker, caplog) -> None: assert validated_conf.items() >= default_conf.items() +def test_load_config_file_error(default_conf, mocker, caplog) -> None: + del default_conf['user_data_dir'] + filedata = json.dumps(default_conf).replace( + '"stake_amount": 0.001,', '"stake_amount": .001,') + mocker.patch('freqtrade.configuration.load_config.open', mocker.mock_open(read_data=filedata)) + mocker.patch.object(Path, "read_text", MagicMock(return_value=filedata)) + + with pytest.raises(OperationalException, match=f".*Please verify the following segment.*"): + load_config_file('somefile') + + def test__args_to_config(caplog): arg_list = ['trade', '--strategy-path', 'TestTest'] From 8f7e113d798bb8b973efd6a66b59d1abf18722f4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Mar 2020 07:54:27 +0100 Subject: [PATCH 0790/1106] Add additional test --- freqtrade/configuration/load_config.py | 7 +++++-- tests/test_configuration.py | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/freqtrade/configuration/load_config.py b/freqtrade/configuration/load_config.py index 0d2dc0955..55da28913 100644 --- a/freqtrade/configuration/load_config.py +++ b/freqtrade/configuration/load_config.py @@ -29,8 +29,11 @@ def log_config_error_range(path: str, errmsg: str) -> str: # Fetch an offset of 80 characters around the error line subtext = text[offset-min(80, offset):offset+80] segments = subtext.split('\n') - # Remove first and last lines, to avoid odd truncations - return '\n'.join(segments[1:-1]) + if len(segments) > 3: + # Remove first and last lines, to avoid odd truncations + return '\n'.join(segments[1:-1]) + else: + return subtext def load_config_file(path: str) -> Dict[str, Any]: diff --git a/tests/test_configuration.py b/tests/test_configuration.py index ec6753feb..a1936aee0 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -18,7 +18,7 @@ from freqtrade.configuration.config_validation import validate_config_schema from freqtrade.configuration.deprecated_settings import ( check_conflicting_settings, process_deprecated_setting, process_temporary_deprecated_settings) -from freqtrade.configuration.load_config import load_config_file +from freqtrade.configuration.load_config import load_config_file, log_config_error_range from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL from freqtrade.exceptions import OperationalException from freqtrade.loggers import _set_loggers, setup_logging @@ -77,6 +77,19 @@ def test_load_config_file_error(default_conf, mocker, caplog) -> None: load_config_file('somefile') +def test_load_config_file_error_range(default_conf, mocker, caplog) -> None: + del default_conf['user_data_dir'] + filedata = json.dumps(default_conf).replace( + '"stake_amount": 0.001,', '"stake_amount": .001,') + mocker.patch.object(Path, "read_text", MagicMock(return_value=filedata)) + + x = log_config_error_range('somefile', 'Parse error at offset 64: Invalid value.') + assert isinstance(x, str) + assert (x == '{"max_open_trades": 1, "stake_currency": "BTC", ' + '"stake_amount": .001, "fiat_display_currency": "USD", ' + '"ticker_interval": "5m", "dry_run": true, ') + + def test__args_to_config(caplog): arg_list = ['trade', '--strategy-path', 'TestTest'] From d581b7e2d79493ddccb6cbd2cbe41b6baa028b38 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 23 Mar 2020 07:57:30 +0100 Subject: [PATCH 0791/1106] Add fallback if no error could be determined --- freqtrade/configuration/load_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/configuration/load_config.py b/freqtrade/configuration/load_config.py index 55da28913..a24ee3d0a 100644 --- a/freqtrade/configuration/load_config.py +++ b/freqtrade/configuration/load_config.py @@ -34,6 +34,7 @@ def log_config_error_range(path: str, errmsg: str) -> str: return '\n'.join(segments[1:-1]) else: return subtext + return '' def load_config_file(path: str) -> Dict[str, Any]: @@ -55,6 +56,7 @@ def load_config_file(path: str) -> Dict[str, Any]: raise OperationalException( f'{e}\n' f'Please verify the following segment of your configuration:\n{err_range}' + if err_range else 'Please verify your configuration file for syntax errors.' ) return config From f4a69ba5a753c38f9b18ec81e596d38c86ce66de Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:04:50 +0000 Subject: [PATCH 0792/1106] Bump numpy from 1.18.1 to 1.18.2 Bumps [numpy](https://github.com/numpy/numpy) from 1.18.1 to 1.18.2. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt) - [Commits](https://github.com/numpy/numpy/compare/v1.18.1...v1.18.2) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 12d7336aa..e69d919e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Load common requirements -r requirements-common.txt -numpy==1.18.1 +numpy==1.18.2 pandas==1.0.2 From de91e169bc6f3316f5d3a5ad52add147ec71eba6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:05:12 +0000 Subject: [PATCH 0793/1106] Bump tabulate from 0.8.6 to 0.8.7 Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.6 to 0.8.7. - [Release notes](https://github.com/astanin/python-tabulate/releases) - [Changelog](https://github.com/astanin/python-tabulate/blob/master/CHANGELOG) - [Commits](https://github.com/astanin/python-tabulate/compare/v0.8.6...v0.8.7) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 7c2ad4283..c1e23dfa9 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -10,7 +10,7 @@ urllib3==1.25.8 wrapt==1.12.1 jsonschema==3.2.0 TA-Lib==0.4.17 -tabulate==0.8.6 +tabulate==0.8.7 pycoingecko==1.2.0 jinja2==2.11.1 From 98dc4b4ca3893452e80db2f58dd9d72baaeb5f26 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:06:41 +0000 Subject: [PATCH 0794/1106] Bump ccxt from 1.24.31 to 1.24.83 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.24.31 to 1.24.83. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.24.31...1.24.83) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 7c2ad4283..6274297c2 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.24.31 +ccxt==1.24.83 SQLAlchemy==1.3.15 python-telegram-bot==12.4.2 arrow==0.15.5 From cb1bc5d5abb1b125be1282c7538f9e169d17d3b8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:15:43 +0000 Subject: [PATCH 0795/1106] Bump pandas from 1.0.2 to 1.0.3 Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/pandas-dev/pandas/releases) - [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md) - [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.2...v1.0.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e69d919e0..b1a4b4403 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ -r requirements-common.txt numpy==1.18.2 -pandas==1.0.2 +pandas==1.0.3 From 0f53e646fd7d3e707f470244d785539211a17793 Mon Sep 17 00:00:00 2001 From: orehunt Date: Tue, 24 Mar 2020 13:54:46 +0100 Subject: [PATCH 0796/1106] check that the strategy dataframe matches the one given by the bot --- freqtrade/strategy/interface.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 696d2b2d2..530cd0af4 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -241,8 +241,18 @@ class IStrategy(ABC): return dataframe - def get_signal(self, pair: str, interval: str, - dataframe: DataFrame) -> Tuple[bool, bool]: + @staticmethod + def preserve_df(d: DataFrame) -> Tuple[int, float, datetime]: + """ keep some data for dataframes """ + return len(d), d["close"].iloc[-1], d["date"].iloc[-1] + + @staticmethod + def assert_df(d: DataFrame, df_len: int, df_close: float, df_date: datetime): + """ make sure data is unmodified """ + if df_len != len(d) or df_close != d["close"].iloc[-1] or df_date != d["date"].iloc[-1]: + raise Exception("Dataframe returned from strategy does not match original") + + def get_signal(self, pair: str, interval: str, dataframe: DataFrame) -> Tuple[bool, bool]: """ Calculates current signal based several technical analysis indicators :param pair: pair in format ANT/BTC @@ -254,8 +264,11 @@ class IStrategy(ABC): logger.warning('Empty candle (OHLCV) data for pair %s', pair) return False, False + latest_date = dataframe['date'].max() try: + df_len, df_close, df_date = self.preserve_df(dataframe) dataframe = self._analyze_ticker_internal(dataframe, {'pair': pair}) + self.assert_df(dataframe, df_len, df_close, df_date) except ValueError as error: logger.warning( 'Unable to analyze candle (OHLCV) data for pair %s: %s', @@ -275,7 +288,7 @@ class IStrategy(ABC): logger.warning('Empty dataframe for pair %s', pair) return False, False - latest = dataframe.iloc[-1] + latest = dataframe.loc[dataframe['date'] == latest_date].iloc[-1] # Check if dataframe is out of date signal_date = arrow.get(latest['date']) From be41981ef08f65d2d377d7a225456fbdc6221b83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 20:10:15 +0100 Subject: [PATCH 0797/1106] Test warnings with filter always on --- tests/test_configuration.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 1e9d6440d..79387ba7a 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -73,6 +73,7 @@ def test__args_to_config(caplog): configuration = Configuration(args) config = {} with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # No warnings ... configuration._args_to_config(config, argname="strategy_path", logstring="DeadBeef") assert len(w) == 0 @@ -82,6 +83,7 @@ def test__args_to_config(caplog): configuration = Configuration(args) config = {} with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") # Deprecation warnings! configuration._args_to_config(config, argname="strategy_path", logstring="DeadBeef", deprecated_msg="Going away soon!") From d9a5e1cd48955041a6e41e1e6138be75b15c46f1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Mar 2020 08:30:18 +0100 Subject: [PATCH 0798/1106] Update docs/exchanges.md Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/exchanges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/exchanges.md b/docs/exchanges.md index c600077ce..06db26f89 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -83,4 +83,4 @@ Whether your exchange returns incomplete candles or not can be checked using [th Due to the danger of repainting, Freqtrade does not allow you to use this incomplete candle. -However, usually, this requirement is based on the need for the latest price - which can be aquired using the [data provider](strategy-customization.md#possible-options-for-dataprovider) from within the strategy. +However, if it is based on the need for the latest price for your strategy - then this requirement can be acquired using the [data provider](strategy-customization.md#possible-options-for-dataprovider) from within the strategy. From dfac7448d1260b81653e600fda27dc57d41af0ab Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Mar 2020 08:33:22 +0100 Subject: [PATCH 0799/1106] fix typo Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 78c643868..9ecb0a13e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,7 +40,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the lenght of your whitelist another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. +| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your whitelist another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Positive float or `"unlimited"`. | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
**Datatype:** Positive float between `0.1` and `1.0`. From 6f687c97ce1743e43dc8b4a1bcb166cf7be4a523 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Mar 2020 09:24:37 +0100 Subject: [PATCH 0800/1106] Update docs/configuration.md Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9ecb0a13e..d8a9653c3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,7 +40,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your whitelist another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. +| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your pairlist is another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades, limited by the pairlist). [More information below](#configuring-amount-per-trade).
**Datatype:** Positive integer or -1. | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
**Datatype:** String | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
**Datatype:** Positive float or `"unlimited"`. | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
**Datatype:** Positive float between `0.1` and `1.0`. From 91b058cf11d2ed585c0a67e9fa4dd89d280907f9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 16:16:10 +0100 Subject: [PATCH 0801/1106] Fix typo in tests --- tests/test_freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e37270bd3..abc9babba 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2129,7 +2129,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap assert rpc_mock.call_count == 2 trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() assert len(trades) == 1 - # Verify that tradehas been updated + # Verify that trade has been updated assert trades[0].amount == (limit_buy_order_old_partial['amount'] - limit_buy_order_old_partial['remaining']) - 0.0001 assert trades[0].open_order_id is None @@ -2168,7 +2168,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, assert rpc_mock.call_count == 2 trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all() assert len(trades) == 1 - # Verify that tradehas been updated + # Verify that trade has been updated assert trades[0].amount == (limit_buy_order_old_partial['amount'] - limit_buy_order_old_partial['remaining']) From 1817e6fbdfecbbca308e2fbaf8bdc9b57756182e Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 16:16:19 +0100 Subject: [PATCH 0802/1106] Combine real_amount updating into one method --- freqtrade/freqtradebot.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 570f8bea8..b30f55ccd 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -916,17 +916,7 @@ class FreqtradeBot: # we need to fall back to the values from order if corder does not contain these keys. trade.amount = order['amount'] - corder.get('remaining', order['remaining']) trade.stake_amount = trade.amount * trade.open_rate - # verify if fees were taken from amount to avoid problems during selling - try: - new_amount = self.get_real_amount(trade, corder if 'fee' in corder else order, - trade.amount) - if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): - trade.amount = new_amount - # Fee was applied, so set to 0 - trade.fee_open = 0 - trade.recalc_open_trade_price() - except DependencyException as e: - logger.warning("Could not update trade amount: %s", e) + self.update_trade_state(trade, corder if 'fee' in corder else order, trade.amount) trade.open_order_id = None logger.info('Partial buy order timeout for %s.', trade) @@ -1122,9 +1112,11 @@ class FreqtradeBot: # Common update trade state methods # - def update_trade_state(self, trade: Trade, action_order: dict = None) -> None: + def update_trade_state(self, trade: Trade, action_order: dict = None, + order_amount: float = None) -> None: """ Checks trades with open orders and updates the amount if necessary + Handles closing both buy and sell orders. """ # Get order details for actual price per unit if trade.open_order_id: @@ -1137,7 +1129,7 @@ class FreqtradeBot: return # Try update amount (binance-fix) try: - new_amount = self.get_real_amount(trade, order) + new_amount = self.get_real_amount(trade, order, order_amount) if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): order['amount'] = new_amount # Fee was applied, so set to 0 From 9c351007f5a1fa4b27f0c123f6a8c736c9843f55 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 17:12:24 +0100 Subject: [PATCH 0803/1106] Provide reason for cancelled sell order --- freqtrade/freqtradebot.py | 12 +++++++----- freqtrade/rpc/telegram.py | 3 ++- tests/rpc/test_rpc_telegram.py | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index b30f55ccd..af0de108a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -926,10 +926,10 @@ class FreqtradeBot: }) return False - def handle_timedout_limit_sell(self, trade: Trade, order: Dict) -> bool: + def handle_timedout_limit_sell(self, trade: Trade, order: Dict) -> str: """ Sell timeout - cancel order and update trade - :return: True if order was fully cancelled + :return: Reason for cancel """ # if trade is not partially completed, just cancel the trade if order['remaining'] == order['amount']: @@ -943,16 +943,17 @@ class FreqtradeBot: logger.info('Sell order %s for %s.', reason, trade) trade.close_rate = None + trade.close_rate_requested = None trade.close_profit = None trade.close_profit_abs = None trade.close_date = None trade.is_open = True trade.open_order_id = None - return True + return reason # TODO: figure out how to handle partially complete sell orders - return False + return 'partially filled - keeping order open' def _safe_sell_amount(self, pair: str, amount: float) -> float: """ @@ -1071,7 +1072,7 @@ class FreqtradeBot: # Send the message self.rpc.send_msg(msg) - def _notify_sell_cancel(self, trade: Trade, order_type: str) -> None: + def _notify_sell_cancel(self, trade: Trade, order_type: str, reason: str) -> None: """ Sends rpc notification when a sell cancel occured. """ @@ -1098,6 +1099,7 @@ class FreqtradeBot: 'close_date': trade.close_date, 'stake_currency': self.config['stake_currency'], 'fiat_currency': self.config.get('fiat_display_currency', None), + 'reason': reason, } if 'fiat_display_currency' in self.config: diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index ad01700ab..a21f7556c 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -172,7 +172,8 @@ class Telegram(RPC): ' / {profit_fiat:.3f} {fiat_currency})`').format(**msg) elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: - message = "*{exchange}:* Cancelling Open Sell Order for {pair}".format(**msg) + message = ("*{exchange}:* Cancelling Open Sell Order " + "for {pair}. Reason: {reason}").format(**msg) elif msg['type'] == RPCMessageType.STATUS_NOTIFICATION: message = '*Status:* `{status}`'.format(**msg) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index d769016c4..bbc961763 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -1316,18 +1316,20 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None: 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'exchange': 'Binance', 'pair': 'KEY/ETH', + 'reason': 'Cancelled on exchange' }) assert msg_mock.call_args[0][0] \ - == ('*Binance:* Cancelling Open Sell Order for KEY/ETH') + == ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: Cancelled on exchange') msg_mock.reset_mock() telegram.send_msg({ 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'exchange': 'Binance', 'pair': 'KEY/ETH', + 'reason': 'timeout' }) assert msg_mock.call_args[0][0] \ - == ('*Binance:* Cancelling Open Sell Order for KEY/ETH') + == ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout') # Reset singleton function to avoid random breaks telegram._fiat_converter.convert_amount = old_convamount From 270ac2e8c113f39a55a14c019e19c578f8b059ab Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 17:15:47 +0100 Subject: [PATCH 0804/1106] Add check_order_cancelled_empty method to exchange --- freqtrade/exchange/exchange.py | 8 ++++++++ tests/exchange/test_exchange.py | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f4c94a1ca..073e28659 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -902,6 +902,14 @@ class Exchange: self._async_get_trade_history(pair=pair, since=since, until=until, from_id=from_id)) + def check_order_canceled_empty(self, order: Dict) -> bool: + """ + Verify if an order has been cancelled without being partially filled + :param order: Order dict as returned from get_order() + :return: True if order has been cancelled without being filled, False otherwise. + """ + return order['status'] in ('closed', 'canceled') and order.get('filled') == 0.0 + @retrier def cancel_order(self, order_id: str, pair: str) -> None: if self._config['dry_run']: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8d8930f66..7f03eb547 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1705,6 +1705,18 @@ def test_cancel_order_dry_run(default_conf, mocker, exchange_name): assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None +@pytest.mark.parametrize("exchange_name", EXCHANGES) +@pytest.mark.parametrize("order,result", [ + ({'status': 'closed', 'filled': 10}, False), + ({'status': 'closed', 'filled': 0.0}, True), + ({'status': 'canceled', 'filled': 0.0}, True), + ({'status': 'canceled', 'filled': 10.0}, False), + ]) +def test_check_order_canceled_empty(mocker, default_conf, exchange_name, order, result): + exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) + assert exchange.check_order_canceled_empty(order) == result + + # Ensure that if not dry_run, we should call API @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_cancel_order(default_conf, mocker, exchange_name): From 7c47c6e3bd52e30d7d81462d0188c5c31baa18a0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 17:16:35 +0100 Subject: [PATCH 0805/1106] check for timeouts before exiting positions --- freqtrade/freqtradebot.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index af0de108a..14cda9192 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -143,6 +143,10 @@ class FreqtradeBot: self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist), self.strategy.informative_pairs()) + with self._sell_lock: + # Check and handle any timed out open orders + self.check_handle_timedout() + # Protect from collisions with forcesell. # Without this, freqtrade my try to recreate stoploss_on_exchange orders # while selling is in process, since telegram messages arrive in an different thread. @@ -154,8 +158,6 @@ class FreqtradeBot: if self.get_free_open_trades(): self.enter_positions() - # Check and handle any timed out open orders - self.check_handle_timedout() Trade.session.flush() def _refresh_whitelist(self, trades: List[Trade] = []) -> List[str]: From 700cedc57312b02e18a2aa98b5f71ab253953c80 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 17:17:40 +0100 Subject: [PATCH 0806/1106] Unify handling of open orders to update_trade_state --- freqtrade/freqtradebot.py | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 14cda9192..e27569317 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -602,7 +602,6 @@ class FreqtradeBot: trades_closed = 0 for trade in trades: try: - self.update_trade_state(trade) if (self.strategy.order_types.get('stoploss_on_exchange') and self.handle_stoploss_on_exchange(trade)): @@ -862,30 +861,32 @@ class FreqtradeBot: continue order = self.exchange.get_order(trade.open_order_id, trade.pair) except (RequestException, DependencyException, InvalidOrderException): - logger.info( - 'Cannot query order for %s due to %s', - trade, - traceback.format_exc()) + logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc()) continue + trade_state_update = self.update_trade_state(trade, order) + # Check if trade is still actually open - if float(order.get('remaining', 0.0)) == 0.0: - self.wallets.update() - continue + # TODO: this seems questionable at best + # if float(order.get('remaining', 0.0)) == 0.0: + # self.wallets.update() + # continue - if ((order['side'] == 'buy' and order['status'] == 'canceled') - or (self._check_timed_out('buy', order))): + if (order['side'] == 'buy' and ( + trade_state_update + or self._check_timed_out('buy', order))): self.handle_timedout_limit_buy(trade, order) self.wallets.update() order_type = self.strategy.order_types['buy'] self._notify_buy_cancel(trade, order_type) - elif ((order['side'] == 'sell' and order['status'] == 'canceled') - or (self._check_timed_out('sell', order))): - self.handle_timedout_limit_sell(trade, order) + elif (order['side'] == 'sell' and ( + trade_state_update + or self._check_timed_out('sell', order))): + reason = self.handle_timedout_limit_sell(trade, order) self.wallets.update() order_type = self.strategy.order_types['sell'] - self._notify_sell_cancel(trade, order_type) + self._notify_sell_cancel(trade, order_type, reason) def handle_timedout_limit_buy(self, trade: Trade, order: Dict) -> bool: """ @@ -934,8 +935,8 @@ class FreqtradeBot: :return: Reason for cancel """ # if trade is not partially completed, just cancel the trade - if order['remaining'] == order['amount']: - if order["status"] != "canceled": + if order['remaining'] == order['amount'] or order['filled'] == 0.0: + if not self.exchange.check_order_canceled_empty(order): reason = "cancelled due to timeout" # if trade is not partially completed, just delete the trade self.exchange.cancel_order(trade.open_order_id, trade.pair) @@ -1117,7 +1118,7 @@ class FreqtradeBot: # def update_trade_state(self, trade: Trade, action_order: dict = None, - order_amount: float = None) -> None: + order_amount: float = None) -> bool: """ Checks trades with open orders and updates the amount if necessary Handles closing both buy and sell orders. @@ -1139,16 +1140,21 @@ class FreqtradeBot: # Fee was applied, so set to 0 trade.fee_open = 0 trade.recalc_open_trade_price() - except DependencyException as exception: logger.warning("Could not update trade amount: %s", exception) + if self.exchange.check_order_canceled_empty(order): + # Trade has been cancelled on exchange + # Handling of this will happen in check_handle_timeout. + return True trade.update(order) # Updating wallets when order is closed if not trade.is_open: self.wallets.update() + return False + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Get real amount for the trade From f3103be15c22a09648b58bffbf88611faf9dc4d1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 17:20:16 +0100 Subject: [PATCH 0807/1106] Fix test --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e27569317..bec08fbc2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -935,7 +935,7 @@ class FreqtradeBot: :return: Reason for cancel """ # if trade is not partially completed, just cancel the trade - if order['remaining'] == order['amount'] or order['filled'] == 0.0: + if order['remaining'] == order['amount'] or order.get('filled') == 0.0: if not self.exchange.check_order_canceled_empty(order): reason = "cancelled due to timeout" # if trade is not partially completed, just delete the trade diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index abc9babba..fd6136799 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1592,13 +1592,13 @@ def test_exit_positions_exception(mocker, default_conf, limit_buy_order, caplog) mocker.patch('freqtrade.exchange.Exchange.get_order', return_value=limit_buy_order) trade = MagicMock() - trade.open_order_id = '123' + trade.open_order_id = None trade.open_fee = 0.001 trades = [trade] # Test raise of DependencyException exception mocker.patch( - 'freqtrade.freqtradebot.FreqtradeBot.update_trade_state', + 'freqtrade.freqtradebot.FreqtradeBot.handle_trade', side_effect=DependencyException() ) n = freqtrade.exit_positions(trades) @@ -1970,7 +1970,7 @@ def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old, o rpc_mock = patch_RPCManager(mocker) cancel_order_mock = MagicMock() patch_exchange(mocker) - limit_buy_order_old.update({"status": "canceled"}) + limit_buy_order_old.update({"status": "canceled", 'filled': 0.0}) mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, @@ -2049,7 +2049,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old, """ Handle sell order cancelled on exchange""" rpc_mock = patch_RPCManager(mocker) cancel_order_mock = MagicMock() - limit_sell_order_old.update({"status": "canceled"}) + limit_sell_order_old.update({"status": "canceled", 'filled': 0.0}) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -2276,7 +2276,7 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None: assert freqtrade.handle_timedout_limit_sell(trade, order) assert cancel_order_mock.call_count == 1 order['amount'] = 2 - assert not freqtrade.handle_timedout_limit_sell(trade, order) + assert freqtrade.handle_timedout_limit_sell(trade, order) == 'partially filled - keeping order open' # Assert cancel_order was not called (callcount remains unchanged) assert cancel_order_mock.call_count == 1 @@ -2544,8 +2544,11 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f # Create some test data freqtrade.enter_positions() + freqtrade.check_handle_timedout() trade = Trade.query.first() trades = [trade] + assert trade.stoploss_order_id is None + freqtrade.exit_positions(trades) assert trade assert trade.stoploss_order_id == '123' From 19e5dbddc6670d9d759bc140bdbd4298ec9c13e4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 19:53:35 +0100 Subject: [PATCH 0808/1106] Add filled to all orders --- tests/conftest.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 64d0cd5ee..4b971c1bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -712,6 +712,7 @@ def limit_buy_order(): 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001099, 'amount': 90.99181073, + 'filled': 90.99181073, 'remaining': 0.0, 'status': 'closed' } @@ -727,6 +728,7 @@ def market_buy_order(): 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004099, 'amount': 91.99181073, + 'filled': 91.99181073, 'remaining': 0.0, 'status': 'closed' } @@ -742,6 +744,7 @@ def market_sell_order(): 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004173, 'amount': 91.99181073, + 'filled': 91.99181073, 'remaining': 0.0, 'status': 'closed' } @@ -757,6 +760,7 @@ def limit_buy_order_old(): 'datetime': str(arrow.utcnow().shift(minutes=-601).datetime), 'price': 0.00001099, 'amount': 90.99181073, + 'filled': 0.0, 'remaining': 90.99181073, 'status': 'open' } @@ -772,6 +776,7 @@ def limit_sell_order_old(): 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, + 'filled': 0.0, 'remaining': 90.99181073, 'status': 'open' } @@ -787,6 +792,7 @@ def limit_buy_order_old_partial(): 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, + 'filled': 23.0, 'remaining': 67.99181073, 'status': 'open' } @@ -810,6 +816,7 @@ def limit_sell_order(): 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001173, 'amount': 90.99181073, + 'filled': 90.99181073, 'remaining': 0.0, 'status': 'closed' } From f04f606b707ee39d03224e3c015610c12c5a252d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 19:53:50 +0100 Subject: [PATCH 0809/1106] Updateing order amount should use filled - not amount if possible --- freqtrade/persistence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 0d668596c..97a6b6084 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -315,7 +315,7 @@ class Trade(_DECL_BASE): if order_type in ('market', 'limit') and order['side'] == 'buy': # Update open rate and actual amount self.open_rate = Decimal(order['price']) - self.amount = Decimal(order['amount']) + self.amount = Decimal(order.get('filled', order['amount'])) self.recalc_open_trade_price() logger.info('%s_BUY has been fulfilled for %s.', order_type.upper(), self) self.open_order_id = None From 1e2fadbc022c93e4e4fb3b2679af3e86938d1182 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 19:54:13 +0100 Subject: [PATCH 0810/1106] Fix failing test --- tests/test_freqtradebot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index fd6136799..4a633e0d8 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2499,6 +2499,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke assert trade trades = [trade] + freqtrade.check_handle_timedout() freqtrade.exit_positions(trades) # Increase the price and sell it From 3c1b155e9ff0f837ffbd950545f93c4f8a9ffe1f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 24 Mar 2020 20:05:25 +0100 Subject: [PATCH 0811/1106] Remove filled if amount is modified to suit fee structure --- freqtrade/freqtradebot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index bec08fbc2..d0b37fefb 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1122,6 +1122,7 @@ class FreqtradeBot: """ Checks trades with open orders and updates the amount if necessary Handles closing both buy and sell orders. + :return: True if order has been cancelled without being filled partially, False otherwise """ # Get order details for actual price per unit if trade.open_order_id: @@ -1131,12 +1132,13 @@ class FreqtradeBot: order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) except InvalidOrderException as exception: logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception) - return + return False # Try update amount (binance-fix) try: new_amount = self.get_real_amount(trade, order, order_amount) if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): order['amount'] = new_amount + del order['filled'] # Fee was applied, so set to 0 trade.fee_open = 0 trade.recalc_open_trade_price() From 95011919d3c2857b6fb34cb61d83d00c8d791a0f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Mar 2020 10:45:05 +0100 Subject: [PATCH 0812/1106] Remove questionable handling of orders --- freqtrade/freqtradebot.py | 6 ------ tests/test_freqtradebot.py | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d0b37fefb..a0d142dee 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -866,12 +866,6 @@ class FreqtradeBot: trade_state_update = self.update_trade_state(trade, order) - # Check if trade is still actually open - # TODO: this seems questionable at best - # if float(order.get('remaining', 0.0)) == 0.0: - # self.wallets.update() - # continue - if (order['side'] == 'buy' and ( trade_state_update or self._check_timed_out('buy', order))): diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 4a633e0d8..9fb545b15 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2276,7 +2276,8 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None: assert freqtrade.handle_timedout_limit_sell(trade, order) assert cancel_order_mock.call_count == 1 order['amount'] = 2 - assert freqtrade.handle_timedout_limit_sell(trade, order) == 'partially filled - keeping order open' + assert (freqtrade.handle_timedout_limit_sell(trade, order) + == 'partially filled - keeping order open') # Assert cancel_order was not called (callcount remains unchanged) assert cancel_order_mock.call_count == 1 From 3ef568029f48a55dc22b64d4ea904da75d50b2d3 Mon Sep 17 00:00:00 2001 From: orehunt Date: Thu, 26 Mar 2020 07:05:30 +0100 Subject: [PATCH 0813/1106] different exception messages --- freqtrade/strategy/interface.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 530cd0af4..4f833be23 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -16,6 +16,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.exchange import timeframe_to_minutes from freqtrade.persistence import Trade from freqtrade.wallets import Wallets +from freqtrade.exceptions import DependencyException logger = logging.getLogger(__name__) @@ -242,15 +243,23 @@ class IStrategy(ABC): return dataframe @staticmethod - def preserve_df(d: DataFrame) -> Tuple[int, float, datetime]: + def preserve_df(dataframe: DataFrame) -> Tuple[int, float, datetime]: """ keep some data for dataframes """ - return len(d), d["close"].iloc[-1], d["date"].iloc[-1] + return len(dataframe), dataframe["close"].iloc[-1], dataframe["date"].iloc[-1] @staticmethod - def assert_df(d: DataFrame, df_len: int, df_close: float, df_date: datetime): + def assert_df(dataframe: DataFrame, df_len: int, df_close: float, df_date: datetime): """ make sure data is unmodified """ - if df_len != len(d) or df_close != d["close"].iloc[-1] or df_date != d["date"].iloc[-1]: - raise Exception("Dataframe returned from strategy does not match original") + message = "" + if df_len != len(dataframe): + message = "length" + elif df_close != dataframe["close"].iloc[-1]: + message = "last close price" + elif df_date != dataframe["date"].iloc[-1]: + message = "last date" + if message: + raise DependencyException("Dataframe returned from strategy has mismatching " + f"{message}.") def get_signal(self, pair: str, interval: str, dataframe: DataFrame) -> Tuple[bool, bool]: """ From 78aa65825550726142ca154b9b0c4427fac283c1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Mar 2020 11:27:40 +0200 Subject: [PATCH 0814/1106] Remove unnecessary test (it's a copy of the remaining test) --- tests/strategy/test_interface.py | 38 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 949dda4a0..4e8d8f708 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -17,33 +17,36 @@ from tests.conftest import get_patched_exchange, log_has _STRATEGY = DefaultStrategy(config={}) -def test_returns_latest_buy_signal(mocker, default_conf, ohlcv_history): - mocker.patch.object( - _STRATEGY, '_analyze_ticker_internal', - return_value=DataFrame([{'buy': 1, 'sell': 0, 'date': arrow.utcnow()}]) - ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False) +def test_returns_latest_signal(mocker, default_conf, ohlcv_history): + ohlcv_history.loc[1, 'date'] = arrow.utcnow() + # Take a copy to correctly modify the call + mocked_history = ohlcv_history.copy() + mocked_history['sell'] = 0 + mocked_history['buy'] = 0 + mocked_history.loc[1, 'sell'] = 1 mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', - return_value=DataFrame([{'buy': 0, 'sell': 1, 'date': arrow.utcnow()}]) - ) - assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True) - - -def test_returns_latest_sell_signal(mocker, default_conf, ohlcv_history): - mocker.patch.object( - _STRATEGY, '_analyze_ticker_internal', - return_value=DataFrame([{'sell': 1, 'buy': 0, 'date': arrow.utcnow()}]) + return_value=mocked_history ) assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True) + mocked_history.loc[1, 'sell'] = 0 + mocked_history.loc[1, 'buy'] = 1 mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', - return_value=DataFrame([{'sell': 0, 'buy': 1, 'date': arrow.utcnow()}]) + return_value=mocked_history ) assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False) + mocked_history.loc[1, 'sell'] = 0 + mocked_history.loc[1, 'buy'] = 0 + + mocker.patch.object( + _STRATEGY, '_analyze_ticker_internal', + return_value=mocked_history + ) + assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, False) def test_get_signal_empty(default_conf, mocker, caplog): @@ -74,6 +77,8 @@ def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ohlcv_history) _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame([]) ) + mocker.patch.object(_STRATEGY, 'assert_df') + assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], ohlcv_history) assert log_has('Empty dataframe for pair xyz', caplog) @@ -89,6 +94,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): _STRATEGY, '_analyze_ticker_internal', return_value=DataFrame(ticks) ) + mocker.patch.object(_STRATEGY, 'assert_df') assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], ohlcv_history) assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog) From 0887a0212c73816e3ae68c7ca7f7a4cb09a3f192 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Mar 2020 11:29:31 +0200 Subject: [PATCH 0815/1106] Adjust tests to pass validation --- tests/strategy/test_interface.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 4e8d8f708..be8750c3c 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -85,14 +85,19 @@ def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ohlcv_history) def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): - caplog.set_level(logging.INFO) # default_conf defines a 5m interval. we check interval * 2 + 5m # this is necessary as the last candle is removed (partial candles) by default - oldtime = arrow.utcnow().shift(minutes=-16) - ticks = DataFrame([{'buy': 1, 'date': oldtime}]) + ohlcv_history.loc[1, 'date'] = arrow.utcnow().shift(minutes=-16) + # Take a copy to correctly modify the call + mocked_history = ohlcv_history.copy() + mocked_history['sell'] = 0 + mocked_history['buy'] = 0 + mocked_history.loc[1, 'buy'] = 1 + + caplog.set_level(logging.INFO) mocker.patch.object( _STRATEGY, '_analyze_ticker_internal', - return_value=DataFrame(ticks) + return_value=mocked_history ) mocker.patch.object(_STRATEGY, 'assert_df') assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], From cd2e738e351ae2e84d144009291c5346848f029b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Mar 2020 11:40:13 +0200 Subject: [PATCH 0816/1106] Add test for assert error --- freqtrade/strategy/interface.py | 11 ++++++----- tests/strategy/test_interface.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4f833be23..89a38bf54 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -279,11 +279,12 @@ class IStrategy(ABC): dataframe = self._analyze_ticker_internal(dataframe, {'pair': pair}) self.assert_df(dataframe, df_len, df_close, df_date) except ValueError as error: - logger.warning( - 'Unable to analyze candle (OHLCV) data for pair %s: %s', - pair, - str(error) - ) + logger.warning('Unable to analyze candle (OHLCV) data for pair %s: %s', + pair, str(error)) + return False, False + except DependencyException as error: + logger.warning("Unable to analyze candle (OHLCV) data for pair %s: %s", + pair, str(error)) return False, False except Exception as error: logger.exception( diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index be8750c3c..1f496a01b 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -6,6 +6,7 @@ from unittest.mock import MagicMock import arrow from pandas import DataFrame +from freqtrade.exceptions import DependencyException from freqtrade.configuration import TimeRange from freqtrade.data.history import load_data from freqtrade.persistence import Trade @@ -105,6 +106,26 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history): assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog) +def test_assert_df_raise(default_conf, mocker, caplog, ohlcv_history): + # default_conf defines a 5m interval. we check interval * 2 + 5m + # this is necessary as the last candle is removed (partial candles) by default + ohlcv_history.loc[1, 'date'] = arrow.utcnow().shift(minutes=-16) + # Take a copy to correctly modify the call + mocked_history = ohlcv_history.copy() + mocked_history['sell'] = 0 + mocked_history['buy'] = 0 + mocked_history.loc[1, 'buy'] = 1 + + caplog.set_level(logging.INFO) + mocker.patch.object( + _STRATEGY, 'assert_df', + side_effect=DependencyException('Dataframe returned...') + ) + assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], + ohlcv_history) + assert log_has('Unable to analyze candle (OHLCV) data for pair xyz: Dataframe returned...', caplog) + + def test_get_signal_handles_exceptions(mocker, default_conf): exchange = get_patched_exchange(mocker, default_conf) mocker.patch.object( From 83cc121b706efe6e364885f24778255e9c0eb60a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 29 Mar 2020 11:44:36 +0200 Subject: [PATCH 0817/1106] Add tsts for assert_df (ensuring it raises when it should) --- tests/strategy/test_interface.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 1f496a01b..8bc399f42 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -4,16 +4,18 @@ import logging from unittest.mock import MagicMock import arrow +import pytest from pandas import DataFrame -from freqtrade.exceptions import DependencyException from freqtrade.configuration import TimeRange from freqtrade.data.history import load_data +from freqtrade.exceptions import DependencyException from freqtrade.persistence import Trade from freqtrade.resolvers import StrategyResolver -from .strats.default_strategy import DefaultStrategy from tests.conftest import get_patched_exchange, log_has +from .strats.default_strategy import DefaultStrategy + # Avoid to reinit the same object again and again _STRATEGY = DefaultStrategy(config={}) @@ -123,7 +125,27 @@ def test_assert_df_raise(default_conf, mocker, caplog, ohlcv_history): ) assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'], ohlcv_history) - assert log_has('Unable to analyze candle (OHLCV) data for pair xyz: Dataframe returned...', caplog) + assert log_has('Unable to analyze candle (OHLCV) data for pair xyz: Dataframe returned...', + caplog) + + +def test_assert_df(default_conf, mocker, ohlcv_history): + # Ensure it's running when passed correctly + _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history), + ohlcv_history.loc[1, 'close'], ohlcv_history.loc[1, 'date']) + + with pytest.raises(DependencyException, match=r"Dataframe returned from strategy.*length\."): + _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history) + 1, + ohlcv_history.loc[1, 'close'], ohlcv_history.loc[1, 'date']) + + with pytest.raises(DependencyException, + match=r"Dataframe returned from strategy.*last close price\."): + _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history), + ohlcv_history.loc[1, 'close'] + 0.01, ohlcv_history.loc[1, 'date']) + with pytest.raises(DependencyException, + match=r"Dataframe returned from strategy.*last date\."): + _STRATEGY.assert_df(ohlcv_history, len(ohlcv_history), + ohlcv_history.loc[1, 'close'], ohlcv_history.loc[0, 'date']) def test_get_signal_handles_exceptions(mocker, default_conf): From a5d00ce7176a78058cb9af3d091a51902fa5b764 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Mar 2020 07:56:17 +0200 Subject: [PATCH 0818/1106] Remove defaultstrategy occurance from docs --- docs/bot-usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 78e137676..60cacfb94 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -145,9 +145,9 @@ It is recommended to use version control to keep track of changes to your strate This parameter will allow you to load your custom strategy class. Per default without `--strategy` or `-s` the bot will load the -`DefaultStrategy` included with the bot (`freqtrade/strategy/default_strategy.py`). +`SampleStrategy` installed by the `create-userdir` subcommand (usually `user_data/strategy/sample_strategy.py`). -The bot will search your strategy file within `user_data/strategies` and `freqtrade/strategy`. +The bot will search your strategy file within `user_data/strategies`. To load a strategy, simply pass the class name (e.g.: `CustomStrategy`) in this parameter. From f1b92e2569f8db26fb092ad3e579d94542d28f01 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Mar 2020 08:11:38 +0200 Subject: [PATCH 0819/1106] Improve wording of documentation --- docs/bot-usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 60cacfb94..b1649374a 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -144,10 +144,10 @@ It is recommended to use version control to keep track of changes to your strate ### How to use **--strategy**? This parameter will allow you to load your custom strategy class. -Per default without `--strategy` or `-s` the bot will load the -`SampleStrategy` installed by the `create-userdir` subcommand (usually `user_data/strategy/sample_strategy.py`). +To test the bot installation, you can use the `SampleStrategy` installed by the `create-userdir` subcommand (usually `user_data/strategy/sample_strategy.py`). The bot will search your strategy file within `user_data/strategies`. +To use other directories, please read the next section about `--strategy-path`. To load a strategy, simply pass the class name (e.g.: `CustomStrategy`) in this parameter. From 7e1719cfc71b0e4a26cf3922b6b279a78c4bd326 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 08:56:50 +0000 Subject: [PATCH 0820/1106] Bump prompt-toolkit from 3.0.4 to 3.0.5 Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases) - [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG) - [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.4...3.0.5) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e490c8927..c3ae57c72 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -30,4 +30,4 @@ flask==1.1.1 colorama==0.4.3 # Building config files interactively questionary==1.5.1 -prompt-toolkit==3.0.4 +prompt-toolkit==3.0.5 From 7e60e0549afd5a20c8d10178baa33ab89ae72d02 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 08:57:16 +0000 Subject: [PATCH 0821/1106] Bump flake8-tidy-imports from 4.0.0 to 4.1.0 Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases) - [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst) - [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.0.0...4.1.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index a4d83eb4f..01f189c56 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ coveralls==1.11.1 flake8==3.7.9 flake8-type-annotations==0.1.0 -flake8-tidy-imports==4.0.0 +flake8-tidy-imports==4.1.0 mypy==0.770 pytest==5.4.1 pytest-asyncio==0.10.0 From 2de10d4c5665e6183f2d9d72f035f20288beb1af Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 08:58:21 +0000 Subject: [PATCH 0822/1106] Bump ccxt from 1.24.83 to 1.25.38 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.24.83 to 1.25.38. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.24.83...1.25.38) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e490c8927..54a738e06 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.24.83 +ccxt==1.25.38 SQLAlchemy==1.3.15 python-telegram-bot==12.4.2 arrow==0.15.5 From d8d6fe3574ae73f8867233fc7f6daeb9cb03a3ec Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 08:58:54 +0000 Subject: [PATCH 0823/1106] Bump python-telegram-bot from 12.4.2 to 12.5 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.4.2 to 12.5. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.4.2...v12.5) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index e490c8927..57617697f 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.24.83 SQLAlchemy==1.3.15 -python-telegram-bot==12.4.2 +python-telegram-bot==12.5 arrow==0.15.5 cachetools==4.0.0 requests==2.23.0 From 54d20cb81c90f567924e4a41a6aabeb19a46b288 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 30 Mar 2020 20:08:07 +0200 Subject: [PATCH 0824/1106] Plot percent correctly --- freqtrade/plot/plotting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index fc8f25612..fac3aa2a3 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -136,8 +136,8 @@ def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> m df_comb.loc[lowdate, 'cum_profit'], ], mode='markers', - name=f"Max drawdown {max_drawdown:.2f}%", - text=f"Max drawdown {max_drawdown:.2f}%", + name=f"Max drawdown {max_drawdown * 100:.2f}%", + text=f"Max drawdown {max_drawdown * 100:.2f}%", marker=dict( symbol='square-open', size=9, From 45fb4d25abf06484c8a0020102fd9786826eaa8b Mon Sep 17 00:00:00 2001 From: orehunt Date: Tue, 31 Mar 2020 18:47:53 +0200 Subject: [PATCH 0825/1106] use equality instead of index for row lookups --- freqtrade/plot/plotting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index fc8f25612..b311c591a 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -132,8 +132,8 @@ def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> m drawdown = go.Scatter( x=[highdate, lowdate], y=[ - df_comb.loc[highdate, 'cum_profit'], - df_comb.loc[lowdate, 'cum_profit'], + df_comb.loc[df_comb.index == highdate, 'cum_profit'], + df_comb.loc[df_comb.index == lowdate, 'cum_profit'], ], mode='markers', name=f"Max drawdown {max_drawdown:.2f}%", From 8bfbbac74889095d6c6c9c97e443fbc50391fa3f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Mar 2020 07:18:13 +0200 Subject: [PATCH 0826/1106] Add default trades columns --- freqtrade/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 54f620631..0a35ab1fe 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -24,6 +24,7 @@ AVAILABLE_DATAHANDLERS = ['json', 'jsongz'] DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons DEFAULT_DATAFRAME_COLUMNS = ['date', 'open', 'high', 'low', 'close', 'volume'] +DEFAULT_TRADES_COLUMNS = ['timestamp', 'type', 'side', 'price', 'amount', 'cost'] USERPATH_HYPEROPTS = 'hyperopts' USERPATH_STRATEGIES = 'strategies' From 1659ddcc5dc44fc00ef41b74f92302fa4d03e093 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Mar 2020 20:12:01 +0200 Subject: [PATCH 0827/1106] Add conversion function from fetch_trades to list --- freqtrade/constants.py | 4 +++- freqtrade/data/converter.py | 16 ++++++++++--- tests/conftest.py | 44 ++++++++++++++++++++++++++++++++++++ tests/data/test_converter.py | 23 +++++++++++++++---- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 0a35ab1fe..34e1c63f1 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -24,7 +24,9 @@ AVAILABLE_DATAHANDLERS = ['json', 'jsongz'] DRY_RUN_WALLET = 1000 MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons DEFAULT_DATAFRAME_COLUMNS = ['date', 'open', 'high', 'low', 'close', 'volume'] -DEFAULT_TRADES_COLUMNS = ['timestamp', 'type', 'side', 'price', 'amount', 'cost'] +# Don't modify sequence of DEFAULT_TRADES_COLUMNS +# it has wide consequences for stored trades files +DEFAULT_TRADES_COLUMNS = ['timestamp', 'id', 'type', 'side', 'price', 'amount', 'cost'] USERPATH_HYPEROPTS = 'hyperopts' USERPATH_STRATEGIES = 'strategies' diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 77371bf27..7abd0453f 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -3,12 +3,13 @@ Functions to convert data from one format to another """ import logging from datetime import datetime, timezone -from typing import Any, Dict +from typing import Any, Dict, List import pandas as pd from pandas import DataFrame, to_datetime -from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS +from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS + logger = logging.getLogger(__name__) @@ -154,7 +155,16 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: return frame -def trades_to_ohlcv(trades: list, timeframe: str) -> DataFrame: +def trades_dict_to_list(trades: List[Dict]) -> List[List]: + """ + Convert fetch_trades result into a List (to be more memory efficient). + :param trades: List of trades, as returned by ccxt.fetch_trades. + :return: List of Lists, with constants.DEFAULT_TRADES_COLUMNS as columns + """ + return [[t[col] for col in DEFAULT_TRADES_COLUMNS]for t in trades] + + +def trades_to_ohlcv(trades: List, timeframe: str) -> DataFrame: """ Converts trades list to OHLCV list TODO: This should get a dedicated test diff --git a/tests/conftest.py b/tests/conftest.py index 64d0cd5ee..72f9bfe46 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1391,6 +1391,50 @@ def buy_order_fee(): } +@pytest.fixture +def fetch_trades_result(): + return [{'info': {'a': 153942751, + 'p': '0.02059000', + 'q': '6.95500000', + 'f': 170811204, + 'l': 170811204, + 'T': 1585670882666, + 'm': True, + 'M': True}, + 'timestamp': 1585670882666, + 'datetime': '2020-03-31T16:08:02.666Z', + 'symbol': 'ETH/BTC', + 'id': '153942751', + 'order': None, + 'type': None, + 'takerOrMaker': None, + 'side': 'sell', + 'price': 0.02059, + 'amount': 6.955, + 'cost': 0.14320345, + 'fee': None}, + {'info': {'a': 153942752, + 'p': '0.02059100', + 'q': '0.04900000', + 'f': 170811205, + 'l': 170811205, + 'T': 1585670889154, + 'm': False, + 'M': True}, + 'timestamp': 1585670889154, + 'datetime': '2020-03-31T16:08:09.154Z', + 'symbol': 'ETH/BTC', + 'id': '153942752', + 'order': None, + 'type': None, + 'takerOrMaker': None, + 'side': 'buy', + 'price': 0.020591, + 'amount': 0.049, + 'cost': 0.001008959, + 'fee': None}] + + @pytest.fixture(scope="function") def edge_conf(default_conf): conf = deepcopy(default_conf) diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index 7dff520e0..1f7837e46 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -5,12 +5,10 @@ from freqtrade.configuration.timerange import TimeRange from freqtrade.data.converter import (convert_ohlcv_format, convert_trades_format, ohlcv_fill_up_missing_data, - ohlcv_to_dataframe, + ohlcv_to_dataframe, trades_dict_to_list, trim_dataframe) -from freqtrade.data.history import (get_timerange, - load_data, - load_pair_history, - validate_backtest_data) +from freqtrade.data.history import (get_timerange, load_data, + load_pair_history, validate_backtest_data) from tests.conftest import log_has from tests.data.test_history import _backup_file, _clean_test_file @@ -197,6 +195,21 @@ def test_trim_dataframe(testdatadir) -> None: assert all(data_modify.iloc[0] == data.iloc[25]) +def test_trades_dict_to_list(mocker, fetch_trades_result): + res = trades_dict_to_list(fetch_trades_result) + assert isinstance(res, list) + assert isinstance(res[0], list) + for i, t in enumerate(res): + assert t[0] == fetch_trades_result[i]['timestamp'] + assert t[1] == fetch_trades_result[i]['id'] + assert t[2] == fetch_trades_result[i]['type'] + assert t[3] == fetch_trades_result[i]['side'] + assert t[4] == fetch_trades_result[i]['price'] + assert t[5] == fetch_trades_result[i]['amount'] + assert t[6] == fetch_trades_result[i]['cost'] + + + def test_convert_trades_format(mocker, default_conf, testdatadir): file = testdatadir / "XRP_ETH-trades.json.gz" file_new = testdatadir / "XRP_ETH-trades.json" From d76bb1ccf4eedbb0da4f2d0077bb264f26338ed8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Mar 2020 20:20:10 +0200 Subject: [PATCH 0828/1106] Use List of Lists instead of list of Dicts for trades data --- freqtrade/data/history/history_utils.py | 14 +++++---- freqtrade/data/history/idatahandler.py | 17 +++++++---- freqtrade/data/history/jsondatahandler.py | 26 ++++++++++++----- freqtrade/exchange/exchange.py | 35 ++++++++++++----------- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 89d29d33b..86d90f8aa 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -261,10 +261,14 @@ def _download_trades_history(exchange: Exchange, trades = data_handler.trades_load(pair) - from_id = trades[-1]['id'] if trades else None + # TradesList columns are defined in constants.DEFAULT_TRADES_COLUMNS + # DEFAULT_TRADES_COLUMNS: 0 -> timestamp + # DEFAULT_TRADES_COLUMNS: 1 -> id + from_id = trades[-1][1] if trades else None - logger.debug("Current Start: %s", trades[0]['datetime'] if trades else 'None') - logger.debug("Current End: %s", trades[-1]['datetime'] if trades else 'None') + logger.debug("Current Start: %s", trades[0][0] if trades else 'None') + logger.debug("Current End: %s", trades[-1][0] if trades else 'None') + logger.info(f"Current Amount of trades: {len(trades)}") # Default since_ms to 30 days if nothing is given new_trades = exchange.get_historic_trades(pair=pair, @@ -276,8 +280,8 @@ def _download_trades_history(exchange: Exchange, trades.extend(new_trades[1]) data_handler.trades_store(pair, data=trades) - logger.debug("New Start: %s", trades[0]['datetime']) - logger.debug("New End: %s", trades[-1]['datetime']) + logger.debug("New Start: %s", trades[0][0]) + logger.debug("New End: %s", trades[-1][0]) logger.info(f"New Amount of trades: {len(trades)}") return True diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index 1bb4d5971..4663c29ac 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -8,7 +8,7 @@ from abc import ABC, abstractclassmethod, abstractmethod from copy import deepcopy from datetime import datetime, timezone from pathlib import Path -from typing import Dict, List, Optional, Type +from typing import List, Optional, Type from pandas import DataFrame @@ -18,6 +18,9 @@ from freqtrade.exchange import timeframe_to_seconds logger = logging.getLogger(__name__) +# Type for trades list +TradeList = List[List] + class IDataHandler(ABC): @@ -89,23 +92,25 @@ class IDataHandler(ABC): """ @abstractmethod - def trades_store(self, pair: str, data: List[Dict]) -> None: + def trades_store(self, pair: str, data: TradeList) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename - :param data: List of Dicts containing trade data + :param data: List of Lists containing trade data, + column sequence as in DEFAULT_TRADES_COLUMNS """ @abstractmethod - def trades_append(self, pair: str, data: List[Dict]): + def trades_append(self, pair: str, data: TradeList): """ Append data to existing files :param pair: Pair - used for filename - :param data: List of Dicts containing trade data + :param data: List of Lists containing trade data, + column sequence as in DEFAULT_TRADES_COLUMNS """ @abstractmethod - def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> List[Dict]: + def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: """ Load a pair from file, either .json.gz or .json :param pair: Load trades for this pair diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 363b03958..d4aa21a1d 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -1,6 +1,7 @@ +import logging import re from pathlib import Path -from typing import Dict, List, Optional +from typing import List, Optional import numpy as np from pandas import DataFrame, read_json, to_datetime @@ -8,8 +9,11 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS +from freqtrade.converter import trades_dict_to_list -from .idatahandler import IDataHandler +from .idatahandler import IDataHandler, TradeList + +logger = logging.getLogger(__name__) class JsonDataHandler(IDataHandler): @@ -113,24 +117,26 @@ class JsonDataHandler(IDataHandler): # Check if regex found something and only return these results to avoid exceptions. return [match[0].replace('_', '/') for match in _tmp if match] - def trades_store(self, pair: str, data: List[Dict]) -> None: + def trades_store(self, pair: str, data: TradeList) -> None: """ Store trades data (list of Dicts) to file :param pair: Pair - used for filename - :param data: List of Dicts containing trade data + :param data: List of Lists containing trade data, + column sequence as in DEFAULT_TRADES_COLUMNS """ filename = self._pair_trades_filename(self._datadir, pair) misc.file_dump_json(filename, data, is_zip=self._use_zip) - def trades_append(self, pair: str, data: List[Dict]): + def trades_append(self, pair: str, data: TradeList): """ Append data to existing files :param pair: Pair - used for filename - :param data: List of Dicts containing trade data + :param data: List of Lists containing trade data, + column sequence as in DEFAULT_TRADES_COLUMNS """ raise NotImplementedError() - def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> List[Dict]: + def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: """ Load a pair from file, either .json.gz or .json # TODO: respect timerange ... @@ -140,9 +146,15 @@ class JsonDataHandler(IDataHandler): """ filename = self._pair_trades_filename(self._datadir, pair) tradesdata = misc.file_load_json(filename) + if not tradesdata: return [] + if isinstance(tradesdata[0], dict): + # Convert trades dict to list + logger.info("Old trades format detected - converting") + tradesdata = trades_dict_to_list(tradesdata) + pass return tradesdata def trades_purge(self, pair: str) -> bool: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f4c94a1ca..da23b290c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -18,13 +18,12 @@ from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, TRUNCATE, decimal_to_precision) from pandas import DataFrame -from freqtrade.data.converter import ohlcv_to_dataframe +from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list from freqtrade.exceptions import (DependencyException, InvalidOrderException, OperationalException, TemporaryError) from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async from freqtrade.misc import deep_merge_dicts - CcxtModuleType = Any @@ -758,7 +757,7 @@ class Exchange: @retrier_async async def _async_fetch_trades(self, pair: str, since: Optional[int] = None, - params: Optional[dict] = None) -> List[Dict]: + params: Optional[dict] = None) -> List[List]: """ Asyncronously gets trade history using fetch_trades. Handles exchange errors, does one call to the exchange. @@ -778,7 +777,7 @@ class Exchange: '(' + arrow.get(since // 1000).isoformat() + ') ' if since is not None else '' ) trades = await self._api_async.fetch_trades(pair, since=since, limit=1000) - return trades + return trades_dict_to_list(trades) except ccxt.NotSupported as e: raise OperationalException( f'Exchange {self._api.name} does not support fetching historical trade data.' @@ -792,7 +791,7 @@ class Exchange: async def _async_get_trade_history_id(self, pair: str, until: int, since: Optional[int] = None, - from_id: Optional[str] = None) -> Tuple[str, List[Dict]]: + from_id: Optional[str] = None) -> Tuple[str, List[List]]: """ Asyncronously gets trade history using fetch_trades use this when exchange uses id-based iteration (check `self._trades_pagination`) @@ -803,7 +802,7 @@ class Exchange: returns tuple: (pair, trades-list) """ - trades: List[Dict] = [] + trades: List[List] = [] if not from_id: # Fetch first elements using timebased method to get an ID to paginate on @@ -812,7 +811,9 @@ class Exchange: # e.g. Binance returns the "last 1000" candles within a 1h time interval # - so we will miss the first trades. t = await self._async_fetch_trades(pair, since=since) - from_id = t[-1]['id'] + # DEFAULT_TRADES_COLUMNS: 0 -> timestamp + # DEFAULT_TRADES_COLUMNS: 1 -> id + from_id = t[-1][1] trades.extend(t[:-1]) while True: t = await self._async_fetch_trades(pair, @@ -820,21 +821,21 @@ class Exchange: if len(t): # Skip last id since its the key for the next call trades.extend(t[:-1]) - if from_id == t[-1]['id'] or t[-1]['timestamp'] > until: + if from_id == t[-1][1] or t[-1][0] > until: logger.debug(f"Stopping because from_id did not change. " - f"Reached {t[-1]['timestamp']} > {until}") + f"Reached {t[-1][0]} > {until}") # Reached the end of the defined-download period - add last trade as well. trades.extend(t[-1:]) break - from_id = t[-1]['id'] + from_id = t[-1][1] else: break return (pair, trades) async def _async_get_trade_history_time(self, pair: str, until: int, - since: Optional[int] = None) -> Tuple[str, List]: + since: Optional[int] = None) -> Tuple[str, List[List]]: """ Asyncronously gets trade history using fetch_trades, when the exchange uses time-based iteration (check `self._trades_pagination`) @@ -844,16 +845,18 @@ class Exchange: returns tuple: (pair, trades-list) """ - trades: List[Dict] = [] + trades: List[List] = [] + # DEFAULT_TRADES_COLUMNS: 0 -> timestamp + # DEFAULT_TRADES_COLUMNS: 1 -> id while True: t = await self._async_fetch_trades(pair, since=since) if len(t): - since = t[-1]['timestamp'] + since = t[-1][1] trades.extend(t) # Reached the end of the defined-download period - if until and t[-1]['timestamp'] > until: + if until and t[-1][0] > until: logger.debug( - f"Stopping because until was reached. {t[-1]['timestamp']} > {until}") + f"Stopping because until was reached. {t[-1][0]} > {until}") break else: break @@ -863,7 +866,7 @@ class Exchange: async def _async_get_trade_history(self, pair: str, since: Optional[int] = None, until: Optional[int] = None, - from_id: Optional[str] = None) -> Tuple[str, List[Dict]]: + from_id: Optional[str] = None) -> Tuple[str, List[List]]: """ Async wrapper handling downloading trades using either time or id based methods. """ From bac0eaab039410041f79beabf8f4651db7f562d5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 31 Mar 2020 20:46:42 +0200 Subject: [PATCH 0829/1106] fix convert to ohlcv --- freqtrade/data/converter.py | 7 ++++--- freqtrade/data/history/history_utils.py | 4 ++++ freqtrade/data/history/jsondatahandler.py | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 7abd0453f..90db82f74 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -174,9 +174,10 @@ def trades_to_ohlcv(trades: List, timeframe: str) -> DataFrame: """ from freqtrade.exchange import timeframe_to_minutes timeframe_minutes = timeframe_to_minutes(timeframe) - df = pd.DataFrame(trades) - df['datetime'] = pd.to_datetime(df['datetime']) - df = df.set_index('datetime') + df = pd.DataFrame(trades, columns=DEFAULT_TRADES_COLUMNS) + df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms', + utc=True,) + df = df.set_index('timestamp') df_new = df['price'].resample(f'{timeframe_minutes}min').ohlc() df_new['volume'] = df['amount'].resample(f'{timeframe_minutes}min').sum() diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 86d90f8aa..a7490f17b 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -264,7 +264,11 @@ def _download_trades_history(exchange: Exchange, # TradesList columns are defined in constants.DEFAULT_TRADES_COLUMNS # DEFAULT_TRADES_COLUMNS: 0 -> timestamp # DEFAULT_TRADES_COLUMNS: 1 -> id + from_id = trades[-1][1] if trades else None + if trades and since < trades[-1][0]: + # Reset since to the last available point + since = trades[-1][0] logger.debug("Current Start: %s", trades[0][0] if trades else 'None') logger.debug("Current End: %s", trades[-1][0] if trades else 'None') diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index d4aa21a1d..50a32603b 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -9,7 +9,7 @@ from pandas import DataFrame, read_json, to_datetime from freqtrade import misc from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS -from freqtrade.converter import trades_dict_to_list +from freqtrade.data.converter import trades_dict_to_list from .idatahandler import IDataHandler, TradeList From b95e9fe3515a15898326fcac2c6fd16453e4b08e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 06:53:04 +0200 Subject: [PATCH 0830/1106] Fix mocks to return correct things --- tests/conftest.py | 52 ++++++++--------------------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 72f9bfe46..517a11b47 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1227,6 +1227,14 @@ def trades_for_order(): @pytest.fixture(scope="function") def trades_history(): + return [[1565798399463, '126181329', None, 'buy', 0.019627, 0.04, 0.00078508], + [1565798399629, '126181330', None, 'buy', 0.019627, 0.244, 0.004788987999999999], + [1565798399752, '126181331', None, 'sell', 0.019626, 0.011, 0.00021588599999999999], + [1565798399862, '126181332', None, 'sell', 0.019626, 0.011, 0.00021588599999999999], + [1565798399872, '126181333', None, 'sell', 0.019626, 0.011, 0.00021588599999999999]] + +@pytest.fixture(scope="function") +def fetch_trades_result(): return [{'info': {'a': 126181329, 'p': '0.01962700', 'q': '0.04000000', @@ -1391,50 +1399,6 @@ def buy_order_fee(): } -@pytest.fixture -def fetch_trades_result(): - return [{'info': {'a': 153942751, - 'p': '0.02059000', - 'q': '6.95500000', - 'f': 170811204, - 'l': 170811204, - 'T': 1585670882666, - 'm': True, - 'M': True}, - 'timestamp': 1585670882666, - 'datetime': '2020-03-31T16:08:02.666Z', - 'symbol': 'ETH/BTC', - 'id': '153942751', - 'order': None, - 'type': None, - 'takerOrMaker': None, - 'side': 'sell', - 'price': 0.02059, - 'amount': 6.955, - 'cost': 0.14320345, - 'fee': None}, - {'info': {'a': 153942752, - 'p': '0.02059100', - 'q': '0.04900000', - 'f': 170811205, - 'l': 170811205, - 'T': 1585670889154, - 'm': False, - 'M': True}, - 'timestamp': 1585670889154, - 'datetime': '2020-03-31T16:08:09.154Z', - 'symbol': 'ETH/BTC', - 'id': '153942752', - 'order': None, - 'type': None, - 'takerOrMaker': None, - 'side': 'buy', - 'price': 0.020591, - 'amount': 0.049, - 'cost': 0.001008959, - 'fee': None}] - - @pytest.fixture(scope="function") def edge_conf(default_conf): conf = deepcopy(default_conf) From 59f1a061f733955c3b62c99d40b1c3b7e945f98c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 06:53:58 +0200 Subject: [PATCH 0831/1106] adapt exchange tests to use lists instead of dicts --- tests/exchange/test_exchange.py | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8d8930f66..535d1f87f 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1511,18 +1511,18 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na @pytest.mark.asyncio @pytest.mark.parametrize("exchange_name", EXCHANGES) async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name, - trades_history): + fetch_trades_result): caplog.set_level(logging.DEBUG) exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) # Monkey-patch async function - exchange._api_async.fetch_trades = get_mock_coro(trades_history) + exchange._api_async.fetch_trades = get_mock_coro(fetch_trades_result) pair = 'ETH/BTC' res = await exchange._async_fetch_trades(pair, since=None, params=None) assert type(res) is list - assert isinstance(res[0], dict) - assert isinstance(res[1], dict) + assert isinstance(res[0], list) + assert isinstance(res[1], list) assert exchange._api_async.fetch_trades.call_count == 1 assert exchange._api_async.fetch_trades.call_args[0][0] == pair @@ -1568,7 +1568,7 @@ async def test__async_get_trade_history_id(default_conf, mocker, caplog, exchang if 'since' in kwargs: # Return first 3 return trades_history[:-2] - elif kwargs.get('params', {}).get(pagination_arg) == trades_history[-3]['id']: + elif kwargs.get('params', {}).get(pagination_arg) == trades_history[-3][1]: # Return 2 return trades_history[-3:-1] else: @@ -1578,8 +1578,8 @@ async def test__async_get_trade_history_id(default_conf, mocker, caplog, exchang exchange._async_fetch_trades = MagicMock(side_effect=mock_get_trade_hist) pair = 'ETH/BTC' - ret = await exchange._async_get_trade_history_id(pair, since=trades_history[0]["timestamp"], - until=trades_history[-1]["timestamp"]-1) + ret = await exchange._async_get_trade_history_id(pair, since=trades_history[0][0], + until=trades_history[-1][0]-1) assert type(ret) is tuple assert ret[0] == pair assert type(ret[1]) is list @@ -1588,7 +1588,7 @@ async def test__async_get_trade_history_id(default_conf, mocker, caplog, exchang fetch_trades_cal = exchange._async_fetch_trades.call_args_list # first call (using since, not fromId) assert fetch_trades_cal[0][0][0] == pair - assert fetch_trades_cal[0][1]['since'] == trades_history[0]["timestamp"] + assert fetch_trades_cal[0][1]['since'] == trades_history[0][0] # 2nd call assert fetch_trades_cal[1][0][0] == pair @@ -1604,7 +1604,7 @@ async def test__async_get_trade_history_time(default_conf, mocker, caplog, excha caplog.set_level(logging.DEBUG) async def mock_get_trade_hist(pair, *args, **kwargs): - if kwargs['since'] == trades_history[0]["timestamp"]: + if kwargs['since'] == trades_history[0][0]: return trades_history[:-1] else: return trades_history[-1:] @@ -1614,8 +1614,8 @@ async def test__async_get_trade_history_time(default_conf, mocker, caplog, excha # Monkey-patch async function exchange._async_fetch_trades = MagicMock(side_effect=mock_get_trade_hist) pair = 'ETH/BTC' - ret = await exchange._async_get_trade_history_time(pair, since=trades_history[0]["timestamp"], - until=trades_history[-1]["timestamp"]-1) + ret = await exchange._async_get_trade_history_time(pair, since=trades_history[0][0], + until=trades_history[-1][0]-1) assert type(ret) is tuple assert ret[0] == pair assert type(ret[1]) is list @@ -1624,11 +1624,11 @@ async def test__async_get_trade_history_time(default_conf, mocker, caplog, excha fetch_trades_cal = exchange._async_fetch_trades.call_args_list # first call (using since, not fromId) assert fetch_trades_cal[0][0][0] == pair - assert fetch_trades_cal[0][1]['since'] == trades_history[0]["timestamp"] + assert fetch_trades_cal[0][1]['since'] == trades_history[0][0] # 2nd call assert fetch_trades_cal[1][0][0] == pair - assert fetch_trades_cal[0][1]['since'] == trades_history[0]["timestamp"] + assert fetch_trades_cal[0][1]['since'] == trades_history[0][0] assert log_has_re(r"Stopping because until was reached.*", caplog) @@ -1640,7 +1640,7 @@ async def test__async_get_trade_history_time_empty(default_conf, mocker, caplog, caplog.set_level(logging.DEBUG) async def mock_get_trade_hist(pair, *args, **kwargs): - if kwargs['since'] == trades_history[0]["timestamp"]: + if kwargs['since'] == trades_history[0][0]: return trades_history[:-1] else: return [] @@ -1650,8 +1650,8 @@ async def test__async_get_trade_history_time_empty(default_conf, mocker, caplog, # Monkey-patch async function exchange._async_fetch_trades = MagicMock(side_effect=mock_get_trade_hist) pair = 'ETH/BTC' - ret = await exchange._async_get_trade_history_time(pair, since=trades_history[0]["timestamp"], - until=trades_history[-1]["timestamp"]-1) + ret = await exchange._async_get_trade_history_time(pair, since=trades_history[0][0], + until=trades_history[-1][0]-1) assert type(ret) is tuple assert ret[0] == pair assert type(ret[1]) is list @@ -1660,7 +1660,7 @@ async def test__async_get_trade_history_time_empty(default_conf, mocker, caplog, fetch_trades_cal = exchange._async_fetch_trades.call_args_list # first call (using since, not fromId) assert fetch_trades_cal[0][0][0] == pair - assert fetch_trades_cal[0][1]['since'] == trades_history[0]["timestamp"] + assert fetch_trades_cal[0][1]['since'] == trades_history[0][0] @pytest.mark.parametrize("exchange_name", EXCHANGES) @@ -1672,8 +1672,8 @@ def test_get_historic_trades(default_conf, mocker, caplog, exchange_name, trades exchange._async_get_trade_history_id = get_mock_coro((pair, trades_history)) exchange._async_get_trade_history_time = get_mock_coro((pair, trades_history)) - ret = exchange.get_historic_trades(pair, since=trades_history[0]["timestamp"], - until=trades_history[-1]["timestamp"]) + ret = exchange.get_historic_trades(pair, since=trades_history[0][0], + until=trades_history[-1][0]) # Depending on the exchange, one or the other method should be called assert sum([exchange._async_get_trade_history_id.call_count, @@ -1694,8 +1694,8 @@ def test_get_historic_trades_notsupported(default_conf, mocker, caplog, exchange with pytest.raises(OperationalException, match="This exchange does not suport downloading Trades."): - exchange.get_historic_trades(pair, since=trades_history[0]["timestamp"], - until=trades_history[-1]["timestamp"]) + exchange.get_historic_trades(pair, since=trades_history[0][0], + until=trades_history[-1][0]) @pytest.mark.parametrize("exchange_name", EXCHANGES) From 0506caf986af7e6bc82e6584e5238e74232edca0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 07:23:43 +0200 Subject: [PATCH 0832/1106] Implement trades_remove_dulicates --- freqtrade/data/converter.py | 17 +++++++++++++++-- tests/data/test_converter.py | 13 +++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index 90db82f74..d2108b9be 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -1,15 +1,17 @@ """ Functions to convert data from one format to another """ +import itertools import logging from datetime import datetime, timezone +from operator import itemgetter from typing import Any, Dict, List import pandas as pd from pandas import DataFrame, to_datetime -from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS - +from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, + DEFAULT_TRADES_COLUMNS) logger = logging.getLogger(__name__) @@ -155,6 +157,17 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame: return frame +def trades_remove_duplicates(trades: List[List]) -> List[List]: + """ + Removes duplicates from the trades list. + Uses itertools.groupby to avoid converting to pandas. + Tests show it as being pretty efficient on lists of 4M Lists. + :param trades: List of Lists with constants.DEFAULT_TRADES_COLUMNS as columns + :return: same format as above, but with duplicates removed + """ + return [i for i, _ in itertools.groupby(sorted(trades, key=itemgetter(0)))] + + def trades_dict_to_list(trades: List[Dict]) -> List[List]: """ Convert fetch_trades result into a List (to be more memory efficient). diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index 1f7837e46..463700d0c 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -6,7 +6,7 @@ from freqtrade.data.converter import (convert_ohlcv_format, convert_trades_format, ohlcv_fill_up_missing_data, ohlcv_to_dataframe, trades_dict_to_list, - trim_dataframe) + trades_remove_duplicates, trim_dataframe) from freqtrade.data.history import (get_timerange, load_data, load_pair_history, validate_backtest_data) from tests.conftest import log_has @@ -195,7 +195,16 @@ def test_trim_dataframe(testdatadir) -> None: assert all(data_modify.iloc[0] == data.iloc[25]) -def test_trades_dict_to_list(mocker, fetch_trades_result): +def test_trades_remove_duplicates(trades_history): + trades_history1 = trades_history * 3 + assert len(trades_history1) == len(trades_history) * 3 + res = trades_remove_duplicates(trades_history1) + assert len(res) == len(trades_history) + for i, t in enumerate(res): + assert t == trades_history[i] + + +def test_trades_dict_to_list(fetch_trades_result): res = trades_dict_to_list(fetch_trades_result) assert isinstance(res, list) assert isinstance(res[0], list) From ff9caf790be4118f18ebf2f9c8779cf717ae507d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 07:58:39 +0200 Subject: [PATCH 0833/1106] remove trade duplicates in datahandler --- freqtrade/data/history/history_utils.py | 6 +++++- freqtrade/data/history/idatahandler.py | 15 +++++++++++++-- freqtrade/data/history/jsondatahandler.py | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index a7490f17b..74c8e8b96 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -9,7 +9,9 @@ from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS -from freqtrade.data.converter import ohlcv_to_dataframe, trades_to_ohlcv +from freqtrade.data.converter import (ohlcv_to_dataframe, + trades_remove_duplicates, + trades_to_ohlcv) from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange @@ -282,6 +284,8 @@ def _download_trades_history(exchange: Exchange, from_id=from_id, ) trades.extend(new_trades[1]) + # Remove duplicates to make sure we're not storing data we don't need + trades = trades_remove_duplicates(trades) data_handler.trades_store(pair, data=trades) logger.debug("New Start: %s", trades[0][0]) diff --git a/freqtrade/data/history/idatahandler.py b/freqtrade/data/history/idatahandler.py index 4663c29ac..d5d7c16db 100644 --- a/freqtrade/data/history/idatahandler.py +++ b/freqtrade/data/history/idatahandler.py @@ -13,7 +13,8 @@ from typing import List, Optional, Type from pandas import DataFrame from freqtrade.configuration import TimeRange -from freqtrade.data.converter import clean_ohlcv_dataframe, trim_dataframe +from freqtrade.data.converter import (clean_ohlcv_dataframe, + trades_remove_duplicates, trim_dataframe) from freqtrade.exchange import timeframe_to_seconds logger = logging.getLogger(__name__) @@ -110,7 +111,7 @@ class IDataHandler(ABC): """ @abstractmethod - def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: + def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: """ Load a pair from file, either .json.gz or .json :param pair: Load trades for this pair @@ -126,6 +127,16 @@ class IDataHandler(ABC): :return: True when deleted, false if file did not exist. """ + def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: + """ + Load a pair from file, either .json.gz or .json + Removes duplicates in the process. + :param pair: Load trades for this pair + :param timerange: Timerange to load trades for - currently not implemented + :return: List of trades + """ + return trades_remove_duplicates(self._trades_load(pair, timerange=timerange)) + def ohlcv_load(self, pair, timeframe: str, timerange: Optional[TimeRange] = None, fill_missing: bool = True, diff --git a/freqtrade/data/history/jsondatahandler.py b/freqtrade/data/history/jsondatahandler.py index 50a32603b..01320f129 100644 --- a/freqtrade/data/history/jsondatahandler.py +++ b/freqtrade/data/history/jsondatahandler.py @@ -136,7 +136,7 @@ class JsonDataHandler(IDataHandler): """ raise NotImplementedError() - def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: + def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList: """ Load a pair from file, either .json.gz or .json # TODO: respect timerange ... From ba03d96961a969bc43a8c930a35c0715e9a006f2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 20:04:36 +0200 Subject: [PATCH 0834/1106] Test 5s offset on since --- freqtrade/data/history/history_utils.py | 3 ++- tests/data/test_history.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 74c8e8b96..27aadc17c 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -270,7 +270,8 @@ def _download_trades_history(exchange: Exchange, from_id = trades[-1][1] if trades else None if trades and since < trades[-1][0]: # Reset since to the last available point - since = trades[-1][0] + # - 5 seconds (to ensure we're getting all trades) + since = trades[-1][0] - (5 * 1000) logger.debug("Current Start: %s", trades[0][0] if trades else 'None') logger.debug("Current End: %s", trades[-1][0] if trades else 'None') diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 12390538a..fedf63353 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -548,6 +548,17 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad assert file1.is_file() # clean files freshly downloaded + _clean_test_file(file1) + ght_mock.reset_mock() + since_time = int(trades_history[-2][0] // 1000) + timerange = TimeRange('date', None, since_time, 0) + assert _download_trades_history(data_handler=data_handler, exchange=exchange, + pair='ETH/BTC', timerange=timerange) + + assert ght_mock.call_count == 1 + # Check this in seconds - since we had to convert to seconds above too. + assert int(ght_mock.call_args_list[0].kwargs['since'] // 1000) == since_time - 5 + _clean_test_file(file1) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', From 437d4cda5d5cdcea0a033326eb9661d2e4b6e629 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 20:12:13 +0200 Subject: [PATCH 0835/1106] Add test data for trades --- tests/testdata/XRP_ETH-trades.json.gz | Bin 473687 -> 190318 bytes tests/testdata/XRP_OLD-trades.json.gz | Bin 0 -> 473687 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/testdata/XRP_OLD-trades.json.gz diff --git a/tests/testdata/XRP_ETH-trades.json.gz b/tests/testdata/XRP_ETH-trades.json.gz index 69b92cac8a2b1abb62e2be99a200063a247dcf10..dad822005b977902d757523b80d1e7c51adfe31a 100644 GIT binary patch literal 190318 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

oRdw^0KXn17$>`U^H8$pok zu;`Zz=+DMeZUoAlRj?nM&JF0#{ziZXw2k!TQOxptALwL@aVW=1^|qh05e3M4zws`} z1^LiB1e)@)CnqY|7eUCrYUOVpzCf;>P(MynLQAmKN)lAhk6j|um&}V*muBpMYGt%$ z%Y(v;!BuvJ?8+*-qAR;b_7gV=Hks`OYB%@^X3B)%-{ZAi*D$^RK+CSZfPafu4l^b` zmtV{MOB@r>wT`D?{7H-uWV3m;WnC|cNZ1xD(2g&Sp|9-rIelojX%fq+# zvo^V>dwB}i`w8qF?N`_8XyUy$C75%AUSJl{)SNjt z3$;DzF|0sXA8!2|g<_rpFo&9S#n1Af@Q!ca#_Pv64?gSt+dFe9RU!uWy}m5_egFC{ z_x)jHb$fkZwgLYAUGCeDEHSJf+QwJ>-kXeJW+$gonwX!D5gr0zR6_9Y?|NULbjD>p z3Mq8GFOqfK>&LY|b^8K=K+bzTe*rO0?Ns`$HYfn20<7mD0|ulDL(7PZ-)aMZbaDvt zfA8LJMyTdj6u;SKBb<4vm}Wc6yb&zDR{VAw481q5yMhvc>n-X~?u6nu-27>Xpib=3 z^g;3aZBPNkVdg$4q}BGMJ^K`X@x^nOz)+j-_jJ}>gAZvejnXeR|vreXG-=Lr#l>WjkffHYzX z5&Tp)f{GtYFkKYgzX1GPw|IO=G5rH83jD9uu6>~4!~zjmlVx1lhL)VU%^Pc(e)f|$ z9oj9gLqrX7wc0L-T{825@QX1j$H4H%aJ`@OuDfv^o0|WD8lVm`YDKj)qeLx!{$|s} z*duV9wxQOesfrBpH@mICawllAF@#>ac?hNYe)beI?BwG_!S+UjAq1f#1f>W;&U;=t zq}&QW!zk@BgdpcVnc4x91?f}BBVwGeoQ}!^Ebl4pn3b2zK4^p zNk)6Jmmy#>t!CqjpT>Eg!Nftf#bcHMmL+%5{E-l0lF9=NE_&_v2SPlsC z9!ID893U+1z9~M@+WTQo4qwdU0ls;L7*h*?OOVcaAL88<=OG5kr%$ye2sXH+7ODzC zxYa0WiqEr#<#6z~-V>K?Fh?tf>pip!k#Nda?JsdNx*FT{F`>^@wETq5?pZZ|uRl~n z`wbAtCNhlb@3oX-fIu`K4u^4@PFt7)prY-!*}NkLpOb8FTy@su*GWbAJvL}6&L?pL z<{ylj`<#p(LIw4_T$+MhBURWmG~8)DM)A9CV0Th6=GDaApT5)4AAmq4uMu{8WVsNbPwVVRK|UE<6c8XA^^sEA z5im4b*lqY)6j?mRY0;kga{7M(=!w@T|(fUQv^x_k%z2Pke=pGT-fWN!! zT_W9iYl=+v`vB9N>AM-}∾5p6&!!$S^zHr&yE!1}tqSY$Rxj;$A}pVro%#@rl)1 z-T{}F=WR!m$�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%0ACnE&qPlEx@G+j9dvm%<0vZbFrgQVf^oUb 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

O<6}YMJB;CFojDpcCU6OXBm5%72Z^b)PnF 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

    ;E<^;~MiMH%Nbo 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�K?P&2!Ea%;4j$*|IW;x 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

  1. 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
      ;E<^;~MiMH%Nbo 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

      x_M!XPLE%oRD~2wx0)=+L_}4j? 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�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�Qk$3gocQAho6wcwBsW*0bL|R5~rW)SVwv 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�K?P&2!Ea%;4j$*|IW;x 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

    1. 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 Date: Wed, 1 Apr 2020 20:12:28 +0200 Subject: [PATCH 0836/1106] Add test for trades data conversation --- tests/data/test_history.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index fedf63353..8df968217 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -612,7 +612,7 @@ def test_jsondatahandler_ohlcv_get_pairs(testdatadir): def test_jsondatahandler_trades_get_pairs(testdatadir): pairs = JsonGzDataHandler.trades_get_pairs(testdatadir) # Convert to set to avoid failures due to sorting - assert set(pairs) == {'XRP/ETH'} + assert set(pairs) == {'XRP/ETH', 'XRP/OLD'} def test_jsondatahandler_ohlcv_purge(mocker, testdatadir): @@ -625,6 +625,17 @@ def test_jsondatahandler_ohlcv_purge(mocker, testdatadir): assert dh.ohlcv_purge('UNITTEST/NONEXIST', '5m') +def test_jsondatahandler_trades_load(mocker, testdatadir, caplog): + dh = JsonGzDataHandler(testdatadir) + logmsg = "Old trades format detected - converting" + dh.trades_load('XRP/ETH') + assert not log_has(logmsg, caplog) + + # Test conversation is happening + dh.trades_load('XRP/OLD') + assert log_has(logmsg, caplog) + + def test_jsondatahandler_trades_purge(mocker, testdatadir): mocker.patch.object(Path, "exists", MagicMock(return_value=False)) mocker.patch.object(Path, "unlink", MagicMock()) From 0d51383b57fa7a09410bdeab9398e3f2b0b27761 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 20:31:21 +0200 Subject: [PATCH 0837/1106] Format logmessages correctly --- freqtrade/data/history/history_utils.py | 11 +++++++---- tests/data/test_history.py | 8 ++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 27aadc17c..1b51b864c 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -15,6 +15,7 @@ from freqtrade.data.converter import (ohlcv_to_dataframe, from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange +from freqtrade.misc import format_ms_time logger = logging.getLogger(__name__) @@ -271,10 +272,12 @@ def _download_trades_history(exchange: Exchange, if trades and since < trades[-1][0]: # Reset since to the last available point # - 5 seconds (to ensure we're getting all trades) + logger.info(f"Using last trade date -5s - Downloading trades for {pair} " + f"since: {format_ms_time(since)}.") since = trades[-1][0] - (5 * 1000) - logger.debug("Current Start: %s", trades[0][0] if trades else 'None') - logger.debug("Current End: %s", trades[-1][0] if trades else 'None') + logger.debug(f"Current Start: {format_ms_time(trades[0][0]) if trades else 'None'}") + logger.debug(f"Current End: {format_ms_time(trades[-1][0]) if trades else 'None'}") logger.info(f"Current Amount of trades: {len(trades)}") # Default since_ms to 30 days if nothing is given @@ -289,8 +292,8 @@ def _download_trades_history(exchange: Exchange, trades = trades_remove_duplicates(trades) data_handler.trades_store(pair, data=trades) - logger.debug("New Start: %s", trades[0][0]) - logger.debug("New End: %s", trades[-1][0]) + logger.debug(f"New Start: {format_ms_time(trades[0][0])}") + logger.debug(f"New End: {format_ms_time(trades[-1][0])}") logger.info(f"New Amount of trades: {len(trades)}") return True diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 8df968217..072bf00f5 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -547,18 +547,18 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad assert log_has("New Amount of trades: 5", caplog) assert file1.is_file() - # clean files freshly downloaded - _clean_test_file(file1) ght_mock.reset_mock() - since_time = int(trades_history[-2][0] // 1000) + since_time = int(trades_history[-3][0] // 1000) + since_time2 = int(trades_history[-1][0] // 1000) timerange = TimeRange('date', None, since_time, 0) assert _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC', timerange=timerange) assert ght_mock.call_count == 1 # Check this in seconds - since we had to convert to seconds above too. - assert int(ght_mock.call_args_list[0].kwargs['since'] // 1000) == since_time - 5 + assert int(ght_mock.call_args_list[0].kwargs['since'] // 1000) == since_time2 - 5 + # clean files freshly downloaded _clean_test_file(file1) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', From eab6c9c5f2838a0d464a5a5f3f2bf672e0f27f1e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 1 Apr 2020 20:50:00 +0200 Subject: [PATCH 0838/1106] Fix message --- freqtrade/data/history/history_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 1b51b864c..5cdcd7276 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -272,9 +272,9 @@ def _download_trades_history(exchange: Exchange, if trades and since < trades[-1][0]: # Reset since to the last available point # - 5 seconds (to ensure we're getting all trades) + since = trades[-1][0] - (5 * 1000) logger.info(f"Using last trade date -5s - Downloading trades for {pair} " f"since: {format_ms_time(since)}.") - since = trades[-1][0] - (5 * 1000) logger.debug(f"Current Start: {format_ms_time(trades[0][0]) if trades else 'None'}") logger.debug(f"Current End: {format_ms_time(trades[-1][0]) if trades else 'None'}") From 9d7ad23d426a1c5e135e05c07cbb24985285efa4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 08:20:50 +0200 Subject: [PATCH 0839/1106] Fix test leakage --- freqtrade/data/history/history_utils.py | 8 +++--- tests/conftest.py | 1 + tests/data/test_converter.py | 36 ++++++++++++++----------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/freqtrade/data/history/history_utils.py b/freqtrade/data/history/history_utils.py index 5cdcd7276..4f3f75a87 100644 --- a/freqtrade/data/history/history_utils.py +++ b/freqtrade/data/history/history_utils.py @@ -260,7 +260,9 @@ def _download_trades_history(exchange: Exchange, """ try: - since = timerange.startts * 1000 if timerange and timerange.starttype == 'date' else None + since = timerange.startts * 1000 if \ + (timerange and timerange.starttype == 'date') else int(arrow.utcnow().shift( + days=-30).float_timestamp) * 1000 trades = data_handler.trades_load(pair) @@ -282,9 +284,7 @@ def _download_trades_history(exchange: Exchange, # Default since_ms to 30 days if nothing is given new_trades = exchange.get_historic_trades(pair=pair, - since=since if since else - int(arrow.utcnow().shift( - days=-30).float_timestamp) * 1000, + since=since, from_id=from_id, ) trades.extend(new_trades[1]) diff --git a/tests/conftest.py b/tests/conftest.py index 517a11b47..a4beeec33 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1233,6 +1233,7 @@ def trades_history(): [1565798399862, '126181332', None, 'sell', 0.019626, 0.011, 0.00021588599999999999], [1565798399872, '126181333', None, 'sell', 0.019626, 0.011, 0.00021588599999999999]] + @pytest.fixture(scope="function") def fetch_trades_result(): return [{'info': {'a': 126181329, diff --git a/tests/data/test_converter.py b/tests/data/test_converter.py index 463700d0c..4a580366f 100644 --- a/tests/data/test_converter.py +++ b/tests/data/test_converter.py @@ -218,33 +218,37 @@ def test_trades_dict_to_list(fetch_trades_result): assert t[6] == fetch_trades_result[i]['cost'] - def test_convert_trades_format(mocker, default_conf, testdatadir): - file = testdatadir / "XRP_ETH-trades.json.gz" - file_new = testdatadir / "XRP_ETH-trades.json" - _backup_file(file, copy_file=True) - default_conf['datadir'] = testdatadir + files = [{'old': testdatadir / "XRP_ETH-trades.json.gz", + 'new': testdatadir / "XRP_ETH-trades.json"}, + {'old': testdatadir / "XRP_OLD-trades.json.gz", + 'new': testdatadir / "XRP_OLD-trades.json"}, + ] + for file in files: + _backup_file(file['old'], copy_file=True) + assert not file['new'].exists() - assert not file_new.exists() + default_conf['datadir'] = testdatadir convert_trades_format(default_conf, convert_from='jsongz', convert_to='json', erase=False) - assert file_new.exists() - assert file.exists() + for file in files: + assert file['new'].exists() + assert file['old'].exists() - # Remove original file - file.unlink() + # Remove original file + file['old'].unlink() # Convert back convert_trades_format(default_conf, convert_from='json', convert_to='jsongz', erase=True) + for file in files: + assert file['old'].exists() + assert not file['new'].exists() - assert file.exists() - assert not file_new.exists() - - _clean_test_file(file) - if file_new.exists(): - file_new.unlink() + _clean_test_file(file['old']) + if file['new'].exists(): + file['new'].unlink() def test_convert_ohlcv_format(mocker, default_conf, testdatadir): From 46f1d1f39f0bb1bf2e7379ab6b520d0c8e1baa47 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 11:54:30 +0200 Subject: [PATCH 0840/1106] Failing test might be incompatibility --- tests/data/test_history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/test_history.py b/tests/data/test_history.py index 072bf00f5..6fd4d9569 100644 --- a/tests/data/test_history.py +++ b/tests/data/test_history.py @@ -556,7 +556,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad assert ght_mock.call_count == 1 # Check this in seconds - since we had to convert to seconds above too. - assert int(ght_mock.call_args_list[0].kwargs['since'] // 1000) == since_time2 - 5 + assert int(ght_mock.call_args_list[0][1]['since'] // 1000) == since_time2 - 5 # clean files freshly downloaded _clean_test_file(file1) From cf6e6488c72c58e80567bdc90a27de0550c9154b Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 17:29:18 +0200 Subject: [PATCH 0841/1106] Fix filename handling with --strategy-list --- freqtrade/optimize/optimize_reports.py | 7 ++++--- tests/optimize/test_optimize_reports.py | 9 +++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 251da9159..646afb5df 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -24,13 +24,14 @@ def store_backtest_result(recordfilename: Path, all_results: Dict[str, DataFrame for index, t in results.iterrows()] if records: + filename = recordfilename if len(all_results) > 1: # Inject strategy to filename - recordfilename = Path.joinpath( + filename = Path.joinpath( recordfilename.parent, f'{recordfilename.stem}-{strategy}').with_suffix(recordfilename.suffix) - logger.info(f'Dumping backtest results to {recordfilename}') - file_dump_json(recordfilename, records) + logger.info(f'Dumping backtest results to {filename}') + file_dump_json(filename, records) def generate_text_table(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index f19668459..3bbc396c8 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -160,10 +160,15 @@ def test_backtest_record(default_conf, fee, mocker): # reset test to test with strategy name names = [] records = [] - results['Strat'] = pd.DataFrame() + results['Strat'] = results['DefStrat'] + results['Strat2'] = results['DefStrat'] store_backtest_result(Path("backtest-result.json"), results) # Assert file_dump_json was only called once - assert names == [Path('backtest-result-DefStrat.json')] + assert names == [ + Path('backtest-result-DefStrat.json'), + Path('backtest-result-Strat.json'), + Path('backtest-result-Strat2.json'), + ] records = records[0] # Ensure records are of correct type assert len(records) == 4 From 3fcd531eacbda7ca89e64ff68e0185efc8bd621d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 4 Nov 2019 20:19:43 +0100 Subject: [PATCH 0842/1106] Copy dataframe in interfac.py (reduces memory consumption) --- freqtrade/strategy/interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 89a38bf54..6307e664e 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -468,7 +468,7 @@ class IStrategy(ABC): Creates a dataframe and populates indicators for given candle (OHLCV) data Used by optimize operations only, not during dry / live runs. """ - return {pair: self.advise_indicators(pair_data, {'pair': pair}) + return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}) for pair, pair_data in data.items()} def advise_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: From de471862635f7344924c47ae91d2b00bd7a3c4e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Jan 2020 11:42:31 +0100 Subject: [PATCH 0843/1106] Use .loc for assignments --- freqtrade/optimize/backtesting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 1725a7d13..f29f599a6 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -149,8 +149,8 @@ class Backtesting: # To avoid using data from future, we use buy/sell signals shifted # from the previous candle - df_analyzed.loc[:, 'buy'] = df_analyzed['buy'].shift(1) - df_analyzed.loc[:, 'sell'] = df_analyzed['sell'].shift(1) + df_analyzed.loc[:, 'buy'] = df_analyzed.loc[:, 'buy'].shift(1) + df_analyzed.loc[:, 'sell'] = df_analyzed.loc[:, 'sell'].shift(1) df_analyzed.drop(df_analyzed.head(1).index, inplace=True) From c465552df4b37be165157a1ad6c7e9e22e92f4b2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 20:17:54 +0200 Subject: [PATCH 0844/1106] Update comment to mention .copy() usage --- freqtrade/strategy/interface.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 6307e664e..c6f711b74 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -467,6 +467,9 @@ class IStrategy(ABC): """ Creates a dataframe and populates indicators for given candle (OHLCV) data Used by optimize operations only, not during dry / live runs. + Using .copy() to get a fresh copy of the dataframe for every strategy run. + Has positive effects on memory usage for whatever reason - also when + using only one strategy. """ return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}) for pair, pair_data in data.items()} From d4dde011405365fced9a93b2c916e31a66233344 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Apr 2020 20:23:20 +0200 Subject: [PATCH 0845/1106] Add test --- tests/strategy/test_interface.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 8bc399f42..1c31aeb6a 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -168,6 +168,19 @@ def test_ohlcvdata_to_dataframe(default_conf, testdatadir) -> None: assert len(processed['UNITTEST/BTC']) == 102 # partial candle was removed +def test_ohlcvdata_to_dataframe_copy(mocker, default_conf, testdatadir) -> None: + default_conf.update({'strategy': 'DefaultStrategy'}) + strategy = StrategyResolver.load_strategy(default_conf) + aimock = mocker.patch('freqtrade.strategy.interface.IStrategy.advise_indicators') + timerange = TimeRange.parse_timerange('1510694220-1510700340') + data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange, + fill_up_missing=True) + strategy.ohlcvdata_to_dataframe(data) + assert aimock.call_count == 1 + # Ensure that a copy of the dataframe is passed to advice_indicators + assert aimock.call_args_list[0][0][0] is not data + + def test_min_roi_reached(default_conf, fee) -> None: # Use list to confirm sequence does not matter From a99c53f1ec4f89cd5fa2fe6c57f958f9fa4fd1cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Apr 2020 14:29:03 +0200 Subject: [PATCH 0846/1106] Add test showing that high is before low --- tests/data/test_btanalysis.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 463e5ae36..9f23ecf8f 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -191,3 +191,18 @@ def test_calculate_max_drawdown(testdatadir): assert low == Timestamp('2018-01-30 04:45:00', tz='UTC') with pytest.raises(ValueError, match='Trade dataframe empty.'): drawdown, h, low = calculate_max_drawdown(DataFrame()) + + +def test_calculate_max_drawdown2(): + values = [0.011580, 0.010048, 0.011340, 0.012161, 0.010416, 0.010009, 0.020024, + -0.024662, -0.022350, 0.020496, -0.029859, -0.030511, 0.010041, 0.010872, + -0.025782, 0.010400, 0.012374, 0.012467, 0.114741, 0.010303, 0.010088, + -0.033961, 0.010680, 0.010886, -0.029274, 0.011178, 0.010693, 0.010711] + + dates = [Arrow(2020, 1, 1).shift(days=i) for i in range(len(values))] + df = DataFrame(zip(values, dates), columns=['profit', 'open_time']) + drawdown, h, low = calculate_max_drawdown(df, date_col='open_time', value_col='profit') + assert isinstance(drawdown, float) + # High must be before low + assert h < low + assert drawdown == 0.091755 From e204170eb65055d487ab68e23150c658162d0007 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Apr 2020 14:29:40 +0200 Subject: [PATCH 0847/1106] Fix max_drawdown bug finding low before high! --- freqtrade/data/btanalysis.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 23a9f720c..1ff737b90 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -219,7 +219,7 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time' max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax() max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value'] - high_date = profit_results.loc[max_drawdown_df['high_value'].idxmax(), date_col] - low_date = profit_results.loc[max_drawdown_df['drawdown'].idxmin(), date_col] - + idxmin = max_drawdown_df['drawdown'].idxmin() + high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col] + low_date = profit_results.loc[idxmin, date_col] return abs(min(max_drawdown_df['drawdown'])), high_date, low_date From 4e907e2304da16c5ed28f93aa239f244e4c2a79d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Apr 2020 14:35:53 +0200 Subject: [PATCH 0848/1106] Use timeframe_to_prev_date to move trade-date to candle --- freqtrade/plot/plotting.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index b311c591a..5da067069 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -10,6 +10,7 @@ from freqtrade.data.btanalysis import (calculate_max_drawdown, create_cum_profit, extract_trades_of_period, load_trades) from freqtrade.data.converter import trim_dataframe +from freqtrade.exchange import timeframe_to_prev_date from freqtrade.data.history import load_data from freqtrade.misc import pair_to_filename from freqtrade.resolvers import StrategyResolver @@ -122,7 +123,8 @@ def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_sub return fig -def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> make_subplots: +def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame, + timeframe: str) -> make_subplots: """ Add scatter points indicating max drawdown """ @@ -132,8 +134,8 @@ def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame) -> m drawdown = go.Scatter( x=[highdate, lowdate], y=[ - df_comb.loc[df_comb.index == highdate, 'cum_profit'], - df_comb.loc[df_comb.index == lowdate, 'cum_profit'], + df_comb.loc[timeframe_to_prev_date(timeframe, highdate), 'cum_profit'], + df_comb.loc[timeframe_to_prev_date(timeframe, lowdate), 'cum_profit'], ], mode='markers', name=f"Max drawdown {max_drawdown:.2f}%", @@ -405,7 +407,7 @@ def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], fig.add_trace(avgclose, 1, 1) fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit') - fig = add_max_drawdown(fig, 2, trades, df_comb) + fig = add_max_drawdown(fig, 2, trades, df_comb, timeframe) for pair in pairs: profit_col = f'cum_profit_{pair}' From 41d5c40f1099a0f35c9906a6554edb7ff1de9015 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Apr 2020 14:43:01 +0200 Subject: [PATCH 0849/1106] Correctly test drawdown plot --- freqtrade/data/btanalysis.py | 2 ++ tests/data/test_btanalysis.py | 4 ++++ tests/test_plotting.py | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 1ff737b90..4505ea52a 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -220,6 +220,8 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time' max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value'] idxmin = max_drawdown_df['drawdown'].idxmin() + if idxmin == 0: + raise ValueError("No losing trade, therefore no drawdown.") high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col] low_date = profit_results.loc[idxmin, date_col] return abs(min(max_drawdown_df['drawdown'])), high_date, low_date diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 9f23ecf8f..4eec20976 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -206,3 +206,7 @@ def test_calculate_max_drawdown2(): # High must be before low assert h < low assert drawdown == 0.091755 + + df = DataFrame(zip(values[:5], dates[:5]), columns=['profit', 'open_time']) + with pytest.raises(ValueError, match='No losing trade, therefore no drawdown.'): + calculate_max_drawdown(df, date_col='open_time', value_col='profit') diff --git a/tests/test_plotting.py b/tests/test_plotting.py index a5c965429..0258b94d1 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -266,7 +266,7 @@ def test_generate_profit_graph(testdatadir): filename = testdatadir / "backtest-result_test.json" trades = load_backtest_data(filename) timerange = TimeRange.parse_timerange("20180110-20180112") - pairs = ["TRX/BTC", "ADA/BTC"] + pairs = ["TRX/BTC", "XLM/BTC"] trades = trades[trades['close_time'] < pd.Timestamp('2018-01-12', tz='UTC')] data = history.load_data(datadir=testdatadir, @@ -292,7 +292,7 @@ def test_generate_profit_graph(testdatadir): profit = find_trace_in_fig_data(figure.data, "Profit") assert isinstance(profit, go.Scatter) - profit = find_trace_in_fig_data(figure.data, "Max drawdown 0.00%") + profit = find_trace_in_fig_data(figure.data, "Max drawdown 10.45%") assert isinstance(profit, go.Scatter) for pair in pairs: From 0a14d5ec467bdab197d1d100446f7c4dd5fdb698 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Sun, 5 Apr 2020 16:14:02 +0200 Subject: [PATCH 0850/1106] trades history RPC --- freqtrade/rpc/api_server.py | 16 ++++++++++++- freqtrade/rpc/rpc.py | 47 +++++++++++++++++++++++++++++++++++++ scripts/rest_client.py | 7 ++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 8f4cc4787..7e0cdd71d 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -173,7 +173,8 @@ class ApiServer(RPC): view_func=self._show_config, methods=['GET']) self.app.add_url_rule(f'{BASE_URI}/ping', 'ping', view_func=self._ping, methods=['GET']) - + self.app.add_url_rule(f'{BASE_URI}/trades', 'trades', + view_func=self._trades, methods=['GET']) # Combined actions and infos self.app.add_url_rule(f'{BASE_URI}/blacklist', 'blacklist', view_func=self._blacklist, methods=['GET', 'POST']) @@ -357,6 +358,19 @@ class ApiServer(RPC): results = self._rpc_balance(self._config['stake_currency'], self._config.get('fiat_display_currency', '')) return self.rest_dump(results) + + @require_login + @rpc_catch_errors + def _trades(self): + """ + Handler for /trades. + + Returns the X last trades in json format + """ + last_trades_number = request.args.get('last_trades_number', 0) + last_trades_number = int(last_trades_number) + results = self._rpc_trade_history(last_trades_number) + return self.rest_dump(results) @require_login @rpc_catch_errors diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index a0f50b070..b0c045e4a 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -226,6 +226,53 @@ class RPC: for key, value in profit_days.items() ] + def _rpc_trade_history( + self, last_trades_number: int) -> List[List[Any]]: + """ Returns the X last trades """ + if last_trades_number > 0: + trades = Trade.get_trades().order_by(Trade.id.desc()).limit(last_trades_number) + else: + trades = Trade.get_trades().order_by(Trade.id.desc()).all() + + output = [] + + for trade in trades: + output.append({ + 'id': trade.id, + 'pair': trade.pair, + 'exchange': trade.exchange, + 'is_open': trade.is_open if trade.is_open is not None else 0, + 'open_rate': trade.open_rate, + 'close_rate': trade.close_rate, + 'fee_open': trade.fee_open, + 'fee_close': trade.fee_close, + 'open_rate_requested': trade.open_rate_requested, + 'open_trade_price': trade.open_trade_price, + 'close_rate_requested': trade.close_rate_requested, + 'close_profit': trade.close_profit, + 'close_profit_abs': trade.close_profit_abs, + 'stake_amount': trade.stake_amount, + 'amount': trade.amount, + 'open_date': trade.open_date, + 'close_date': trade.close_date, + 'open_order_id': trade.open_order_id, + 'stop_loss': trade.stop_loss, + 'stop_loss_pct': trade.stop_loss_pct, + 'initial_stop_loss': trade.initial_stop_loss, + 'initial_stop_loss_pct': trade.initial_stop_loss_pct, + 'stoploss_order_id': trade.stoploss_order_id, + 'stoploss_last_update': trade.stoploss_last_update, + 'max_rate': trade.max_rate, + 'min_rate': trade.min_rate, + 'sell_reason': trade.sell_reason, + 'strategy': trade.strategy, + 'ticker_interval': trade.ticker_interval, + }) + + return { + "trades" : output + } + def _rpc_trade_statistics( self, stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]: """ Returns cumulative profit statistics """ diff --git a/scripts/rest_client.py b/scripts/rest_client.py index ccb33604f..5cbdd8e07 100755 --- a/scripts/rest_client.py +++ b/scripts/rest_client.py @@ -156,6 +156,13 @@ class FtRestClient(): """ return self._get("show_config") + def history(self, number=None): + """Return the amount of open trades. + + :return: json object + """ + return self._get("trades", params={"last_trades_number": number} if number else 0) + def whitelist(self): """Show the current whitelist. From 15c45b984d20d3079875d4b1480e9bac0067b7cd Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Sun, 5 Apr 2020 16:47:46 +0200 Subject: [PATCH 0851/1106] removing whitespace --- freqtrade/rpc/api_server.py | 2 +- freqtrade/rpc/rpc.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 7e0cdd71d..d2fb5bfad 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -358,7 +358,7 @@ class ApiServer(RPC): results = self._rpc_balance(self._config['stake_currency'], self._config.get('fiat_display_currency', '')) return self.rest_dump(results) - + @require_login @rpc_catch_errors def _trades(self): diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index b0c045e4a..a3506816b 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -270,7 +270,7 @@ class RPC: }) return { - "trades" : output + "trades": output } def _rpc_trade_statistics( From 8555c5b2110b29a65d20843fa1a66bf79a3a8219 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Sun, 5 Apr 2020 17:03:51 +0200 Subject: [PATCH 0852/1106] fix return value --- freqtrade/rpc/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index a3506816b..01e593e82 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -227,7 +227,7 @@ class RPC: ] def _rpc_trade_history( - self, last_trades_number: int) -> List[List[Any]]: + self, last_trades_number: int) -> Dict[str, List[Dict[str, Any]]]: """ Returns the X last trades """ if last_trades_number > 0: trades = Trade.get_trades().order_by(Trade.id.desc()).limit(last_trades_number) From 6256025c73ae59ce9f9f3c9e52216bd157db0a22 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Mon, 6 Apr 2020 11:00:31 +0200 Subject: [PATCH 0853/1106] various adjustement from PR discussion --- freqtrade/persistence.py | 15 +++++++++++++- freqtrade/rpc/api_server.py | 5 ++--- freqtrade/rpc/rpc.py | 41 ++++++------------------------------- scripts/rest_client.py | 7 ++++--- 4 files changed, 26 insertions(+), 42 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 0d668596c..b0ef4bd8f 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -188,7 +188,7 @@ class Trade(_DECL_BASE): fee_close = Column(Float, nullable=False, default=0.0) open_rate = Column(Float) open_rate_requested = Column(Float) - # open_trade_price - calcuated via _calc_open_trade_price + # open_trade_price - calculated via _calc_open_trade_price open_trade_price = Column(Float) close_rate = Column(Float) close_rate_requested = Column(Float) @@ -233,6 +233,9 @@ class Trade(_DECL_BASE): return { 'trade_id': self.id, 'pair': self.pair, + 'is_open': self.is_open, + 'fee_open': self.fee_open, + 'fee_close': self.fee_close, 'open_date_hum': arrow.get(self.open_date).humanize(), 'open_date': self.open_date.strftime("%Y-%m-%d %H:%M:%S"), 'close_date_hum': (arrow.get(self.close_date).humanize() @@ -240,14 +243,24 @@ class Trade(_DECL_BASE): 'close_date': (self.close_date.strftime("%Y-%m-%d %H:%M:%S") if self.close_date else None), 'open_rate': self.open_rate, + 'open_rate_requested': self.open_rate_requested, + 'open_trade_price': self.open_trade_price, 'close_rate': self.close_rate, + 'close_rate_requested': self.close_rate_requested, 'amount': round(self.amount, 8), 'stake_amount': round(self.stake_amount, 8), + 'close_profit': self.close_profit, + 'sell_reason': self.sell_reason, 'stop_loss': self.stop_loss, 'stop_loss_pct': (self.stop_loss_pct * 100) if self.stop_loss_pct else None, 'initial_stop_loss': self.initial_stop_loss, 'initial_stop_loss_pct': (self.initial_stop_loss_pct * 100 if self.initial_stop_loss_pct else None), + 'min_rate': self.min_rate, + 'max_rate': self.max_rate, + 'strategy': self.strategy, + 'ticker_interval': self.ticker_interval, + 'open_order_id': self.open_order_id, } def adjust_min_max_rates(self, current_price: float) -> None: diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index d2fb5bfad..0335bb151 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -367,9 +367,8 @@ class ApiServer(RPC): Returns the X last trades in json format """ - last_trades_number = request.args.get('last_trades_number', 0) - last_trades_number = int(last_trades_number) - results = self._rpc_trade_history(last_trades_number) + limit = int(request.args.get('limit', 0)) + results = self._rpc_trade_history(limit) return self.rest_dump(results) @require_login diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 01e593e82..b78856265 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -227,50 +227,21 @@ class RPC: ] def _rpc_trade_history( - self, last_trades_number: int) -> Dict[str, List[Dict[str, Any]]]: + self, limit: int) -> Dict[str, List[Dict[str, Any]]]: """ Returns the X last trades """ - if last_trades_number > 0: - trades = Trade.get_trades().order_by(Trade.id.desc()).limit(last_trades_number) + if limit > 0: + trades = Trade.get_trades().order_by(Trade.id.desc()).limit(limit) else: trades = Trade.get_trades().order_by(Trade.id.desc()).all() output = [] for trade in trades: - output.append({ - 'id': trade.id, - 'pair': trade.pair, - 'exchange': trade.exchange, - 'is_open': trade.is_open if trade.is_open is not None else 0, - 'open_rate': trade.open_rate, - 'close_rate': trade.close_rate, - 'fee_open': trade.fee_open, - 'fee_close': trade.fee_close, - 'open_rate_requested': trade.open_rate_requested, - 'open_trade_price': trade.open_trade_price, - 'close_rate_requested': trade.close_rate_requested, - 'close_profit': trade.close_profit, - 'close_profit_abs': trade.close_profit_abs, - 'stake_amount': trade.stake_amount, - 'amount': trade.amount, - 'open_date': trade.open_date, - 'close_date': trade.close_date, - 'open_order_id': trade.open_order_id, - 'stop_loss': trade.stop_loss, - 'stop_loss_pct': trade.stop_loss_pct, - 'initial_stop_loss': trade.initial_stop_loss, - 'initial_stop_loss_pct': trade.initial_stop_loss_pct, - 'stoploss_order_id': trade.stoploss_order_id, - 'stoploss_last_update': trade.stoploss_last_update, - 'max_rate': trade.max_rate, - 'min_rate': trade.min_rate, - 'sell_reason': trade.sell_reason, - 'strategy': trade.strategy, - 'ticker_interval': trade.ticker_interval, - }) + output.append(trade.to_json()) return { - "trades": output + "trades": output, + "trades_count": len(output) } def _rpc_trade_statistics( diff --git a/scripts/rest_client.py b/scripts/rest_client.py index 5cbdd8e07..116c00063 100755 --- a/scripts/rest_client.py +++ b/scripts/rest_client.py @@ -156,12 +156,13 @@ class FtRestClient(): """ return self._get("show_config") - def history(self, number=None): - """Return the amount of open trades. + def history(self, limit=None): + """Return trades history. + :param limit: Limits trades to the X last trades . No limit to get all the trades. :return: json object """ - return self._get("trades", params={"last_trades_number": number} if number else 0) + return self._get("trades", params={"limit": limit} if limit else 0) def whitelist(self): """Show the current whitelist. From a1e81a51efcc8497e1cdae8cb0303d894b6f2a17 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:09:54 +0000 Subject: [PATCH 0854/1106] Bump ccxt from 1.25.38 to 1.25.81 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.25.38 to 1.25.81. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.25.38...1.25.81) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 3c9802990..7e873aa83 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.25.38 +ccxt==1.25.81 SQLAlchemy==1.3.15 python-telegram-bot==12.5 arrow==0.15.5 From 5de7ee3bdb1f11d3ae082face12a960c804136db Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:10:07 +0000 Subject: [PATCH 0855/1106] Bump plotly from 4.5.4 to 4.6.0 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.4 to 4.6.0. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.5.4...v4.6.0) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 7a5b21e2d..3db48a201 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.5.4 +plotly==4.6.0 From 144d252e19bff28837f3f22fb29b3d42024e99eb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:10:30 +0000 Subject: [PATCH 0856/1106] Bump flask from 1.1.1 to 1.1.2 Bumps [flask](https://github.com/pallets/flask) from 1.1.1 to 1.1.2. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/1.1.1...1.1.2) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 3c9802990..310383680 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -24,7 +24,7 @@ python-rapidjson==0.9.1 sdnotify==0.3.2 # Api server -flask==1.1.1 +flask==1.1.2 # Support for colorized terminal output colorama==0.4.3 From 0b30cb7f8f42fd0e1fe430c3ec5299fda03dec09 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:11:33 +0000 Subject: [PATCH 0857/1106] Bump pytest-mock from 2.0.0 to 3.0.0 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 2.0.0 to 3.0.0. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v2.0.0...v3.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 01f189c56..814003cbf 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ mypy==0.770 pytest==5.4.1 pytest-asyncio==0.10.0 pytest-cov==2.8.1 -pytest-mock==2.0.0 +pytest-mock==3.0.0 pytest-random-order==1.0.4 # Convert jupyter notebooks to markdown documents From be76e3c55482e9ae55bc820ca8b8e53dec247b75 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2020 09:23:21 +0000 Subject: [PATCH 0858/1106] Bump python-telegram-bot from 12.5 to 12.5.1 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.5 to 12.5.1. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.5...v12.5.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 7e873aa83..7f2b39ff2 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.25.81 SQLAlchemy==1.3.15 -python-telegram-bot==12.5 +python-telegram-bot==12.5.1 arrow==0.15.5 cachetools==4.0.0 requests==2.23.0 From 815660c0700726d7c7cb9a8b82bf9e76186f016f Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Mon, 6 Apr 2020 11:32:00 +0200 Subject: [PATCH 0859/1106] fix tests --- tests/rpc/test_rpc.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 47ffb771b..875a234b2 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -49,6 +49,18 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'base_currency': 'BTC', 'open_date': ANY, 'open_date_hum': ANY, + 'is_open': ANY, + 'fee_open': ANY, + 'fee_close': ANY, + 'open_rate_requested': ANY, + 'open_trade_price': ANY, + 'close_rate_requested': ANY, + 'sell_reason': ANY, + 'min_rate': ANY, + 'max_rate': ANY, + 'strategy': ANY, + 'ticker_interval': ANY, + 'open_order_id': ANY, 'close_date': None, 'close_date_hum': None, 'open_rate': 1.098e-05, @@ -76,6 +88,18 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'base_currency': 'BTC', 'open_date': ANY, 'open_date_hum': ANY, + 'is_open': ANY, + 'fee_open': ANY, + 'fee_close': ANY, + 'open_rate_requested': ANY, + 'open_trade_price': ANY, + 'close_rate_requested': ANY, + 'sell_reason': ANY, + 'min_rate': ANY, + 'max_rate': ANY, + 'strategy': ANY, + 'ticker_interval': ANY, + 'open_order_id': ANY, 'close_date': None, 'close_date_hum': None, 'open_rate': 1.098e-05, From d5609d49972f2d8ddc873b945090bba2635db00f Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 6 Apr 2020 13:12:32 +0200 Subject: [PATCH 0860/1106] Changed back to progressbar2 for better handling of logger. Coloring still needs some work (bug + what colors to use) --- freqtrade/optimize/hyperopt.py | 107 ++++++++++++++++++--------------- requirements-hyperopt.txt | 2 +- setup.py | 1 + 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a5921703f..1adaf54e1 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -22,7 +22,7 @@ from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna -from tqdm import tqdm +import progressbar import tabulate from os import path import io @@ -44,7 +44,8 @@ with warnings.catch_warnings(): from skopt import Optimizer from skopt.space import Dimension - +progressbar.streams.wrap_stderr() +progressbar.streams.wrap_stdout() logger = logging.getLogger(__name__) @@ -682,55 +683,67 @@ class Hyperopt: logger.info(f'Effective number of parallel workers used: {jobs}') # Define progressbar - self.progress_bar = tqdm( - total=self.total_epochs, ncols=108, unit=' Epoch', - bar_format='Epoch {n_fmt}/{total_fmt} ({percentage:3.0f}%)|{bar}|' - ' [{elapsed}<{remaining} {rate_fmt}{postfix}]' - ) + if self.print_colorized: + widgets = [ + ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), + ' (', progressbar.Percentage(), ')] ', + progressbar.Bar(marker=progressbar.AnimatedMarker( + fill='█', + fill_wrap='\x1b[32m{}\x1b[39m', + marker_wrap='\x1b[31m{}\x1b[39m', + )), + ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', + ] + else: + widgets = [ + ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), '] ', + progressbar.Bar(marker='█'), + ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', + ] + with progressbar.ProgressBar( + maxval=self.total_epochs, redirect_stdout=True, redirect_stderr=True, + widgets=widgets + ) as pbar: + EVALS = ceil(self.total_epochs / jobs) + for i in range(EVALS): + # Correct the number of epochs to be processed for the last + # iteration (should not exceed self.total_epochs in total) + n_rest = (i + 1) * jobs - self.total_epochs + current_jobs = jobs - n_rest if n_rest > 0 else jobs - EVALS = ceil(self.total_epochs / jobs) - for i in range(EVALS): - # Correct the number of epochs to be processed for the last - # iteration (should not exceed self.total_epochs in total) - 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) + f_val = self.run_optimizer_parallel(parallel, asked, i) + self.opt.tell(asked, [v['loss'] for v in f_val]) + self.fix_optimizer_models_list() - 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]) - self.fix_optimizer_models_list() + # Calculate progressbar outputs + for j, val in enumerate(f_val): + # Use human-friendly indexes here (starting from 1) + current = i * jobs + j + 1 + val['current_epoch'] = current + val['is_initial_point'] = current <= INITIAL_POINTS - # Calculate progressbar outputs - for j, val in enumerate(f_val): - # Use human-friendly indexes here (starting from 1) - current = i * jobs + j + 1 - val['current_epoch'] = current - val['is_initial_point'] = current <= INITIAL_POINTS - logger.debug(f"Optimizer epoch evaluated: {val}") + logger.debug(f"Optimizer epoch evaluated: {val}") - is_best = self.is_best_loss(val, self.current_best_loss) - # This value is assigned here and not in the optimization method - # to keep proper order in the list of results. That's because - # evaluations can take different time. Here they are aligned in the - # order they will be shown to the user. - val['is_best'] = is_best - output = self.get_results(val) - if output: - self.progress_bar.write(output) - self.progress_bar.ncols = 108 - self.progress_bar.update(1) + is_best = self.is_best_loss(val, self.current_best_loss) + # This value is assigned here and not in the optimization method + # to keep proper order in the list of results. That's because + # evaluations can take different time. Here they are aligned in the + # order they will be shown to the user. + val['is_best'] = is_best + self.print_results(val) - if is_best: - self.current_best_loss = val['loss'] - self.trials.append(val) - # Save results after each best epoch and every 100 epochs - if is_best or current % 100 == 0: - self.save_trials() - self.progress_bar.ncols = 108 - self.progress_bar.close() + if is_best: + self.current_best_loss = val['loss'] + self.trials.append(val) + + # Save results after each best epoch and every 100 epochs + if is_best or current % 100 == 0: + self.save_trials() + + pbar.update(current) except KeyboardInterrupt: - self.progress_bar.close() print('User interrupted..') self.save_trials(final=True) @@ -743,9 +756,3 @@ 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 __getstate__(self): - state = self.__dict__.copy() - del state['trials'] - del state['progress_bar'] - return state diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 7469674cd..6df1eb157 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -7,4 +7,4 @@ scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 -tqdm==4.43.0 +progressbar2==3.50.1 diff --git a/setup.py b/setup.py index 7890f862e..94c48a6a7 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,7 @@ hyperopt = [ 'scikit-optimize', 'filelock', 'joblib', + 'progressbar2', ] develop = [ From c1f9595086b3a3b2f7871ac0818c878a9c11b876 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Mon, 6 Apr 2020 15:49:24 +0200 Subject: [PATCH 0861/1106] fix broken tests --- tests/rpc/test_rpc_apiserver.py | 33 +++++++++++++++++++++++++++++++-- tests/test_persistence.py | 30 ++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index e0abd886d..79073825d 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -444,7 +444,22 @@ def test_api_status(botclient, mocker, ticker, fee, markets): 'stake_amount': 0.001, 'stop_loss': 0.0, 'stop_loss_pct': None, - 'trade_id': 1}] + 'trade_id': 1, + 'close_rate_requested': None, + 'current_profit': -0.41, + 'current_rate': 1.099e-05, + 'fee_close': 0.0025, + 'fee_open': 0.0025, + 'open_date': ANY, + 'is_open': True, + 'max_rate': 0.0, + 'min_rate': None, + 'open_order_id': ANY, + 'open_rate_requested': 1.098e-05, + 'open_trade_price': 0.0010025, + 'sell_reason': None, + 'strategy': 'DefaultStrategy', + 'ticker_interval': 5}] def test_api_version(botclient): @@ -533,7 +548,21 @@ def test_api_forcebuy(botclient, mocker, fee): 'stake_amount': 1, 'stop_loss': None, 'stop_loss_pct': None, - 'trade_id': None} + 'trade_id': None, + 'close_profit': None, + 'close_rate_requested': None, + 'fee_close': 0.0025, + 'fee_open': 0.0025, + 'is_open': False, + 'max_rate': None, + 'min_rate': None, + 'open_order_id': '123456', + 'open_rate_requested': None, + 'open_trade_price': 0.2460546025, + 'sell_reason': None, + 'strategy': None, + 'ticker_interval': None + } def test_api_forcesell(botclient, mocker, ticker, fee, markets): diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 991922cba..c6de10e3d 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -777,18 +777,31 @@ def test_to_json(default_conf, fee): assert result == {'trade_id': None, 'pair': 'ETH/BTC', + 'is_open': None, 'open_date_hum': '2 hours ago', 'open_date': trade.open_date.strftime("%Y-%m-%d %H:%M:%S"), + 'open_order_id': 'dry_run_buy_12345', 'close_date_hum': None, 'close_date': None, 'open_rate': 0.123, + 'open_rate_requested': None, + 'open_trade_price': 15.1668225, + 'fee_close': 0.0025, + 'fee_open': 0.0025, 'close_rate': None, + 'close_rate_requested': None, 'amount': 123.0, 'stake_amount': 0.001, + 'close_profit': None, + 'sell_reason': None, 'stop_loss': None, 'stop_loss_pct': None, 'initial_stop_loss': None, - 'initial_stop_loss_pct': None} + 'initial_stop_loss_pct': None, + 'min_rate': None, + 'max_rate': None, + 'strategy': None, + 'ticker_interval': None} # Simulate dry_run entries trade = Trade( @@ -819,7 +832,20 @@ def test_to_json(default_conf, fee): 'stop_loss': None, 'stop_loss_pct': None, 'initial_stop_loss': None, - 'initial_stop_loss_pct': None} + 'initial_stop_loss_pct': None, + 'close_profit': None, + 'close_rate_requested': None, + 'fee_close': 0.0025, + 'fee_open': 0.0025, + 'is_open': None, + 'max_rate': None, + 'min_rate': None, + 'open_order_id': None, + 'open_rate_requested': None, + 'open_trade_price': 12.33075, + 'sell_reason': None, + 'strategy': None, + 'ticker_interval': None} def test_stoploss_reinitialization(default_conf, fee): From 20abb379aaeaea97f63b193d5e1a2caddb892533 Mon Sep 17 00:00:00 2001 From: orehunt Date: Mon, 6 Apr 2020 15:49:59 +0200 Subject: [PATCH 0862/1106] trim trades to the available ohlcv data before plotting profits --- freqtrade/data/btanalysis.py | 13 ++++++++++--- freqtrade/plot/plotting.py | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 23a9f720c..780980ad6 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -151,13 +151,20 @@ def load_trades(source: str, db_url: str, exportfilename: Path, return load_backtest_data(exportfilename) -def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame: +def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame, + date_index=False) -> pd.DataFrame: """ Compare trades and backtested pair DataFrames to get trades performed on backtested period :return: the DataFrame of a trades of period """ - trades = trades.loc[(trades['open_time'] >= dataframe.iloc[0]['date']) & - (trades['close_time'] <= dataframe.iloc[-1]['date'])] + if date_index: + trades_start = dataframe.index[0] + trades_stop = dataframe.index[-1] + else: + trades_start = dataframe.iloc[0]['date'] + trades_stop = dataframe.iloc[-1]['date'] + trades = trades.loc[(trades['open_time'] >= trades_start) & + (trades['close_time'] <= trades_stop)] return trades diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 5da067069..6dcb71cc4 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -385,6 +385,9 @@ def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], # Combine close-values for all pairs, rename columns to "pair" df_comb = combine_dataframes_with_mean(data, "close") + # Trim trades to available OHLCV data + trades = extract_trades_of_period(df_comb, trades, date_index=True) + # Add combined cumulative profit df_comb = create_cum_profit(df_comb, trades, 'cum_profit', timeframe) From 2444fb9cd6afe8fe9cd086872d7e6d0b29e95ab7 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Mon, 6 Apr 2020 15:56:57 +0200 Subject: [PATCH 0863/1106] fix broken tests: remove duplicated value --- tests/rpc/test_rpc_apiserver.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 79073825d..c96f68f29 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -446,7 +446,6 @@ def test_api_status(botclient, mocker, ticker, fee, markets): 'stop_loss_pct': None, 'trade_id': 1, 'close_rate_requested': None, - 'current_profit': -0.41, 'current_rate': 1.099e-05, 'fee_close': 0.0025, 'fee_open': 0.0025, From 200111fef6b4b8ff90818a4e76d6caa207fb4034 Mon Sep 17 00:00:00 2001 From: Ork Blutt Date: Mon, 6 Apr 2020 16:07:43 +0200 Subject: [PATCH 0864/1106] fix method return value --- freqtrade/rpc/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index b78856265..35386760d 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -227,7 +227,7 @@ class RPC: ] def _rpc_trade_history( - self, limit: int) -> Dict[str, List[Dict[str, Any]]]: + self, limit: int) -> Dict: """ Returns the X last trades """ if limit > 0: trades = Trade.get_trades().order_by(Trade.id.desc()).limit(limit) From c95906cfcf89210b7045fc9f95ace14aa6c2cc31 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 7 Apr 2020 10:42:15 +0200 Subject: [PATCH 0865/1106] 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 1adaf54e1..a839d2111 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -649,7 +649,7 @@ class Hyperopt: self.hyperopt_table_header = -1 data, timerange = self.backtesting.load_bt_data() - preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data) + preprocessed = self.backtesting.strategy.ohlcvdata_to_dataframe(data) # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): preprocessed[pair] = trim_dataframe(df, timerange) From 132f5f73f5bd7c083891802704e7bb208b12012b Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Tue, 7 Apr 2020 10:44:18 +0200 Subject: [PATCH 0866/1106] Update hyperopt.py --- freqtrade/optimize/hyperopt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a839d2111..bf32997c1 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -650,6 +650,7 @@ class Hyperopt: data, timerange = self.backtesting.load_bt_data() preprocessed = self.backtesting.strategy.ohlcvdata_to_dataframe(data) + # Trim startup period from analyzed dataframe for pair, df in preprocessed.items(): preprocessed[pair] = trim_dataframe(df, timerange) From bdc85ec89b23a99abebe8722da799d81c42a208c Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 7 Apr 2020 19:42:16 +0200 Subject: [PATCH 0867/1106] Move create_mock_tests to conftest and add test for test_trade-history --- tests/conftest.py | 46 +++++++++++++++++++++++++++++++++ tests/data/test_btanalysis.py | 2 +- tests/rpc/test_rpc.py | 28 +++++++++++++++++++- tests/test_persistence.py | 48 +---------------------------------- 4 files changed, 75 insertions(+), 49 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 64d0cd5ee..da1fbd6d4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -166,6 +166,52 @@ def patch_get_signal(freqtrade: FreqtradeBot, value=(True, False)) -> None: freqtrade.exchange.refresh_latest_ohlcv = lambda p: None +def create_mock_trades(fee): + """ + Create some fake trades ... + """ + # Simulate dry_run entries + trade = Trade( + pair='ETH/BTC', + stake_amount=0.001, + amount=123.0, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_rate=0.123, + exchange='bittrex', + open_order_id='dry_run_buy_12345' + ) + Trade.session.add(trade) + + trade = Trade( + pair='ETC/BTC', + stake_amount=0.001, + amount=123.0, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_rate=0.123, + close_rate=0.128, + close_profit=0.005, + exchange='bittrex', + is_open=False, + open_order_id='dry_run_sell_12345' + ) + Trade.session.add(trade) + + # Simulate prod entry + trade = Trade( + pair='ETC/BTC', + stake_amount=0.001, + amount=123.0, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_rate=0.123, + exchange='bittrex', + open_order_id='prod_buy_12345' + ) + Trade.session.add(trade) + + @pytest.fixture(autouse=True) def patch_coingekko(mocker) -> None: """ diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 463e5ae36..0edad8e78 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -15,7 +15,7 @@ from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, load_backtest_data, load_trades, load_trades_from_db) from freqtrade.data.history import load_data, load_pair_history -from tests.test_persistence import create_mock_trades +from tests.conftest import create_mock_trades def test_load_backtest_data(testdatadir): diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 875a234b2..d2af4bd87 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -13,7 +13,7 @@ from freqtrade.persistence import Trade from freqtrade.rpc import RPC, RPCException from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.state import State -from tests.conftest import get_patched_freqtradebot, patch_get_signal +from tests.conftest import get_patched_freqtradebot, patch_get_signal, create_mock_trades # Functions for recurrent object patching @@ -211,6 +211,32 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, rpc._rpc_daily_profit(0, stake_currency, fiat_display_currency) +def test_rpc_trade_history(mocker, default_conf, markets, fee): + mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets) + ) + + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + create_mock_trades(fee) + rpc = RPC(freqtradebot) + rpc._fiat_converter = CryptoToFiatConverter() + trades = rpc._rpc_trade_history(2) + assert len(trades['trades']) == 2 + assert trades['trades_count'] == 2 + assert isinstance(trades['trades'][0], dict) + assert isinstance(trades['trades'][1], dict) + + trades = rpc._rpc_trade_history(0) + assert len(trades['trades']) == 3 + assert trades['trades_count'] == 3 + # The first trade is for ETH ... sorting is descending + assert trades['trades'][-1]['pair'] == 'ETH/BTC' + assert trades['trades'][0]['pair'] == 'ETC/BTC' + assert trades['trades'][1]['pair'] == 'ETC/BTC' + + def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, limit_buy_order, limit_sell_order, mocker) -> None: mocker.patch.multiple( diff --git a/tests/test_persistence.py b/tests/test_persistence.py index c6de10e3d..ceac24356 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -9,53 +9,7 @@ from sqlalchemy import create_engine from freqtrade import constants from freqtrade.exceptions import OperationalException from freqtrade.persistence import Trade, clean_dry_run_db, init -from tests.conftest import log_has - - -def create_mock_trades(fee): - """ - Create some fake trades ... - """ - # Simulate dry_run entries - trade = Trade( - pair='ETH/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='bittrex', - open_order_id='dry_run_buy_12345' - ) - Trade.session.add(trade) - - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - close_rate=0.128, - close_profit=0.005, - exchange='bittrex', - is_open=False, - open_order_id='dry_run_sell_12345' - ) - Trade.session.add(trade) - - # Simulate prod entry - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='bittrex', - open_order_id='prod_buy_12345' - ) - Trade.session.add(trade) +from tests.conftest import log_has, create_mock_trades def test_init_create_session(default_conf): From 296c616ce7c2595ec65ba11d4c0ad0d7e670721f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 7 Apr 2020 19:50:13 +0200 Subject: [PATCH 0868/1106] Add test for api-trades call --- tests/rpc/test_rpc_apiserver.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index c96f68f29..6548790cb 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -13,7 +13,7 @@ from freqtrade.__init__ import __version__ from freqtrade.persistence import Trade from freqtrade.rpc.api_server import BASE_URI, ApiServer from freqtrade.state import State -from tests.conftest import get_patched_freqtradebot, log_has, patch_get_signal +from tests.conftest import get_patched_freqtradebot, log_has, patch_get_signal, create_mock_trades _TEST_USER = "FreqTrader" _TEST_PASS = "SuperSecurePassword1!" @@ -302,6 +302,30 @@ def test_api_daily(botclient, mocker, ticker, fee, markets): assert rc.json[0][0] == str(datetime.utcnow().date()) +def test_api_trades(botclient, mocker, ticker, fee, markets): + ftbot, client = botclient + patch_get_signal(ftbot, (True, False)) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets) + ) + rc = client_get(client, f"{BASE_URI}/trades") + assert_response(rc) + assert len(rc.json) == 2 + assert rc.json['trades_count'] == 0 + + create_mock_trades(fee) + + rc = client_get(client, f"{BASE_URI}/trades") + assert_response(rc) + assert len(rc.json['trades']) == 3 + assert rc.json['trades_count'] == 3 + rc = client_get(client, f"{BASE_URI}/trades?limit=2") + assert_response(rc) + assert len(rc.json['trades']) == 2 + assert rc.json['trades_count'] == 2 + + def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): ftbot, client = botclient patch_get_signal(ftbot, (True, False)) From 492c2799dc78c38ece251c06f4377fdf03113b61 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 7 Apr 2020 19:52:34 +0200 Subject: [PATCH 0869/1106] Rename rest-client script history to trades --- scripts/rest_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/rest_client.py b/scripts/rest_client.py index 116c00063..b26c32479 100755 --- a/scripts/rest_client.py +++ b/scripts/rest_client.py @@ -156,10 +156,10 @@ class FtRestClient(): """ return self._get("show_config") - def history(self, limit=None): + def trades(self, limit=None): """Return trades history. - :param limit: Limits trades to the X last trades . No limit to get all the trades. + :param limit: Limits trades to the X last trades. No limit to get all the trades. :return: json object """ return self._get("trades", params={"limit": limit} if limit else 0) From 02192f28cd62a1fe4b0bf95545f718079122b715 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 8 Apr 2020 07:56:21 +0200 Subject: [PATCH 0870/1106] Small stylistic updates --- freqtrade/rpc/rpc.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 35386760d..8645e466e 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -226,18 +226,14 @@ class RPC: for key, value in profit_days.items() ] - def _rpc_trade_history( - self, limit: int) -> Dict: + def _rpc_trade_history(self, limit: int) -> Dict: """ Returns the X last trades """ if limit > 0: trades = Trade.get_trades().order_by(Trade.id.desc()).limit(limit) else: trades = Trade.get_trades().order_by(Trade.id.desc()).all() - output = [] - - for trade in trades: - output.append(trade.to_json()) + output = [trade.to_json() for trade in trades] return { "trades": output, From 5cff72a42e1ab58d841d42cae43cf59f6fbcf932 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Apr 2020 09:22:38 +0200 Subject: [PATCH 0871/1106] Improve logging to ensure which branch is used for buy order cancels --- freqtrade/freqtradebot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 570f8bea8..16e4d4d2d 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -904,6 +904,7 @@ class FreqtradeBot: logger.info('Buy order %s for %s.', reason, trade) if corder.get('remaining', order['remaining']) == order['amount']: + logger.info('Buy order removed from database %s', trade) # if trade is not partially completed, just delete the trade Trade.session.delete(trade) Trade.session.flush() From 4707484a4cf8982bb9aa1548b5ba754356981d0d Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 9 Apr 2020 11:42:13 +0200 Subject: [PATCH 0872/1106] Fix issue with colring enabled + styling --- freqtrade/optimize/hyperopt.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index fac613549..f34967af2 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -7,7 +7,6 @@ This module contains the hyperopt logic import locale import logging import random -import sys import warnings from math import ceil from collections import OrderedDict @@ -18,7 +17,6 @@ from typing import Any, Dict, List, Optional import rapidjson from colorama import Fore, Style -from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) from pandas import DataFrame, json_normalize, isna @@ -268,17 +266,10 @@ class Hyperopt: Log results if it is better than any previous evaluation """ is_best = results['is_best'] - if not self.print_all: - # Print '\n' after each 100th epoch to separate dots from the log messages. - # Otherwise output is messy on a terminal. - print('.', end='' if results['current_epoch'] % 100 != 0 else None) # type: ignore - sys.stdout.flush() if self.print_all or is_best: - if not self.print_all: - # Separate the results explanation string from dots - print("\n") - print(self.get_result_table( + print( + self.get_result_table( self.config, results, self.total_epochs, self.print_all, self.print_colorized, self.hyperopt_table_header @@ -675,9 +666,6 @@ class Hyperopt: self.dimensions: List[Dimension] = self.hyperopt_space() self.opt = self.get_optimizer(self.dimensions, config_jobs) - if self.print_colorized: - colorama_init(autoreset=True) - try: with Parallel(n_jobs=config_jobs) as parallel: jobs = parallel._effective_n_jobs() @@ -690,15 +678,18 @@ class Hyperopt: ' (', progressbar.Percentage(), ')] ', progressbar.Bar(marker=progressbar.AnimatedMarker( fill='█', - fill_wrap='\x1b[32m{}\x1b[39m', - marker_wrap='\x1b[31m{}\x1b[39m', + fill_wrap=Fore.GREEN + '{}' + Fore.RESET, + marker_wrap=Style.BRIGHT + '{}' + Style.RESET_ALL, )), ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', ] else: widgets = [ - ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), '] ', - progressbar.Bar(marker='█'), + ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), + ' (', progressbar.Percentage(), ')] ', + progressbar.Bar(marker=progressbar.AnimatedMarker( + fill='█', + )), ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', ] with progressbar.ProgressBar( From 346e09fed1045b73a9fa5aa25fa8226660fb7356 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Apr 2020 19:32:10 +0200 Subject: [PATCH 0873/1106] Add test verifying that cancel_order with empty remaining is causing the bug --- tests/test_freqtradebot.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e37270bd3..2536d57db 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2204,14 +2204,11 @@ def test_check_handle_timedout_exception(default_conf, ticker, open_trade, mocke caplog) -def test_handle_timedout_limit_buy(mocker, default_conf, limit_buy_order) -> None: +def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order) -> None: patch_RPCManager(mocker) patch_exchange(mocker) cancel_order_mock = MagicMock(return_value=limit_buy_order) - mocker.patch.multiple( - 'freqtrade.exchange.Exchange', - cancel_order=cancel_order_mock - ) + mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock) freqtrade = FreqtradeBot(default_conf) @@ -2227,9 +2224,14 @@ def test_handle_timedout_limit_buy(mocker, default_conf, limit_buy_order) -> Non assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 + mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException) + assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + assert log_has_re(r"Could not cancel buy order", caplog) + @pytest.mark.parametrize('cancelorder', [ {}, + {'remaining': None}, 'String Return value', 123 ]) From cbf5bf6735fa1b0aabfce9ba58fe370dd2d600c4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Apr 2020 19:34:48 +0200 Subject: [PATCH 0874/1106] Add safe_value_fallback function --- freqtrade/misc.py | 15 +++++++++++++++ tests/test_misc.py | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 1f52b75ec..ea7bab843 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -134,6 +134,21 @@ def round_dict(d, n): return {k: (round(v, n) if isinstance(v, float) else v) for k, v in d.items()} +def safe_value_fallback(dict1: dict, dict2: dict, key1: str, key2: str, default_value=None): + """ + Search a value in dict1, return this if it's not None. + Fall back to dict2 - return key2 from dict2 if it's not None. + Else falls back to None. + + """ + if key1 in dict1 and dict1[key1] is not None: + return dict1[key1] + else: + if key2 in dict2 and dict2[key2] is not None: + return dict2[key2] + return default_value + + def plural(num: float, singular: str, plural: str = None) -> str: return singular if (num == 1 or num == -1) else plural or singular + 's' diff --git a/tests/test_misc.py b/tests/test_misc.py index c1e23926b..1bb5b40af 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -9,7 +9,7 @@ import pytest from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, file_load_json, format_ms_time, pair_to_filename, - plural, shorten_date) + plural, safe_value_fallback, shorten_date) def test_shorten_date() -> None: @@ -93,6 +93,19 @@ def test_format_ms_time() -> None: assert format_ms_time(date_in_epoch_ms) == res.astimezone(None).strftime('%Y-%m-%dT%H:%M:%S') +def test_safe_value_fallback(): + dict1 = {'keya': None, 'keyb': 2, 'keyc': 5} + dict2 = {'keya': 20, 'keyb': None, 'keyc': 6} + assert safe_value_fallback(dict1, dict2, 'keya', 'keya') == 20 + assert safe_value_fallback(dict2, dict1, 'keya', 'keya') == 20 + + assert safe_value_fallback(dict1, dict2, 'keyb', 'keyb') == 2 + assert safe_value_fallback(dict2, dict1, 'keyb', 'keyb') == 2 + + assert safe_value_fallback(dict1, dict2, 'keyc', 'keyc') == 5 + assert safe_value_fallback(dict2, dict1, 'keyc', 'keyc') == 6 + + def test_plural() -> None: assert plural(0, "page") == "pages" assert plural(0.0, "page") == "pages" From f39706cabd78c35aaf668bf290ba4c79ae744bcb Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Apr 2020 19:35:27 +0200 Subject: [PATCH 0875/1106] Fix #3130 - when corder['remaining'] contains none-type --- freqtrade/freqtradebot.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 16e4d4d2d..b5c2ac4ee 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -20,6 +20,7 @@ from freqtrade.data.dataprovider import DataProvider from freqtrade.edge import Edge from freqtrade.exceptions import DependencyException, InvalidOrderException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date +from freqtrade.misc import safe_value_fallback from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver @@ -892,18 +893,23 @@ class FreqtradeBot: """ if order['status'] != 'canceled': reason = "cancelled due to timeout" - corder = self.exchange.cancel_order(trade.open_order_id, trade.pair) - # Some exchanges don't return a dict here. - if not isinstance(corder, dict): + try: + corder = self.exchange.cancel_order(trade.open_order_id, trade.pair) + # Some exchanges don't return a dict here. + if not isinstance(corder, dict): + corder = {} + logger.info('Buy order %s for %s.', reason, trade) + except InvalidOrderException: corder = {} - logger.info('Buy order %s for %s.', reason, trade) + logger.exception( + f"Could not cancel buy order {trade.open_order_id} for pair {trade.pair}") else: # Order was cancelled already, so we can reuse the existing dict corder = order reason = "cancelled on exchange" logger.info('Buy order %s for %s.', reason, trade) - if corder.get('remaining', order['remaining']) == order['amount']: + if safe_value_fallback(corder, order, 'remaining', 'remaining') == order['amount']: logger.info('Buy order removed from database %s', trade) # if trade is not partially completed, just delete the trade Trade.session.delete(trade) @@ -915,7 +921,8 @@ class FreqtradeBot: # cancel_order may not contain the full order dict, so we need to fallback # to the order dict aquired before cancelling. # we need to fall back to the values from order if corder does not contain these keys. - trade.amount = order['amount'] - corder.get('remaining', order['remaining']) + trade.amount = order['amount'] - safe_value_fallback(corder, order, + 'remaining', 'remaining') trade.stake_amount = trade.amount * trade.open_rate # verify if fees were taken from amount to avoid problems during selling try: From c03f637f5b629b55e74c4b8e0405bc8f7767bd7e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Apr 2020 19:40:04 +0200 Subject: [PATCH 0876/1106] Improve safe_value_fallback test --- tests/test_misc.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 1bb5b40af..832bcb3a9 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -94,8 +94,8 @@ def test_format_ms_time() -> None: def test_safe_value_fallback(): - dict1 = {'keya': None, 'keyb': 2, 'keyc': 5} - dict2 = {'keya': 20, 'keyb': None, 'keyc': 6} + dict1 = {'keya': None, 'keyb': 2, 'keyc': 5, 'keyd': None} + dict2 = {'keya': 20, 'keyb': None, 'keyc': 6, 'keyd': None} assert safe_value_fallback(dict1, dict2, 'keya', 'keya') == 20 assert safe_value_fallback(dict2, dict1, 'keya', 'keya') == 20 @@ -105,6 +105,14 @@ def test_safe_value_fallback(): assert safe_value_fallback(dict1, dict2, 'keyc', 'keyc') == 5 assert safe_value_fallback(dict2, dict1, 'keyc', 'keyc') == 6 + assert safe_value_fallback(dict1, dict2, 'keyd', 'keyd') is None + assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd') is None + assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd', 1234) == 1234 + + assert safe_value_fallback(dict1, dict2, 'keyNo', 'keyNo') is None + assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo') is None + assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo', 1234) == 1234 + def test_plural() -> None: assert plural(0, "page") == "pages" From d9e54ab7a4b386a1faa89dbb995fceb1f1c90a92 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 11 Apr 2020 17:42:19 +0200 Subject: [PATCH 0877/1106] Update freqtrade/optimize/hyperopt.py nice find Co-Authored-By: Matthias --- 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 f34967af2..4b9139681 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -677,7 +677,7 @@ class Hyperopt: ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), ' (', progressbar.Percentage(), ')] ', progressbar.Bar(marker=progressbar.AnimatedMarker( - fill='█', + fill='\N{FULL BLOCK}', fill_wrap=Fore.GREEN + '{}' + Fore.RESET, marker_wrap=Style.BRIGHT + '{}' + Style.RESET_ALL, )), From 2c1c1c7f166871d1ba7ce95803426c50f85ff4df Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Sat, 11 Apr 2020 17:42:32 +0200 Subject: [PATCH 0878/1106] Update freqtrade/optimize/hyperopt.py nice find Co-Authored-By: Matthias --- 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 4b9139681..affd6f3b3 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -688,7 +688,7 @@ class Hyperopt: ' [Epoch ', progressbar.Counter(), ' of ', str(self.total_epochs), ' (', progressbar.Percentage(), ')] ', progressbar.Bar(marker=progressbar.AnimatedMarker( - fill='█', + fill='\N{FULL BLOCK}', )), ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', ] From 952d2f7513a7b28d6ee0fad8142169aeb6ebe166 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2020 09:55:21 +0200 Subject: [PATCH 0879/1106] have version-detection fall back to freqtrade_commit this allows freqtrade --version to work in docker too. sample command: `docker-compose run --rm freqtrade -version` --- freqtrade/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index ad432a20b..4da56c3aa 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -24,4 +24,11 @@ if __version__ == 'develop': # stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') except Exception: # git not available, ignore - pass + try: + # Try Fallback to freqtrade_commit file (created by CI whild building docker image) + from pathlib import Path + versionfile = Path('./freqtrade_commit') + if versionfile.is_file(): + __version__ = f"docker-{versionfile.read_text()[:8]}" + except Exception: + pass From 4ee0cbb5751c2bdb67724d379c6f2e3b1d12b339 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 12 Apr 2020 10:40:02 +0200 Subject: [PATCH 0880/1106] Reset index to correctly gather index --- freqtrade/data/btanalysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index 4505ea52a..a96e43dff 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -213,7 +213,7 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time' """ if len(trades) == 0: raise ValueError("Trade dataframe empty.") - profit_results = trades.sort_values(date_col) + profit_results = trades.sort_values(date_col).reset_index() max_drawdown_df = pd.DataFrame() max_drawdown_df['cumulative'] = profit_results[value_col].cumsum() max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax() From eac4dbcd287871aeff837b875d730118d2165081 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 08:30:31 +0000 Subject: [PATCH 0881/1106] Bump sqlalchemy from 1.3.15 to 1.3.16 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.15 to 1.3.16. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index eb6ed8464..4a5d66c09 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,7 +1,7 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs ccxt==1.25.81 -SQLAlchemy==1.3.15 +SQLAlchemy==1.3.16 python-telegram-bot==12.5.1 arrow==0.15.5 cachetools==4.0.0 From 350b4d5e7deaca04b36805503616f8f8001cad17 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 08:31:00 +0000 Subject: [PATCH 0882/1106] Bump coveralls from 1.11.1 to 2.0.0 Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.11.1 to 2.0.0. - [Release notes](https://github.com/coveralls-clients/coveralls-python/releases) - [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.11.1...2.0.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 814003cbf..ae240d7c8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,7 +3,7 @@ -r requirements-plot.txt -r requirements-hyperopt.txt -coveralls==1.11.1 +coveralls==2.0.0 flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.1.0 From cfcce0e657feb91f69198f426d9f91f2a46ea290 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 08:32:29 +0000 Subject: [PATCH 0883/1106] Bump mkdocs-material from 4.6.3 to 5.1.0 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.3 to 5.1.0. - [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/4.6.3...5.1.0) Signed-off-by: dependabot-preview[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 48ade026e..138b6e862 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==4.6.3 +mkdocs-material==5.1.0 mdx_truly_sane_lists==1.2 From fb0d76b94a73c4764adff2fc89dbf98bfc2e5589 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 11:47:12 +0000 Subject: [PATCH 0884/1106] Bump cachetools from 4.0.0 to 4.1.0 Bumps [cachetools](https://github.com/tkem/cachetools) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/tkem/cachetools/releases) - [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tkem/cachetools/compare/v4.0.0...v4.1.0) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 4a5d66c09..e22bebf28 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -4,7 +4,7 @@ ccxt==1.25.81 SQLAlchemy==1.3.16 python-telegram-bot==12.5.1 arrow==0.15.5 -cachetools==4.0.0 +cachetools==4.1.0 requests==2.23.0 urllib3==1.25.8 wrapt==1.12.1 From a166fc887f27e1670ea29f38155059206e85e8cf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 11:47:14 +0000 Subject: [PATCH 0885/1106] Bump python-telegram-bot from 12.5.1 to 12.6.1 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.5.1 to 12.6.1. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.5.1...v12.6.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 4a5d66c09..e1572e215 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.25.81 SQLAlchemy==1.3.16 -python-telegram-bot==12.5.1 +python-telegram-bot==12.6.1 arrow==0.15.5 cachetools==4.0.0 requests==2.23.0 From a1d2124e450db4993c9d0bd8c81db0aab8f59fc2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 12:29:38 +0000 Subject: [PATCH 0886/1106] Bump ccxt from 1.25.81 to 1.26.12 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.25.81 to 1.26.12. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.25.81...1.26.12) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index ca8918caf..a6a0fb78e 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.25.81 +ccxt==1.26.12 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 arrow==0.15.5 From ddf37ef059655c93ec9109382815e683ae834dd2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 08:02:42 +0200 Subject: [PATCH 0887/1106] Add test to demonstrate that the dataframe is not changed --- freqtrade/data/btanalysis.py | 2 +- tests/data/test_btanalysis.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index a96e43dff..0c2fbff1e 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -213,7 +213,7 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time' """ if len(trades) == 0: raise ValueError("Trade dataframe empty.") - profit_results = trades.sort_values(date_col).reset_index() + profit_results = trades.sort_values(date_col).reset_index(drop=True) max_drawdown_df = pd.DataFrame() max_drawdown_df['cumulative'] = profit_results[value_col].cumsum() max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax() diff --git a/tests/data/test_btanalysis.py b/tests/data/test_btanalysis.py index 4eec20976..7b894cccc 100644 --- a/tests/data/test_btanalysis.py +++ b/tests/data/test_btanalysis.py @@ -201,7 +201,13 @@ def test_calculate_max_drawdown2(): dates = [Arrow(2020, 1, 1).shift(days=i) for i in range(len(values))] df = DataFrame(zip(values, dates), columns=['profit', 'open_time']) + # sort by profit and reset index + df = df.sort_values('profit').reset_index(drop=True) + df1 = df.copy() drawdown, h, low = calculate_max_drawdown(df, date_col='open_time', value_col='profit') + # Ensure df has not been altered. + assert df.equals(df1) + assert isinstance(drawdown, float) # High must be before low assert h < low From 55a052bcf6853e0b1a6e2e21b3d1ff61d730db40 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 08:05:46 +0200 Subject: [PATCH 0888/1106] fix typo in comment Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- freqtrade/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/__init__.py b/freqtrade/__init__.py index 4da56c3aa..e96e7f530 100644 --- a/freqtrade/__init__.py +++ b/freqtrade/__init__.py @@ -25,7 +25,7 @@ if __version__ == 'develop': except Exception: # git not available, ignore try: - # Try Fallback to freqtrade_commit file (created by CI whild building docker image) + # Try Fallback to freqtrade_commit file (created by CI while building docker image) from pathlib import Path versionfile = Path('./freqtrade_commit') if versionfile.is_file(): From cfe1e4876a00196cd40b938360042d08468b8ca2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 19:20:47 +0200 Subject: [PATCH 0889/1106] Improve testcase for cancel_order_empty --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 073e28659..ad4824a10 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -908,7 +908,7 @@ class Exchange: :param order: Order dict as returned from get_order() :return: True if order has been cancelled without being filled, False otherwise. """ - return order['status'] in ('closed', 'canceled') and order.get('filled') == 0.0 + return order.get('status') in ('closed', 'canceled') and order.get('filled') == 0.0 @retrier def cancel_order(self, order_id: str, pair: str) -> None: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 7f03eb547..cc3f95735 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1711,6 +1711,8 @@ def test_cancel_order_dry_run(default_conf, mocker, exchange_name): ({'status': 'closed', 'filled': 0.0}, True), ({'status': 'canceled', 'filled': 0.0}, True), ({'status': 'canceled', 'filled': 10.0}, False), + ({'status': 'unknown', 'filled': 10.0}, False), + ({'result': 'testest123'}, False), ]) def test_check_order_canceled_empty(mocker, default_conf, exchange_name, order, result): exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) From 7c15375f5da6fb66efc00f356486eb4a5736534d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:20:36 +0200 Subject: [PATCH 0890/1106] Add log_on_refresh - using TTL caching to avoid spamming logs --- freqtrade/pairlist/IPairList.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index 35844a99e..e57bc4e88 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -9,6 +9,8 @@ from abc import ABC, abstractmethod, abstractproperty from copy import deepcopy from typing import Any, Dict, List +from cachetools import TTLCache, cached + from freqtrade.exchange import market_is_active logger = logging.getLogger(__name__) @@ -31,6 +33,9 @@ class IPairList(ABC): self._config = config self._pairlistconfig = pairlistconfig self._pairlist_pos = pairlist_pos + self.refresh_period = self._pairlistconfig.get('refresh_period', 1800) + self._last_refresh = 0 + self._log_cache = TTLCache(maxsize=1024, ttl=self.refresh_period) @property def name(self) -> str: @@ -40,6 +45,24 @@ class IPairList(ABC): """ return self.__class__.__name__ + def log_on_refresh(self, logmethod, message: str) -> None: + """ + Logs message - not more often than "refresh_period" to avoid log spamming + Logs the log-message as debug as well to simplify debugging. + :param logmethod: Function that'll be called. Most likely `logger.info`. + :param message: String containing the message to be sent to the function. + :return: None. + """ + + @cached(cache=self._log_cache) + def _log_on_refresh(logmethod, message: str): + logmethod(message) + + # Log as debug first + logger.debug(message) + # Call hidden function. + _log_on_refresh(logmethod, message) + @abstractproperty def needstickers(self) -> bool: """ From 5d876ca0a359f129a79a3f486216261734fd9003 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:21:10 +0200 Subject: [PATCH 0891/1106] Use log-spamprevention methods --- freqtrade/pairlist/PriceFilter.py | 4 ++-- freqtrade/pairlist/SpreadFilter.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index dc02ae251..7ea1e6003 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -43,8 +43,8 @@ class PriceFilter(IPairList): compare = ticker['last'] + 1 / pow(10, precision) changeperc = (compare - ticker['last']) / ticker['last'] if changeperc > self._low_price_ratio: - logger.info(f"Removed {ticker['symbol']} from whitelist, " - f"because 1 unit is {changeperc * 100:.3f}%") + self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " + f"because 1 unit is {changeperc * 100:.3f}%") return False return True diff --git a/freqtrade/pairlist/SpreadFilter.py b/freqtrade/pairlist/SpreadFilter.py index 9361837cc..49731ef11 100644 --- a/freqtrade/pairlist/SpreadFilter.py +++ b/freqtrade/pairlist/SpreadFilter.py @@ -49,9 +49,9 @@ class SpreadFilter(IPairList): if 'bid' in ticker and 'ask' in ticker: spread = 1 - ticker['bid'] / ticker['ask'] if not ticker or spread > self._max_spread_ratio: - logger.info(f"Removed {ticker['symbol']} from whitelist, " - f"because spread {spread * 100:.3f}% >" - f"{self._max_spread_ratio * 100}%") + self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " + f"because spread {spread * 100:.3f}% >" + f"{self._max_spread_ratio * 100}%") pairlist.remove(p) else: pairlist.remove(p) From 13ee7a55c4756035d647f00a25767407e2cafe40 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:21:30 +0200 Subject: [PATCH 0892/1106] Fix #3166 Always call _gen_pair_whitelist if volumepairlist is not the first in the list. --- freqtrade/pairlist/VolumePairList.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 9ce2adc9e..65f43245c 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -39,7 +39,6 @@ class VolumePairList(IPairList): if not self._validate_keys(self._sort_key): raise OperationalException( f'key {self._sort_key} not in {SORT_VALUES}') - self._last_refresh = 0 @property def needstickers(self) -> bool: @@ -68,16 +67,18 @@ class VolumePairList(IPairList): :return: new whitelist """ # Generate dynamic whitelist - if self._last_refresh + self.refresh_period < datetime.now().timestamp(): + # Must always run if this pairlist is not the first in the list. + if (self._pairlist_pos != 0 or + (self._last_refresh + self.refresh_period < datetime.now().timestamp())): + self._last_refresh = int(datetime.now().timestamp()) - return self._gen_pair_whitelist(pairlist, - tickers, - self._config['stake_currency'], - self._sort_key, - self._min_value - ) + pairs = self._gen_pair_whitelist(pairlist, tickers, + self._config['stake_currency'], + self._sort_key, self._min_value) else: - return pairlist + pairs = pairlist + self.log_on_refresh(logger.info, f"Searching {self._number_pairs} pairs: {pairs}") + return pairs def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict, base_currency: str, key: str, min_val: int) -> List[str]: @@ -88,7 +89,6 @@ class VolumePairList(IPairList): :param tickers: Tickers (from exchange.get_tickers()). :return: List of pairs """ - if self._pairlist_pos == 0: # If VolumePairList is the first in the list, use fresh pairlist # Check if pair quote currency equals to the stake currency. @@ -109,6 +109,5 @@ class VolumePairList(IPairList): pairs = self._verify_blacklist(pairs, aswarning=False) # Limit to X number of pairs pairs = pairs[:self._number_pairs] - logger.info(f"Searching {self._number_pairs} pairs: {pairs}") return pairs From ceca0a659cef27ed872bcb504af6ec74c99f1511 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:25:58 +0200 Subject: [PATCH 0893/1106] Simplify cached stuff to only what's needed --- freqtrade/pairlist/IPairList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index e57bc4e88..e089e546c 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -55,13 +55,13 @@ class IPairList(ABC): """ @cached(cache=self._log_cache) - def _log_on_refresh(logmethod, message: str): + def _log_on_refresh(message: str): logmethod(message) # Log as debug first logger.debug(message) # Call hidden function. - _log_on_refresh(logmethod, message) + _log_on_refresh(message) @abstractproperty def needstickers(self) -> bool: From 1b2bf2c9b69680d2ed09e3edfeffc1d00451932a Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:39:54 +0200 Subject: [PATCH 0894/1106] Add test for cached log method --- tests/pairlist/test_pairlist.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 1ce1151b7..6275bdafc 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -46,6 +46,28 @@ def static_pl_conf(whitelist_conf): return whitelist_conf +def test_log_on_refresh(mocker, static_pl_conf, markets, tickers): + mocker.patch.multiple('freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets), + exchange_has=MagicMock(return_value=True), + get_tickers=tickers + ) + freqtrade = get_patched_freqtradebot(mocker, static_pl_conf) + logmock = MagicMock() + # Assign starting whitelist + pl = freqtrade.pairlists._pairlists[0] + pl.log_on_refresh(logmock, 'Hello world') + assert logmock.call_count == 1 + pl.log_on_refresh(logmock, 'Hello world') + assert logmock.call_count == 1 + assert pl._log_cache.currsize == 1 + assert ('Hello world',) in pl._log_cache._Cache__data + + pl.log_on_refresh(logmock, 'Hello world2') + assert logmock.call_count == 2 + assert pl._log_cache.currsize == 2 + + def test_load_pairlist_noexist(mocker, markets, default_conf): bot = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)) From 2b7376f6f334d78ede1d98fb1fee5ca3af4a9b34 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 14 Apr 2020 20:45:30 +0200 Subject: [PATCH 0895/1106] Implement log-filtering for all pairlists --- freqtrade/pairlist/PrecisionFilter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index f16458ca5..2a2ba46b7 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -39,8 +39,9 @@ class PrecisionFilter(IPairList): stop_gap_price = self._exchange.price_to_precision(ticker["symbol"], stop_price * 0.99) logger.debug(f"{ticker['symbol']} - {sp} : {stop_gap_price}") if sp <= stop_gap_price: - logger.info(f"Removed {ticker['symbol']} from whitelist, " - f"because stop price {sp} would be <= stop limit {stop_gap_price}") + self.log_on_refresh(logger.info, + f"Removed {ticker['symbol']} from whitelist, " + f"because stop price {sp} would be <= stop limit {stop_gap_price}") return False return True From ac008a4758e16ef7da0523bc32a37e25ea85e32c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2020 06:58:54 +0200 Subject: [PATCH 0896/1106] Remove obsolete comment in tests --- tests/optimize/test_optimize_reports.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 3bbc396c8..e0782146a 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -163,7 +163,6 @@ def test_backtest_record(default_conf, fee, mocker): results['Strat'] = results['DefStrat'] results['Strat2'] = results['DefStrat'] store_backtest_result(Path("backtest-result.json"), results) - # Assert file_dump_json was only called once assert names == [ Path('backtest-result-DefStrat.json'), Path('backtest-result-Strat.json'), From 36e714a7b258576df0d920fef50fba700037ffad Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2020 07:19:27 +0200 Subject: [PATCH 0897/1106] Add price_get_one_pip filter --- freqtrade/exchange/exchange.py | 11 +++++++++++ freqtrade/pairlist/PriceFilter.py | 5 ++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f4c94a1ca..7dd910fab 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -452,6 +452,17 @@ class Exchange: price = ceil(big_price) / pow(10, symbol_prec) return price + def price_get_one_pip(self, pair: str, price: float) -> float: + """ + Get's the "1 pip" value for this pair. + Used in PriceFilter to calculate the 1pip movements. + """ + precision = self.markets[pair]['precision']['price'] + if self.precisionMode == TICK_SIZE: + return price % precision + else: + return 1 / pow(10, precision) + def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float, rate: float, params: Dict = {}) -> Dict[str, Any]: order_id = f'dry_run_{side}_{randint(0, 10**6)}' diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index dc02ae251..00c9d44c9 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -38,9 +38,8 @@ class PriceFilter(IPairList): :param precision: Precision :return: True if the pair can stay, false if it should be removed """ - precision = self._exchange.markets[ticker['symbol']]['precision']['price'] - - compare = ticker['last'] + 1 / pow(10, precision) + compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'], + ticker['last']) changeperc = (compare - ticker['last']) / ticker['last'] if changeperc > self._low_price_ratio: logger.info(f"Removed {ticker['symbol']} from whitelist, " From 33b6c7de5b01fdb31026da307b9546c6cbca3529 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2020 07:53:31 +0200 Subject: [PATCH 0898/1106] Add tests for price_one_pip --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7dd910fab..b3255f1bd 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -459,7 +459,7 @@ class Exchange: """ precision = self.markets[pair]['precision']['price'] if self.precisionMode == TICK_SIZE: - return price % precision + return precision else: return 1 / pow(10, precision) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 8d8930f66..c0aedc7f9 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -253,6 +253,32 @@ def test_price_to_precision(default_conf, mocker, price, precision_mode, precisi assert pytest.approx(exchange.price_to_precision(pair, price)) == expected +@pytest.mark.parametrize("price,precision_mode,precision,expected", [ + (2.34559, 2, 4, 0.0001), + (2.34559, 2, 5, 0.00001), + (2.34559, 2, 3, 0.001), + (2.9999, 2, 3, 0.001), + (200.0511, 2, 3, 0.001), + # Tests for Tick_size + (2.34559, 4, 0.0001, 0.0001), + (2.34559, 4, 0.00001, 0.00001), + (2.34559, 4, 0.0025, 0.0025), + (2.9909, 4, 0.0025, 0.0025), + (234.43, 4, 0.5, 0.5), + (234.43, 4, 0.0025, 0.0025), + (234.43, 4, 0.00013, 0.00013), + +]) +def test_price_get_one_pip(default_conf, mocker, price, precision_mode, precision, expected): + markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': precision}}}) + exchange = get_patched_exchange(mocker, default_conf, id="binance") + mocker.patch('freqtrade.exchange.Exchange.markets', markets) + mocker.patch('freqtrade.exchange.Exchange.precisionMode', + PropertyMock(return_value=precision_mode)) + pair = 'ETH/BTC' + assert pytest.approx(exchange.price_get_one_pip(pair, price)) == expected + + def test_set_sandbox(default_conf, mocker): """ Test working scenario From 99f3e9ed777c33ad537e799893d4675da8aa8aec Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Apr 2020 07:55:15 +0200 Subject: [PATCH 0899/1106] Remove wrong comment --- freqtrade/pairlist/PriceFilter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index 00c9d44c9..f0ba6cd7f 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -35,7 +35,6 @@ class PriceFilter(IPairList): """ Check if if one price-step (pip) is > than a certain barrier. :param ticker: ticker dict as returned from ccxt.load_markets() - :param precision: Precision :return: True if the pair can stay, false if it should be removed """ compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'], From 8314759228f019488df8e204b64ddc06dc0e0c0f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2020 12:14:35 +0000 Subject: [PATCH 0900/1106] Bump ccxt from 1.26.12 to 1.26.32 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.12 to 1.26.32. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.26.12...1.26.32) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a6a0fb78e..206e104ae 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.26.12 +ccxt==1.26.32 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 arrow==0.15.5 From 16a810a0f61e59bb29f35fdd2333427b63f6c1a2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2020 12:14:53 +0000 Subject: [PATCH 0901/1106] Bump jinja2 from 2.11.1 to 2.11.2 Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.1 to 2.11.2. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/2.11.1...2.11.2) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a6a0fb78e..e98540e18 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -12,7 +12,7 @@ jsonschema==3.2.0 TA-Lib==0.4.17 tabulate==0.8.7 pycoingecko==1.2.0 -jinja2==2.11.1 +jinja2==2.11.2 # find first, C search in arrays py_find_1st==1.1.4 From d36e2cf6ab85be1e0993f8ef69f67e117385dbf2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 16 Apr 2020 07:06:47 +0200 Subject: [PATCH 0902/1106] Fix random test failure in hyperopt --- freqtrade/optimize/hyperopt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index affd6f3b3..68e7032d9 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -665,7 +665,6 @@ class Hyperopt: self.dimensions: List[Dimension] = self.hyperopt_space() self.opt = self.get_optimizer(self.dimensions, config_jobs) - try: with Parallel(n_jobs=config_jobs) as parallel: jobs = parallel._effective_n_jobs() @@ -693,7 +692,7 @@ class Hyperopt: ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', ] with progressbar.ProgressBar( - maxval=self.total_epochs, redirect_stdout=True, redirect_stderr=True, + maxval=self.total_epochs, redirect_stdout=False, redirect_stderr=False, widgets=widgets ) as pbar: EVALS = ceil(self.total_epochs / jobs) From 1f70fcfa2da744b70f71190f575928c0c42ea6ca Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 16 Apr 2020 20:19:34 +0200 Subject: [PATCH 0903/1106] Update logmessage --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index b5c2ac4ee..8afe7d6f9 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -910,7 +910,7 @@ class FreqtradeBot: logger.info('Buy order %s for %s.', reason, trade) if safe_value_fallback(corder, order, 'remaining', 'remaining') == order['amount']: - logger.info('Buy order removed from database %s', trade) + logger.info('Buy order fully cancelled. Removing %s from database.', trade) # if trade is not partially completed, just delete the trade Trade.session.delete(trade) Trade.session.flush() From 7aba9bc62abc56bdebc2015316f6ac4c38064c5f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 06:22:25 +0200 Subject: [PATCH 0904/1106] Update freqtrade/data/converter.py Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- freqtrade/data/converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/converter.py b/freqtrade/data/converter.py index d2108b9be..0ef7955a4 100644 --- a/freqtrade/data/converter.py +++ b/freqtrade/data/converter.py @@ -174,7 +174,7 @@ def trades_dict_to_list(trades: List[Dict]) -> List[List]: :param trades: List of trades, as returned by ccxt.fetch_trades. :return: List of Lists, with constants.DEFAULT_TRADES_COLUMNS as columns """ - return [[t[col] for col in DEFAULT_TRADES_COLUMNS]for t in trades] + return [[t[col] for col in DEFAULT_TRADES_COLUMNS] for t in trades] def trades_to_ohlcv(trades: List, timeframe: str) -> DataFrame: From fc684b00917d2d135704e52a2974e0c5a272fb26 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 06:59:52 +0200 Subject: [PATCH 0905/1106] Ensure deleting filled is not raising an error if filled does not exist --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 213444f72..8865dd20b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1140,7 +1140,7 @@ class FreqtradeBot: new_amount = self.get_real_amount(trade, order, order_amount) if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): order['amount'] = new_amount - del order['filled'] + order.pop('filled', None) # Fee was applied, so set to 0 trade.fee_open = 0 trade.recalc_open_trade_price() From 800891a4759b3f2e96f3593be9471f089c7e2e92 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 07:18:46 +0200 Subject: [PATCH 0906/1106] Add tests for cancel_order_with_result --- freqtrade/exchange/exchange.py | 30 ++++++++++++++++++++++++++++++ tests/exchange/test_exchange.py | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index f2f8cd69f..412a60386 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -937,6 +937,36 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e + def is_cancel_order_result_suitable(self, corder) -> bool: + if not isinstance(corder, dict): + return False + + required = ('fee', 'status', 'amount') + return all(k in corder for k in required) + + def cancel_order_with_result(self, order_id: str, pair: str, amount: float) -> Dict: + """ + Cancel order returning a result. + Creates a fake result if cancel order returns a non-usable result + and get_order does not work (certain exchanges don't return cancelled orders) + :param order_id: Orderid to cancel + :param pair: Pair corresponding to order_id + :param amount: Amount to use for fake response + :return: Result from either cancel_order if usable, or fetch_order + """ + if self._config['dry_run']: + return {'fee': {}, 'status': 'canceled', 'amount': amount, 'info': {}} + corder = self.cancel_order(order_id, pair) + if self.is_cancel_order_result_suitable(corder): + return corder + try: + order = self.get_order(order_id, pair) + except InvalidOrderException: + logger.warning(f"Could not fetch cancelled order {order_id}.") + order = {'fee': {}, 'status': 'canceled', 'amount': amount, 'info': {}} + + return order + @retrier def get_order(self, order_id: str, pair: str) -> Dict: if self._config['dry_run']: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index b74ea1a6b..1f0df5aa5 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1745,6 +1745,20 @@ def test_check_order_canceled_empty(mocker, default_conf, exchange_name, order, assert exchange.check_order_canceled_empty(order) == result +@pytest.mark.parametrize("exchange_name", EXCHANGES) +@pytest.mark.parametrize("order,result", [ + ({'status': 'closed', 'amount': 10, 'fee': {}}, True), + ({'status': 'closed', 'amount': 0.0, 'fee': {}}, True), + ({'status': 'canceled', 'amount': 0.0, 'fee': {}}, True), + ({'status': 'canceled', 'amount': 10.0}, False), + ({'amount': 10.0, 'fee': {}}, False), + ({'result': 'testest123'}, False), + ('hello_world', False), +]) +def test_is_cancel_order_result_suitable(mocker, default_conf, exchange_name, order, result): + exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) + assert exchange.is_cancel_order_result_suitable(order) == result + # Ensure that if not dry_run, we should call API @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_cancel_order(default_conf, mocker, exchange_name): From 5e3e0e819f20869b4d3e9a04abe4cb3b040bede9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 17:53:18 +0200 Subject: [PATCH 0907/1106] Add tests for cancel_order_with_result --- freqtrade/exchange/exchange.py | 11 ++++++----- tests/exchange/test_exchange.py | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 412a60386..d3a520eaa 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -954,11 +954,12 @@ class Exchange: :param amount: Amount to use for fake response :return: Result from either cancel_order if usable, or fetch_order """ - if self._config['dry_run']: - return {'fee': {}, 'status': 'canceled', 'amount': amount, 'info': {}} - corder = self.cancel_order(order_id, pair) - if self.is_cancel_order_result_suitable(corder): - return corder + try: + corder = self.cancel_order(order_id, pair) + if self.is_cancel_order_result_suitable(corder): + return corder + except InvalidOrderException: + logger.warning(f"Could not cancel order {order_id}.") try: order = self.get_order(order_id, pair) except InvalidOrderException: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 1f0df5aa5..e3ab76b92 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1759,6 +1759,40 @@ def test_is_cancel_order_result_suitable(mocker, default_conf, exchange_name, or exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) assert exchange.is_cancel_order_result_suitable(order) == result + +@pytest.mark.parametrize("exchange_name", EXCHANGES) +@pytest.mark.parametrize("corder,call_corder,call_forder", [ + ({'status': 'closed', 'amount': 10, 'fee': {}}, 1, 0), + ({'amount': 10, 'fee': {}}, 1, 1), +]) +def test_cancel_order_with_result(default_conf, mocker, exchange_name, corder, + call_corder, call_forder): + default_conf['dry_run'] = False + api_mock = MagicMock() + api_mock.cancel_order = MagicMock(return_value=corder) + api_mock.fetch_order = MagicMock(return_value={}) + exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) + res = exchange.cancel_order_with_result('1234', 'ETH/BTC', 1234) + assert isinstance(res, dict) + assert api_mock.cancel_order.call_count == call_corder + assert api_mock.fetch_order.call_count == call_forder + + +@pytest.mark.parametrize("exchange_name", EXCHANGES) +def test_cancel_order_with_result_error(default_conf, mocker, exchange_name, caplog): + default_conf['dry_run'] = False + api_mock = MagicMock() + api_mock.cancel_order = MagicMock(side_effect=ccxt.InvalidOrder("Did not find order")) + api_mock.fetch_order = MagicMock(side_effect=ccxt.InvalidOrder("Did not find order")) + exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) + + res = exchange.cancel_order_with_result('1234', 'ETH/BTC', 1541) + assert isinstance(res, dict) + assert log_has("Could not cancel order 1234.", caplog) + assert log_has("Could not fetch cancelled order 1234.", caplog) + assert res['amount'] == 1541 + + # Ensure that if not dry_run, we should call API @pytest.mark.parametrize("exchange_name", EXCHANGES) def test_cancel_order(default_conf, mocker, exchange_name): From 1069cb3616001e44bdc17e68e36d46bb93544d4a Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 17:53:56 +0200 Subject: [PATCH 0908/1106] Use cancel_order_with_result when cancelling orders after timeout --- freqtrade/freqtradebot.py | 12 +++++------- tests/test_freqtradebot.py | 13 ++++++------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8865dd20b..f4aeba3fe 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -891,11 +891,8 @@ class FreqtradeBot: if order['status'] != 'canceled': reason = "cancelled due to timeout" try: - corder = self.exchange.cancel_order(trade.open_order_id, trade.pair) - # Some exchanges don't return a dict here. - if not isinstance(corder, dict): - corder = {} - logger.info('Buy order %s for %s.', reason, trade) + corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, + trade.amount) except InvalidOrderException: corder = {} logger.exception( @@ -904,7 +901,8 @@ class FreqtradeBot: # Order was cancelled already, so we can reuse the existing dict corder = order reason = "cancelled on exchange" - logger.info('Buy order %s for %s.', reason, trade) + + logger.info('Buy order %s for %s.', reason, trade) if safe_value_fallback(corder, order, 'remaining', 'remaining') == order['amount']: logger.info('Buy order fully cancelled. Removing %s from database.', trade) @@ -921,7 +919,7 @@ class FreqtradeBot: trade.amount = order['amount'] - safe_value_fallback(corder, order, 'remaining', 'remaining') trade.stake_amount = trade.amount * trade.open_rate - self.update_trade_state(trade, corder if 'fee' in corder else order, trade.amount) + self.update_trade_state(trade, corder, trade.amount) trade.open_order_id = None logger.info('Partial buy order timeout for %s.', trade) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 1102dd344..c3e78c9be 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1948,7 +1948,7 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, op 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old), - cancel_order=cancel_order_mock, + cancel_order_with_result=cancel_order_mock, get_fee=fee ) freqtrade = FreqtradeBot(default_conf) @@ -2055,7 +2055,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old, 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_order=MagicMock(return_value=limit_sell_order_old), - cancel_order=cancel_order_mock + cancel_order_with_result=cancel_order_mock ) freqtrade = FreqtradeBot(default_conf) @@ -2082,7 +2082,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), - cancel_order=cancel_order_mock + cancel_order_with_result=cancel_order_mock ) freqtrade = FreqtradeBot(default_conf) @@ -2109,7 +2109,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), - cancel_order=cancel_order_mock, + cancel_order_with_result=cancel_order_mock, get_trades_for_order=MagicMock(return_value=trades_for_order), ) freqtrade = FreqtradeBot(default_conf) @@ -2146,7 +2146,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_order=MagicMock(return_value=limit_buy_order_old_partial), - cancel_order=cancel_order_mock, + cancel_order_with_result=cancel_order_mock, get_trades_for_order=MagicMock(return_value=trades_for_order), ) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', @@ -2208,7 +2208,7 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order patch_RPCManager(mocker) patch_exchange(mocker) cancel_order_mock = MagicMock(return_value=limit_buy_order) - mocker.patch('freqtrade.exchange.Exchange.cancel_order', cancel_order_mock) + mocker.patch('freqtrade.exchange.Exchange.cancel_order_with_result', cancel_order_mock) freqtrade = FreqtradeBot(default_conf) @@ -2226,7 +2226,6 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException) assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) - assert log_has_re(r"Could not cancel buy order", caplog) @pytest.mark.parametrize('cancelorder', [ From 55af8bf26f33cca56cf9b0ccda4f088bb2c7ef83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 19:49:43 +0200 Subject: [PATCH 0909/1106] document to install hyperopt dependencies --- docs/hyperopt.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index c5055a3a8..825cc0267 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -16,6 +16,24 @@ To learn how to get data for the pairs and exchange you're interested in, head o !!! Bug Hyperopt can crash when used with only 1 CPU Core as found out in [Issue #1133](https://github.com/freqtrade/freqtrade/issues/1133) +## Install hyperopt dependencies + +Since Hyperopt dependencies are not needed to run a bot, they are not installed by default. + +### Docker + +The docker-image includes hyperopt dependencies, no further action needed + +!!! Note + Since Hyperopt is a resource intensive process, running it on a Raspberry Pi is not recommended, therefore the Raspberry image does not include Hyperopt dependencies. + +### Simple installation script (setup.sh) / Manual installation + +```bash +source .env/bin/activate +pip install -r requirements-hyperopt.txt +``` + ## Prepare Hyperopting Before we start digging into Hyperopt, we recommend you to take a look at From 0273539f0614d58578f354bbc55448152d5036c8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 19:55:53 +0200 Subject: [PATCH 0910/1106] Remove exceptionhandler, this exception is handled in cancel_with_response --- freqtrade/freqtradebot.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f4aeba3fe..65ba46987 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -890,13 +890,8 @@ class FreqtradeBot: """ if order['status'] != 'canceled': reason = "cancelled due to timeout" - try: - corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, - trade.amount) - except InvalidOrderException: - corder = {} - logger.exception( - f"Could not cancel buy order {trade.open_order_id} for pair {trade.pair}") + corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, + trade.amount) else: # Order was cancelled already, so we can reuse the existing dict corder = order From 506781f4102064651423a923c2342e931c08f3d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 17 Apr 2020 20:48:27 +0200 Subject: [PATCH 0911/1106] Reword hyperopt install docs --- docs/hyperopt.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 825cc0267..ad812a5ad 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -18,16 +18,16 @@ To learn how to get data for the pairs and exchange you're interested in, head o ## Install hyperopt dependencies -Since Hyperopt dependencies are not needed to run a bot, they are not installed by default. +Since Hyperopt dependencies are not needed to run the bot itself, are heavy, can not be easily built on some platforms (like Raspberry PI), they are not installed by default. Before you run Hyperopt, you need to install the corresponding dependencies, as described in this section below. + +!!! Note + Since Hyperopt is a resource intensive process, running it on a Raspberry Pi is not recommended nor supported. ### Docker -The docker-image includes hyperopt dependencies, no further action needed +The docker-image includes hyperopt dependencies, no further action needed. -!!! Note - Since Hyperopt is a resource intensive process, running it on a Raspberry Pi is not recommended, therefore the Raspberry image does not include Hyperopt dependencies. - -### Simple installation script (setup.sh) / Manual installation +### Easy installation script (setup.sh) / Manual installation ```bash source .env/bin/activate From 2f60d9cad4a6cc73542c6ff4f00d982241993f89 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 17 Apr 2020 23:23:22 +0300 Subject: [PATCH 0912/1106] minor: fix typo in the docs --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index d8a9653c3..338299781 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -34,7 +34,7 @@ The prevelance for all Options is as follows: - CLI arguments override any other option - Configuration files are used in sequence (last file wins), and override Strategy configurations. -- Strategy configurations are only used if they are not set via configuration or via command line arguments. These options are market with [Strategy Override](#parameters-in-the-strategy) in the below table. +- Strategy configurations are only used if they are not set via configuration or via command line arguments. These options are marked with [Strategy Override](#parameters-in-the-strategy) in the below table. Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways. From c775d6512670916f206d39d02ca2ec8dc52ecfd8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Apr 2020 06:55:25 +0200 Subject: [PATCH 0913/1106] Update typehint for cancel_order --- freqtrade/exchange/exchange.py | 4 ++-- tests/exchange/test_exchange.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index d3a520eaa..1a0565959 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -922,9 +922,9 @@ class Exchange: return order.get('status') in ('closed', 'canceled') and order.get('filled') == 0.0 @retrier - def cancel_order(self, order_id: str, pair: str) -> None: + def cancel_order(self, order_id: str, pair: str) -> Dict: if self._config['dry_run']: - return + return {} try: return self._api.cancel_order(order_id, pair) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index e3ab76b92..3c92612a0 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1728,7 +1728,7 @@ def test_get_historic_trades_notsupported(default_conf, mocker, caplog, exchange def test_cancel_order_dry_run(default_conf, mocker, exchange_name): default_conf['dry_run'] = True exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) - assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None + assert exchange.cancel_order(order_id='123', pair='TKN/BTC') == {} @pytest.mark.parametrize("exchange_name", EXCHANGES) From 76dd388b3cba461d48139599c9daf47a7d8e87bb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:25:17 +0000 Subject: [PATCH 0914/1106] Bump pytest-mock from 3.0.0 to 3.1.0 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.0.0...v3.1.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index ae240d7c8..d269676af 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -11,7 +11,7 @@ mypy==0.770 pytest==5.4.1 pytest-asyncio==0.10.0 pytest-cov==2.8.1 -pytest-mock==3.0.0 +pytest-mock==3.1.0 pytest-random-order==1.0.4 # Convert jupyter notebooks to markdown documents From 4742fc665733b719d68e1455fc31ceb1bb8ea66d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:26:09 +0000 Subject: [PATCH 0915/1106] Bump urllib3 from 1.25.8 to 1.25.9 Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.8 to 1.25.9. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/master/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.25.8...1.25.9) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index caf1c226a..6d49f3f89 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -6,7 +6,7 @@ python-telegram-bot==12.6.1 arrow==0.15.5 cachetools==4.1.0 requests==2.23.0 -urllib3==1.25.8 +urllib3==1.25.9 wrapt==1.12.1 jsonschema==3.2.0 TA-Lib==0.4.17 From d395d7ac7d94a0e16a1b32f76481a7fe481fe2c5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:26:31 +0000 Subject: [PATCH 0916/1106] Bump mkdocs-material from 5.1.0 to 5.1.1 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.0 to 5.1.1. - [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/5.1.0...5.1.1) Signed-off-by: dependabot-preview[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 138b6e862..1f8d710a9 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==5.1.0 +mkdocs-material==5.1.1 mdx_truly_sane_lists==1.2 From 84d09eb96da22cee3c1485ed6b5ead2c32ca4361 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:27:16 +0000 Subject: [PATCH 0917/1106] Bump questionary from 1.5.1 to 1.5.2 Bumps [questionary](https://github.com/tmbo/questionary) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/tmbo/questionary/releases) - [Commits](https://github.com/tmbo/questionary/compare/1.5.1...1.5.2) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index caf1c226a..133f961ae 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -29,5 +29,5 @@ flask==1.1.2 # Support for colorized terminal output colorama==0.4.3 # Building config files interactively -questionary==1.5.1 +questionary==1.5.2 prompt-toolkit==3.0.5 From 597f053ae3a9fa0ebc167c07a1098b2c9bdde42a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:27:37 +0000 Subject: [PATCH 0918/1106] Bump numpy from 1.18.2 to 1.18.3 Bumps [numpy](https://github.com/numpy/numpy) from 1.18.2 to 1.18.3. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt) - [Commits](https://github.com/numpy/numpy/compare/v1.18.2...v1.18.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b1a4b4403..967f8df10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Load common requirements -r requirements-common.txt -numpy==1.18.2 +numpy==1.18.3 pandas==1.0.3 From a7249f3865d5cca2d98c5a5c30c01fd094850a72 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:28:19 +0000 Subject: [PATCH 0919/1106] Bump ccxt from 1.26.32 to 1.26.53 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.32 to 1.26.53. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.26.32...1.26.53) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index caf1c226a..ccaaecc07 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.26.32 +ccxt==1.26.53 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 arrow==0.15.5 From 87f1060abc09c801ca2296c06f8c219353764bce Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 21 Apr 2020 19:47:49 +0200 Subject: [PATCH 0920/1106] Default docker to log into log-dir --- docker-compose.yml | 3 ++- freqtrade/configuration/directory_operations.py | 4 ++-- tests/test_directory_operations.py | 2 +- user_data/logs/.gitkeep | 0 4 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 user_data/logs/.gitkeep diff --git a/docker-compose.yml b/docker-compose.yml index 3a4c4c2db..49d83aa5e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,7 @@ version: '3' services: freqtrade: image: freqtradeorg/freqtrade:master + # image: freqtradeorg/freqtrade:develop # Build step - only needed when additional dependencies are needed # build: # context: . @@ -14,7 +15,7 @@ services: # Default command used when running `docker compose up` command: > trade - --logfile /freqtrade/user_data/freqtrade.log + --logfile /freqtrade/user_data/logs/freqtrade.log --db-url sqlite:////freqtrade/user_data/tradesv3.sqlite --config /freqtrade/user_data/config.json --strategy SampleStrategy diff --git a/freqtrade/configuration/directory_operations.py b/freqtrade/configuration/directory_operations.py index 5f8eb76b0..6b8c8cb5a 100644 --- a/freqtrade/configuration/directory_operations.py +++ b/freqtrade/configuration/directory_operations.py @@ -33,8 +33,8 @@ def create_userdata_dir(directory: str, create_dir: bool = False) -> Path: :param create_dir: Create directory if it does not exist. :return: Path object containing the directory """ - sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "notebooks", - "plot", "strategies", ] + sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "logs", + "notebooks", "plot", "strategies", ] folder = Path(directory) if not folder.is_dir(): if create_dir: diff --git a/tests/test_directory_operations.py b/tests/test_directory_operations.py index 889338a64..71c91549f 100644 --- a/tests/test_directory_operations.py +++ b/tests/test_directory_operations.py @@ -25,7 +25,7 @@ def test_create_userdata_dir(mocker, default_conf, caplog) -> None: md = mocker.patch.object(Path, 'mkdir', MagicMock()) x = create_userdata_dir('/tmp/bar', create_dir=True) - assert md.call_count == 8 + assert md.call_count == 9 assert md.call_args[1]['parents'] is False assert log_has(f'Created user-data directory: {Path("/tmp/bar")}', caplog) assert isinstance(x, Path) diff --git a/user_data/logs/.gitkeep b/user_data/logs/.gitkeep new file mode 100644 index 000000000..e69de29bb From 6b53197dfc820ae5ce899a869bdd37187b4368e2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 21 Apr 2020 20:42:58 +0200 Subject: [PATCH 0921/1106] Fix documentation to use --logfile, not --logfilename (which does not exist) --- docs/advanced-setup.md | 24 ++++++++++++------------ docs/faq.md | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/advanced-setup.md b/docs/advanced-setup.md index 2d3fe36f5..95480a2c6 100644 --- a/docs/advanced-setup.md +++ b/docs/advanced-setup.md @@ -37,30 +37,30 @@ as the watchdog. ## Advanced Logging -On many Linux systems the bot can be configured to send its log messages to `syslog` or `journald` system services. Logging to a remote `syslog` server is also available on Windows. The special values for the `--logfilename` command line option can be used for this. +On many Linux systems the bot can be configured to send its log messages to `syslog` or `journald` system services. Logging to a remote `syslog` server is also available on Windows. The special values for the `--logfile` command line option can be used for this. ### Logging to syslog -To send Freqtrade log messages to a local or remote `syslog` service use the `--logfilename` command line option with the value in the following format: +To send Freqtrade log messages to a local or remote `syslog` service use the `--logfile` command line option with the value in the following format: -* `--logfilename syslog:` -- send log messages to `syslog` service using the `` as the syslog address. +* `--logfile syslog:` -- send log messages to `syslog` service using the `` as the syslog address. The syslog address can be either a Unix domain socket (socket filename) or a UDP socket specification, consisting of IP address and UDP port, separated by the `:` character. So, the following are the examples of possible usages: -* `--logfilename syslog:/dev/log` -- log to syslog (rsyslog) using the `/dev/log` socket, suitable for most systems. -* `--logfilename syslog` -- same as above, the shortcut for `/dev/log`. -* `--logfilename syslog:/var/run/syslog` -- log to syslog (rsyslog) using the `/var/run/syslog` socket. Use this on MacOS. -* `--logfilename syslog:localhost:514` -- log to local syslog using UDP socket, if it listens on port 514. -* `--logfilename syslog::514` -- log to remote syslog at IP address and port 514. This may be used on Windows for remote logging to an external syslog server. +* `--logfile syslog:/dev/log` -- log to syslog (rsyslog) using the `/dev/log` socket, suitable for most systems. +* `--logfile syslog` -- same as above, the shortcut for `/dev/log`. +* `--logfile syslog:/var/run/syslog` -- log to syslog (rsyslog) using the `/var/run/syslog` socket. Use this on MacOS. +* `--logfile syslog:localhost:514` -- log to local syslog using UDP socket, if it listens on port 514. +* `--logfile syslog::514` -- log to remote syslog at IP address and port 514. This may be used on Windows for remote logging to an external syslog server. Log messages are send to `syslog` with the `user` facility. So you can see them with the following commands: * `tail -f /var/log/user`, or * install a comprehensive graphical viewer (for instance, 'Log File Viewer' for Ubuntu). -On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfilename syslog` or `--logfilename journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better. +On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfile syslog` or `--logfile journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better. For `rsyslog` the messages from the bot can be redirected into a separate dedicated log file. To achieve this, add ``` @@ -78,9 +78,9 @@ $RepeatedMsgReduction on This needs the `systemd` python package installed as the dependency, which is not available on Windows. Hence, the whole journald logging functionality is not available for a bot running on Windows. -To send Freqtrade log messages to `journald` system service use the `--logfilename` command line option with the value in the following format: +To send Freqtrade log messages to `journald` system service use the `--logfile` command line option with the value in the following format: -* `--logfilename journald` -- send log messages to `journald`. +* `--logfile journald` -- send log messages to `journald`. Log messages are send to `journald` with the `user` facility. So you can see them with the following commands: @@ -89,4 +89,4 @@ Log messages are send to `journald` with the `user` facility. So you can see the There are many other options in the `journalctl` utility to filter the messages, see manual pages for this utility. -On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfilename syslog` or `--logfilename journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better. +On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfile syslog` or `--logfile journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better. diff --git a/docs/faq.md b/docs/faq.md index 94818964b..8e8a1bf35 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -100,7 +100,7 @@ $ tail -f /path/to/mylogfile.log | grep 'something' ``` from a separate terminal window. -On Windows, the `--logfilename` option is also supported by Freqtrade and you can use the `findstr` command to search the log for the string of interest: +On Windows, the `--logfile` option is also supported by Freqtrade and you can use the `findstr` command to search the log for the string of interest: ``` > type \path\to\mylogfile.log | findstr "something" ``` From adf0bb69b8ecef7c974b8a29cb63ef2ebb1da826 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 22 Apr 2020 06:39:03 +0200 Subject: [PATCH 0922/1106] Update sql cheatsheet to allow manual closing trades correctly --- docs/sql_cheatsheet.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/sql_cheatsheet.md b/docs/sql_cheatsheet.md index f41520bd9..b7b38c3dc 100644 --- a/docs/sql_cheatsheet.md +++ b/docs/sql_cheatsheet.md @@ -67,22 +67,32 @@ SELECT * FROM trades; !!! Warning Manually selling a pair on the exchange will not be detected by the bot and it will try to sell anyway. Whenever possible, forcesell should be used to accomplish the same thing. - It is strongly advised to backup your database file before making any manual changes. + It is strongly advised to backup your database file before making any manual changes. !!! Note This should not be necessary after /forcesell, as forcesell orders are closed automatically by the bot on the next iteration. ```sql UPDATE trades -SET is_open=0, close_date=, close_rate=, close_profit=close_rate/open_rate-1, sell_reason= +SET is_open=0, + close_date=, + close_rate=, + close_profit=close_rate/open_rate-1, + close_profit_abs = (amount * * (1 - fee_close) - (amount * open_rate * 1 - fee_open), + sell_reason= WHERE id=; ``` -##### Example +### Example ```sql UPDATE trades -SET is_open=0, close_date='2017-12-20 03:08:45.103418', close_rate=0.19638016, close_profit=0.0496, sell_reason='force_sell' +SET is_open=0, + close_date='2017-12-20 03:08:45.103418', + close_rate=0.19638016, + close_profit=0.0496, + close_profit_abs = (amount * 0.19638016 * (1 - fee_close) - (amount * open_rate * 1 - fee_open) + sell_reason='force_sell' WHERE id=31; ``` @@ -99,10 +109,3 @@ VALUES ('bittrex', 'ETH/BTC', 1, 0.0025, 0.0025, , , Date: Wed, 22 Apr 2020 18:45:33 -0600 Subject: [PATCH 0923/1106] Update wording in expectancy docs and add example --- docs/edge.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/edge.md b/docs/edge.md index 721f570c7..029844c0b 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -79,7 +79,7 @@ So lets say your Win rate is 28% and your Risk Reward Ratio is 5: Expectancy = (5 X 0.28) – 0.72 = 0.68 ``` -Superficially, this means that on average you expect this strategy’s trades to return .68 times the size of your loses. This is important for two reasons: First, it may seem obvious, but you know right away that you have a positive return. Second, you now have a number you can compare to other candidate systems to make decisions about which ones you employ. +Superficially, this means that on average you expect this strategy’s trades to return 1.68 times the size of your loses. Said another way, you can expect to win $1.68 for every $1 you lose. This is important for two reasons: First, it may seem obvious, but you know right away that you have a positive return. Second, you now have a number you can compare to other candidate systems to make decisions about which ones you employ. It is important to remember that any system with an expectancy greater than 0 is profitable using past data. The key is finding one that will be profitable in the future. From 461b0ef7381c0ca4cdcb37de6888b3e22ab582e6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Apr 2020 20:03:59 +0200 Subject: [PATCH 0924/1106] Add test verifying we're not reintroducing this in the future Tests case of FTX, which returns mostly empty ticker info --- tests/conftest.py | 48 +++++++++++++++++++++++++++++++++ tests/pairlist/test_pairlist.py | 9 +++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 62c1d7046..d95475b8c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -739,6 +739,31 @@ def shitcoinmarkets(markets): "future": False, "active": True }, + 'ADAHALF/USDT': { + "percentage": True, + "tierBased": False, + "taker": 0.001, + "maker": 0.001, + "precision": { + "base": 8, + "quote": 8, + "amount": 2, + "price": 4 + }, + "limits": { + }, + "id": "ADAHALFUSDT", + "symbol": "ADAHALF/USDT", + "base": "ADAHALF", + "quote": "USDT", + "baseId": "ADAHALF", + "quoteId": "USDT", + "info": {}, + "type": "spot", + "spot": True, + "future": False, + "active": True + }, }) return shitmarkets @@ -1243,6 +1268,29 @@ def tickers(): "quoteVolume": 323652.075405, "info": {} }, + # Example of leveraged pair with incomplete info + "ADAHALF/USDT": { + "symbol": "ADAHALF/USDT", + "timestamp": 1580469388244, + "datetime": "2020-01-31T11:16:28.244Z", + "high": None, + "low": None, + "bid": 0.7305, + "bidVolume": None, + "ask": 0.7342, + "askVolume": None, + "vwap": None, + "open": None, + "close": None, + "last": None, + "previousClose": None, + "change": None, + "percentage": 2.628, + "average": None, + "baseVolume": 0.0, + "quoteVolume": 0.0, + "info": {} + }, }) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 6275bdafc..9184beaa0 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -163,7 +163,7 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}], "BTC", ['HOT/BTC', 'FUEL/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']), ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}], - "USDT", ['ETH/USDT', 'NANO/USDT']), + "USDT", ['ETH/USDT', 'NANO/USDT', 'ADAHALF/USDT']), # No pair for ETH ... ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}], "ETH", []), @@ -177,6 +177,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}, {"method": "PriceFilter", "low_price_ratio": 0.03}], "BTC", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC']), + # PriceFilter and VolumePairList + ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}, + {"method": "PriceFilter", "low_price_ratio": 0.03}], + "USDT", ['ETH/USDT', 'NANO/USDT']), # Hot is removed by precision_filter, Fuel by low_price_filter. ([{"method": "VolumePairList", "number_assets": 6, "sort_key": "quoteVolume"}, {"method": "PrecisionFilter"}, @@ -221,7 +225,8 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t assert log_has_re(r'^Removed .* from whitelist, because stop price .* ' r'would be <= stop limit.*', caplog) if pairlist['method'] == 'PriceFilter': - assert log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog) + assert (log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog) or + log_has_re(r"^Removed .* from whitelist, because 'last' is empty.*", caplog)) def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None: From f4995780e5c15c8b270a3118bed0a1215557c05c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 23 Apr 2020 20:04:36 +0200 Subject: [PATCH 0925/1106] Verify last is not None - to avoid crashing fix #3117 --- freqtrade/pairlist/PriceFilter.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index 0f7e0782f..31d0eec58 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -37,6 +37,12 @@ class PriceFilter(IPairList): :param ticker: ticker dict as returned from ccxt.load_markets() :return: True if the pair can stay, false if it should be removed """ + if ticker['last'] is None: + + self.log_on_refresh(logger.info, + f"Removed {ticker['symbol']} from whitelist, " + "because 'last' is empty (Usually no trade in the last 24h).") + return False compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'], ticker['last']) changeperc = (compare - ticker['last']) / ticker['last'] @@ -47,7 +53,6 @@ class PriceFilter(IPairList): return True def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: - """ Filters and sorts pairlist and returns the whitelist again. Called on each bot iteration - please use internal caching if necessary From 9627604ec3d13ada6aa50f77b5cb4e8be6456523 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 24 Apr 2020 07:57:43 +0200 Subject: [PATCH 0926/1106] change wording of log message --- freqtrade/pairlist/PriceFilter.py | 4 ++-- tests/pairlist/test_pairlist.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index 31d0eec58..2f7e98e24 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -40,8 +40,8 @@ class PriceFilter(IPairList): if ticker['last'] is None: self.log_on_refresh(logger.info, - f"Removed {ticker['symbol']} from whitelist, " - "because 'last' is empty (Usually no trade in the last 24h).") + f"Removed {ticker['symbol']} from whitelist, because " + "ticker['last'] is empty (Usually no trade in the last 24h).") return False compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'], ticker['last']) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 9184beaa0..7dfe8bcca 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -226,7 +226,8 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t r'would be <= stop limit.*', caplog) if pairlist['method'] == 'PriceFilter': assert (log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog) or - log_has_re(r"^Removed .* from whitelist, because 'last' is empty.*", caplog)) + log_has_re(r"^Removed .* from whitelist, because ticker\['last'\] is empty.*", + caplog)) def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None: From 5c012d79eb284a9f44dd46c93d235a64319b7934 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 24 Apr 2020 18:14:07 +0300 Subject: [PATCH 0927/1106] Remove unused method --- freqtrade/optimize/hyperopt.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 68e7032d9..61e2a9b6f 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -293,21 +293,6 @@ class Hyperopt: self.hyperopt_table_header = 2 return output - @staticmethod - def print_results_explanation(results, total_epochs, highlight_best: bool, - print_colorized: bool) -> None: - """ - Log results explanation string - """ - explanation_str = Hyperopt._format_explanation_string(results, total_epochs) - # Colorize output - if print_colorized: - if results['total_profit'] > 0: - explanation_str = Fore.GREEN + explanation_str - if highlight_best and results['is_best']: - explanation_str = Style.BRIGHT + explanation_str - print(explanation_str) - @staticmethod def _format_explanation_string(results, total_epochs) -> str: return (("*" if results['is_initial_point'] else " ") + From 6e5f0869b33ac4e5059f9b96b80fb880e9be225a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 24 Apr 2020 18:39:08 +0300 Subject: [PATCH 0928/1106] Remove another unused method --- freqtrade/optimize/hyperopt.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 61e2a9b6f..fcf50af6a 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -277,22 +277,6 @@ class Hyperopt: ) self.hyperopt_table_header = 2 - def get_results(self, results) -> str: - """ - Log results if it is better than any previous evaluation - """ - output = '' - is_best = results['is_best'] - - if self.print_all or is_best: - output = self.get_result_table( - self.config, results, self.total_epochs, - self.print_all, self.print_colorized, - self.hyperopt_table_header - ) - self.hyperopt_table_header = 2 - return output - @staticmethod def _format_explanation_string(results, total_epochs) -> str: return (("*" if results['is_initial_point'] else " ") + From 2d994f6feb137edc224a47c0b48d95fb12ddf4fa Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 24 Apr 2020 21:57:29 +0300 Subject: [PATCH 0929/1106] Better printing of asterisk --- 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 fcf50af6a..ea27430ee 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -304,8 +304,9 @@ class Hyperopt: trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] trials['is_profit'] = False - trials.loc[trials['is_initial_point'], 'Best'] = '*' + trials.loc[trials['is_initial_point'], 'Best'] = '* ' trials.loc[trials['is_best'], 'Best'] = 'Best' + trials.loc[trials['is_initial_point'] & trials['is_best'], 'Best'] = '* Best' trials.loc[trials['Total profit'] > 0, 'is_profit'] = True trials['Trades'] = trials['Trades'].astype(str) From c230a94d553a5b38c7118bff7ccb1a7e374f5442 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 25 Apr 2020 11:23:54 +0300 Subject: [PATCH 0930/1106] Fix #3065 --- docs/hyperopt.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index ad812a5ad..30a22a969 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -6,9 +6,7 @@ algorithms included in the `scikit-optimize` package to accomplish this. The search will burn all your CPU cores, make your laptop sound like a fighter jet and still take a long time. -In general, the search for best parameters starts with a few random combinations and then uses Bayesian search with a -ML regressor algorithm (currently ExtraTreesRegressor) to quickly find a combination of parameters in the search hyperspace -that minimizes the value of the [loss function](#loss-functions). +In general, the search for best parameters starts with a few random combinations (see [below](#reproducible-results) for more details) and then uses Bayesian search with a ML regressor algorithm (currently ExtraTreesRegressor) to quickly find a combination of parameters in the search hyperspace that minimizes the value of the [loss function](#loss-functions). Hyperopt requires historic data to be available, just as backtesting does. To learn how to get data for the pairs and exchange you're interested in, head over to the [Data Downloading](data-download.md) section of the documentation. @@ -311,7 +309,7 @@ You can also enable position stacking in the configuration file by explicitly se ### Reproducible results -The search for optimal parameters starts with a few (currently 30) random combinations in the hyperspace of parameters, random Hyperopt epochs. These random epochs are marked with a leading asterisk sign at the Hyperopt output. +The search for optimal parameters starts with a few (currently 30) random combinations in the hyperspace of parameters, random Hyperopt epochs. These random epochs are marked with an asterisk character (`*`) in the first column in the Hyperopt output. The initial state for generation of these random values (random state) is controlled by the value of the `--random-state` command line option. You can set it to some arbitrary value of your choice to obtain reproducible results. From d9f255a6c07809ea28981e39c3bb576f1394461a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 25 Apr 2020 12:49:14 +0300 Subject: [PATCH 0931/1106] Fix asterisk printing for csv output --- freqtrade/optimize/hyperopt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ea27430ee..79b6b8cb0 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -397,6 +397,7 @@ class Hyperopt: trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' trials.loc[trials['is_best'], 'Best'] = 'Best' + trials.loc[trials['is_initial_point'] & trials['is_best'], 'Best'] = '* Best' trials.loc[trials['Total profit'] > 0, 'is_profit'] = True trials['Epoch'] = trials['Epoch'].astype(str) trials['Trades'] = trials['Trades'].astype(str) From 8987859044df53cda8086a72d792d22635b93d87 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 15:37:13 +0200 Subject: [PATCH 0932/1106] Enable pairlist parsing for backtesting and hyperopt --- freqtrade/optimize/backtesting.py | 11 ++++++-- tests/optimize/test_backtesting.py | 40 ++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index f29f599a6..c01e3de50 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -20,6 +20,7 @@ from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.optimize.optimize_reports import (show_backtest_results, store_backtest_result) +from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.state import RunMode @@ -63,10 +64,16 @@ class Backtesting: self.strategylist: List[IStrategy] = [] self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) + self.pairlists = PairListManager(self.exchange, self.config) + self.pairlists.refresh_pairlist() + + if len(self.pairlists.whitelist) == 0: + raise OperationalException("No pair in whitelist.") + if config.get('fee'): self.fee = config['fee'] else: - self.fee = self.exchange.get_fee(symbol=self.config['exchange']['pair_whitelist'][0]) + self.fee = self.exchange.get_fee(symbol=self.pairlists.whitelist[0]) if self.config.get('runmode') != RunMode.HYPEROPT: self.dataprovider = DataProvider(self.config, self.exchange) @@ -111,7 +118,7 @@ class Backtesting: data = history.load_data( datadir=self.config['datadir'], - pairs=self.config['exchange']['pair_whitelist'], + pairs=self.pairlists.whitelist, timeframe=self.timeframe, timerange=timerange, startup_candles=self.required_startup, diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 1c4d3b16a..862dbe3aa 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -2,7 +2,7 @@ import random from pathlib import Path -from unittest.mock import MagicMock +from unittest.mock import MagicMock, PropertyMock import numpy as np import pandas as pd @@ -10,8 +10,9 @@ import pytest from arrow import Arrow from freqtrade import constants +from freqtrade.commands.optimize_commands import (setup_optimize_configuration, + start_backtesting) from freqtrade.configuration import TimeRange -from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_backtesting from freqtrade.data import history from freqtrade.data.btanalysis import evaluate_result_multi from freqtrade.data.converter import clean_ohlcv_dataframe @@ -333,8 +334,9 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None: patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') mocker.patch('freqtrade.optimize.backtesting.show_backtest_results') + mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', + PropertyMock(return_value=['UNITTEST/BTC'])) - default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = '1m' default_conf['datadir'] = testdatadir default_conf['export'] = None @@ -362,9 +364,9 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> mocker.patch('freqtrade.data.history.get_timerange', get_timerange) patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') - mocker.patch('freqtrade.optimize.backtesting.show_backtest_results') + mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', + PropertyMock(return_value=['UNITTEST/BTC'])) - default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] default_conf['ticker_interval'] = "1m" default_conf['datadir'] = testdatadir default_conf['export'] = None @@ -375,6 +377,27 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> backtesting.start() +def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) -> None: + def get_timerange(input1): + return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) + + mocker.patch('freqtrade.data.history.history_utils.load_pair_history', + MagicMock(return_value=pd.DataFrame())) + mocker.patch('freqtrade.data.history.get_timerange', get_timerange) + patch_exchange(mocker) + mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') + mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', + PropertyMock(return_value=[])) + + default_conf['ticker_interval'] = "1m" + default_conf['datadir'] = testdatadir + default_conf['export'] = None + default_conf['timerange'] = '20180101-20180102' + + with pytest.raises(OperationalException, match='No pair in whitelist.'): + Backtesting(default_conf) + + def test_backtest(default_conf, fee, mocker, testdatadir) -> None: default_conf['ask_strategy']['use_sell_signal'] = False mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) @@ -585,12 +608,12 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): - default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) mocker.patch('freqtrade.optimize.backtesting.show_backtest_results', MagicMock()) - + mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', + PropertyMock(return_value=['UNITTEST/BTC'])) patched_configuration_load_config_file(mocker, default_conf) args = [ @@ -625,10 +648,11 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): - default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] patch_exchange(mocker) backtestmock = MagicMock() + mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', + PropertyMock(return_value=['UNITTEST/BTC'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) gen_table_mock = MagicMock() mocker.patch('freqtrade.optimize.optimize_reports.generate_text_table', gen_table_mock) From 57345476abf5992fca61d4537cef95e7e206cb48 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 15:38:20 +0200 Subject: [PATCH 0933/1106] Document pairlists for backtesting --- docs/backtesting.md | 8 ++++++-- docs/configuration.md | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 3d08d5332..d6775e17c 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -17,8 +17,12 @@ For details on downloading, please refer to the [Data Downloading](data-download The result of backtesting will confirm if your bot has better odds of making a profit than a loss. -!!! Tip "Using dynamic pairlists for backtesting" - While using dynamic pairlists during backtesting is not possible, a dynamic pairlist using current data can be generated via the [`test-pairlist`](utils.md#test-pairlist) command, and needs to be specified as `"pair_whitelist"` attribute in the configuration. +!!! Warning "Using dynamic pairlists for backtesting" + Using dynamic pairlists is possible, however it relies on the current market conditions - which will not reflect the historic status of the pairlist. + Also, when using pairlists other than StaticPairlist, reproducability of backtesting-results cannot be guaranteed. + Please read the [pairlists documentation](configuration.md#pairlists) for more information. + + To achieve reproducible results, best generate a pairlist via the [`test-pairlist`](utils.md#test-pairlist) command and use that as static pairlist. ### Run a backtesting against the currencies listed in your config file diff --git a/docs/configuration.md b/docs/configuration.md index 338299781..3de89301f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -544,7 +544,6 @@ A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly. It is therefore advised to not use this setting for dry-runs. - #### 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. @@ -622,6 +621,7 @@ Min price precision is 8 decimals. If price is 0.00000011 - one step would be 0. These pairs are dangerous since it may be impossible to place the desired stoploss - and often result in high losses. #### Spread Filter + Removes pairs that have a difference between asks and bids above the specified ratio (default `0.005`). Example: If `DOGE/BTC` maximum bid is 0.00000026 and minimum ask is 0.00000027 the ratio is calculated as: `1 - bid/ask ~= 0.037` which is `> 0.005` From e8530c36d3a8bcf92d509d98d1ba6459a656a399 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 15:46:20 +0200 Subject: [PATCH 0934/1106] Remove pairlists from hyperopt too (it holds a reference to exchange) --- freqtrade/optimize/hyperopt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index fcf50af6a..f9dddd573 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -624,6 +624,7 @@ class Hyperopt: # We don't need exchange instance anymore while running hyperopt self.backtesting.exchange = None # type: ignore + self.backtesting.pairlists = None # type: ignore self.trials = self.load_previous_results(self.trials_file) From a3a045dbd4a650b35d1430ab4609bd1947354a01 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 15:54:23 +0200 Subject: [PATCH 0935/1106] Add small section noting that a strategy file is always necessary fix #3047 --- docs/hyperopt.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 30a22a969..55d2d984c 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -63,6 +63,9 @@ Optional - can also be loaded from a strategy: !!! Note Assuming the optional methods are not in your hyperopt file, please use `--strategy AweSomeStrategy` which contains these methods so hyperopt can use these methods instead. +!!! Note + You will always have to provide a strategy to Hyperopt even if it contains all methods. + Rarely you may also need to override: * `roi_space` - for custom ROI optimization (if you need the ranges for the ROI parameters in the optimization hyperspace that differ from default) From d1a24db6b7bce1eb118f9fd19fb5017049f958cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 16:04:10 +0200 Subject: [PATCH 0936/1106] Remove deprecated pairlist and binary --- bin/freqtrade | 11 --------- docs/deprecated.md | 6 +++++ .../configuration/deprecated_settings.py | 23 ------------------- tests/test_configuration.py | 12 ---------- 4 files changed, 6 insertions(+), 46 deletions(-) delete mode 100755 bin/freqtrade diff --git a/bin/freqtrade b/bin/freqtrade deleted file mode 100755 index eee7cbef4..000000000 --- a/bin/freqtrade +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import logging - -logger = logging.getLogger(__name__) - - -logger.error("DEPRECATED installation detected, please run `pip install -e .` again.") - -sys.exit(2) diff --git a/docs/deprecated.md b/docs/deprecated.md index 349d41a09..a9a914f44 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -24,3 +24,9 @@ and in freqtrade 2019.7 (master branch). `--live` in the context of backtesting allowed to download the latest tick data for backtesting. Did only download the latest 500 candles, so was ineffective in getting good backtest data. Removed in 2019-7-dev (develop branch) and in freqtrade 2019-8 (master branch) + +### Allow running multiple pairlists in sequence + +The former `"pairlists"` section in the configuration has been removed, and is replaced by `pairlist` - being a list to specify a sequence of pairlists. + +The old option has been deprecated in 2019.11 and has been removed in 2020.4. diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index 55497d4f5..3999ea422 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -58,29 +58,6 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: process_deprecated_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal', 'experimental', 'ignore_roi_if_buy_signal') - if not config.get('pairlists') and not config.get('pairlists'): - config['pairlists'] = [{'method': 'StaticPairList'}] - logger.warning( - "DEPRECATED: " - "Pairlists must be defined explicitly in the future." - "Defaulting to StaticPairList for now.") - - if config.get('pairlist', {}).get("method") == 'VolumePairList': - logger.warning( - "DEPRECATED: " - f"Using VolumePairList in pairlist is deprecated and must be moved to pairlists. " - "Please refer to the docs on configuration details") - pl = {'method': 'VolumePairList'} - pl.update(config.get('pairlist', {}).get('config')) - config['pairlists'].append(pl) - - if config.get('pairlist', {}).get('config', {}).get('precision_filter'): - logger.warning( - "DEPRECATED: " - f"Using precision_filter setting is deprecated and has been replaced by" - "PrecisionFilter. Please refer to the docs on configuration details") - config['pairlists'].append({'method': 'PrecisionFilter'}) - if (config.get('edge', {}).get('enabled', False) and 'capital_available_percentage' in config.get('edge', {})): logger.warning( diff --git a/tests/test_configuration.py b/tests/test_configuration.py index f29f2eaf2..c89f1381e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1041,18 +1041,6 @@ def test_process_temporary_deprecated_settings(mocker, default_conf, setting, ca assert default_conf[setting[0]][setting[1]] == setting[5] -def test_process_deprecated_setting_pairlists(mocker, default_conf, caplog): - patched_configuration_load_config_file(mocker, default_conf) - default_conf.update({'pairlist': { - 'method': 'VolumePairList', - 'config': {'precision_filter': True} - }}) - - process_temporary_deprecated_settings(default_conf) - assert log_has_re(r'DEPRECATED.*precision_filter.*', caplog) - assert log_has_re(r'DEPRECATED.*in pairlist is deprecated and must be moved*', caplog) - - def test_process_deprecated_setting_edge(mocker, edge_conf, caplog): patched_configuration_load_config_file(mocker, edge_conf) edge_conf.update({'edge': { From 9fa21628d7cf77fe81dca35373b9caa21c0c6515 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 16:29:17 +0200 Subject: [PATCH 0937/1106] Deprecate keys other than quoteVolume fixes #2981 --- docs/configuration.md | 4 +--- docs/deprecated.md | 6 +++++- freqtrade/pairlist/VolumePairList.py | 4 ++++ tests/pairlist/test_pairlist.py | 13 ++++++++++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 338299781..2942014be 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -585,7 +585,7 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis #### Volume Pair List -`VolumePairList` selects `number_assets` top pairs based on `sort_key`, which can be one of `askVolume`, `bidVolume` and `quoteVolume` and defaults to `quoteVolume`. +`VolumePairList` selects `number_assets` top pairs based on `sort_key`, which can only be `quoteVolume`. `VolumePairList` considers outputs of previous pairlists unless it's the first configured pairlist, it does not consider `pair_whitelist`, but selects the top assets from all available markets (with matching stake-currency) on the exchange. @@ -593,8 +593,6 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis `VolumePairList` is based on the ticker data, as reported by the ccxt library: -* The `bidVolume` is the volume (amount) of current best bid in the orderbook. -* The `askVolume` is the volume (amount) of current best ask in the orderbook. * The `quoteVolume` is the amount of quote (stake) currency traded (bought or sold) in last 24 hours. ```json diff --git a/docs/deprecated.md b/docs/deprecated.md index a9a914f44..408c7b2ac 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -27,6 +27,10 @@ Removed in 2019-7-dev (develop branch) and in freqtrade 2019-8 (master branch) ### Allow running multiple pairlists in sequence -The former `"pairlists"` section in the configuration has been removed, and is replaced by `pairlist` - being a list to specify a sequence of pairlists. +The former `"pairlist"` section in the configuration has been removed, and is replaced by `pairlists` - being a list to specify a sequence of pairlists. The old option has been deprecated in 2019.11 and has been removed in 2020.4. + +### deprecation of bidVolume and askVolume from volumepairlist + +Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4. diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 65f43245c..eb44fe725 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -39,6 +39,10 @@ class VolumePairList(IPairList): if not self._validate_keys(self._sort_key): raise OperationalException( f'key {self._sort_key} not in {SORT_VALUES}') + if self._sort_key != 'quoteVolume': + logger.warning( + "DEPRECATED: using any key other than quoteVolume for VolumePairList is deprecated." + ) @property def needstickers(self) -> bool: diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 7dfe8bcca..f9e2893c3 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -4,11 +4,11 @@ from unittest.mock import MagicMock, PropertyMock import pytest -from freqtrade.exceptions import OperationalException from freqtrade.constants import AVAILABLE_PAIRLISTS -from freqtrade.resolvers import PairListResolver +from freqtrade.exceptions import OperationalException from freqtrade.pairlist.pairlistmanager import PairListManager -from tests.conftest import get_patched_freqtradebot, log_has_re +from freqtrade.resolvers import PairListResolver +from tests.conftest import get_patched_freqtradebot, log_has, log_has_re # whitelist, blacklist @@ -228,6 +228,13 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t assert (log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog) or log_has_re(r"^Removed .* from whitelist, because ticker\['last'\] is empty.*", caplog)) + if pairlist['method'] == 'VolumePairList': + logmsg = ("DEPRECATED: using any key other than quoteVolume for " + "VolumePairList is deprecated.") + if pairlist['sort_key'] != 'quoteVolume': + assert log_has(logmsg, caplog) + else: + assert not log_has(logmsg, caplog) def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None: From deb14e0c8522da23bd2a4b487d6afa4187b4015a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 16:32:11 +0200 Subject: [PATCH 0938/1106] Update "final" message in setup.sh closes #2773 --- setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index e120190ce..d6e0006f1 100755 --- a/setup.sh +++ b/setup.sh @@ -252,7 +252,8 @@ function install() { echo "-------------------------" echo "Run the bot !" echo "-------------------------" - echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade trade'." + echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade '." + echo "You verify that freqtrade is installed successfully by running 'source .env/bin/activate; freqtrade --version'." } function plot() { From e1a347df90efa8517dc9a0e51bc144403ba53a43 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 16:55:13 +0200 Subject: [PATCH 0939/1106] Use subcommand, add 3rd line --- setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index d6e0006f1..918c41e6b 100755 --- a/setup.sh +++ b/setup.sh @@ -252,7 +252,8 @@ function install() { echo "-------------------------" echo "Run the bot !" echo "-------------------------" - echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade '." + echo "You can now use the bot by executing 'source .env/bin/activate; freqtrade '." + echo "You can see the list of available bot subcommands by executing 'source .env/bin/activate; freqtrade --help'." echo "You verify that freqtrade is installed successfully by running 'source .env/bin/activate; freqtrade --version'." } From 255a43c98e75d18fe0a6bc04c513467c7ce85ffe Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 25 Apr 2020 17:25:18 +0200 Subject: [PATCH 0940/1106] Update price timeout example --- docs/strategy-advanced.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index dcb8018f9..39e92d651 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -56,7 +56,6 @@ class Awesomestrategy(IStrategy): !!! Note For the above example, `unfilledtimeout` must be set to something bigger than 24h, otherwise that type of timeout will apply first. - ### Custom order timeout example (using additional data) ``` python @@ -77,7 +76,7 @@ class Awesomestrategy(IStrategy): ob = self.dp.orderbook(pair, 1) current_price = ob['bids'][0][0] # Cancel buy order if price is more than 2% above the order. - if order['price'] > current_price * 1.02: + if current_price > order['price'] * 1.02: return True return False @@ -86,7 +85,7 @@ class Awesomestrategy(IStrategy): ob = self.dp.orderbook(pair, 1) current_price = ob['asks'][0][0] # Cancel sell order if price is more than 2% below the order. - if order['price'] < current_price * 0.98: + if current_price < order['price'] * 0.98: return True return False ``` From e928c5fdaf3c46588ecb427427ff2c848104d16b Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 27 Apr 2020 07:15:37 +0200 Subject: [PATCH 0941/1106] Update docs/hyperopt.md Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/hyperopt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 55d2d984c..11161e58b 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -64,7 +64,7 @@ Optional - can also be loaded from a strategy: Assuming the optional methods are not in your hyperopt file, please use `--strategy AweSomeStrategy` which contains these methods so hyperopt can use these methods instead. !!! Note - You will always have to provide a strategy to Hyperopt even if it contains all methods. + You always have to provide a strategy to Hyperopt, even if your custom Hyperopt class contains all methods. Rarely you may also need to override: From fb8a85da01e7a0c108a3a132e313cb4a7bb79224 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 27 Apr 2020 07:56:17 +0200 Subject: [PATCH 0942/1106] Disallow VolumePairList from backtesting for now --- freqtrade/optimize/backtesting.py | 3 +++ tests/optimize/test_backtesting.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index c01e3de50..3bf211d99 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -65,6 +65,9 @@ class Backtesting: self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) self.pairlists = PairListManager(self.exchange, self.config) + if 'VolumePairList' in self.pairlists.name_list: + raise OperationalException("VolumePairList not allowed for backtesting.") + self.pairlists.refresh_pairlist() if len(self.pairlists.whitelist) == 0: diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 862dbe3aa..6c2d6c9dd 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -378,9 +378,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) -> def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) -> None: - def get_timerange(input1): - return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59) - + mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True)) mocker.patch('freqtrade.data.history.history_utils.load_pair_history', MagicMock(return_value=pd.DataFrame())) mocker.patch('freqtrade.data.history.get_timerange', get_timerange) @@ -397,6 +395,10 @@ def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) -> with pytest.raises(OperationalException, match='No pair in whitelist.'): Backtesting(default_conf) + default_conf['pairlists'] = [{"method": "VolumePairList", "number_assets": 5}] + with pytest.raises(OperationalException, match='VolumePairList not allowed for backtesting.'): + Backtesting(default_conf) + def test_backtest(default_conf, fee, mocker, testdatadir) -> None: default_conf['ask_strategy']['use_sell_signal'] = False From 77a2ff8917e37271f906d92dde9e2b622c56cbd1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 09:02:21 +0000 Subject: [PATCH 0943/1106] Bump ccxt from 1.26.53 to 1.27.1 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.53 to 1.27.1. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.26.53...1.27.1) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 861c3bdd5..a53fc3999 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.26.53 +ccxt==1.27.1 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 arrow==0.15.5 From 2122384ec1c1f072870ca39ea47d765930d735e5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 09:02:49 +0000 Subject: [PATCH 0944/1106] Bump progressbar2 from 3.50.1 to 3.51.0 Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.50.1 to 3.51.0. - [Release notes](https://github.com/WoLpH/python-progressbar/releases) - [Changelog](https://github.com/WoLpH/python-progressbar/blob/develop/CHANGES.rst) - [Commits](https://github.com/WoLpH/python-progressbar/compare/v3.50.1...v3.51.0) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 6df1eb157..b0e18867d 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -7,4 +7,4 @@ scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 -progressbar2==3.50.1 +progressbar2==3.51.0 From 52c92a19e320ca6fb5be23fab736d35b44e80d0b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 09:03:30 +0000 Subject: [PATCH 0945/1106] Bump pytest-asyncio from 0.10.0 to 0.11.0 Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.10.0 to 0.11.0. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.10.0...v0.11.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index d269676af..508716bde 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,7 +9,7 @@ flake8-type-annotations==0.1.0 flake8-tidy-imports==4.1.0 mypy==0.770 pytest==5.4.1 -pytest-asyncio==0.10.0 +pytest-asyncio==0.11.0 pytest-cov==2.8.1 pytest-mock==3.1.0 pytest-random-order==1.0.4 From abbb3254b2ed287604587c2be5ac5fccddd5c8d3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 09:03:59 +0000 Subject: [PATCH 0946/1106] Bump mkdocs-material from 5.1.1 to 5.1.3 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.1 to 5.1.3. - [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/5.1.1...5.1.3) Signed-off-by: dependabot-preview[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 1f8d710a9..1c0e280ae 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==5.1.1 +mkdocs-material==5.1.3 mdx_truly_sane_lists==1.2 From 3754bf46ed8b028101a07df96a2a3efc338f4fb7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 27 Apr 2020 17:13:30 +0200 Subject: [PATCH 0947/1106] Change wording in deprecation messages Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/deprecated.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/deprecated.md b/docs/deprecated.md index 408c7b2ac..a7b57b10e 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -27,9 +27,9 @@ Removed in 2019-7-dev (develop branch) and in freqtrade 2019-8 (master branch) ### Allow running multiple pairlists in sequence -The former `"pairlist"` section in the configuration has been removed, and is replaced by `pairlists` - being a list to specify a sequence of pairlists. +The former `"pairlist"` section in the configuration has been removed, and is replaced by `"pairlists"` - being a list to specify a sequence of pairlists. -The old option has been deprecated in 2019.11 and has been removed in 2020.4. +The old section of configuration parameters (`"pairlist"`) has been deprecated in 2019.11 and has been removed in 2020.4. ### deprecation of bidVolume and askVolume from volumepairlist From a01ed170f55a2a2cf07b4b5fcc721933308dc623 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 28 Apr 2020 17:33:07 +0300 Subject: [PATCH 0948/1106] Improve hyperopt-list logging --- freqtrade/optimize/hyperopt.py | 6 +++--- tests/commands/test_commands.py | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ad9d7d44c..1e8077f10 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -376,13 +376,13 @@ class Hyperopt: # Verification for overwrite if path.isfile(csv_file): - logger.error("CSV-File already exists!") + logger.error(f"CSV file already exists: {csv_file}") return try: io.open(csv_file, 'w+').close() except IOError: - logger.error("Filed to create CSV-File!") + logger.error(f"Failed to create CSV file: {csv_file}") return trials = json_normalize(results, max_level=1) @@ -420,7 +420,7 @@ class Hyperopt: trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) trials.to_csv(csv_file, index=False, header=True, mode='w', encoding='UTF-8') - print("CSV-File created!") + logger.info(f"CSV file created: {csv_file}") def has_space(self, space: str) -> bool: """ diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 4530cd03d..264ae9a63 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -727,7 +727,7 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): assert re.match("['ETH/BTC', 'TKN/BTC', 'BLK/BTC', 'LTC/BTC', 'XRP/BTC']", captured.out) -def test_hyperopt_list(mocker, capsys, hyperopt_results): +def test_hyperopt_list(mocker, capsys, caplog, hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.load_previous_results', MagicMock(return_value=hyperopt_results) @@ -911,8 +911,7 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() - assert all(x in captured.out - for x in ["CSV-File created!"]) + log_has("CSV file created: test_file.csv", caplog) f = Path("test_file.csv") assert 'Best,1,2,-1.25%,-0.00125625,,-2.51,"3,930.0 m",0.43662' in f.read_text() assert f.is_file() From c26835048c9efb76325b36a8efa4a9e752e230aa Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 28 Apr 2020 22:56:19 +0300 Subject: [PATCH 0949/1106] Hyperopt cleanup, do not use 'trials' --- freqtrade/optimize/hyperopt.py | 72 +++++++++++++++++---------------- tests/optimize/test_hyperopt.py | 41 ++++++++++--------- 2 files changed, 59 insertions(+), 54 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 1e8077f10..a3e636988 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -75,8 +75,8 @@ class Hyperopt: self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config) self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function - self.trials_file = (self.config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') + self.results_file = (self.config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') self.data_pickle_file = (self.config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_tickerdata.pkl') self.total_epochs = config.get('epochs', 0) @@ -88,10 +88,10 @@ class Hyperopt: else: logger.info("Continuing on previous hyperopt results.") - self.num_trials_saved = 0 + self.num_epochs_saved = 0 # Previous evaluations - self.trials: List = [] + self.epochs: List = [] # Populate functions here (hasattr is slow so should not be run during "regular" operations) if hasattr(self.custom_hyperopt, 'populate_indicators'): @@ -132,7 +132,7 @@ class Hyperopt: """ Remove hyperopt pickle files to restart hyperopt. """ - for f in [self.data_pickle_file, self.trials_file]: + for f in [self.data_pickle_file, self.results_file]: p = Path(f) if p.is_file(): logger.info(f"Removing `{p}`.") @@ -151,27 +151,26 @@ class Hyperopt: # and the values are taken from the list of parameters. return {d.name: v for d, v in zip(dimensions, raw_params)} - def save_trials(self, final: bool = False) -> None: + def _save_results(self) -> None: """ - Save hyperopt trials to file + Save hyperopt results to file """ - num_trials = len(self.trials) - if num_trials > self.num_trials_saved: - logger.debug(f"Saving {num_trials} {plural(num_trials, 'epoch')}.") - dump(self.trials, self.trials_file) - self.num_trials_saved = num_trials - if final: - logger.info(f"{num_trials} {plural(num_trials, 'epoch')} " - f"saved to '{self.trials_file}'.") + num_epochs = len(self.epochs) + if num_epochs > self.num_epochs_saved: + logger.debug(f"Saving {num_epochs} {plural(num_epochs, 'epoch')}.") + dump(self.epochs, self.results_file) + self.num_epochs_saved = num_epochs + logger.debug(f"{self.num_epochs_saved} {plural(self.num_epochs_saved, 'epoch')} " + f"saved to '{self.results_file}'.") @staticmethod - def _read_trials(trials_file: Path) -> List: + def _read_results(results_file: Path) -> List: """ - Read hyperopt trials file + Read hyperopt results from file """ - logger.info("Reading Trials from '%s'", trials_file) - trials = load(trials_file) - return trials + logger.info("Reading epochs from '%s'", results_file) + data = load(results_file) + return data def _get_params_details(self, params: Dict) -> Dict: """ @@ -588,19 +587,20 @@ class Hyperopt: wrap_non_picklable_objects(self.generate_optimizer))(v, i) for v in asked) @staticmethod - def load_previous_results(trials_file: Path) -> List: + def load_previous_results(results_file: Path) -> List: """ Load data for epochs from the file if we have one """ - trials: List = [] - if trials_file.is_file() and trials_file.stat().st_size > 0: - trials = Hyperopt._read_trials(trials_file) - if trials[0].get('is_best') is None: + epochs: List = [] + if results_file.is_file() and results_file.stat().st_size > 0: + epochs = Hyperopt._read_results(results_file) + # Detection of some old format, without 'is_best' field saved + if epochs[0].get('is_best') is None: raise OperationalException( "The file with Hyperopt results is incompatible with this version " "of Freqtrade and cannot be loaded.") - logger.info(f"Loaded {len(trials)} previous evaluations from disk.") - return trials + logger.info(f"Loaded {len(epochs)} previous evaluations from disk.") + return epochs def _set_random_state(self, random_state: Optional[int]) -> int: return random_state or random.randint(1, 2**16 - 1) @@ -628,7 +628,7 @@ class Hyperopt: self.backtesting.exchange = None # type: ignore self.backtesting.pairlists = None # type: ignore - self.trials = self.load_previous_results(self.trials_file) + self.epochs = self.load_previous_results(self.results_file) cpus = cpu_count() logger.info(f"Found {cpus} CPU cores. Let's make them scream!") @@ -698,23 +698,25 @@ class Hyperopt: if is_best: self.current_best_loss = val['loss'] - self.trials.append(val) + self.epochs.append(val) # Save results after each best epoch and every 100 epochs if is_best or current % 100 == 0: - self.save_trials() + self._save_results() pbar.update(current) except KeyboardInterrupt: print('User interrupted..') - self.save_trials(final=True) + self._save_results() + logger.info(f"{self.num_epochs_saved} {plural(self.num_epochs_saved, 'epoch')} " + f"saved to '{self.results_file}'.") - if self.trials: - sorted_trials = sorted(self.trials, key=itemgetter('loss')) - results = sorted_trials[0] - self.print_epoch_details(results, self.total_epochs, self.print_json) + if self.epochs: + sorted_epochs = sorted(self.epochs, key=itemgetter('loss')) + best_epoch = sorted_epochs[0] + self.print_epoch_details(best_epoch, self.total_epochs, self.print_json) else: # This is printed when Ctrl+C is pressed quickly, before first epochs have # a chance to be evaluated. diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index b5106be0c..cc8b9aa37 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -1,5 +1,6 @@ # pragma pylint: disable=missing-docstring,W0212,C0103 import locale +import logging from datetime import datetime from pathlib import Path from typing import Dict, List @@ -56,14 +57,14 @@ def hyperopt_results(): # Functions for recurrent object patching -def create_trials(mocker, hyperopt, testdatadir) -> List[Dict]: +def create_results(mocker, hyperopt, testdatadir) -> List[Dict]: """ - When creating trials, mock the hyperopt Trials so that *by default* + When creating results, mock the hyperopt so that *by default* - we don't create any pickle'd files in the filesystem - we might have a pickle'd file so make sure that we return false when looking for it """ - hyperopt.trials_file = testdatadir / 'optimize/ut_trials.pickle' + hyperopt.results_file = testdatadir / 'optimize/ut_results.pickle' mocker.patch.object(Path, "is_file", MagicMock(return_value=False)) stat_mock = MagicMock() @@ -477,28 +478,30 @@ def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: assert caplog.record_tuples == [] -def test_save_trials_saves_trials(mocker, hyperopt, testdatadir, caplog) -> None: - trials = create_trials(mocker, hyperopt, testdatadir) +def test_save_results_saves_epochs(mocker, hyperopt, testdatadir, caplog) -> None: + epochs = create_results(mocker, hyperopt, testdatadir) mock_dump = mocker.patch('freqtrade.optimize.hyperopt.dump', return_value=None) - trials_file = testdatadir / 'optimize' / 'ut_trials.pickle' + results_file = testdatadir / 'optimize' / 'ut_results.pickle' - hyperopt.trials = trials - hyperopt.save_trials(final=True) - assert log_has(f"1 epoch saved to '{trials_file}'.", caplog) + caplog.set_level(logging.DEBUG) + + hyperopt.epochs = epochs + hyperopt._save_results() + assert log_has(f"1 epoch saved to '{results_file}'.", caplog) mock_dump.assert_called_once() - hyperopt.trials = trials + trials - hyperopt.save_trials(final=True) - assert log_has(f"2 epochs saved to '{trials_file}'.", caplog) + hyperopt.epochs = epochs + epochs + hyperopt._save_results() + assert log_has(f"2 epochs saved to '{results_file}'.", caplog) -def test_read_trials_returns_trials_file(mocker, hyperopt, testdatadir, caplog) -> None: - trials = create_trials(mocker, hyperopt, testdatadir) - mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=trials) - trials_file = testdatadir / 'optimize' / 'ut_trials.pickle' - hyperopt_trial = hyperopt._read_trials(trials_file) - assert log_has(f"Reading Trials from '{trials_file}'", caplog) - assert hyperopt_trial == trials +def test_read_results_returns_epochs(mocker, hyperopt, testdatadir, caplog) -> None: + epochs = create_results(mocker, hyperopt, testdatadir) + mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=epochs) + results_file = testdatadir / 'optimize' / 'ut_results.pickle' + hyperopt_epochs = hyperopt._read_results(results_file) + assert log_has(f"Reading epochs from '{results_file}'", caplog) + assert hyperopt_epochs == epochs mock_load.assert_called_once() From c6787d7e9faf4f3ad6a3d00ed7c806ad83cd5485 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 28 Apr 2020 23:14:02 +0300 Subject: [PATCH 0950/1106] Do not use 'trials' in commands --- freqtrade/commands/hyperopt_commands.py | 106 ++++++++++++------------ 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 3f61ea66c..517f47d16 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -38,33 +38,33 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') + results_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations - trials = Hyperopt.load_previous_results(trials_file) - total_epochs = len(trials) + epochs = Hyperopt.load_previous_results(results_file) + total_epochs = len(epochs) - trials = _hyperopt_filter_trials(trials, filteroptions) + epochs = _hyperopt_filter_epochs(epochs, filteroptions) if print_colorized: colorama_init(autoreset=True) if not export_csv: try: - print(Hyperopt.get_result_table(config, trials, total_epochs, + print(Hyperopt.get_result_table(config, epochs, total_epochs, not filteroptions['only_best'], print_colorized, 0)) except KeyboardInterrupt: print('User interrupted..') - if trials and not no_details: - sorted_trials = sorted(trials, key=itemgetter('loss')) - results = sorted_trials[0] + if epochs and not no_details: + sorted_epochs = sorted(epochs, key=itemgetter('loss')) + results = sorted_epochs[0] Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header) - if trials and export_csv: + if epochs and export_csv: Hyperopt.export_csv_file( - config, trials, total_epochs, not filteroptions['only_best'], export_csv + config, epochs, total_epochs, not filteroptions['only_best'], export_csv ) @@ -78,8 +78,8 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: print_json = config.get('print_json', False) no_header = config.get('hyperopt_show_no_header', False) - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') + results_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') n = config.get('hyperopt_show_index', -1) filteroptions = { @@ -96,89 +96,87 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: } # Previous evaluations - trials = Hyperopt.load_previous_results(trials_file) - total_epochs = len(trials) + epochs = Hyperopt.load_previous_results(results_file) + total_epochs = len(epochs) - trials = _hyperopt_filter_trials(trials, filteroptions) - trials_epochs = len(trials) + epochs = _hyperopt_filter_epochs(epochs, filteroptions) + filtered_epochs = len(epochs) - if n > trials_epochs: + if n > filtered_epochs: raise OperationalException( - f"The index of the epoch to show should be less than {trials_epochs + 1}.") - if n < -trials_epochs: + f"The index of the epoch to show should be less than {filtered_epochs + 1}.") + if n < -filtered_epochs: raise OperationalException( - f"The index of the epoch to show should be greater than {-trials_epochs - 1}.") + f"The index of the epoch to show should be greater than {-filtered_epochs - 1}.") # Translate epoch index from human-readable format to pythonic if n > 0: n -= 1 - if trials: - val = trials[n] + if epochs: + val = epochs[n] Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, header_str="Epoch details") -def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: +def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List: """ Filter our items from the list of hyperopt results """ if filteroptions['only_best']: - trials = [x for x in trials if x['is_best']] + epochs = [x for x in epochs if x['is_best']] if filteroptions['only_profitable']: - trials = [x for x in trials if x['results_metrics']['profit'] > 0] + epochs = [x for x in epochs if x['results_metrics']['profit'] > 0] if filteroptions['filter_min_trades'] > 0: - trials = [ - x for x in trials + epochs = [ + x for x in epochs if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades'] ] if filteroptions['filter_max_trades'] > 0: - trials = [ - x for x in trials + epochs = [ + x for x in epochs if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades'] ] if filteroptions['filter_min_avg_time'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time'] ] if filteroptions['filter_max_avg_time'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time'] ] if filteroptions['filter_min_avg_profit'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['avg_profit'] - > filteroptions['filter_min_avg_profit'] + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs + if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit'] ] if filteroptions['filter_max_avg_profit'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials - if x['results_metrics']['avg_profit'] - < filteroptions['filter_max_avg_profit'] + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs + if x['results_metrics']['avg_profit'] < filteroptions['filter_max_avg_profit'] ] if filteroptions['filter_min_total_profit'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] ] if filteroptions['filter_max_total_profit'] is not None: - trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] - trials = [ - x for x in trials + epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0] + epochs = [ + x for x in epochs if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit'] ] - logger.info(f"{len(trials)} " + + logger.info(f"{len(epochs)} " + ("best " if filteroptions['only_best'] else "") + ("profitable " if filteroptions['only_profitable'] else "") + "epochs found.") - return trials + return epochs From 726e52aaa7932595a0f67e3a6c591b74d45b5962 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Wed, 29 Apr 2020 10:49:25 +0300 Subject: [PATCH 0951/1106] Use skopt model_queue_size instead of custom hack --- freqtrade/optimize/hyperopt.py | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index a3e636988..12310311c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -49,9 +49,9 @@ logger = logging.getLogger(__name__) INITIAL_POINTS = 30 -# Keep no more than 2*SKOPT_MODELS_MAX_NUM models -# in the skopt models list -SKOPT_MODELS_MAX_NUM = 10 +# Keep no more than SKOPT_MODEL_QUEUE_SIZE models +# in the skopt model queue, to optimize memory consumption +SKOPT_MODEL_QUEUE_SIZE = 10 MAX_LOSS = 100000 # just a big enough number to be bad result in loss optimization @@ -563,25 +563,9 @@ class Hyperopt: n_initial_points=INITIAL_POINTS, acq_optimizer_kwargs={'n_jobs': cpu_count}, random_state=self.random_state, + model_queue_size=SKOPT_MODEL_QUEUE_SIZE, ) - def fix_optimizer_models_list(self) -> None: - """ - WORKAROUND: Since skopt is not actively supported, this resolves problems with skopt - memory usage, see also: https://github.com/scikit-optimize/scikit-optimize/pull/746 - - This may cease working when skopt updates if implementation of this intrinsic - part changes. - """ - n = len(self.opt.models) - SKOPT_MODELS_MAX_NUM - # Keep no more than 2*SKOPT_MODELS_MAX_NUM models in the skopt models list, - # remove the old ones. These are actually of no use, the current model - # from the estimator is the only one used in the skopt optimizer. - # Freqtrade code also does not inspect details of the models. - if n >= SKOPT_MODELS_MAX_NUM: - logger.debug(f"Fixing skopt models list, removing {n} old items...") - del self.opt.models[0:n] - def run_optimizer_parallel(self, parallel, asked, i) -> List: return parallel(delayed( wrap_non_picklable_objects(self.generate_optimizer))(v, i) for v in asked) @@ -677,7 +661,6 @@ 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]) - self.fix_optimizer_models_list() # Calculate progressbar outputs for j, val in enumerate(f_val): From 1a6ddfcaebaf2c75c67aca115379db70aa9d96c1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Apr 2020 10:37:48 +0200 Subject: [PATCH 0952/1106] Be clear on evaluation logic during backtesting --- docs/backtesting.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index d6775e17c..d5a4cf3a7 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -202,7 +202,8 @@ Since backtesting lacks some detailed information about what happens within a ca - Buys happen at open-price - Sell signal sells happen at open-price of the following candle -- Low happens before high for stoploss, protecting capital first. +- Low happens before high for stoploss, protecting capital first +- Stoploss is evaluated before ROI - ROI - sells are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the sell will be at 2%) - sells are never "below the candle", so a ROI of 2% may result in a sell at 2.4% if low was at 2.4% profit From 74281a16fdda730216e13d1654766a14432e664b Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Apr 2020 10:39:55 +0200 Subject: [PATCH 0953/1106] Move to the last point and clarify further --- docs/backtesting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index d5a4cf3a7..1f518658d 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -203,7 +203,6 @@ Since backtesting lacks some detailed information about what happens within a ca - Buys happen at open-price - Sell signal sells happen at open-price of the following candle - Low happens before high for stoploss, protecting capital first -- Stoploss is evaluated before ROI - ROI - sells are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the sell will be at 2%) - sells are never "below the candle", so a ROI of 2% may result in a sell at 2.4% if low was at 2.4% profit @@ -213,6 +212,7 @@ Since backtesting lacks some detailed information about what happens within a ca - High happens first - adjusting stoploss - Low uses the adjusted stoploss (so sells with large high-low difference are backtested correctly) - Sell-reason does not explain if a trade was positive or negative, just what triggered the sell (this can look odd if negative ROI values are used) +- Stoploss (and trailing stoploss) is evaluated before ROI within one candle Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode. Also, keep in mind that past results don't guarantee future success. From 69b44234a48245c546ac0eb3d21b7fc6052e1034 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 29 Apr 2020 10:47:53 +0200 Subject: [PATCH 0954/1106] Update docs/backtesting.md Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/backtesting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 1f518658d..9b2997510 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -212,7 +212,7 @@ Since backtesting lacks some detailed information about what happens within a ca - High happens first - adjusting stoploss - Low uses the adjusted stoploss (so sells with large high-low difference are backtested correctly) - Sell-reason does not explain if a trade was positive or negative, just what triggered the sell (this can look odd if negative ROI values are used) -- Stoploss (and trailing stoploss) is evaluated before ROI within one candle +- Stoploss (and trailing stoploss) is evaluated before ROI within one candle. So you can often see more trades with the `stoploss` and/or `trailing_stop` sell reason comparing to the results obtained with the same strategy in the Dry Run/Live Trade modes. Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode. Also, keep in mind that past results don't guarantee future success. From 9152e76966dc35f3cff4d2be83359f31d557e4ba Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Wed, 29 Apr 2020 12:17:08 +0300 Subject: [PATCH 0955/1106] Add skopt version check into setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 94c48a6a7..5a332057f 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ plot = ['plotly>=4.0'] hyperopt = [ 'scipy', 'scikit-learn', - 'scikit-optimize', + 'scikit-optimize>=0.7.4', 'filelock', 'joblib', 'progressbar2', From 38c6ba6c0840a2f2c575c5ee67e083d0a5a65182 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Wed, 29 Apr 2020 13:21:04 +0300 Subject: [PATCH 0956/1106] Update setup.py Co-Authored-By: Matthias --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5a332057f..9c253ea4e 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ plot = ['plotly>=4.0'] hyperopt = [ 'scipy', 'scikit-learn', - 'scikit-optimize>=0.7.4', + 'scikit-optimize>=0.7.0', 'filelock', 'joblib', 'progressbar2', From dec1b10743c3420a71b9dcc49d14c83d0dacb289 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 06:51:42 +0200 Subject: [PATCH 0957/1106] Add fee_cost and currency columns --- freqtrade/persistence.py | 22 +++++++++++++++++++--- tests/test_persistence.py | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index fb314f439..36e2c7ffd 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -86,11 +86,15 @@ def check_migrate(engine) -> None: logger.debug(f'trying {table_back_name}') # Check for latest column - if not has_column(cols, 'close_profit_abs'): + if not has_column(cols, 'fee_close_cost'): logger.info(f'Running database migration - backup available as {table_back_name}') fee_open = get_column_def(cols, 'fee_open', 'fee') + fee_open_cost = get_column_def(cols, 'fee_open_cost', 'null') + fee_open_currency = get_column_def(cols, 'fee_open_currency', 'null') fee_close = get_column_def(cols, 'fee_close', 'fee') + fee_close_cost = get_column_def(cols, 'fee_close_cost', 'null') + fee_close_currency = get_column_def(cols, 'fee_close_currency', 'null') open_rate_requested = get_column_def(cols, 'open_rate_requested', 'null') close_rate_requested = get_column_def(cols, 'close_rate_requested', 'null') stop_loss = get_column_def(cols, 'stop_loss', '0.0') @@ -120,7 +124,9 @@ def check_migrate(engine) -> None: # Copy data back - following the correct schema engine.execute(f"""insert into trades - (id, exchange, pair, is_open, fee_open, fee_close, open_rate, + (id, exchange, pair, is_open, + fee_open, fee_open_cost, fee_open_currency, + fee_close, fee_close_cost, fee_open_currency, open_rate, open_rate_requested, close_rate, close_rate_requested, close_profit, stake_amount, amount, open_date, close_date, open_order_id, stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct, @@ -136,7 +142,9 @@ def check_migrate(engine) -> None: else pair end pair, - is_open, {fee_open} fee_open, {fee_close} fee_close, + is_open, {fee_open} fee_open, {fee_open_cost} fee_open_cost, + {fee_open_currency} fee_open_currency, {fee_close} fee_close, + {fee_close_cost} fee_close_cost, {fee_close_currency} fee_close_currency, open_rate, {open_rate_requested} open_rate_requested, close_rate, {close_rate_requested} close_rate_requested, close_profit, stake_amount, amount, open_date, close_date, open_order_id, @@ -185,7 +193,11 @@ class Trade(_DECL_BASE): pair = Column(String, nullable=False, index=True) is_open = Column(Boolean, nullable=False, default=True, index=True) fee_open = Column(Float, nullable=False, default=0.0) + fee_open_cost = Column(Float, nullable=True) + fee_open_currency = Column(String, nullable=True) fee_close = Column(Float, nullable=False, default=0.0) + fee_close_cost = Column(Float, nullable=True) + fee_close_currency = Column(String, nullable=True) open_rate = Column(Float) open_rate_requested = Column(Float) # open_trade_price - calculated via _calc_open_trade_price @@ -235,7 +247,11 @@ class Trade(_DECL_BASE): 'pair': self.pair, 'is_open': self.is_open, 'fee_open': self.fee_open, + 'fee_open_cost': self.fee_open_cost, + 'fee_open_currency': self.fee_open_currency, 'fee_close': self.fee_close, + 'fee_close_cost': self.fee_close_cost, + 'fee_close_currency': self.fee_close_currency, 'open_date_hum': arrow.get(self.open_date).humanize(), 'open_date': self.open_date.strftime("%Y-%m-%d %H:%M:%S"), 'close_date_hum': (arrow.get(self.close_date).humanize() diff --git a/tests/test_persistence.py b/tests/test_persistence.py index ceac24356..f54802ceb 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -465,6 +465,10 @@ def test_migrate_old(mocker, default_conf, fee): assert trade.initial_stop_loss == 0.0 assert trade.open_trade_price == trade._calc_open_trade_price() assert trade.close_profit_abs is None + assert trade.fee_open_cost is None + assert trade.fee_open_currency is None + assert trade.fee_close_cost is None + assert trade.fee_close_currency is None trade = Trade.query.filter(Trade.id == 2).first() assert trade.close_rate is not None From 7936120afc26104179fd1c8115e4f858fbc06b85 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 06:58:43 +0200 Subject: [PATCH 0958/1106] Adapt tests to support new db fields --- tests/rpc/test_rpc.py | 8 ++++++++ tests/rpc/test_rpc_apiserver.py | 8 ++++++++ tests/test_persistence.py | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index d2af4bd87..a1e6d9f26 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -51,7 +51,11 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_date_hum': ANY, 'is_open': ANY, 'fee_open': ANY, + 'fee_open_cost': ANY, + 'fee_open_currency': ANY, 'fee_close': ANY, + 'fee_close_cost': ANY, + 'fee_close_currency': ANY, 'open_rate_requested': ANY, 'open_trade_price': ANY, 'close_rate_requested': ANY, @@ -90,7 +94,11 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_date_hum': ANY, 'is_open': ANY, 'fee_open': ANY, + 'fee_open_cost': ANY, + 'fee_open_currency': ANY, 'fee_close': ANY, + 'fee_close_cost': ANY, + 'fee_close_currency': ANY, 'open_rate_requested': ANY, 'open_trade_price': ANY, 'close_rate_requested': ANY, diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 6548790cb..01e9c0e96 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -472,7 +472,11 @@ def test_api_status(botclient, mocker, ticker, fee, markets): 'close_rate_requested': None, 'current_rate': 1.099e-05, 'fee_close': 0.0025, + 'fee_close_cost': None, + 'fee_close_currency': None, 'fee_open': 0.0025, + 'fee_open_cost': None, + 'fee_open_currency': None, 'open_date': ANY, 'is_open': True, 'max_rate': 0.0, @@ -575,7 +579,11 @@ def test_api_forcebuy(botclient, mocker, fee): 'close_profit': None, 'close_rate_requested': None, 'fee_close': 0.0025, + 'fee_close_cost': None, + 'fee_close_currency': None, 'fee_open': 0.0025, + 'fee_open_cost': None, + 'fee_open_currency': None, 'is_open': False, 'max_rate': None, 'min_rate': None, diff --git a/tests/test_persistence.py b/tests/test_persistence.py index f54802ceb..aa3a59b87 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -745,7 +745,11 @@ def test_to_json(default_conf, fee): 'open_rate_requested': None, 'open_trade_price': 15.1668225, 'fee_close': 0.0025, + 'fee_close_cost': None, + 'fee_close_currency': None, 'fee_open': 0.0025, + 'fee_open_cost': None, + 'fee_open_currency': None, 'close_rate': None, 'close_rate_requested': None, 'amount': 123.0, @@ -794,7 +798,11 @@ def test_to_json(default_conf, fee): 'close_profit': None, 'close_rate_requested': None, 'fee_close': 0.0025, + 'fee_close_cost': None, + 'fee_close_currency': None, 'fee_open': 0.0025, + 'fee_open_cost': None, + 'fee_open_currency': None, 'is_open': None, 'max_rate': None, 'min_rate': None, From b125dd3728b516f628363f5a7b7c8009a955c24e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 07:06:06 +0200 Subject: [PATCH 0959/1106] Extract order_has_fee method --- freqtrade/freqtradebot.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7ae87e807..80470f9e7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1162,6 +1162,17 @@ class FreqtradeBot: return False + def _order_has_fee(self, order: Dict) -> bool: + """ + Verifies if the passed in order dict has the needed keys to extract fees + :param order: Order or trade (one trade) dict + :return: True if the fee substructure contains currency and cost, false otherwise + """ + if not isinstance(order, dict): + return False + return ('fee' in order and order['fee'] is not None and + (order['fee'].keys() >= {'currency', 'cost'})) + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Get real amount for the trade @@ -1175,8 +1186,7 @@ class FreqtradeBot: trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible - if ('fee' in order and order['fee'] is not None and - (order['fee'].keys() >= {'currency', 'cost'})): + if self._order_has_fee(order): if (order['fee']['currency'] is not None and order['fee']['cost'] is not None and trade_base_currency == order['fee']['currency']): @@ -1196,8 +1206,7 @@ class FreqtradeBot: fee_abs = 0 for exectrade in trades: amount += exectrade['amount'] - if ("fee" in exectrade and exectrade['fee'] is not None and - (exectrade['fee'].keys() >= {'currency', 'cost'})): + if self._order_has_fee(exectrade): # only applies if fee is in quote currency! if (exectrade['fee']['currency'] is not None and exectrade['fee']['cost'] is not None and From 6d7a3a0cc99d8e47b7e27e54d3827335af61a8bf Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 07:12:08 +0200 Subject: [PATCH 0960/1106] Extract more logic into order-has_fee --- freqtrade/freqtradebot.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 80470f9e7..4db9f9a1c 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1164,14 +1164,18 @@ class FreqtradeBot: def _order_has_fee(self, order: Dict) -> bool: """ - Verifies if the passed in order dict has the needed keys to extract fees + Verifies if the passed in order dict has the needed keys to extract fees, + and that these keys (currency, cost) are not empty. :param order: Order or trade (one trade) dict :return: True if the fee substructure contains currency and cost, false otherwise """ if not isinstance(order, dict): return False - return ('fee' in order and order['fee'] is not None and - (order['fee'].keys() >= {'currency', 'cost'})) + return ('fee' in order and order['fee'] is not None + and (order['fee'].keys() >= {'currency', 'cost'}) + and order['fee']['currency'] is not None + and order['fee']['cost'] is not None + ) def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ @@ -1187,9 +1191,7 @@ class FreqtradeBot: trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible if self._order_has_fee(order): - if (order['fee']['currency'] is not None and - order['fee']['cost'] is not None and - trade_base_currency == order['fee']['currency']): + if trade_base_currency == order['fee']['currency']: new_amount = order_amount - order['fee']['cost'] logger.info("Applying fee on amount for %s (from %s to %s) from Order", trade, order['amount'], new_amount) @@ -1208,9 +1210,7 @@ class FreqtradeBot: amount += exectrade['amount'] if self._order_has_fee(exectrade): # only applies if fee is in quote currency! - if (exectrade['fee']['currency'] is not None and - exectrade['fee']['cost'] is not None and - trade_base_currency == exectrade['fee']['currency']): + if trade_base_currency == exectrade['fee']['currency']: fee_abs += exectrade['fee']['cost'] if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): From d3b9f4d393850de9d846735d8790d32dbc459c4c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 19:28:36 +0200 Subject: [PATCH 0961/1106] Add extract_cost_curr_rate --- freqtrade/freqtradebot.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4db9f9a1c..7963fbec3 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1177,6 +1177,15 @@ class FreqtradeBot: and order['fee']['cost'] is not None ) + def _extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, float]: + """ + :param order: Order or trade (one trade) dict + :return: Tuple with cost, currency, rate of the given fee dict + """ + return (order['fee']['cost'], + order['fee']['currency'], + order['fee'].get('rate', None)) + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Get real amount for the trade From a867d40eac3ab040eac09ac9905cefa4e74178fc Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 19:33:09 +0200 Subject: [PATCH 0962/1106] Move fee_methods to exchange --- freqtrade/exchange/exchange.py | 26 ++++++++++++++++++++++++++ freqtrade/freqtradebot.py | 24 ------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 1a0565959..9a0364b07 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1063,6 +1063,32 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e + @staticmethod + def order_has_fee(order: Dict) -> bool: + """ + Verifies if the passed in order dict has the needed keys to extract fees, + and that these keys (currency, cost) are not empty. + :param order: Order or trade (one trade) dict + :return: True if the fee substructure contains currency and cost, false otherwise + """ + if not isinstance(order, dict): + return False + return ('fee' in order and order['fee'] is not None + and (order['fee'].keys() >= {'currency', 'cost'}) + and order['fee']['currency'] is not None + and order['fee']['cost'] is not None + ) + + @staticmethod + def extract_cost_curr_rate(order: Dict) -> Tuple[float, str, float]: + """ + :param order: Order or trade (one trade) dict + :return: Tuple with cost, currency, rate of the given fee dict + """ + return (order['fee']['cost'], + order['fee']['currency'], + order['fee'].get('rate', None)) + def is_exchange_bad(exchange_name: str) -> bool: return exchange_name in BAD_EXCHANGES diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7963fbec3..a297f1823 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1162,30 +1162,6 @@ class FreqtradeBot: return False - def _order_has_fee(self, order: Dict) -> bool: - """ - Verifies if the passed in order dict has the needed keys to extract fees, - and that these keys (currency, cost) are not empty. - :param order: Order or trade (one trade) dict - :return: True if the fee substructure contains currency and cost, false otherwise - """ - if not isinstance(order, dict): - return False - return ('fee' in order and order['fee'] is not None - and (order['fee'].keys() >= {'currency', 'cost'}) - and order['fee']['currency'] is not None - and order['fee']['cost'] is not None - ) - - def _extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, float]: - """ - :param order: Order or trade (one trade) dict - :return: Tuple with cost, currency, rate of the given fee dict - """ - return (order['fee']['cost'], - order['fee']['currency'], - order['fee'].get('rate', None)) - def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Get real amount for the trade From 2e4dc6c25388feaa8ce13407bf62d2eabfb27938 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 19:56:48 +0200 Subject: [PATCH 0963/1106] Exchange should return fee dict for dry-run orders --- freqtrade/exchange/exchange.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 9a0364b07..22d477e6c 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -472,26 +472,31 @@ class Exchange: 'pair': pair, 'price': rate, 'amount': _amount, - "cost": _amount * rate, + 'cost': _amount * rate, 'type': ordertype, 'side': side, 'remaining': _amount, 'datetime': arrow.utcnow().isoformat(), 'status': "closed" if ordertype == "market" else "open", 'fee': None, - "info": {} + 'info': {} } - self._store_dry_order(dry_order) + self._store_dry_order(dry_order, pair) # Copy order and close it - so the returned order is open unless it's a market order return dry_order - def _store_dry_order(self, dry_order: Dict) -> None: + def _store_dry_order(self, dry_order: Dict, pair: str) -> None: closed_order = dry_order.copy() - if closed_order["type"] in ["market", "limit"]: + if closed_order['type'] in ["market", "limit"]: closed_order.update({ - "status": "closed", - "filled": closed_order["amount"], - "remaining": 0 + 'status': 'closed', + 'filled': closed_order['amount'], + 'remaining': 0, + 'fee': { + 'currency': self.get_pair_quote_currency(pair), + 'cost': dry_order['amount'] * self.get_fee(pair), + 'rate': self.get_fee(pair) + } }) if closed_order["type"] in ["stop_loss_limit"]: closed_order["info"].update({"stopPrice": closed_order["price"]}) From e74ed0ba7b7ba4f9f8f6cd8f456d1ccc35901614 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 20:05:27 +0200 Subject: [PATCH 0964/1106] Add tests for fee extraction methods --- freqtrade/exchange/exchange.py | 2 ++ tests/exchange/test_exchange.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 22d477e6c..bd6d617c0 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1087,6 +1087,8 @@ class Exchange: @staticmethod def extract_cost_curr_rate(order: Dict) -> Tuple[float, str, float]: """ + Extract tuple of cost, currency, rate. + Requires order_has_fee to run first! :param order: Order or trade (one trade) dict :return: Tuple with cost, currency, rate of the given fee dict """ diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 3c92612a0..f8c572dc8 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2145,3 +2145,23 @@ def test_symbol_is_pair(market_symbol, base_currency, quote_currency, expected_r ]) def test_market_is_active(market, expected_result) -> None: assert market_is_active(market) == expected_result + + +@pytest.mark.parametrize("order,expected", [ + ([{'fee'}], False), + ({'fee': None}, False), + ({'fee': {'currency': 'ETH/BTC'}}, False), + ({'fee': {'currency': 'ETH/BTC', 'cost': None}}, False), + ({'fee': {'currency': 'ETH/BTC', 'cost': 0.01}}, True), +]) +def test_order_has_fee(order, expected) -> None: + assert Exchange.order_has_fee(order) == expected + + +@pytest.mark.parametrize("order,expected", [ + ({'fee': {'currency': 'ETH/BTC', 'cost': 0.43}}, (0.43, 'ETH/BTC', None)), + ({'fee': {'currency': 'ETH/USDT', 'cost': 0.01}}, (0.01, 'ETH/USDT', None)), + ({'fee': {'currency': 'ETH/USDT', 'cost': 0.34, 'rate': 0.01}}, (0.34, 'ETH/USDT', 0.01)), +]) +def test_extract_cost_curr_rate(order, expected) -> None: + assert Exchange.extract_cost_curr_rate(order) == expected From 63b55658ac07ab3b6e44ee7bda9093031f2133ba Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 1 May 2020 05:11:30 +0300 Subject: [PATCH 0965/1106] Add ticker to dataprovider --- freqtrade/data/dataprovider.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 1df710152..b197ed1a5 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -97,8 +97,7 @@ class DataProvider: """ Return last ticker data """ - # TODO: Implement me - pass + return self._exchange.fetch_ticker(pair) def orderbook(self, pair: str, maximum: int) -> Dict[str, List]: """ From f8f794a8038ec9d532b39cf7a947956e02b7bac0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 20:15:35 +0200 Subject: [PATCH 0966/1106] Simplify fee-related tests --- tests/test_freqtradebot.py | 60 ++++++++------------------------------ 1 file changed, 12 insertions(+), 48 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6f2ce9f3c..43ee4c79d 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3285,8 +3285,6 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order, def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fee, caplog, mocker): mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) - patch_RPCManager(mocker) - patch_exchange(mocker) amount = sum(x['amount'] for x in trades_for_order) trade = Trade( pair='LTC/ETH', @@ -3297,8 +3295,7 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fe fee_close=fee.return_value, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001) @@ -3310,8 +3307,6 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fe def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker, fee): mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) - patch_RPCManager(mocker) - patch_exchange(mocker) amount = buy_order_fee['amount'] trade = Trade( pair='LTC/ETH', @@ -3322,8 +3317,7 @@ def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker, f fee_close=fee.return_value, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, buy_order_fee) == amount @@ -3335,8 +3329,6 @@ def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker, f def test_get_real_amount_stake(default_conf, trades_for_order, buy_order_fee, fee, mocker): trades_for_order[0]['fee']['currency'] = 'ETH' - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = sum(x['amount'] for x in trades_for_order) trade = Trade( @@ -3348,8 +3340,7 @@ def test_get_real_amount_stake(default_conf, trades_for_order, buy_order_fee, fe open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change assert freqtrade.get_real_amount(trade, buy_order_fee) == amount @@ -3362,8 +3353,6 @@ def test_get_real_amount_no_currency_in_fee(default_conf, trades_for_order, buy_ limit_buy_order['fee'] = {'cost': 0.004, 'currency': None} trades_for_order[0]['fee']['currency'] = None - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = sum(x['amount'] for x in trades_for_order) trade = Trade( @@ -3375,8 +3364,7 @@ def test_get_real_amount_no_currency_in_fee(default_conf, trades_for_order, buy_ open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change assert freqtrade.get_real_amount(trade, limit_buy_order) == amount @@ -3386,8 +3374,6 @@ def test_get_real_amount_BNB(default_conf, trades_for_order, buy_order_fee, fee, trades_for_order[0]['fee']['currency'] = 'BNB' trades_for_order[0]['fee']['cost'] = 0.00094518 - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = sum(x['amount'] for x in trades_for_order) trade = Trade( @@ -3399,16 +3385,13 @@ def test_get_real_amount_BNB(default_conf, trades_for_order, buy_order_fee, fee, open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change assert freqtrade.get_real_amount(trade, buy_order_fee) == amount def test_get_real_amount_multi(default_conf, trades_for_order2, buy_order_fee, caplog, fee, mocker): - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order2) amount = float(sum(x['amount'] for x in trades_for_order2)) trade = Trade( @@ -3420,8 +3403,7 @@ def test_get_real_amount_multi(default_conf, trades_for_order2, buy_order_fee, c open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001) @@ -3435,8 +3417,6 @@ def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee limit_buy_order = deepcopy(buy_order_fee) limit_buy_order['fee'] = {'cost': 0.004, 'currency': 'LTC'} - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[trades_for_order]) amount = float(sum(x['amount'] for x in trades_for_order)) @@ -3449,8 +3429,7 @@ def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, limit_buy_order) == amount - 0.004 @@ -3463,8 +3442,6 @@ def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order limit_buy_order = deepcopy(buy_order_fee) limit_buy_order['fee'] = {'cost': 0.004} - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) amount = float(sum(x['amount'] for x in trades_for_order)) trade = Trade( @@ -3476,8 +3453,7 @@ def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change assert freqtrade.get_real_amount(trade, limit_buy_order) == amount @@ -3487,8 +3463,6 @@ def test_get_real_amount_wrong_amount(default_conf, trades_for_order, buy_order_ limit_buy_order = deepcopy(buy_order_fee) limit_buy_order['amount'] = limit_buy_order['amount'] - 0.001 - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = float(sum(x['amount'] for x in trades_for_order)) trade = Trade( @@ -3500,8 +3474,7 @@ def test_get_real_amount_wrong_amount(default_conf, trades_for_order, buy_order_ fee_close=fee.return_value, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change with pytest.raises(DependencyException, match=r"Half bought\? Amounts don't match"): @@ -3514,8 +3487,6 @@ def test_get_real_amount_wrong_amount_rounding(default_conf, trades_for_order, b limit_buy_order = deepcopy(buy_order_fee) trades_for_order[0]['amount'] = trades_for_order[0]['amount'] + 1e-15 - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = float(sum(x['amount'] for x in trades_for_order)) trade = Trade( @@ -3527,8 +3498,7 @@ def test_get_real_amount_wrong_amount_rounding(default_conf, trades_for_order, b open_rate=0.245441, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount changes by fee amount. assert isclose(freqtrade.get_real_amount(trade, limit_buy_order), amount - (amount * 0.001), @@ -3539,8 +3509,6 @@ def test_get_real_amount_invalid(default_conf, trades_for_order, buy_order_fee, # Remove "Currency" from fee dict trades_for_order[0]['fee'] = {'cost': 0.008} - patch_RPCManager(mocker) - patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) amount = sum(x['amount'] for x in trades_for_order) trade = Trade( @@ -3553,15 +3521,12 @@ def test_get_real_amount_invalid(default_conf, trades_for_order, buy_order_fee, open_order_id="123456" ) - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) # Amount does not change assert freqtrade.get_real_amount(trade, buy_order_fee) == amount def test_get_real_amount_open_trade(default_conf, fee, mocker): - patch_RPCManager(mocker) - patch_exchange(mocker) amount = 12345 trade = Trade( pair='LTC/ETH', @@ -3577,8 +3542,7 @@ def test_get_real_amount_open_trade(default_conf, fee, mocker): 'amount': amount, 'status': 'open', } - freqtrade = FreqtradeBot(default_conf) - patch_get_signal(freqtrade) + freqtrade = get_patched_freqtradebot(mocker, default_conf) assert freqtrade.get_real_amount(trade, order) == amount From 45c97fde2dc125f00255f197f5bbf4fe63a20a06 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 30 Apr 2020 22:16:52 +0200 Subject: [PATCH 0967/1106] Use correct typehint for extract_cost_curr_rate --- freqtrade/exchange/exchange.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index bd6d617c0..df7f3005e 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1085,7 +1085,7 @@ class Exchange: ) @staticmethod - def extract_cost_curr_rate(order: Dict) -> Tuple[float, str, float]: + def extract_cost_curr_rate(order: Dict) -> Tuple[float, str, Optional[float]]: """ Extract tuple of cost, currency, rate. Requires order_has_fee to run first! @@ -1095,6 +1095,7 @@ class Exchange: return (order['fee']['cost'], order['fee']['currency'], order['fee'].get('rate', None)) + # calculate rate ? (order['fee']['cost'] / (order['amount'] * order['price'])) def is_exchange_bad(exchange_name: str) -> bool: From 59bafc8d02e291bb0797eeecdc1cd92feadb5517 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 15:17:52 +0200 Subject: [PATCH 0968/1106] Implement fee rate calculation --- freqtrade/exchange/exchange.py | 33 +++++++++++++++++++++--- tests/exchange/test_exchange.py | 45 +++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index df7f3005e..ebadd4c8a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -22,7 +22,7 @@ from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.exceptions import (DependencyException, InvalidOrderException, OperationalException, TemporaryError) from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async -from freqtrade.misc import deep_merge_dicts +from freqtrade.misc import deep_merge_dicts, safe_value_fallback CcxtModuleType = Any @@ -1084,8 +1084,33 @@ class Exchange: and order['fee']['cost'] is not None ) - @staticmethod - def extract_cost_curr_rate(order: Dict) -> Tuple[float, str, Optional[float]]: + def calculate_fee_rate(self, order: Dict) -> Optional[float]: + """ + Calculate fee rate if it's not given by the exchange. + :param order: Order or trade (one trade) dict + """ + if order['fee'].get('rate') is not None: + return order['fee'].get('rate') + fee_curr = order['fee']['currency'] + # Calculate fee based on order details + if fee_curr in self.get_pair_base_currency(order['symbol']): + # Base currency - divide by amount + return round(order['fee']['cost'] / order['amount'], 8) + elif fee_curr in self.get_pair_quote_currency(order['symbol']): + # Quote currency - divide by cost + return round(order['fee']['cost'] / order['cost'], 8) + else: + # If Fee currency is a different currency + try: + comb = self.get_valid_pair_combination(fee_curr, self._config['stake_currency']) + tick = self.fetch_ticker(comb) + + fee_to_quote_rate = safe_value_fallback(tick, tick, 'last', 'ask') + return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8) + except DependencyException: + return None + + def extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, Optional[float]]: """ Extract tuple of cost, currency, rate. Requires order_has_fee to run first! @@ -1094,7 +1119,7 @@ class Exchange: """ return (order['fee']['cost'], order['fee']['currency'], - order['fee'].get('rate', None)) + self.calculate_fee_rate(order)) # calculate rate ? (order['fee']['cost'] / (order['amount'] * order['price'])) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index f8c572dc8..7a1df5103 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2159,9 +2159,44 @@ def test_order_has_fee(order, expected) -> None: @pytest.mark.parametrize("order,expected", [ - ({'fee': {'currency': 'ETH/BTC', 'cost': 0.43}}, (0.43, 'ETH/BTC', None)), - ({'fee': {'currency': 'ETH/USDT', 'cost': 0.01}}, (0.01, 'ETH/USDT', None)), - ({'fee': {'currency': 'ETH/USDT', 'cost': 0.34, 'rate': 0.01}}, (0.34, 'ETH/USDT', 0.01)), + ({'symbol': 'ETH/BTC', 'fee': {'currency': 'ETH', 'cost': 0.43}}, + (0.43, 'ETH', 0.01)), + ({'symbol': 'ETH/USDT', 'fee': {'currency': 'USDT', 'cost': 0.01}}, + (0.01, 'USDT', 0.01)), + ({'symbol': 'BTC/USDT', 'fee': {'currency': 'USDT', 'cost': 0.34, 'rate': 0.01}}, + (0.34, 'USDT', 0.01)), ]) -def test_extract_cost_curr_rate(order, expected) -> None: - assert Exchange.extract_cost_curr_rate(order) == expected +def test_extract_cost_curr_rate(mocker, default_conf, order, expected) -> None: + mocker.patch('freqtrade.exchange.Exchange.calculate_fee_rate', MagicMock(return_value=0.01)) + ex = get_patched_exchange(mocker, default_conf) + assert ex.extract_cost_curr_rate(order) == expected + + +@pytest.mark.parametrize("order,expected", [ + # Using base-currency + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'ETH', 'cost': 0.004, 'rate': None}}, 0.1), + ({'symbol': 'ETH/BTC', 'amount': 0.05, 'cost': 0.05, + 'fee': {'currency': 'ETH', 'cost': 0.004, 'rate': None}}, 0.08), + # Using quote currency + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'BTC', 'cost': 0.005}}, 0.1), + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'BTC', 'cost': 0.002, 'rate': None}}, 0.04), + # Using foreign currency + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'NEO', 'cost': 0.0012}}, 0.001944), + ({'symbol': 'ETH/BTC', 'amount': 2.21, 'cost': 0.02992561, + 'fee': {'currency': 'NEO', 'cost': 0.00027452}}, 0.00074305), + # TODO: More tests here! + # Rate included in return - return as is + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'USDT', 'cost': 0.34, 'rate': 0.01}}, 0.01), + ({'symbol': 'ETH/BTC', 'amount': 0.04, 'cost': 0.05, + 'fee': {'currency': 'USDT', 'cost': 0.34, 'rate': 0.005}}, 0.005), +]) +def test_calculate_fee_rate(mocker, default_conf, order, expected) -> None: + mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value={'last': 0.081}) + + ex = get_patched_exchange(mocker, default_conf) + assert ex.calculate_fee_rate(order) == expected From db8fb39a3860caca6000f384055d5476ba60f03b Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 15:20:38 +0200 Subject: [PATCH 0969/1106] don't use trade.update directly! --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a297f1823..ff2d1d759 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1032,7 +1032,7 @@ class FreqtradeBot: trade.sell_reason = sell_reason.value # In case of market sell orders the order can be closed immediately if order.get('status', 'unknown') == 'closed': - trade.update(order) + self.update_trade_state(trade, order) Trade.session.flush() # Lock pair for one candle to prevent immediate rebuys From b93d33a93a652c3c870d43a1ca75b4c7aadbe39b Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 15:30:49 +0200 Subject: [PATCH 0970/1106] Fix mock order dicts --- tests/conftest.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d95475b8c..621f45407 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -779,7 +779,7 @@ def limit_buy_order(): 'id': 'mocked_limit_buy', 'type': 'limit', 'side': 'buy', - 'pair': 'mocked', + 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -795,7 +795,7 @@ def market_buy_order(): 'id': 'mocked_market_buy', 'type': 'market', 'side': 'buy', - 'pair': 'mocked', + 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004099, 'amount': 91.99181073, @@ -811,7 +811,7 @@ def market_sell_order(): 'id': 'mocked_limit_sell', 'type': 'market', 'side': 'sell', - 'pair': 'mocked', + 'symbol': 'mocked', 'datetime': arrow.utcnow().isoformat(), 'price': 0.00004173, 'amount': 91.99181073, @@ -827,7 +827,7 @@ def limit_buy_order_old(): 'id': 'mocked_limit_buy_old', 'type': 'limit', 'side': 'buy', - 'pair': 'mocked', + 'symbol': 'mocked', 'datetime': str(arrow.utcnow().shift(minutes=-601).datetime), 'price': 0.00001099, 'amount': 90.99181073, @@ -843,7 +843,7 @@ def limit_sell_order_old(): 'id': 'mocked_limit_sell_old', 'type': 'limit', 'side': 'sell', - 'pair': 'ETH/BTC', + 'symbol': 'ETH/BTC', 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -859,7 +859,7 @@ def limit_buy_order_old_partial(): 'id': 'mocked_limit_buy_old_partial', 'type': 'limit', 'side': 'buy', - 'pair': 'ETH/BTC', + 'symbol': 'ETH/BTC', 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), 'price': 0.00001099, 'amount': 90.99181073, @@ -1482,7 +1482,7 @@ def buy_order_fee(): 'id': 'mocked_limit_buy_old', 'type': 'limit', 'side': 'buy', - 'pair': 'mocked', + 'symbol': 'mocked', 'datetime': str(arrow.utcnow().shift(minutes=-601).datetime), 'price': 0.245441, 'amount': 8.0, From fdcc507f06ff725a7c0053676509ba049c7e8129 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 15:35:57 +0200 Subject: [PATCH 0971/1106] Fix integration tests --- tests/test_integration.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index c40da7e9d..ee6ef3cb2 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -67,7 +67,6 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', create_stoploss_order=MagicMock(return_value=True), - update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock) @@ -97,8 +96,9 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, # Only order for 3rd trade needs to be cancelled assert cancel_order_mock.call_count == 1 - # Wallets must be updated between stoploss cancellation and selling. - assert wallets_mock.call_count == 2 + # Wallets must be updated between stoploss cancellation and selling, and will be updated again + # During update_trade_state + assert wallets_mock.call_count == 3 trade = trades[0] assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value @@ -144,7 +144,6 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', create_stoploss_order=MagicMock(return_value=True), - update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) should_sell_mock = MagicMock(side_effect=[ From a2ff6326470afde76cdfe9d70966d83151afbded Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 16:00:42 +0200 Subject: [PATCH 0972/1106] Add update_fee method to persistence --- freqtrade/persistence.py | 18 ++++++++++++++++++ tests/test_persistence.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 36e2c7ffd..fec095daa 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -376,6 +376,24 @@ class Trade(_DECL_BASE): self ) + def update_fee(self, fee_cost: float, fee_currency: Optional[str], fee_rate: Optional[float], + side: str) -> None: + """ + Update Fee parameters. Only acts once per side + """ + if side == 'buy' and self.fee_open_currency is None: + self.fee_open_cost = fee_cost + self.fee_open_currency = fee_currency + if fee_rate is not None: + self.fee_open = fee_rate + # Assume close-fee will fall into the same fee category and take an educated guess + self.fee_close = fee_rate + elif side == 'sell' and self.fee_close_currency is None: + self.fee_close_cost = fee_cost + self.fee_close_currency = fee_currency + if fee_rate is not None: + self.fee_close = fee_rate + def _calc_open_trade_price(self) -> float: """ Calculate the open_rate including open_fee. diff --git a/tests/test_persistence.py b/tests/test_persistence.py index aa3a59b87..fa6f84ce0 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -874,6 +874,39 @@ def test_stoploss_reinitialization(default_conf, fee): assert trade_adj.initial_stop_loss_pct == -0.04 +def test_update_fee(fee): + trade = Trade( + pair='ETH/BTC', + stake_amount=0.001, + fee_open=fee.return_value, + open_date=arrow.utcnow().shift(hours=-2).datetime, + amount=10, + fee_close=fee.return_value, + exchange='bittrex', + open_rate=1, + max_rate=1, + ) + fee_cost = 0.15 + fee_currency = 'BTC' + fee_rate = 0.0075 + assert trade.fee_open_currency is None + + trade.update_fee(fee_cost, fee_currency, fee_rate, 'buy') + assert trade.fee_open_currency == fee_currency + assert trade.fee_open_cost == fee_cost + assert trade.fee_open == fee_rate + # Setting buy rate should "guess" close rate + assert trade.fee_close == fee_rate + assert trade.fee_close_currency is None + assert trade.fee_close_cost is None + + fee_rate = 0.0076 + trade.update_fee(fee_cost, fee_currency, fee_rate, 'sell') + assert trade.fee_close == 0.0076 + assert trade.fee_close_cost == fee_cost + assert trade.fee_close == fee_rate + + @pytest.mark.usefixtures("init_persistence") def test_total_open_trades_stakes(fee): From 371100a97c049d4090358b97c36d4372ebfe8616 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 16:01:33 +0200 Subject: [PATCH 0973/1106] Update fee handling --- freqtrade/freqtradebot.py | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ff2d1d759..063712ed8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1167,20 +1167,25 @@ class FreqtradeBot: Get real amount for the trade Necessary for exchanges which charge fees in base currency (e.g. binance) """ + fee_currency = None + # Init variables if order_amount is None: order_amount = order['amount'] # Only run for closed orders - if trade.fee_open == 0 or order['status'] == 'open': + if trade.fee_open_currency is not None or order['status'] == 'open': return order_amount trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible - if self._order_has_fee(order): - if trade_base_currency == order['fee']['currency']: - new_amount = order_amount - order['fee']['cost'] - logger.info("Applying fee on amount for %s (from %s to %s) from Order", - trade, order['amount'], new_amount) - return new_amount + if self.exchange.order_has_fee(order): + fee_cost, fee_currency, fee_rate = self.exchange.extract_cost_curr_rate(order) + logger.info(f"Fee for Trade {trade}: {fee_cost:.8g} {fee_currency} - rate: {fee_rate}") + if trade_base_currency == fee_currency: + order_amount = order_amount - fee_cost + logger.info(f"Applying fee on amount for {trade} (from {order['amount']} " + f"to {order_amount}) from Order") + trade.update_fee(fee_cost, fee_currency, fee_rate, order['side']) + return order_amount # Fallback to Trades trades = self.exchange.get_trades_for_order(trade.open_order_id, trade.pair, @@ -1190,13 +1195,25 @@ class FreqtradeBot: logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade) return order_amount amount = 0 - fee_abs = 0 + fee_abs = 0.0 + fee_cost = 0.0 + fee_rate_array: List[float] = [] for exectrade in trades: amount += exectrade['amount'] - if self._order_has_fee(exectrade): + if self.exchange.order_has_fee(exectrade): + fee_cost_, fee_currency, fee_rate_ = self.exchange.extract_cost_curr_rate(exectrade) + fee_cost += fee_cost_ + if fee_rate_ is not None: + fee_rate_array.append(fee_rate_) # only applies if fee is in quote currency! - if trade_base_currency == exectrade['fee']['currency']: - fee_abs += exectrade['fee']['cost'] + if trade_base_currency == fee_currency: + fee_abs += fee_cost_ + # Ensure at least one trade was found: + if fee_currency: + # fee_rate should use mean + + fee_rate = sum(fee_rate_array) / float(len(fee_rate_array)) if fee_rate_array else None + trade.update_fee(fee_cost, fee_currency, fee_rate, order['side']) if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): logger.warning(f"Amount {amount} does not match amount {trade.amount}") From 7558e4bffe6fdcb5a2883f16d5b817defb56f59f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 16:13:07 +0200 Subject: [PATCH 0974/1106] Split fee detection from trades from general logic --- freqtrade/freqtradebot.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 063712ed8..ed228f6ad 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1164,10 +1164,12 @@ class FreqtradeBot: def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ - Get real amount for the trade + Detect and update trade fee. + Calls trade.update_fee() uppon correct detection. + Returns modified amount if the fee was taken from the destination currency. Necessary for exchanges which charge fees in base currency (e.g. binance) + :return: identical (or new) amount for the trade """ - fee_currency = None # Init variables if order_amount is None: order_amount = order['amount'] @@ -1186,17 +1188,23 @@ class FreqtradeBot: f"to {order_amount}) from Order") trade.update_fee(fee_cost, fee_currency, fee_rate, order['side']) return order_amount + return self.fee_detection_from_trades(trade, order, order_amount) - # Fallback to Trades + def fee_detection_from_trades(self, trade: Trade, order: Dict, order_amount: float) -> float: + """ + fee-detection fallback to Trades. Parses result of fetch_my_trades to get correct fee. + """ trades = self.exchange.get_trades_for_order(trade.open_order_id, trade.pair, trade.open_date) if len(trades) == 0: logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade) return order_amount + fee_currency = None amount = 0 fee_abs = 0.0 fee_cost = 0.0 + trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) fee_rate_array: List[float] = [] for exectrade in trades: amount += exectrade['amount'] From 40d4949f0669423c89011a98b804f41a437815d0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 17:46:01 +0200 Subject: [PATCH 0975/1106] Don't handle trades if they've just been closed. --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ed228f6ad..72531c9f9 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -610,7 +610,7 @@ class FreqtradeBot: trades_closed += 1 continue # Check if we can sell our current pair - if trade.open_order_id is None and self.handle_trade(trade): + if trade.open_order_id is None and trade.is_open and self.handle_trade(trade): trades_closed += 1 except DependencyException as exception: From 509f38d3aaacb94a6b6278d59a8bce8a79d642f9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 17:59:24 +0200 Subject: [PATCH 0976/1106] Use non-deprectated parameter for progressbar --- 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 12310311c..02695d1aa 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -648,7 +648,7 @@ class Hyperopt: ' [', progressbar.ETA(), ', ', progressbar.Timer(), ']', ] with progressbar.ProgressBar( - maxval=self.total_epochs, redirect_stdout=False, redirect_stderr=False, + max_value=self.total_epochs, redirect_stdout=False, redirect_stderr=False, widgets=widgets ) as pbar: EVALS = ceil(self.total_epochs / jobs) From bd51cd332bc89801ea3e4af4ee4e217833e7bd79 Mon Sep 17 00:00:00 2001 From: jpribyl Date: Fri, 24 Apr 2020 16:16:52 -0600 Subject: [PATCH 0977/1106] Cancel all open orders after receiving /stop or ctrl+c --- config.json.example | 1 + config_binance.json.example | 1 + config_full.json.example | 1 + config_kraken.json.example | 1 + docs/configuration.md | 1 + freqtrade/commands/arguments.py | 2 +- freqtrade/commands/cli_options.py | 5 ++ freqtrade/configuration/configuration.py | 5 ++ freqtrade/constants.py | 8 ++ freqtrade/freqtradebot.py | 108 +++++++++++++++-------- freqtrade/templates/base_config.json.j2 | 1 + freqtrade/worker.py | 3 +- tests/conftest.py | 1 + tests/test_arguments.py | 8 ++ tests/test_configuration.py | 2 + tests/test_freqtradebot.py | 28 +++--- 16 files changed, 124 insertions(+), 52 deletions(-) diff --git a/config.json.example b/config.json.example index 8ebb092e1..d37a6b336 100644 --- a/config.json.example +++ b/config.json.example @@ -6,6 +6,7 @@ "fiat_display_currency": "USD", "ticker_interval": "5m", "dry_run": false, + "cancel_open_orders_on_exit": false, "trailing_stop": false, "unfilledtimeout": { "buy": 10, diff --git a/config_binance.json.example b/config_binance.json.example index d324ce883..5d7b6b656 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -6,6 +6,7 @@ "fiat_display_currency": "USD", "ticker_interval": "5m", "dry_run": true, + "cancel_open_orders_on_exit": false, "trailing_stop": false, "unfilledtimeout": { "buy": 10, diff --git a/config_full.json.example b/config_full.json.example index 181740b9a..79154b0d4 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -8,6 +8,7 @@ "amend_last_stake_amount": false, "last_stake_amount_min_ratio": 0.5, "dry_run": false, + "cancel_open_orders_on_exit": false, "ticker_interval": "5m", "trailing_stop": false, "trailing_stop_positive": 0.005, diff --git a/config_kraken.json.example b/config_kraken.json.example index dcf4c552a..54fbf4a00 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -6,6 +6,7 @@ "fiat_display_currency": "EUR", "ticker_interval": "5m", "dry_run": true, + "cancel_open_orders_on_exit": false, "trailing_stop": false, "unfilledtimeout": { "buy": 10, diff --git a/docs/configuration.md b/docs/configuration.md index 67e8578dd..28df5bd95 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -51,6 +51,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
      **Datatype:** String | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
      *Defaults to `true`.*
      **Datatype:** Boolean | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
      *Defaults to `1000`.*
      **Datatype:** Float +| `cancel_open_orders_on_exit` | Cancel orders when `/stop` is issued or `ctrl+c` is pressed. Including this will allow you to use `/stop` to cancel unfilled orders in the event of a market crash. This will not impact open positions.
      *Defaults to `False`.*
      **Datatype:** Boolean | `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
      *Defaults to `false`.*
      **Datatype:** Boolean | `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
      **Datatype:** Dict | `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
      **Datatype:** Float (as ratio) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 8c64c5857..be03bb906 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -13,7 +13,7 @@ ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_dat ARGS_STRATEGY = ["strategy", "strategy_path"] -ARGS_TRADE = ["db_url", "sd_notify", "dry_run"] +ARGS_TRADE = ["db_url", "sd_notify", "dry_run", "cancel_open_orders_on_exit"] ARGS_COMMON_OPTIMIZE = ["ticker_interval", "timerange", "max_open_trades", "stake_amount", "fee"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 498ea9359..adb28399a 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -109,6 +109,11 @@ AVAILABLE_CLI_OPTIONS = { help='Enforce dry-run for trading (removes Exchange secrets and simulates trades).', action='store_true', ), + "cancel_open_orders_on_exit": Arg( + '--cancel-open-orders-on-exit', + help='Close unfilled open orders when the bot stops / exits', + action='store_true', + ), # Optimize common "ticker_interval": Arg( '-i', '--ticker-interval', diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index e5515670d..cfbba9987 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -134,6 +134,11 @@ class Configuration: if config['runmode'] not in TRADING_MODES: return + if self.args.get('cancel_open_orders_on_exit', False): + config.update({ + 'cancel_open_orders_on_exit': self.args.get('cancel_open_orders_on_exit') + }) + if config.get('dry_run', False): logger.info('Dry run is enabled') if config.get('db_url') in [None, constants.DEFAULT_DB_PROD_URL]: diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 54f620631..c238f227b 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -85,6 +85,7 @@ CONF_SCHEMA = { 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, + 'cancel_open_orders_on_exit': {'type': 'boolean', 'default': False}, 'process_only_new_candles': {'type': 'boolean'}, 'minimal_roi': { 'type': 'object', @@ -318,3 +319,10 @@ SCHEMA_MINIMAL_REQUIRED = [ 'dataformat_ohlcv', 'dataformat_trades', ] + +CANCEL_REASON = { + "TIMEOUT": "cancelled due to timeout", + "PARTIALLY_FILLED": "partially filled - keeping order open", + "ALL_CANCELLED": "cancelled (all unfilled orders cancelled)", + "CANCELLED_ON_EXCHANGE": "cancelled on exchange", +} diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7ae87e807..5b8d59ed2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -113,6 +113,9 @@ class FreqtradeBot: """ logger.info('Cleaning up modules ...') + if self.config['cancel_open_orders_on_exit']: + self.cancel_all_open_orders() + self.rpc.cleanup() persistence.cleanup() @@ -162,6 +165,13 @@ class FreqtradeBot: Trade.session.flush() + def process_stopped(self) -> None: + """ + Close all trades that were left open + """ + if self.config['cancel_open_orders_on_exit']: + self.cancel_all_open_orders() + def _refresh_whitelist(self, trades: List[Trade] = []) -> List[str]: """ Refresh whitelist from pairlist or edge and extend it with trades. @@ -875,11 +885,7 @@ class FreqtradeBot: default_retval=False)(pair=trade.pair, trade=trade, order=order))): - - self.handle_timedout_limit_buy(trade, order) - self.wallets.update() - order_type = self.strategy.order_types['buy'] - self._notify_buy_cancel(trade, order_type) + self.handle_cancel_buy(trade, order, constants.CANCEL_REASON['TIMEOUT']) elif (order['side'] == 'sell' and ( trade_state_update @@ -888,24 +894,42 @@ class FreqtradeBot: default_retval=False)(pair=trade.pair, trade=trade, order=order))): - reason = self.handle_timedout_limit_sell(trade, order) - self.wallets.update() - order_type = self.strategy.order_types['sell'] - self._notify_sell_cancel(trade, order_type, reason) + self.handle_cancel_sell(trade, order, constants.CANCEL_REASON['TIMEOUT']) - def handle_timedout_limit_buy(self, trade: Trade, order: Dict) -> bool: + def cancel_all_open_orders(self) -> None: """ - Buy timeout - cancel order + Cancel all orders that are currently open + :return: None + """ + + for trade in Trade.get_open_order_trades(): + try: + order = self.exchange.get_order(trade.open_order_id, trade.pair) + except (DependencyException, InvalidOrderException): + logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc()) + continue + + if order['side'] == 'buy': + self.handle_cancel_buy(trade, order, constants.CANCEL_REASON['ALL_CANCELLED']) + + elif order['side'] == 'sell': + self.handle_cancel_sell(trade, order, constants.CANCEL_REASON['ALL_CANCELLED']) + + def handle_cancel_buy(self, trade: Trade, order: Dict, reason: str) -> bool: + """ + Buy cancel - cancel order :return: True if order was fully cancelled """ + was_trade_fully_canceled = False + if order['status'] != 'canceled': - reason = "cancelled due to timeout" + reason = constants.CANCEL_REASON['TIMEOUT'] corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, trade.amount) else: # Order was cancelled already, so we can reuse the existing dict corder = order - reason = "cancelled on exchange" + reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE'] logger.info('Buy order %s for %s.', reason, trade) @@ -914,40 +938,42 @@ class FreqtradeBot: # if trade is not partially completed, just delete the trade Trade.session.delete(trade) Trade.session.flush() - return True + was_trade_fully_canceled = True + else: + # if trade is partially complete, edit the stake details for the trade + # and close the order + # cancel_order may not contain the full order dict, so we need to fallback + # to the order dict aquired before cancelling. + # we need to fall back to the values from order if corder does not contain these keys. + trade.amount = order['amount'] - safe_value_fallback(corder, order, + 'remaining', 'remaining') + trade.stake_amount = trade.amount * trade.open_rate + self.update_trade_state(trade, corder, trade.amount) - # if trade is partially complete, edit the stake details for the trade - # and close the order - # cancel_order may not contain the full order dict, so we need to fallback - # to the order dict aquired before cancelling. - # we need to fall back to the values from order if corder does not contain these keys. - trade.amount = order['amount'] - safe_value_fallback(corder, order, - 'remaining', 'remaining') - trade.stake_amount = trade.amount * trade.open_rate - self.update_trade_state(trade, corder, trade.amount) + trade.open_order_id = None + logger.info('Partial buy order timeout for %s.', trade) + self.rpc.send_msg({ + 'type': RPCMessageType.STATUS_NOTIFICATION, + 'status': f'Remaining buy order for {trade.pair} cancelled due to timeout' + }) - trade.open_order_id = None - logger.info('Partial buy order timeout for %s.', trade) - self.rpc.send_msg({ - 'type': RPCMessageType.STATUS_NOTIFICATION, - 'status': f'Remaining buy order for {trade.pair} cancelled due to timeout' - }) - return False + self.wallets.update() + self._notify_buy_cancel(trade, order_type=self.strategy.order_types['buy']) + return was_trade_fully_canceled - def handle_timedout_limit_sell(self, trade: Trade, order: Dict) -> str: + def handle_cancel_sell(self, trade: Trade, order: Dict, reason: str) -> str: """ - Sell timeout - cancel order and update trade + Sell cancel - cancel order and update trade :return: Reason for cancel """ # if trade is not partially completed, just cancel the trade if order['remaining'] == order['amount'] or order.get('filled') == 0.0: if not self.exchange.check_order_canceled_empty(order): - reason = "cancelled due to timeout" # if trade is not partially completed, just delete the trade self.exchange.cancel_order(trade.open_order_id, trade.pair) logger.info('Sell order %s for %s.', reason, trade) else: - reason = "cancelled on exchange" + reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE'] logger.info('Sell order %s for %s.', reason, trade) trade.close_rate = None @@ -957,11 +983,17 @@ class FreqtradeBot: trade.close_date = None trade.is_open = True trade.open_order_id = None + else: + # TODO: figure out how to handle partially complete sell orders + reason = constants.CANCEL_REASON['PARTIALLY_FILLED'] - return reason - - # TODO: figure out how to handle partially complete sell orders - return 'partially filled - keeping order open' + self.wallets.update() + self._notify_sell_cancel( + trade, + order_type=self.strategy.order_types['sell'], + reason=reason + ) + return reason def _safe_sell_amount(self, pair: str, amount: float) -> float: """ diff --git a/freqtrade/templates/base_config.json.j2 b/freqtrade/templates/base_config.json.j2 index 134719273..6d3174347 100644 --- a/freqtrade/templates/base_config.json.j2 +++ b/freqtrade/templates/base_config.json.j2 @@ -6,6 +6,7 @@ "fiat_display_currency": "{{ fiat_display_currency }}", "ticker_interval": "{{ ticker_interval }}", "dry_run": {{ dry_run | lower }}, + "cancel_open_orders_on_exit": false, "unfilledtimeout": { "buy": 10, "sell": 30 diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 4c28ecaeb..55cf30d16 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -131,8 +131,7 @@ class Worker: return result def _process_stopped(self) -> None: - # Maybe do here something in the future... - pass + self.freqtrade.process_stopped() def _process_running(self) -> None: try: diff --git a/tests/conftest.py b/tests/conftest.py index d95475b8c..2f5f468f6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -249,6 +249,7 @@ def default_conf(testdatadir): "fiat_display_currency": "USD", "ticker_interval": '5m', "dry_run": True, + "cancel_open_orders_on_exit": False, "minimal_roi": { "40": 0.0, "30": 0.01, diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 0052a61d0..91501384b 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -64,6 +64,14 @@ def test_parse_args_db_url() -> None: assert args["db_url"] == 'sqlite:///test.sqlite' +def test_parse_args_cancel_open_orders_on_exit() -> None: + args = Arguments(['trade']).get_parsed_arg() + assert args["cancel_open_orders_on_exit"] is False + + args = Arguments(['trade', '--cancel-open-orders-on-exit']).get_parsed_arg() + assert args["cancel_open_orders_on_exit"] is True + + def test_parse_args_verbose() -> None: args = Arguments(['trade', '-v']).get_parsed_arg() assert args["verbosity"] == 1 diff --git a/tests/test_configuration.py b/tests/test_configuration.py index c89f1381e..0315ffe1b 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -250,6 +250,7 @@ def test_load_config_with_params(default_conf, mocker) -> None: '--strategy', 'TestStrategy', '--strategy-path', '/some/path', '--db-url', 'sqlite:///someurl', + '--cancel-open-orders-on-exit', ] args = Arguments(arglist).get_parsed_arg() configuration = Configuration(args) @@ -258,6 +259,7 @@ def test_load_config_with_params(default_conf, mocker) -> None: assert validated_conf.get('strategy') == 'TestStrategy' assert validated_conf.get('strategy_path') == '/some/path' assert validated_conf.get('db_url') == 'sqlite:///someurl' + assert validated_conf.get('cancel_open_orders_on_exit') is True # Test conf provided db_url prod conf = default_conf.copy() diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6f2ce9f3c..8adc834cf 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -11,7 +11,7 @@ import arrow import pytest import requests -from freqtrade.constants import MATH_CLOSE_PREC, UNLIMITED_STAKE_AMOUNT +from freqtrade.constants import MATH_CLOSE_PREC, UNLIMITED_STAKE_AMOUNT, CANCEL_REASON from freqtrade.exceptions import (DependencyException, InvalidOrderException, OperationalException, TemporaryError) from freqtrade.freqtradebot import FreqtradeBot @@ -2281,8 +2281,8 @@ def test_check_handle_timedout_exception(default_conf, ticker, open_trade, mocke mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', - handle_timedout_limit_buy=MagicMock(), - handle_timedout_limit_sell=MagicMock(), + handle_cancel_buy=MagicMock(), + handle_cancel_sell=MagicMock(), ) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -2309,21 +2309,23 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order mocker.patch('freqtrade.exchange.Exchange.cancel_order_with_result', cancel_order_mock) freqtrade = FreqtradeBot(default_conf) + freqtrade._notify_buy_cancel = MagicMock() Trade.session = MagicMock() trade = MagicMock() trade.pair = 'LTC/ETH' limit_buy_order['remaining'] = limit_buy_order['amount'] - assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + reason = CANCEL_REASON['TIMEOUT'] + assert freqtrade.handle_cancel_buy(trade, limit_buy_order, reason) assert cancel_order_mock.call_count == 1 cancel_order_mock.reset_mock() limit_buy_order['amount'] = 2 - assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason) assert cancel_order_mock.call_count == 1 mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException) - assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason) @pytest.mark.parametrize('cancelorder', [ @@ -2343,17 +2345,19 @@ def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_ ) freqtrade = FreqtradeBot(default_conf) + freqtrade._notify_buy_cancel = MagicMock() Trade.session = MagicMock() trade = MagicMock() trade.pair = 'LTC/ETH' limit_buy_order['remaining'] = limit_buy_order['amount'] - assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + reason = CANCEL_REASON['TIMEOUT'] + assert freqtrade.handle_cancel_buy(trade, limit_buy_order, reason) assert cancel_order_mock.call_count == 1 cancel_order_mock.reset_mock() limit_buy_order['amount'] = 2 - assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) + assert not freqtrade.handle_cancel_buy(trade, limit_buy_order, reason) assert cancel_order_mock.call_count == 1 @@ -2367,16 +2371,18 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None: ) freqtrade = FreqtradeBot(default_conf) + freqtrade._notify_sell_cancel = MagicMock() trade = MagicMock() order = {'remaining': 1, 'amount': 1, 'status': "open"} - assert freqtrade.handle_timedout_limit_sell(trade, order) + reason = CANCEL_REASON['TIMEOUT'] + assert freqtrade.handle_cancel_sell(trade, order, reason) assert cancel_order_mock.call_count == 1 order['amount'] = 2 - assert (freqtrade.handle_timedout_limit_sell(trade, order) - == 'partially filled - keeping order open') + assert (freqtrade.handle_cancel_sell(trade, order, reason) + == CANCEL_REASON['PARTIALLY_FILLED']) # Assert cancel_order was not called (callcount remains unchanged) assert cancel_order_mock.call_count == 1 From 6b33d5af1e440253019a125551423f52fa26d7d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 19:51:35 +0200 Subject: [PATCH 0978/1106] Fix fee-calculation for dry-run orders --- freqtrade/exchange/exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ebadd4c8a..b7547cacb 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -494,7 +494,7 @@ class Exchange: 'remaining': 0, 'fee': { 'currency': self.get_pair_quote_currency(pair), - 'cost': dry_order['amount'] * self.get_fee(pair), + 'cost': dry_order['cost'] * self.get_fee(pair), 'rate': self.get_fee(pair) } }) From 6d620ba1f6946b5b79a95ec3cc1c3c63ec8f5a1f Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 19:54:16 +0200 Subject: [PATCH 0979/1106] Verify if fee for this side has been updated --- freqtrade/freqtradebot.py | 2 +- freqtrade/persistence.py | 9 +++++++++ tests/test_persistence.py | 6 ++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 72531c9f9..a3dd29771 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1174,7 +1174,7 @@ class FreqtradeBot: if order_amount is None: order_amount = order['amount'] # Only run for closed orders - if trade.fee_open_currency is not None or order['status'] == 'open': + if trade.fee_updated(order['side']) or order['status'] == 'open': return order_amount trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index fec095daa..a541dcbcc 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -394,6 +394,15 @@ class Trade(_DECL_BASE): if fee_rate is not None: self.fee_close = fee_rate + def fee_updated(self, side: str) -> bool: + """ + Verify if this side (buy / sell) has already been updated + """ + if side == 'buy': + return self.fee_open_currency is not None + elif side == 'sell': + return self.fee_close_currency is not None + def _calc_open_trade_price(self) -> float: """ Calculate the open_rate including open_fee. diff --git a/tests/test_persistence.py b/tests/test_persistence.py index fa6f84ce0..1a42d95fe 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -890,8 +890,12 @@ def test_update_fee(fee): fee_currency = 'BTC' fee_rate = 0.0075 assert trade.fee_open_currency is None + assert not trade.fee_updated('buy') + assert not trade.fee_updated('sell') trade.update_fee(fee_cost, fee_currency, fee_rate, 'buy') + assert trade.fee_updated('buy') + assert not trade.fee_updated('sell') assert trade.fee_open_currency == fee_currency assert trade.fee_open_cost == fee_cost assert trade.fee_open == fee_rate @@ -902,6 +906,8 @@ def test_update_fee(fee): fee_rate = 0.0076 trade.update_fee(fee_cost, fee_currency, fee_rate, 'sell') + assert trade.fee_updated('buy') + assert trade.fee_updated('sell') assert trade.fee_close == 0.0076 assert trade.fee_close_cost == fee_cost assert trade.fee_close == fee_rate From 71c90422ba5f4c34b8689864d35c92cee0c5e8d5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 20:02:38 +0200 Subject: [PATCH 0980/1106] Add explicit test for fee_updated --- freqtrade/persistence.py | 2 ++ tests/test_persistence.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index a541dcbcc..ea34fd5bf 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -402,6 +402,8 @@ class Trade(_DECL_BASE): return self.fee_open_currency is not None elif side == 'sell': return self.fee_close_currency is not None + else: + return False def _calc_open_trade_price(self) -> float: """ diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 1a42d95fe..5c7686e28 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -913,6 +913,36 @@ def test_update_fee(fee): assert trade.fee_close == fee_rate +def test_fee_updated(fee): + trade = Trade( + pair='ETH/BTC', + stake_amount=0.001, + fee_open=fee.return_value, + open_date=arrow.utcnow().shift(hours=-2).datetime, + amount=10, + fee_close=fee.return_value, + exchange='bittrex', + open_rate=1, + max_rate=1, + ) + + assert trade.fee_open_currency is None + assert not trade.fee_updated('buy') + assert not trade.fee_updated('sell') + assert not trade.fee_updated('asdf') + + trade.update_fee(0.15, 'BTC', 0.0075, 'buy') + assert trade.fee_updated('buy') + assert not trade.fee_updated('sell') + assert trade.fee_open_currency is not None + assert trade.fee_close_currency is None + + trade.update_fee(0.15, 'ABC', 0.0075, 'sell') + assert trade.fee_updated('buy') + assert trade.fee_updated('sell') + assert not trade.fee_updated('asfd') + + @pytest.mark.usefixtures("init_persistence") def test_total_open_trades_stakes(fee): From 737fc6d19837c816504c7dd910e9ec702fe1bc57 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 20:03:06 +0200 Subject: [PATCH 0981/1106] Fix bug when querying side --- freqtrade/freqtradebot.py | 9 +++++---- freqtrade/persistence.py | 2 +- tests/test_freqtradebot.py | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a3dd29771..d0a9a8348 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1174,19 +1174,20 @@ class FreqtradeBot: if order_amount is None: order_amount = order['amount'] # Only run for closed orders - if trade.fee_updated(order['side']) or order['status'] == 'open': + if trade.fee_updated(order.get('side')) or order['status'] == 'open': return order_amount trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) # use fee from order-dict if possible if self.exchange.order_has_fee(order): fee_cost, fee_currency, fee_rate = self.exchange.extract_cost_curr_rate(order) - logger.info(f"Fee for Trade {trade}: {fee_cost:.8g} {fee_currency} - rate: {fee_rate}") + logger.info(f"Fee for Trade {trade} [{order.get('side')}]: " + f"{fee_cost:.8g} {fee_currency} - rate: {fee_rate}") if trade_base_currency == fee_currency: order_amount = order_amount - fee_cost logger.info(f"Applying fee on amount for {trade} (from {order['amount']} " f"to {order_amount}) from Order") - trade.update_fee(fee_cost, fee_currency, fee_rate, order['side']) + trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side')) return order_amount return self.fee_detection_from_trades(trade, order, order_amount) @@ -1221,7 +1222,7 @@ class FreqtradeBot: # fee_rate should use mean fee_rate = sum(fee_rate_array) / float(len(fee_rate_array)) if fee_rate_array else None - trade.update_fee(fee_cost, fee_currency, fee_rate, order['side']) + trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side')) if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): logger.warning(f"Amount {amount} does not match amount {trade.amount}") diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index ea34fd5bf..0f2c6bb52 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -394,7 +394,7 @@ class Trade(_DECL_BASE): if fee_rate is not None: self.fee_close = fee_rate - def fee_updated(self, side: str) -> bool: + def fee_updated(self, side) -> bool: """ Verify if this side (buy / sell) has already been updated """ diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 43ee4c79d..cf5d30a79 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3541,6 +3541,7 @@ def test_get_real_amount_open_trade(default_conf, fee, mocker): 'id': 'mocked_order', 'amount': amount, 'status': 'open', + 'side': 'buy', } freqtrade = get_patched_freqtradebot(mocker, default_conf) assert freqtrade.get_real_amount(trade, order) == amount From 021e2b58ca87babab4d18f574cdc0ca435e1639d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 20:17:22 +0200 Subject: [PATCH 0982/1106] Support partially cancelled orders for fee calculation --- freqtrade/exchange/exchange.py | 3 ++- freqtrade/freqtradebot.py | 2 -- freqtrade/persistence.py | 2 +- tests/conftest.py | 2 +- tests/test_freqtradebot.py | 5 +++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b7547cacb..e649e5ed2 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1095,7 +1095,8 @@ class Exchange: # Calculate fee based on order details if fee_curr in self.get_pair_base_currency(order['symbol']): # Base currency - divide by amount - return round(order['fee']['cost'] / order['amount'], 8) + return round( + order['fee']['cost'] / safe_value_fallback(order, order, 'filled', 'amount'), 8) elif fee_curr in self.get_pair_quote_currency(order['symbol']): # Quote currency - divide by cost return round(order['fee']['cost'] / order['cost'], 8) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d0a9a8348..32adc6d57 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1144,8 +1144,6 @@ class FreqtradeBot: if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): order['amount'] = new_amount order.pop('filled', None) - # Fee was applied, so set to 0 - trade.fee_open = 0 trade.recalc_open_trade_price() except DependencyException as exception: logger.warning("Could not update trade amount: %s", exception) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 0f2c6bb52..17246633c 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -377,7 +377,7 @@ class Trade(_DECL_BASE): ) def update_fee(self, fee_cost: float, fee_currency: Optional[str], fee_rate: Optional[float], - side: str) -> None: + side) -> None: """ Update Fee parameters. Only acts once per side """ diff --git a/tests/conftest.py b/tests/conftest.py index 621f45407..10885d667 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -873,7 +873,7 @@ def limit_buy_order_old_partial(): def limit_buy_order_old_partial_canceled(limit_buy_order_old_partial): res = deepcopy(limit_buy_order_old_partial) res['status'] = 'canceled' - res['fee'] = {'cost': 0.0001, 'currency': 'ETH'} + res['fee'] = {'cost': 0.023, 'currency': 'ETH'} return res diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index cf5d30a79..19a094fab 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2229,9 +2229,10 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap assert len(trades) == 1 # Verify that trade has been updated assert trades[0].amount == (limit_buy_order_old_partial['amount'] - - limit_buy_order_old_partial['remaining']) - 0.0001 + limit_buy_order_old_partial['remaining']) - 0.023 assert trades[0].open_order_id is None - assert trades[0].fee_open == 0 + assert trades[0].fee_updated('buy') + assert pytest.approx(trades[0].fee_open) == 0.001 def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade, caplog, fee, From 78b3d8487f8509c602818f1b241e524c5f24feac Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 1 May 2020 20:34:58 +0200 Subject: [PATCH 0983/1106] Add typehint --- freqtrade/freqtradebot.py | 6 +++--- freqtrade/persistence.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 32adc6d57..163c4faaa 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1172,7 +1172,7 @@ class FreqtradeBot: if order_amount is None: order_amount = order['amount'] # Only run for closed orders - if trade.fee_updated(order.get('side')) or order['status'] == 'open': + if trade.fee_updated(order.get('side', '')) or order['status'] == 'open': return order_amount trade_base_currency = self.exchange.get_pair_base_currency(trade.pair) @@ -1185,7 +1185,7 @@ class FreqtradeBot: order_amount = order_amount - fee_cost logger.info(f"Applying fee on amount for {trade} (from {order['amount']} " f"to {order_amount}) from Order") - trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side')) + trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', '')) return order_amount return self.fee_detection_from_trades(trade, order, order_amount) @@ -1220,7 +1220,7 @@ class FreqtradeBot: # fee_rate should use mean fee_rate = sum(fee_rate_array) / float(len(fee_rate_array)) if fee_rate_array else None - trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side')) + trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', '')) if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): logger.warning(f"Amount {amount} does not match amount {trade.amount}") diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 17246633c..ea34fd5bf 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -377,7 +377,7 @@ class Trade(_DECL_BASE): ) def update_fee(self, fee_cost: float, fee_currency: Optional[str], fee_rate: Optional[float], - side) -> None: + side: str) -> None: """ Update Fee parameters. Only acts once per side """ @@ -394,7 +394,7 @@ class Trade(_DECL_BASE): if fee_rate is not None: self.fee_close = fee_rate - def fee_updated(self, side) -> bool: + def fee_updated(self, side: str) -> bool: """ Verify if this side (buy / sell) has already been updated """ From 56bb5f7a111d4be4dc4c6bd59b5ab2dae9775c83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 May 2020 11:26:12 +0200 Subject: [PATCH 0984/1106] Add show-trades command --- freqtrade/commands/__init__.py | 3 ++- freqtrade/commands/arguments.py | 15 +++++++++++++-- freqtrade/commands/cli_options.py | 7 ++++++- freqtrade/commands/list_commands.py | 22 ++++++++++++++++++++++ freqtrade/configuration/configuration.py | 4 ++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/__init__.py b/freqtrade/commands/__init__.py index f80c74e05..2d0c7733c 100644 --- a/freqtrade/commands/__init__.py +++ b/freqtrade/commands/__init__.py @@ -19,7 +19,8 @@ from freqtrade.commands.list_commands import (start_list_exchanges, start_list_hyperopts, start_list_markets, start_list_strategies, - start_list_timeframes) + start_list_timeframes, + start_show_trades) from freqtrade.commands.optimize_commands import (start_backtesting, start_edge, start_hyperopt) from freqtrade.commands.pairlist_commands import start_test_pairlist diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 8c64c5857..a03da00ab 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -64,6 +64,8 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] +ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"] + ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_trades", "hyperopt_list_max_trades", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", @@ -78,7 +80,7 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", "list-markets", "list-pairs", "list-strategies", "list-hyperopts", "hyperopt-list", "hyperopt-show", - "plot-dataframe", "plot-profit"] + "plot-dataframe", "plot-profit", "show-trades"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] @@ -163,7 +165,7 @@ class Arguments: start_list_markets, start_list_strategies, start_list_timeframes, start_new_config, start_new_hyperopt, start_new_strategy, - start_plot_dataframe, start_plot_profit, + start_plot_dataframe, start_plot_profit, start_show_trades, start_backtesting, start_hyperopt, start_edge, start_test_pairlist, start_trading) @@ -330,6 +332,15 @@ class Arguments: plot_profit_cmd.set_defaults(func=start_plot_profit) self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd) + # Add show-trades subcommand + show_trades = subparsers.add_parser( + 'show-trades', + help='Show trades.', + parents=[_common_parser], + ) + show_trades.set_defaults(func=start_show_trades) + self._build_args(optionlist=ARGS_SHOW_TRADES, parser=show_trades) + # Add hyperopt-list subcommand hyperopt_list_cmd = subparsers.add_parser( 'hyperopt-list', diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 498ea9359..4c51802f0 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -217,7 +217,7 @@ AVAILABLE_CLI_OPTIONS = { ), "print_json": Arg( '--print-json', - help='Print best result detailization in JSON format.', + help='Print output in JSON format.', action='store_true', default=False, ), @@ -425,6 +425,11 @@ AVAILABLE_CLI_OPTIONS = { choices=["DB", "file"], default="file", ), + "trade_ids": Arg( + '--tradeids', + help='Specify Trade ids to trade', + nargs='+', + ), # hyperopt-list, hyperopt-show "hyperopt_list_profitable": Arg( '--profitable', diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 327901dc0..79e742618 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -197,3 +197,25 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: args.get('list_pairs_print_json', False) or args.get('print_csv', False)): print(f"{summary_str}.") + + +def start_show_trades(args: Dict[str, Any]) -> None: + """ + Show trades + """ + from freqtrade.persistence import init, Trade + import json + config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + init(config['db_url'], clean_open_orders=False) + tfilter = [] + + if config.get('trade_ids'): + tfilter.append(Trade.id.in_(config['trade_ids'])) + + trades = Trade.get_trades(tfilter) + logger.info("Printing Trades: ") + if config.get('print_json', False): + print(json.dumps([trade.to_json() for trade in trades], indent=4)) + else: + for trade in trades: + print(trade) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index e5515670d..7edd9bca1 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -351,8 +351,12 @@ class Configuration: self._args_to_config(config, argname='indicators2', logstring='Using indicators2: {}') + self._args_to_config(config, argname='trade_ids', + logstring='Filtering on trade_ids: {}') + self._args_to_config(config, argname='plot_limit', logstring='Limiting plot to: {}') + self._args_to_config(config, argname='trade_source', logstring='Using trades from: {}') From 1066a4504b58c91b51c85f6f2be2512ad27feaa0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 May 2020 11:44:18 +0200 Subject: [PATCH 0985/1106] Add test for show_trades --- freqtrade/commands/list_commands.py | 4 +-- tests/commands/test_commands.py | 41 +++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 79e742618..61d6f7244 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -212,8 +212,8 @@ def start_show_trades(args: Dict[str, Any]) -> None: if config.get('trade_ids'): tfilter.append(Trade.id.in_(config['trade_ids'])) - trades = Trade.get_trades(tfilter) - logger.info("Printing Trades: ") + trades = Trade.get_trades(tfilter).all() + logger.info(f"Printing {len(trades)} Trades: ") if config.get('print_json', False): print(json.dumps([trade.to_json() for trade in trades], indent=4)) else: diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 264ae9a63..0465858c0 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -10,11 +10,13 @@ from freqtrade.commands import (start_convert_data, start_create_userdir, start_list_hyperopts, start_list_markets, start_list_strategies, start_list_timeframes, start_new_hyperopt, start_new_strategy, - start_test_pairlist, start_trading) + start_show_trades, start_test_pairlist, + start_trading) from freqtrade.configuration import setup_utils_configuration from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, +from tests.conftest import (create_mock_trades, get_args, log_has, log_has_re, + patch_exchange, patched_configuration_load_config_file) @@ -1040,3 +1042,38 @@ def test_convert_data_trades(mocker, testdatadir): assert trades_mock.call_args[1]['convert_from'] == 'jsongz' assert trades_mock.call_args[1]['convert_to'] == 'json' assert trades_mock.call_args[1]['erase'] is False + + +@pytest.mark.usefixtures("init_persistence") +def test_show_trades(mocker, fee, capsys, caplog): + mocker.patch("freqtrade.persistence.init") + create_mock_trades(fee) + args = [ + "show-trades", + "--db-url", + "sqlite:///" + ] + pargs = get_args(args) + pargs['config'] = None + start_show_trades(pargs) + assert log_has("Printing 3 Trades: ", caplog) + captured = capsys.readouterr() + assert "Trade(id=1" in captured.out + assert "Trade(id=2" in captured.out + assert "Trade(id=3" in captured.out + args = [ + "show-trades", + "--db-url", + "sqlite:///", + "--print-json", + "--tradeids", "1", "2" + ] + pargs = get_args(args) + pargs['config'] = None + start_show_trades(pargs) + + captured = capsys.readouterr() + assert log_has("Printing 2 Trades: ", caplog) + assert '"trade_id": 1' in captured.out + assert '"trade_id": 2' in captured.out + assert '"trade_id": 3' not in captured.out From 7dcef58f15ea7954135b284001bff0c196c8d574 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 2 May 2020 11:50:48 +0200 Subject: [PATCH 0986/1106] Add show-trades to documentation --- docs/utils.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/utils.md b/docs/utils.md index 57210ac7e..12597220a 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -521,3 +521,48 @@ Prints JSON data with details for the last best epoch (i.e., the best of all epo ``` freqtrade hyperopt-show --best -n -1 --print-json --no-header ``` + +## Show trades + +Print selected (or all) trades from database to screen. + +``` +usage: freqtrade show-trades [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--db-url PATH] + [--tradeids TRADE_IDS [TRADE_IDS ...]] + [--print-json] + +optional arguments: + -h, --help show this help message and exit + --db-url PATH Override trades database URL, this is useful in custom + deployments (default: `sqlite:///tradesv3.sqlite` for + Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for + Dry Run). + --tradeids TRADE_IDS [TRADE_IDS ...] + Specify Trade ids to trade + --print-json Print output in JSON format. + +Common arguments: + -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified. Special values are: + 'syslog', 'journald'. See the documentation for more + details. + -V, --version show program's version number and exit + -c PATH, --config PATH + Specify configuration file (default: + `userdir/config.json` or `config.json` whichever + exists). Multiple --config options may be used. Can be + set to `-` to read config from stdin. + -d PATH, --datadir PATH + Path to directory with historical backtesting data. + --userdir PATH, --user-data-dir PATH + Path to userdata directory. +``` + +### Examples + +Print trades with id 2 and 3 as json + +``` bash +freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --tradeids 2 3 --print-json +``` From 38c49493606e409aae7b6f8a081e06cca1414e51 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 10:50:59 +0200 Subject: [PATCH 0987/1106] Align applying of fee when comming from orders or trades --- freqtrade/freqtradebot.py | 36 +++++++++++++++++++++++++++--------- tests/test_freqtradebot.py | 8 ++++---- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 163c4faaa..5ef4888e0 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1160,6 +1160,23 @@ class FreqtradeBot: return False + def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, + amount: float, fee: float) -> float: + """ + Applies the fee to amount (either from Order or from Trades). + Can eat into dust if more than the required asset is available. + """ + if fee != 0 and self.wallets.get_free(trade_base_currency) >= amount: + # Eat into dust if we own more than base currency + logger.info(f"Fee amount for {trade} was in base currency - " + f"Eating Fee {fee} into dust.") + elif fee != 0: + real_amount = self.exchange.amount_to_precision(trade.pair, amount - fee) + logger.info(f"Applying fee on amount for {trade} " + f"(from {amount} to {real_amount}).") + return real_amount + return amount + def get_real_amount(self, trade: Trade, order: Dict, order_amount: float = None) -> float: """ Detect and update trade fee. @@ -1181,11 +1198,12 @@ class FreqtradeBot: fee_cost, fee_currency, fee_rate = self.exchange.extract_cost_curr_rate(order) logger.info(f"Fee for Trade {trade} [{order.get('side')}]: " f"{fee_cost:.8g} {fee_currency} - rate: {fee_rate}") - if trade_base_currency == fee_currency: - order_amount = order_amount - fee_cost - logger.info(f"Applying fee on amount for {trade} (from {order['amount']} " - f"to {order_amount}) from Order") + trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', '')) + if trade_base_currency == fee_currency: + # Apply fee to amount + return self.apply_fee_conditional(trade, trade_base_currency, + amount=order_amount, fee=fee_cost) return order_amount return self.fee_detection_from_trades(trade, order, order_amount) @@ -1218,15 +1236,15 @@ class FreqtradeBot: # Ensure at least one trade was found: if fee_currency: # fee_rate should use mean - fee_rate = sum(fee_rate_array) / float(len(fee_rate_array)) if fee_rate_array else None trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', '')) if not isclose(amount, order_amount, abs_tol=constants.MATH_CLOSE_PREC): logger.warning(f"Amount {amount} does not match amount {trade.amount}") raise DependencyException("Half bought? Amounts don't match") - real_amount = amount - fee_abs + if fee_abs != 0: - logger.info(f"Applying fee on amount for {trade} " - f"(from {order_amount} to {real_amount}) from Trades") - return real_amount + return self.apply_fee_conditional(trade, trade_base_currency, + amount=amount, fee=fee_abs) + else: + return amount diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 19a094fab..4a28147fc 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2221,7 +2221,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap # and apply fees if necessary. freqtrade.check_handle_timedout() - assert log_has_re(r"Applying fee on amount for Trade.* Order", caplog) + assert log_has_re(r"Applying fee on amount for Trade.*", caplog) assert cancel_order_mock.call_count == 1 assert rpc_mock.call_count == 2 @@ -3301,7 +3301,7 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fe # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001) assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' - 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades', + 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992).', caplog) @@ -3409,7 +3409,7 @@ def test_get_real_amount_multi(default_conf, trades_for_order2, buy_order_fee, c # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001) assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' - 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades', + 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992).', caplog) @@ -3435,7 +3435,7 @@ def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee # Amount is reduced by "fee" assert freqtrade.get_real_amount(trade, limit_buy_order) == amount - 0.004 assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, ' - 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.996) from Order', + 'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.996).', caplog) From 58168336e1801ba061c5498c007380759756f89d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 11:13:59 +0200 Subject: [PATCH 0988/1106] Add test for apply_fee_conditional --- freqtrade/freqtradebot.py | 15 ++++++++------- tests/test_freqtradebot.py | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5ef4888e0..1f9573122 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1161,17 +1161,18 @@ class FreqtradeBot: return False def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, - amount: float, fee: float) -> float: + amount: float, fee_abs: float) -> float: """ Applies the fee to amount (either from Order or from Trades). Can eat into dust if more than the required asset is available. """ - if fee != 0 and self.wallets.get_free(trade_base_currency) >= amount: + self.wallets.update() + if fee_abs != 0 and self.wallets.get_free(trade_base_currency) >= amount: # Eat into dust if we own more than base currency logger.info(f"Fee amount for {trade} was in base currency - " - f"Eating Fee {fee} into dust.") - elif fee != 0: - real_amount = self.exchange.amount_to_precision(trade.pair, amount - fee) + f"Eating Fee {fee_abs} into dust.") + elif fee_abs != 0: + real_amount = self.exchange.amount_to_precision(trade.pair, amount - fee_abs) logger.info(f"Applying fee on amount for {trade} " f"(from {amount} to {real_amount}).") return real_amount @@ -1203,7 +1204,7 @@ class FreqtradeBot: if trade_base_currency == fee_currency: # Apply fee to amount return self.apply_fee_conditional(trade, trade_base_currency, - amount=order_amount, fee=fee_cost) + amount=order_amount, fee_abs=fee_cost) return order_amount return self.fee_detection_from_trades(trade, order, order_amount) @@ -1245,6 +1246,6 @@ class FreqtradeBot: if fee_abs != 0: return self.apply_fee_conditional(trade, trade_base_currency, - amount=amount, fee=fee_abs) + amount=amount, fee_abs=fee_abs) else: return amount diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 4a28147fc..e69c88a13 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3305,6 +3305,30 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fe caplog) +def test_get_real_amount_quote_dust(default_conf, trades_for_order, buy_order_fee, fee, caplog, mocker): + mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) + walletmock = mocker.patch('freqtrade.wallets.Wallets.update') + mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=8.1122) + amount = sum(x['amount'] for x in trades_for_order) + trade = Trade( + pair='LTC/ETH', + amount=amount, + exchange='binance', + open_rate=0.245441, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_order_id="123456" + ) + freqtrade = get_patched_freqtradebot(mocker, default_conf) + + walletmock.reset_mock() + # Amount is kept as is + assert freqtrade.get_real_amount(trade, buy_order_fee) == amount + assert walletmock.call_count == 1 + assert log_has_re(r'Fee amount for Trade.* was in base currency ' + '- Eating Fee 0.008 into dust', caplog) + + def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker, fee): mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[]) From 72282a22396b59ee92c4e6a3c01dd365dafac9e3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 11:28:29 +0200 Subject: [PATCH 0989/1106] Add explicit test for fee_conditional --- tests/test_freqtradebot.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index e69c88a13..2c97b9fe1 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3305,7 +3305,8 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, fe caplog) -def test_get_real_amount_quote_dust(default_conf, trades_for_order, buy_order_fee, fee, caplog, mocker): +def test_get_real_amount_quote_dust(default_conf, trades_for_order, buy_order_fee, fee, + caplog, mocker): mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order) walletmock = mocker.patch('freqtrade.wallets.Wallets.update') mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=8.1122) @@ -3326,7 +3327,7 @@ def test_get_real_amount_quote_dust(default_conf, trades_for_order, buy_order_fe assert freqtrade.get_real_amount(trade, buy_order_fee) == amount assert walletmock.call_count == 1 assert log_has_re(r'Fee amount for Trade.* was in base currency ' - '- Eating Fee 0.008 into dust', caplog) + '- Eating Fee 0.008 into dust', caplog) def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker, fee): @@ -3572,6 +3573,36 @@ def test_get_real_amount_open_trade(default_conf, fee, mocker): assert freqtrade.get_real_amount(trade, order) == amount +@pytest.mark.parametrize('amount,fee_abs,wallet,amount_exp', [ + (8.0, 0.0, 10, 8), + (8.0, 0.0, 0, 8), + (8.0, 0.1, 0, 7.9), + (8.0, 0.1, 10, 8), + (8.0, 0.1, 8.0, 8.0), + (8.0, 0.1, 7.9, 7.9), +]) +def test_apply_fee_conditional(default_conf, fee, caplog, mocker, + amount, fee_abs, wallet, amount_exp): + walletmock = mocker.patch('freqtrade.wallets.Wallets.update') + # mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) + mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=wallet) + trade = Trade( + pair='LTC/ETH', + amount=amount, + exchange='binance', + open_rate=0.245441, + fee_open=fee.return_value, + fee_close=fee.return_value, + open_order_id="123456" + ) + freqtrade = get_patched_freqtradebot(mocker, default_conf) + + walletmock.reset_mock() + # Amount is kept as is + assert freqtrade.apply_fee_conditional(trade, 'LTC', amount, fee_abs) == amount_exp + assert walletmock.call_count == 1 + + def test_order_book_depth_of_market(default_conf, ticker, limit_buy_order, fee, mocker, order_book_l2): default_conf['bid_strategy']['check_depth_of_market']['enabled'] = True From 81397874eb3a2002136f8ffdd544408fe8755c2b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 11:29:51 +0200 Subject: [PATCH 0990/1106] Remove commented mock --- tests/test_freqtradebot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 2c97b9fe1..11d9abb31 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3584,7 +3584,6 @@ def test_get_real_amount_open_trade(default_conf, fee, mocker): def test_apply_fee_conditional(default_conf, fee, caplog, mocker, amount, fee_abs, wallet, amount_exp): walletmock = mocker.patch('freqtrade.wallets.Wallets.update') - # mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) mocker.patch('freqtrade.wallets.Wallets.get_free', return_value=wallet) trade = Trade( pair='LTC/ETH', From e92d3867cfc54a95d3625c3c35c57a7538ec0111 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 15:25:54 +0200 Subject: [PATCH 0991/1106] Fix failing test --- tests/test_freqtradebot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 11d9abb31..b426368c9 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2202,6 +2202,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap limit_buy_order_old_partial_canceled, mocker) -> None: rpc_mock = patch_RPCManager(mocker) cancel_order_mock = MagicMock(return_value=limit_buy_order_old_partial_canceled) + mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock(return_value=0)) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', From 1c9c72937e078265be0212fe79edca03b89881ee Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 15:32:09 +0200 Subject: [PATCH 0992/1106] Adjust trade-ids param --- docs/utils.md | 8 ++++---- freqtrade/commands/cli_options.py | 4 ++-- tests/commands/test_commands.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 12597220a..7ed31376f 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -529,7 +529,7 @@ Print selected (or all) trades from database to screen. ``` usage: freqtrade show-trades [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--db-url PATH] - [--tradeids TRADE_IDS [TRADE_IDS ...]] + [--trade-ids TRADE_IDS [TRADE_IDS ...]] [--print-json] optional arguments: @@ -538,8 +538,8 @@ optional arguments: deployments (default: `sqlite:///tradesv3.sqlite` for Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for Dry Run). - --tradeids TRADE_IDS [TRADE_IDS ...] - Specify Trade ids to trade + --trade-ids TRADE_IDS [TRADE_IDS ...] + Specify the list of trade ids. --print-json Print output in JSON format. Common arguments: @@ -564,5 +564,5 @@ Common arguments: Print trades with id 2 and 3 as json ``` bash -freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --tradeids 2 3 --print-json +freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --trade-ids 2 3 --print-json ``` diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 4c51802f0..a8f2ffdba 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -426,8 +426,8 @@ AVAILABLE_CLI_OPTIONS = { default="file", ), "trade_ids": Arg( - '--tradeids', - help='Specify Trade ids to trade', + '--trade-ids', + help='Specify the list of trade ids.', nargs='+', ), # hyperopt-list, hyperopt-show diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 0465858c0..2796a8b45 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1066,7 +1066,7 @@ def test_show_trades(mocker, fee, capsys, caplog): "--db-url", "sqlite:///", "--print-json", - "--tradeids", "1", "2" + "--trade-ids", "1", "2" ] pargs = get_args(args) pargs['config'] = None From 690bb7646a35839ce434062800f1841dbd1adaf9 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Sun, 3 May 2020 16:54:42 +0200 Subject: [PATCH 0993/1106] hyperopt csv export - add params --- freqtrade/optimize/hyperopt.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 02695d1aa..29d48802c 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -387,12 +387,19 @@ class Hyperopt: trials = json_normalize(results, max_level=1) trials['Best'] = '' trials['Stake currency'] = config['stake_currency'] - trials = trials[['Best', 'current_epoch', 'results_metrics.trade_count', - 'results_metrics.avg_profit', 'results_metrics.total_profit', - 'Stake currency', 'results_metrics.profit', 'results_metrics.duration', - 'loss', 'is_initial_point', 'is_best']] - trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Stake currency', - 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] + + base_metrics = ['Best', 'current_epoch', 'results_metrics.trade_count', + 'results_metrics.avg_profit', 'results_metrics.total_profit', + 'Stake currency', 'results_metrics.profit', 'results_metrics.duration', + 'loss', 'is_initial_point', 'is_best'] + param_metrics = [("params_dict."+param) for param in results[0]['params_dict'].keys()] + trials = trials[base_metrics + param_metrics] + + base_metrics_columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Stake currency', + 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] + param_metrics_columns = list(results[0]['params_dict'].keys()) + trials.columns = base_metrics_columns + param_metrics_columns + trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' trials.loc[trials['is_best'], 'Best'] = 'Best' From 889a153731451fa180e845eeb8a8e0b3f481d35d Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Sun, 3 May 2020 17:29:56 +0200 Subject: [PATCH 0994/1106] fix PEP8 --- freqtrade/optimize/hyperopt.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 29d48802c..3a28de785 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -388,17 +388,17 @@ class Hyperopt: trials['Best'] = '' trials['Stake currency'] = config['stake_currency'] - base_metrics = ['Best', 'current_epoch', 'results_metrics.trade_count', - 'results_metrics.avg_profit', 'results_metrics.total_profit', - 'Stake currency', 'results_metrics.profit', 'results_metrics.duration', - 'loss', 'is_initial_point', 'is_best'] + base_metrics = ['Best', 'current_epoch', 'results_metrics.trade_count', + 'results_metrics.avg_profit', 'results_metrics.total_profit', + 'Stake currency', 'results_metrics.profit', 'results_metrics.duration', + 'loss', 'is_initial_point', 'is_best'] param_metrics = [("params_dict."+param) for param in results[0]['params_dict'].keys()] trials = trials[base_metrics + param_metrics] - base_metrics_columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Stake currency', - 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] - param_metrics_columns = list(results[0]['params_dict'].keys()) - trials.columns = base_metrics_columns + param_metrics_columns + base_columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Stake currency', + 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] + param_columns = list(results[0]['params_dict'].keys()) + trials.columns = base_columns + param_columns trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' From 2a4c9bf3d38d48fcf5aa0a06692137fd3ec4fbfa Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 20:32:45 +0200 Subject: [PATCH 0995/1106] Improve logmessage when falling back to wallet amount --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7ae87e807..30eebb962 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -982,7 +982,7 @@ class FreqtradeBot: if wallet_amount >= amount: return amount elif wallet_amount > amount * 0.98: - logger.info(f"{pair} - Falling back to wallet-amount.") + logger.info(f"{pair} - Falling back to wallet-amount {wallet_amount} -> {amount}.") return wallet_amount else: raise DependencyException( From b38f9ed5e7967e116a36ff088f1ade46e61a1abd Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 3 May 2020 20:44:18 +0200 Subject: [PATCH 0996/1106] Increase cache for rate limit to avoid delays Helps when calling /status or /status table frequently on slowish exchanges --- freqtrade/freqtradebot.py | 7 +++++-- tests/conftest.py | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7ae87e807..32fbde562 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -54,8 +54,11 @@ class FreqtradeBot: # Init objects self.config = config - self._sell_rate_cache = TTLCache(maxsize=100, ttl=5) - self._buy_rate_cache = TTLCache(maxsize=100, ttl=5) + _process_throttle_secs = self.config['internals'].get('process_throttle_secs', + constants.PROCESS_THROTTLE_SECS) + # Use 3x process_throttle_secs for caching to avoid delays in RPC methods. + self._sell_rate_cache = TTLCache(maxsize=100, ttl=_process_throttle_secs * 3) + self._buy_rate_cache = TTLCache(maxsize=100, ttl=_process_throttle_secs * 3) self.strategy: IStrategy = StrategyResolver.load_strategy(self.config) diff --git a/tests/conftest.py b/tests/conftest.py index d95475b8c..5c2e3e8e9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -304,7 +304,8 @@ def default_conf(testdatadir): "user_data_dir": Path("user_data"), "verbosity": 3, "strategy_path": str(Path(__file__).parent / "strategy" / "strats"), - "strategy": "DefaultStrategy" + "strategy": "DefaultStrategy", + "internals": {}, } return configuration From f7a3bb82da64fff55db045c0e3c5b9cfcfa91a61 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:16:28 +0000 Subject: [PATCH 0997/1106] Bump numpy from 1.18.3 to 1.18.4 Bumps [numpy](https://github.com/numpy/numpy) from 1.18.3 to 1.18.4. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt) - [Commits](https://github.com/numpy/numpy/compare/v1.18.3...v1.18.4) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 967f8df10..18cab206b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Load common requirements -r requirements-common.txt -numpy==1.18.3 +numpy==1.18.4 pandas==1.0.3 From a14e027ad4a7449025b615b6861c79f56c287488 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:16:50 +0000 Subject: [PATCH 0998/1106] Bump arrow from 0.15.5 to 0.15.6 Bumps [arrow](https://github.com/crsmithdev/arrow) from 0.15.5 to 0.15.6. - [Release notes](https://github.com/crsmithdev/arrow/releases) - [Changelog](https://github.com/crsmithdev/arrow/blob/master/CHANGELOG.rst) - [Commits](https://github.com/crsmithdev/arrow/compare/0.15.5...0.15.6) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a53fc3999..9de50f800 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -3,7 +3,7 @@ ccxt==1.27.1 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 -arrow==0.15.5 +arrow==0.15.6 cachetools==4.1.0 requests==2.23.0 urllib3==1.25.9 From 68f0b105a989213f5a42b75ecdfad67bbb651b48 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:17:23 +0000 Subject: [PATCH 0999/1106] Bump pytest-asyncio from 0.11.0 to 0.12.0 Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.11.0 to 0.12.0. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.11.0...v0.12.0) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 508716bde..9881df083 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,7 +9,7 @@ flake8-type-annotations==0.1.0 flake8-tidy-imports==4.1.0 mypy==0.770 pytest==5.4.1 -pytest-asyncio==0.11.0 +pytest-asyncio==0.12.0 pytest-cov==2.8.1 pytest-mock==3.1.0 pytest-random-order==1.0.4 From 2c352e6b82a55367fb313eae69fa7ebe531d74bd Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:18:02 +0000 Subject: [PATCH 1000/1106] Bump progressbar2 from 3.51.0 to 3.51.3 Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.51.0 to 3.51.3. - [Release notes](https://github.com/WoLpH/python-progressbar/releases) - [Changelog](https://github.com/WoLpH/python-progressbar/blob/develop/CHANGES.rst) - [Commits](https://github.com/WoLpH/python-progressbar/compare/v3.51.0...v3.51.3) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index b0e18867d..9afd07357 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -7,4 +7,4 @@ scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 joblib==0.14.1 -progressbar2==3.51.0 +progressbar2==3.51.3 From 611b9c88d1019a21c41d142a4bb2cd0d38152b49 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:18:49 +0000 Subject: [PATCH 1001/1106] Bump ccxt from 1.27.1 to 1.27.20 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.1 to 1.27.20. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.27.1...1.27.20) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index a53fc3999..b910db9b3 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.27.1 +ccxt==1.27.20 SQLAlchemy==1.3.16 python-telegram-bot==12.6.1 arrow==0.15.5 From 32eb1c570524ebc2bbf3c2656f102b32ec5d46b7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 09:19:26 +0000 Subject: [PATCH 1002/1106] Bump mkdocs-material from 5.1.3 to 5.1.5 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.3 to 5.1.5. - [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/5.1.3...5.1.5) Signed-off-by: dependabot-preview[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 1c0e280ae..e9553a8e4 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==5.1.3 +mkdocs-material==5.1.5 mdx_truly_sane_lists==1.2 From 5dde6d3fac65a1502c85cf8dc67ad918f52236f0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 4 May 2020 12:40:24 +0000 Subject: [PATCH 1003/1106] Bump python-telegram-bot from 12.6.1 to 12.7 Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.6.1 to 12.7. - [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases) - [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst) - [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.6.1...v12.7) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index d9808a19f..cd302e348 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -2,7 +2,7 @@ # mainly used for Raspberry pi installs ccxt==1.27.20 SQLAlchemy==1.3.16 -python-telegram-bot==12.6.1 +python-telegram-bot==12.7 arrow==0.15.6 cachetools==4.1.0 requests==2.23.0 From 648723fb8325fe3e3c4fb1a371ed360b1b0d6e32 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 06:32:03 +0200 Subject: [PATCH 1004/1106] Use 30min rate cache --- freqtrade/freqtradebot.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 32fbde562..86c8e03b7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -54,11 +54,11 @@ class FreqtradeBot: # Init objects self.config = config - _process_throttle_secs = self.config['internals'].get('process_throttle_secs', - constants.PROCESS_THROTTLE_SECS) - # Use 3x process_throttle_secs for caching to avoid delays in RPC methods. - self._sell_rate_cache = TTLCache(maxsize=100, ttl=_process_throttle_secs * 3) - self._buy_rate_cache = TTLCache(maxsize=100, ttl=_process_throttle_secs * 3) + # Cache values for 1800 to avoid frequent polling of the exchange for prices + # Caching only applies to RPC methods, so prices for open trades are still + # refreshed once every iteration. + self._sell_rate_cache = TTLCache(maxsize=100, ttl=1800) + self._buy_rate_cache = TTLCache(maxsize=100, ttl=1800) self.strategy: IStrategy = StrategyResolver.load_strategy(self.config) From f040c2068850641bea7c04ff2b991dbaf728dfbb Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 06:41:01 +0200 Subject: [PATCH 1005/1106] Use filled in tests --- tests/test_freqtradebot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6f2ce9f3c..a098709a6 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2348,11 +2348,12 @@ def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_ trade = MagicMock() trade.pair = 'LTC/ETH' limit_buy_order['remaining'] = limit_buy_order['amount'] + limit_buy_order['filled'] = 0.0 assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 cancel_order_mock.reset_mock() - limit_buy_order['amount'] = 2 + limit_buy_order['filled'] = 1.0 assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 From b4aeb93a183d53d456ce81bdd5f28b941b88aebe Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 07:07:42 +0200 Subject: [PATCH 1006/1106] Add test testing the different ways exchanges may return data --- tests/conftest.py | 93 ++++++++++++++++++++++++++++++++++++++ tests/test_freqtradebot.py | 25 +++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d95475b8c..29bb36f64 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -877,6 +877,99 @@ def limit_buy_order_old_partial_canceled(limit_buy_order_old_partial): return res +@pytest.fixture(scope='function') +def limit_buy_order_canceled_empty(request): + # Indirect fixture + # Documentation: + # https://docs.pytest.org/en/latest/example/parametrize.html#apply-indirect-on-particular-arguments + + exchange_name = request.param + if exchange_name == 'ftx': + return { + 'info': {}, + 'id': '1234512345', + 'clientOrderId': None, + 'timestamp': arrow.utcnow().shift(minutes=-601).timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'lastTradeTimestamp': None, + 'symbol': 'LTC/USDT', + 'type': 'limit', + 'side': 'buy', + 'price': 34.3225, + 'amount': 0.55, + 'cost': 0.0, + 'average': None, + 'filled': 0.0, + 'remaining': 0.0, + 'status': 'closed', + 'fee': None, + 'trades': None + } + elif exchange_name == 'kraken': + return { + 'info': {}, + 'id': 'AZNPFF-4AC4N-7MKTAT', + 'clientOrderId': None, + 'timestamp': arrow.utcnow().shift(minutes=-601).timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'lastTradeTimestamp': None, + 'status': 'canceled', + 'symbol': 'LTC/USDT', + 'type': 'limit', + 'side': 'buy', + 'price': 34.3225, + 'cost': 0.0, + 'amount': 0.55, + 'filled': 0.0, + 'average': 0.0, + 'remaining': 0.55, + 'fee': {'cost': 0.0, 'rate': None, 'currency': 'USDT'}, + 'trades': [] + } + elif exchange_name == 'binance': + return { + 'info': {}, + 'id': '1234512345', + 'clientOrderId': 'alb1234123', + 'timestamp': arrow.utcnow().shift(minutes=-601).timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'lastTradeTimestamp': None, + 'symbol': 'LTC/USDT', + 'type': 'limit', + 'side': 'buy', + 'price': 0.016804, + 'amount': 0.55, + 'cost': 0.0, + 'average': None, + 'filled': 0.0, + 'remaining': 0.55, + 'status': 'canceled', + 'fee': None, + 'trades': None + } + else: + return { + 'info': {}, + 'id': '1234512345', + 'clientOrderId': 'alb1234123', + 'timestamp': arrow.utcnow().shift(minutes=-601).timestamp, + 'datetime': arrow.utcnow().shift(minutes=-601).isoformat(), + 'lastTradeTimestamp': None, + 'symbol': 'LTC/USDT', + 'type': 'limit', + 'side': 'buy', + 'price': 0.016804, + 'amount': 0.55, + 'cost': 0.0, + 'average': None, + 'filled': 0.0, + 'remaining': 0.55, + 'status': 'canceled', + 'fee': None, + 'trades': None + } + + @pytest.fixture def limit_sell_order(): return { diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a098709a6..2b5127cc0 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2313,12 +2313,12 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order Trade.session = MagicMock() trade = MagicMock() trade.pair = 'LTC/ETH' - limit_buy_order['remaining'] = limit_buy_order['amount'] + limit_buy_order['filled'] = 0 assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 cancel_order_mock.reset_mock() - limit_buy_order['amount'] = 2 + limit_buy_order['filled'] = 2 assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 @@ -2326,6 +2326,27 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) +@pytest.mark.parametrize("limit_buy_order_canceled_empty", ['binance', 'ftx', 'kraken', 'bittrex'], + indirect=['limit_buy_order_canceled_empty']) +def test_handle_timedout_limit_buy_exchanges(mocker, caplog, default_conf, + limit_buy_order_canceled_empty) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + cancel_order_mock = mocker.patch( + 'freqtrade.exchange.Exchange.cancel_order_with_result', + return_value=limit_buy_order_canceled_empty) + + freqtrade = FreqtradeBot(default_conf) + + Trade.session = MagicMock() + trade = MagicMock() + trade.pair = 'LTC/ETH' + assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order_canceled_empty) + assert cancel_order_mock.call_count == 0 + assert log_has_re(r'Buy order fully cancelled. Removing .* from database\.', caplog) + + + @pytest.mark.parametrize('cancelorder', [ {}, {'remaining': None}, From 981976681a88423117ef9bd6fe18e56f96df4476 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 07:08:24 +0200 Subject: [PATCH 1007/1106] Use filled, it's the safer choice when determining the filled amount. --- freqtrade/freqtradebot.py | 7 +++---- tests/test_freqtradebot.py | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 30eebb962..9db7e4467 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -898,7 +898,7 @@ class FreqtradeBot: Buy timeout - cancel order :return: True if order was fully cancelled """ - if order['status'] != 'canceled': + if order['status'] not in ('canceled', 'closed'): reason = "cancelled due to timeout" corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, trade.amount) @@ -909,7 +909,7 @@ class FreqtradeBot: logger.info('Buy order %s for %s.', reason, trade) - if safe_value_fallback(corder, order, 'remaining', 'remaining') == order['amount']: + if safe_value_fallback(corder, order, 'filled', 'filled') == 0.0: logger.info('Buy order fully cancelled. Removing %s from database.', trade) # if trade is not partially completed, just delete the trade Trade.session.delete(trade) @@ -921,8 +921,7 @@ class FreqtradeBot: # cancel_order may not contain the full order dict, so we need to fallback # to the order dict aquired before cancelling. # we need to fall back to the values from order if corder does not contain these keys. - trade.amount = order['amount'] - safe_value_fallback(corder, order, - 'remaining', 'remaining') + trade.amount = safe_value_fallback(corder, order, 'filled', 'filled') trade.stake_amount = trade.amount * trade.open_rate self.update_trade_state(trade, corder, trade.amount) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 2b5127cc0..f2b2f6b5c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2346,7 +2346,6 @@ def test_handle_timedout_limit_buy_exchanges(mocker, caplog, default_conf, assert log_has_re(r'Buy order fully cancelled. Removing .* from database\.', caplog) - @pytest.mark.parametrize('cancelorder', [ {}, {'remaining': None}, From d3a0ab8096bcd119ca3fd57c4880a8648783ee4d Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 07:12:49 +0200 Subject: [PATCH 1008/1106] Change mock-status to be open when testing unfilled... --- tests/test_freqtradebot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index f2b2f6b5c..7a30e9015 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2314,6 +2314,7 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order trade = MagicMock() trade.pair = 'LTC/ETH' limit_buy_order['filled'] = 0 + limit_buy_order['status'] = 'open' assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 @@ -2367,8 +2368,9 @@ def test_handle_timedout_limit_buy_corder_empty(mocker, default_conf, limit_buy_ Trade.session = MagicMock() trade = MagicMock() trade.pair = 'LTC/ETH' - limit_buy_order['remaining'] = limit_buy_order['amount'] limit_buy_order['filled'] = 0.0 + limit_buy_order['status'] = 'open' + assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 From ffef4bc4744b03ac35e625924c034c0b7dacb51f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 19:48:28 +0200 Subject: [PATCH 1009/1106] Humanize show-trades error when no database is specified --- freqtrade/commands/list_commands.py | 5 +++++ tests/commands/test_commands.py | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 61d6f7244..e5131f9b2 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -206,6 +206,11 @@ def start_show_trades(args: Dict[str, Any]) -> None: from freqtrade.persistence import init, Trade import json config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + + if 'db_url' not in config: + raise OperationalException("--db-url is required for this command.") + + logger.info(f'Using DB: "{config["db_url"]}"') init(config['db_url'], clean_open_orders=False) tfilter = [] diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 2796a8b45..93b123069 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1077,3 +1077,11 @@ def test_show_trades(mocker, fee, capsys, caplog): assert '"trade_id": 1' in captured.out assert '"trade_id": 2' in captured.out assert '"trade_id": 3' not in captured.out + args = [ + "show-trades", + ] + pargs = get_args(args) + pargs['config'] = None + + with pytest.raises(OperationalException, match=r"--db-url is required for this command."): + start_show_trades(pargs) From e4023a6567cdf50b40c1aee1427c5ceaadcff38b Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 21:19:35 +0200 Subject: [PATCH 1010/1106] Add some minor things to show_config --- freqtrade/rpc/rpc.py | 2 ++ freqtrade/state.py | 3 +++ tests/rpc/test_rpc_apiserver.py | 1 + 3 files changed, 6 insertions(+) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 8645e466e..10eeb572f 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -94,6 +94,7 @@ class RPC: 'dry_run': config['dry_run'], 'stake_currency': config['stake_currency'], 'stake_amount': config['stake_amount'], + 'max_open_trades': config['max_open_trades'], 'minimal_roi': config['minimal_roi'].copy(), 'stoploss': config['stoploss'], 'trailing_stop': config['trailing_stop'], @@ -103,6 +104,7 @@ class RPC: 'ticker_interval': config['ticker_interval'], 'exchange': config['exchange']['name'], 'strategy': config['strategy'], + 'state': str(self._freqtrade.state) } return val diff --git a/freqtrade/state.py b/freqtrade/state.py index 415f6f5f2..38784c6a4 100644 --- a/freqtrade/state.py +++ b/freqtrade/state.py @@ -14,6 +14,9 @@ class State(Enum): STOPPED = 2 RELOAD_CONF = 3 + def __str__(self): + return f"{self.name.lower()}" + class RunMode(Enum): """ diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 6548790cb..9b2f893e3 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -283,6 +283,7 @@ def test_api_show_config(botclient, mocker): assert 'dry_run' in rc.json assert rc.json['exchange'] == 'bittrex' assert rc.json['ticker_interval'] == '5m' + assert rc.json['state'] == 'running' assert not rc.json['trailing_stop'] From 593d13ebddde143b438f59eb7ff84991c903e2cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 21:21:05 +0200 Subject: [PATCH 1011/1106] Show new values also in Telegram --- freqtrade/rpc/telegram.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index a21f7556c..38888313e 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -621,10 +621,12 @@ class Telegram(RPC): f"*Mode:* `{'Dry-run' if val['dry_run'] else 'Live'}`\n" f"*Exchange:* `{val['exchange']}`\n" f"*Stake per trade:* `{val['stake_amount']} {val['stake_currency']}`\n" + f"*Max open Trades:* `{val['max_open_trades']}`\n" f"*Minimum ROI:* `{val['minimal_roi']}`\n" f"{sl_info}" f"*Ticker Interval:* `{val['ticker_interval']}`\n" - f"*Strategy:* `{val['strategy']}`" + f"*Strategy:* `{val['strategy']}\n`" + f"*Current state:* `{val['state']}`" ) def _send_msg(self, msg: str, parse_mode: ParseMode = ParseMode.MARKDOWN) -> None: From a62d7495ca443d3c17997604106d62c4debf2300 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 5 May 2020 21:28:59 +0200 Subject: [PATCH 1012/1106] FIx typo in telegram method --- freqtrade/rpc/telegram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 38888313e..66d8ad936 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -625,7 +625,7 @@ class Telegram(RPC): f"*Minimum ROI:* `{val['minimal_roi']}`\n" f"{sl_info}" f"*Ticker Interval:* `{val['ticker_interval']}`\n" - f"*Strategy:* `{val['strategy']}\n`" + f"*Strategy:* `{val['strategy']}`\n" f"*Current state:* `{val['state']}`" ) From 1ba2df79c6a770958bddb3bf1e1fee6bd8c41f0f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 7 May 2020 06:51:02 +0200 Subject: [PATCH 1013/1106] Ause isclose for comparison, assign filled to variable add some comments --- freqtrade/freqtradebot.py | 8 ++++++-- tests/test_freqtradebot.py | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9db7e4467..57eb7d1a8 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -898,6 +898,7 @@ class FreqtradeBot: Buy timeout - cancel order :return: True if order was fully cancelled """ + # Cancelled orders may have the status of 'canceled' or 'closed' if order['status'] not in ('canceled', 'closed'): reason = "cancelled due to timeout" corder = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair, @@ -909,7 +910,10 @@ class FreqtradeBot: logger.info('Buy order %s for %s.', reason, trade) - if safe_value_fallback(corder, order, 'filled', 'filled') == 0.0: + # Using filled to determine the filled amount + filled_amount = safe_value_fallback(corder, order, 'filled', 'filled') + + if isclose(filled_amount, 0.0, abs_tol=constants.MATH_CLOSE_PREC): logger.info('Buy order fully cancelled. Removing %s from database.', trade) # if trade is not partially completed, just delete the trade Trade.session.delete(trade) @@ -921,7 +925,7 @@ class FreqtradeBot: # cancel_order may not contain the full order dict, so we need to fallback # to the order dict aquired before cancelling. # we need to fall back to the values from order if corder does not contain these keys. - trade.amount = safe_value_fallback(corder, order, 'filled', 'filled') + trade.amount = filled_amount trade.stake_amount = trade.amount * trade.open_rate self.update_trade_state(trade, corder, trade.amount) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 7a30e9015..c502e264c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2313,7 +2313,7 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order Trade.session = MagicMock() trade = MagicMock() trade.pair = 'LTC/ETH' - limit_buy_order['filled'] = 0 + limit_buy_order['filled'] = 0.0 limit_buy_order['status'] = 'open' assert freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 @@ -2323,6 +2323,7 @@ def test_handle_timedout_limit_buy(mocker, caplog, default_conf, limit_buy_order assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) assert cancel_order_mock.call_count == 1 + limit_buy_order['filled'] = 2 mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException) assert not freqtrade.handle_timedout_limit_buy(trade, limit_buy_order) From c560de41113c749de0b4f3ab6d7a0c155150486e Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 8 May 2020 11:44:24 +0200 Subject: [PATCH 1014/1106] Improve exception handling on critical errors --- freqtrade/commands/trade_commands.py | 3 +++ tests/commands/test_commands.py | 11 +++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/freqtrade/commands/trade_commands.py b/freqtrade/commands/trade_commands.py index 352fac26d..c058e4f9d 100644 --- a/freqtrade/commands/trade_commands.py +++ b/freqtrade/commands/trade_commands.py @@ -18,6 +18,9 @@ def start_trading(args: Dict[str, Any]) -> int: try: worker = Worker(args) worker.run() + except Exception as e: + logger.error(str(e)) + logger.exception("Fatal exception!") except KeyboardInterrupt: logger.info('SIGINT received, aborting ...') finally: diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 93b123069..46350beff 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -32,7 +32,7 @@ def test_setup_utils_configuration(): assert config['exchange']['secret'] == '' -def test_start_trading_fail(mocker): +def test_start_trading_fail(mocker, caplog): mocker.patch("freqtrade.worker.Worker.run", MagicMock(side_effect=OperationalException)) @@ -43,16 +43,15 @@ def test_start_trading_fail(mocker): 'trade', '-c', 'config.json.example' ] - with pytest.raises(OperationalException): - start_trading(get_args(args)) + start_trading(get_args(args)) assert exitmock.call_count == 1 exitmock.reset_mock() - + caplog.clear() mocker.patch("freqtrade.worker.Worker.__init__", MagicMock(side_effect=OperationalException)) - with pytest.raises(OperationalException): - start_trading(get_args(args)) + start_trading(get_args(args)) assert exitmock.call_count == 0 + assert log_has('Fatal exception!', caplog) def test_list_exchanges(capsys): From 5272ec85eab94d2d0fb801050429a766e6011058 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 8 May 2020 12:34:24 +0200 Subject: [PATCH 1015/1106] Add additional test --- tests/test_main.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index 70b784002..a7180a5d2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -115,6 +115,28 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None: assert log_has('Oh snap!', caplog) +def test_main_operational_exception1(mocker, default_conf, caplog) -> None: + patch_exchange(mocker) + mocker.patch( + 'freqtrade.commands.list_commands.available_exchanges', + MagicMock(side_effect=ValueError('Oh snap!')) + ) + patched_configuration_load_config_file(mocker, default_conf) + + args = ['list-exchanges'] + + # Test Main + the KeyboardInterrupt exception + with pytest.raises(SystemExit): + main(args) + + assert log_has('Fatal exception!', caplog) + assert not log_has_re(r'SIGINT.*', caplog) + mocker.patch( + 'freqtrade.commands.list_commands.available_exchanges', + MagicMock(side_effect=KeyboardInterrupt) + ) + + def test_main_reload_conf(mocker, default_conf, caplog) -> None: patch_exchange(mocker) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock()) From 80d367fa0871d5ec16bba77312581cf6115a08f0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 8 May 2020 14:24:30 +0200 Subject: [PATCH 1016/1106] Add test for keyboardinterrupt --- tests/test_main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index a7180a5d2..11d0ede3a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -135,6 +135,10 @@ def test_main_operational_exception1(mocker, default_conf, caplog) -> None: 'freqtrade.commands.list_commands.available_exchanges', MagicMock(side_effect=KeyboardInterrupt) ) + with pytest.raises(SystemExit): + main(args) + + assert log_has_re(r'SIGINT.*', caplog) def test_main_reload_conf(mocker, default_conf, caplog) -> None: From 2307495f2837971f6325efa97afea7d874ae8c1d Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 8 May 2020 20:10:16 +0300 Subject: [PATCH 1017/1106] Update docs/configuration.md Co-authored-by: Matthias --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 28df5bd95..59d8ba1eb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -51,7 +51,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
      **Datatype:** String | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
      *Defaults to `true`.*
      **Datatype:** Boolean | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
      *Defaults to `1000`.*
      **Datatype:** Float -| `cancel_open_orders_on_exit` | Cancel orders when `/stop` is issued or `ctrl+c` is pressed. Including this will allow you to use `/stop` to cancel unfilled orders in the event of a market crash. This will not impact open positions.
      *Defaults to `False`.*
      **Datatype:** Boolean +| `cancel_open_orders_on_exit` | Cancel orders when `/stop` is issued or `ctrl+c` is pressed. This will allow you to use `/stop` to cancel unfilled orders in the event of a market crash. This will not impact open positions.
      *Defaults to `False`.*
      **Datatype:** Boolean | `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
      *Defaults to `false`.*
      **Datatype:** Boolean | `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
      **Datatype:** Dict | `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
      **Datatype:** Float (as ratio) From d4362ed357a41408460b5339219ae4e7e24a2a4c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 9 May 2020 09:29:40 +0300 Subject: [PATCH 1018/1106] Minor: improve exception handling in exchange --- freqtrade/exchange/exchange.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 1a0565959..ce973f373 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1041,9 +1041,9 @@ class Exchange: return matched_trades - except ccxt.NetworkError as e: + except (ccxt.NetworkError, ccxt.ExchangeError) as e: raise TemporaryError( - f'Could not get trades due to networking error. Message: {e}') from e + f'Could not get trades due to {e.__class__.__name__}. Message: {e}') from e except ccxt.BaseError as e: raise OperationalException(e) from e From b72997fc2bbb1d685a27605026bf3fa269973ca5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 9 May 2020 20:16:04 +0200 Subject: [PATCH 1019/1106] Add flask-jwt-extended dependency --- requirements-common.txt | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index cd302e348..9fb4e209b 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -25,6 +25,7 @@ sdnotify==0.3.2 # Api server flask==1.1.2 +flask-jwt-extended==3.24.1 # Support for colorized terminal output colorama==0.4.3 diff --git a/setup.py b/setup.py index 9c253ea4e..8c0de095e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ if readme_file.is_file(): readme_long = (Path(__file__).parent / "README.md").read_text() # Requirements used for submodules -api = ['flask'] +api = ['flask', 'flask-jwt-extended'] plot = ['plotly>=4.0'] hyperopt = [ 'scipy', From 7e08fa2631d1553bbfedf113817f6309b771a7bb Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 10 May 2020 02:22:16 +0300 Subject: [PATCH 1020/1106] Fix usage of fee value in Edge --- freqtrade/edge/edge_positioning.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index 5305e23cf..bae7a0743 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -238,20 +238,13 @@ class Edge: :param result Dataframe :return: result Dataframe """ - - # stake and fees - # stake = 0.015 - # 0.05% is 0.0005 - # fee = 0.001 - - # we set stake amount to an arbitrary amount. - # as it doesn't change the calculation. - # all returned values are relative. - # they are defined as ratios. + # We set stake amount to an arbitrary amount, as it doesn't change the calculation. + # All returned values are relative, they are defined as ratios. stake = 0.015 - fee = self.fee - open_fee = fee / 2 - close_fee = fee / 2 + + # Fee should be applied twice + open_fee = self.fee + close_fee = self.fee result['trade_duration'] = result['close_time'] - result['open_time'] From b6a2c3894133426ae25dd68adfbdf86f148bb92c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 10 May 2020 02:22:49 +0300 Subject: [PATCH 1021/1106] Adjust tests --- tests/edge/test_edge.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/edge/test_edge.py b/tests/edge/test_edge.py index 2304c53c2..163ceff4b 100644 --- a/tests/edge/test_edge.py +++ b/tests/edge/test_edge.py @@ -335,12 +335,16 @@ def test_edge_init_error(mocker, edge_conf,): get_patched_freqtradebot(mocker, edge_conf) -def test_process_expectancy(mocker, edge_conf): +@pytest.mark.parametrize("fee,risk_reward_ratio,expectancy", [ + (0.0005, 306.5384615384, 101.5128205128), + (0.001, 152.6923076923, 50.2307692308), +]) +def test_process_expectancy(mocker, edge_conf, fee, risk_reward_ratio, expectancy): edge_conf['edge']['min_trade_number'] = 2 freqtrade = get_patched_freqtradebot(mocker, edge_conf) def get_fee(*args, **kwargs): - return 0.001 + return fee freqtrade.exchange.get_fee = get_fee edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy) @@ -394,9 +398,9 @@ def test_process_expectancy(mocker, edge_conf): assert 'TEST/BTC' in final assert final['TEST/BTC'].stoploss == -0.9 assert round(final['TEST/BTC'].winrate, 10) == 0.3333333333 - assert round(final['TEST/BTC'].risk_reward_ratio, 10) == 306.5384615384 + assert round(final['TEST/BTC'].risk_reward_ratio, 10) == risk_reward_ratio assert round(final['TEST/BTC'].required_risk_reward, 10) == 2.0 - assert round(final['TEST/BTC'].expectancy, 10) == 101.5128205128 + assert round(final['TEST/BTC'].expectancy, 10) == expectancy # Pop last item so no trade is profitable trades.pop() From 0bd2fca40b648d6bef54388616832fce82528a59 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 09:55:41 +0200 Subject: [PATCH 1022/1106] Update tests/test_integration.py Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- tests/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index ee6ef3cb2..90cdde61f 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -97,7 +97,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, # Only order for 3rd trade needs to be cancelled assert cancel_order_mock.call_count == 1 # Wallets must be updated between stoploss cancellation and selling, and will be updated again - # During update_trade_state + # during update_trade_state assert wallets_mock.call_count == 3 trade = trades[0] From 8139058fcc5c471e762f182f1608fbff3c6bbed9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 10:35:38 +0200 Subject: [PATCH 1023/1106] Implement token/login and token/refresh endpoints --- freqtrade/rpc/api_server.py | 56 +++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 0335bb151..1e20bf8f8 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -2,11 +2,16 @@ import logging import threading from datetime import date, datetime from ipaddress import IPv4Address -from typing import Dict, Callable, Any +from typing import Any, Callable, Dict from arrow import Arrow from flask import Flask, jsonify, request from flask.json import JSONEncoder +from flask_jwt_extended import (JWTManager, create_access_token, + create_refresh_token, get_jwt_identity, + jwt_refresh_token_required, + verify_jwt_in_request_optional) +from werkzeug.security import safe_str_cmp from werkzeug.serving import make_server from freqtrade.__init__ import __version__ @@ -38,9 +43,10 @@ class ArrowJSONEncoder(JSONEncoder): def require_login(func: Callable[[Any, Any], Any]): def func_wrapper(obj, *args, **kwargs): - + verify_jwt_in_request_optional() auth = request.authorization - if auth and obj.check_auth(auth.username, auth.password): + i = get_jwt_identity() + if i or auth and obj.check_auth(auth.username, auth.password): return func(obj, *args, **kwargs) else: return jsonify({"error": "Unauthorized"}), 401 @@ -70,8 +76,8 @@ class ApiServer(RPC): """ def check_auth(self, username, password): - return (username == self._config['api_server'].get('username') and - password == self._config['api_server'].get('password')) + return (safe_str_cmp(username, self._config['api_server'].get('username')) and + safe_str_cmp(password, self._config['api_server'].get('password'))) def __init__(self, freqtrade) -> None: """ @@ -83,6 +89,11 @@ class ApiServer(RPC): self._config = freqtrade.config self.app = Flask(__name__) + + # Setup the Flask-JWT-Extended extension + self.app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this! + + self.jwt = JWTManager(self.app) self.app.json_encoder = ArrowJSONEncoder # Register application handling @@ -148,6 +159,10 @@ class ApiServer(RPC): self.app.register_error_handler(404, self.page_not_found) # Actions to control the bot + self.app.add_url_rule(f'{BASE_URI}/token/login', 'login', + view_func=self._login, methods=['POST']) + self.app.add_url_rule(f'{BASE_URI}/token/refresh', 'token_refresh', + view_func=self._refresh_token, methods=['POST']) self.app.add_url_rule(f'{BASE_URI}/start', 'start', view_func=self._start, methods=['POST']) self.app.add_url_rule(f'{BASE_URI}/stop', 'stop', view_func=self._stop, methods=['POST']) @@ -199,6 +214,37 @@ class ApiServer(RPC): 'code': 404 }), 404 + @require_login + @rpc_catch_errors + def _login(self): + """ + Handler for /token/login + Returns a JWT token + """ + auth = request.authorization + if auth and self.check_auth(auth.username, auth.password): + keystuff = {'u': auth.username} + ret = { + 'access_token': create_access_token(identity=keystuff), + 'refresh_token': create_refresh_token(identity=keystuff), + } + return self.rest_dump(ret) + + return jsonify({"error": "Unauthorized"}), 401 + + @jwt_refresh_token_required + @rpc_catch_errors + def _refresh_token(self): + """ + Handler for /token/refresh + Returns a JWT token based on a JWT refresh token + """ + current_user = get_jwt_identity() + new_token = create_access_token(identity=current_user, fresh=False) + + ret = {'access_token': new_token} + return self.rest_dump(ret) + @require_login @rpc_catch_errors def _start(self): From bc64619f301fb870b91fe4682e255b975f1cd5f7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 10:43:13 +0200 Subject: [PATCH 1024/1106] Tests for JWT implementation --- tests/rpc/test_rpc_apiserver.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 9b2f893e3..0d4cdeb2f 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -94,6 +94,33 @@ def test_api_unauthorized(botclient): assert rc.json == {'error': 'Unauthorized'} +def test_api_token_login(botclient): + ftbot, client = botclient + rc = client_post(client, f"{BASE_URI}/token/login") + assert_response(rc) + assert 'access_token' in rc.json + assert 'refresh_token' in rc.json + + # test Authentication is working with JWT tokens too + rc = client.get(f"{BASE_URI}/count", + content_type="application/json", + headers={'Authorization': f'Bearer {rc.json["access_token"]}'}) + assert_response(rc) + + +def test_api_token_refresh(botclient): + ftbot, client = botclient + rc = client_post(client, f"{BASE_URI}/token/login") + assert_response(rc) + rc = client.post(f"{BASE_URI}/token/refresh", + content_type="application/json", + data=None, + headers={'Authorization': f'Bearer {rc.json["refresh_token"]}'}) + assert_response(rc) + assert 'access_token' in rc.json + assert 'refresh_token' not in rc.json + + def test_api_stop_workflow(botclient): ftbot, client = botclient assert ftbot.state == State.RUNNING From 51d2b817ae50773f743d8ba00c060acf8d897e11 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 10 May 2020 11:51:33 +0300 Subject: [PATCH 1025/1106] Use self.fee --- freqtrade/edge/edge_positioning.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/freqtrade/edge/edge_positioning.py b/freqtrade/edge/edge_positioning.py index bae7a0743..c19d4552a 100644 --- a/freqtrade/edge/edge_positioning.py +++ b/freqtrade/edge/edge_positioning.py @@ -242,10 +242,6 @@ class Edge: # All returned values are relative, they are defined as ratios. stake = 0.015 - # Fee should be applied twice - open_fee = self.fee - close_fee = self.fee - result['trade_duration'] = result['close_time'] - result['open_time'] result['trade_duration'] = result['trade_duration'].map( @@ -255,12 +251,12 @@ class Edge: # Buy Price result['buy_vol'] = stake / result['open_rate'] # How many target are we buying - result['buy_fee'] = stake * open_fee + result['buy_fee'] = stake * self.fee result['buy_spend'] = stake + result['buy_fee'] # How much we're spending # Sell price result['sell_sum'] = result['buy_vol'] * result['close_rate'] - result['sell_fee'] = result['sell_sum'] * close_fee + result['sell_fee'] = result['sell_sum'] * self.fee result['sell_take'] = result['sell_sum'] - result['sell_fee'] # profit_ratio From 570c51b0b03fbaf3419cccfe08bdf8013a5f756f Mon Sep 17 00:00:00 2001 From: Mohamad Tarbin Date: Sun, 10 May 2020 05:07:49 -0400 Subject: [PATCH 1026/1106] Fix Typo in telegram Plugin --- freqtrade/rpc/telegram.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 66d8ad936..856b8f138 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -579,7 +579,7 @@ class Telegram(RPC): "*/whitelist:* `Show current whitelist` \n" \ "*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs " \ "to the blacklist.` \n" \ - "*/edge:* `Shows validated pairs by Edge if it is enabeld` \n" \ + "*/edge:* `Shows validated pairs by Edge if it is enabled` \n" \ "*/help:* `This help message`\n" \ "*/version:* `Show version`" From d9e4f41a359647bb50f1cc7e00571c7758aba40f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 16:14:35 +0200 Subject: [PATCH 1027/1106] Add documentation for JWt --- docs/rest-api.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/rest-api.md b/docs/rest-api.md index b68364f39..d750f74af 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -202,3 +202,28 @@ whitelist Show the current whitelist :returns: json object ``` + +## Advanced API usage using JWT tokens + +!!! Note + The below should be done in an application, and is not intended to be used on a regular basis. + +Freqtrade's REST API also offers JWT tokens. +You can login using the following command, and subsequently use the resulting access_token. + +``` bash +> curl -X POST --user Freqtrader http://localhost:8080/api/v1/token/login +{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g","refresh_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiZWQ1ZWI3YjAtYjMwMy00YzAyLTg2N2MtNWViMjIxNWQ2YTMxIiwiZXhwIjoxNTkxNzExNjgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJ0eXBlIjoicmVmcmVzaCJ9.d1AT_jYICyTAjD0fiQAr52rkRqtxCjUGEMwlNuuzgNQ"} + +> access_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g" +# Use tccess_token for authentication +> curl -X GET --header "Authorization: Bearer ${access_token}" http://localhost:8080/api/v1/count + +``` + +Since the access-token has a short timeout (15 min) - the refresh-token should be used to get a fresh access token: + +``` bash +> curl -X POST --header "Authorization: Bearer ${refresh_token}"http://localhost:8080/api/v1/token/refresh +{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk5NzQsIm5iZiI6MTU4OTExOTk3NCwianRpIjoiMDBjNTlhMWUtMjBmYS00ZTk0LTliZjAtNWQwNTg2MTdiZDIyIiwiZXhwIjoxNTg5MTIwODc0LCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.1seHlII3WprjjclY6DpRhen0rqdF4j6jbvxIhUFaSbs"} +``` From 80faa5feb14913ad6c17307b893aead1272b9040 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 16:24:00 +0200 Subject: [PATCH 1028/1106] Add test to cancel sell order --- tests/test_freqtradebot.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index c502e264c..01e74c7a2 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2405,6 +2405,21 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None: assert cancel_order_mock.call_count == 1 +def test_handle_timedout_limit_sell_cancel_exception(mocker, default_conf) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch( + 'freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException()) + + freqtrade = FreqtradeBot(default_conf) + + trade = MagicMock() + order = {'remaining': 1, + 'amount': 1, + 'status': "open"} + assert freqtrade.handle_timedout_limit_sell(trade, order) == 'error cancelling order' + + def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> None: rpc_mock = patch_RPCManager(mocker) patch_exchange(mocker) From 2406e20be2a8af33c33ca06eeb01a3e77cef5f88 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 17:36:43 +0200 Subject: [PATCH 1029/1106] Update docs/rest-api.md Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/rest-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rest-api.md b/docs/rest-api.md index d750f74af..599ad870f 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -206,7 +206,7 @@ whitelist ## Advanced API usage using JWT tokens !!! Note - The below should be done in an application, and is not intended to be used on a regular basis. + The below should be done in an application (a Freqtrade REST API client, which fetches info via API), and is not intended to be used on a regular basis. Freqtrade's REST API also offers JWT tokens. You can login using the following command, and subsequently use the resulting access_token. From 73a1496318d1b9e594a098f5e8bc25d62137fc3b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 17:44:45 +0200 Subject: [PATCH 1030/1106] Catch exception on cancel_order --- freqtrade/freqtradebot.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 930baff1f..4f4b3e3bb 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -949,8 +949,12 @@ class FreqtradeBot: if order['remaining'] == order['amount'] or order.get('filled') == 0.0: if not self.exchange.check_order_canceled_empty(order): reason = "cancelled due to timeout" - # if trade is not partially completed, just delete the trade - self.exchange.cancel_order(trade.open_order_id, trade.pair) + try: + # if trade is not partially completed, just delete the trade + self.exchange.cancel_order(trade.open_order_id, trade.pair) + except InvalidOrderException: + logger.exception(f"Could not cancel sell order {trade.open_order_id}") + return 'error cancelling order' logger.info('Sell order %s for %s.', reason, trade) else: reason = "cancelled on exchange" From c2224ed6b7496d043853f84c9d5e1762372c102c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 17:47:43 +0200 Subject: [PATCH 1031/1106] Fix doc typos Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/rest-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rest-api.md b/docs/rest-api.md index 599ad870f..42671f0c3 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -208,7 +208,7 @@ whitelist !!! Note The below should be done in an application (a Freqtrade REST API client, which fetches info via API), and is not intended to be used on a regular basis. -Freqtrade's REST API also offers JWT tokens. +Freqtrade's REST API also offers JWT (JSON Web Tokens). You can login using the following command, and subsequently use the resulting access_token. ``` bash @@ -216,7 +216,7 @@ You can login using the following command, and subsequently use the resulting ac {"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g","refresh_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiZWQ1ZWI3YjAtYjMwMy00YzAyLTg2N2MtNWViMjIxNWQ2YTMxIiwiZXhwIjoxNTkxNzExNjgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJ0eXBlIjoicmVmcmVzaCJ9.d1AT_jYICyTAjD0fiQAr52rkRqtxCjUGEMwlNuuzgNQ"} > access_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g" -# Use tccess_token for authentication +# Use access_token for authentication > curl -X GET --header "Authorization: Bearer ${access_token}" http://localhost:8080/api/v1/count ``` From b163bb76503041798ecf2898f0eabc53771a9052 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 17:48:29 +0200 Subject: [PATCH 1032/1106] Apply suggestions from code review Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/rest-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rest-api.md b/docs/rest-api.md index 42671f0c3..337a00b4f 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -221,7 +221,7 @@ You can login using the following command, and subsequently use the resulting ac ``` -Since the access-token has a short timeout (15 min) - the refresh-token should be used to get a fresh access token: +Since the access token has a short timeout (15 min) - the `token/refresh` request should be used periodically to get a fresh access token: ``` bash > curl -X POST --header "Authorization: Bearer ${refresh_token}"http://localhost:8080/api/v1/token/refresh From c3f0b5d4eb89d0f71bfca021e89625395457c01d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 19:37:41 +0200 Subject: [PATCH 1033/1106] Rename methods to match endpoints --- freqtrade/rpc/api_server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 1e20bf8f8..3a46d2c88 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -160,9 +160,9 @@ class ApiServer(RPC): # Actions to control the bot self.app.add_url_rule(f'{BASE_URI}/token/login', 'login', - view_func=self._login, methods=['POST']) + view_func=self._token_login, methods=['POST']) self.app.add_url_rule(f'{BASE_URI}/token/refresh', 'token_refresh', - view_func=self._refresh_token, methods=['POST']) + view_func=self._token_refresh, methods=['POST']) self.app.add_url_rule(f'{BASE_URI}/start', 'start', view_func=self._start, methods=['POST']) self.app.add_url_rule(f'{BASE_URI}/stop', 'stop', view_func=self._stop, methods=['POST']) @@ -216,7 +216,7 @@ class ApiServer(RPC): @require_login @rpc_catch_errors - def _login(self): + def _token_login(self): """ Handler for /token/login Returns a JWT token @@ -234,7 +234,7 @@ class ApiServer(RPC): @jwt_refresh_token_required @rpc_catch_errors - def _refresh_token(self): + def _token_refresh(self): """ Handler for /token/refresh Returns a JWT token based on a JWT refresh token From 21c2af2b92208c8ee811a91fba7046f99d556db6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 19:42:06 +0200 Subject: [PATCH 1034/1106] Load jwt_key from config --- config_full.json.example | 1 + docs/rest-api.md | 6 +++++- freqtrade/rpc/api_server.py | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config_full.json.example b/config_full.json.example index 181740b9a..ee1c14d27 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -120,6 +120,7 @@ "enabled": false, "listen_ip_address": "127.0.0.1", "listen_port": 8080, + "jwt_secret_key": "somethingrandom", "username": "freqtrader", "password": "SuperSecurePassword" }, diff --git a/docs/rest-api.md b/docs/rest-api.md index 337a00b4f..7f1a95b12 100644 --- a/docs/rest-api.md +++ b/docs/rest-api.md @@ -11,6 +11,7 @@ Sample configuration: "enabled": true, "listen_ip_address": "127.0.0.1", "listen_port": 8080, + "jwt_secret_key": "somethingrandom", "username": "Freqtrader", "password": "SuperSecret1!" }, @@ -29,7 +30,7 @@ This should return the response: {"status":"pong"} ``` -All other endpoints return sensitive info and require authentication, so are not available through a web browser. +All other endpoints return sensitive info and require authentication and are therefore not available through a web browser. To generate a secure password, either use a password manager, or use the below code snipped. @@ -38,6 +39,9 @@ import secrets secrets.token_hex() ``` +!!! Hint + Use the same method to also generate a JWT secret key (`jwt_secret_key`). + ### Configuration with docker If you run your bot using docker, you'll need to have the bot listen to incomming connections. The security is then handled by docker. diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 3a46d2c88..21f28f601 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -91,7 +91,8 @@ class ApiServer(RPC): self.app = Flask(__name__) # Setup the Flask-JWT-Extended extension - self.app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this! + self.app.config['JWT_SECRET_KEY'] = self._config['api_server'].get( + 'jwt_secret_key', 'super-secret') self.jwt = JWTManager(self.app) self.app.json_encoder = ArrowJSONEncoder From d291ca0071b2e73dc0750bedced1257c37d73032 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 19:43:16 +0200 Subject: [PATCH 1035/1106] Simplify code section --- freqtrade/rpc/api_server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 21f28f601..68f4b1ca9 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -45,8 +45,7 @@ def require_login(func: Callable[[Any, Any], Any]): def func_wrapper(obj, *args, **kwargs): verify_jwt_in_request_optional() auth = request.authorization - i = get_jwt_identity() - if i or auth and obj.check_auth(auth.username, auth.password): + if get_jwt_identity() or auth and obj.check_auth(auth.username, auth.password): return func(obj, *args, **kwargs) else: return jsonify({"error": "Unauthorized"}), 401 From 9eca268a498ed129299dd9910f01f5bf1ea81363 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 May 2020 20:00:19 +0200 Subject: [PATCH 1036/1106] Fix test --- tests/rpc/test_rpc_apiserver.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 0d4cdeb2f..5d8f79920 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -150,6 +150,12 @@ def test_api__init__(default_conf, mocker): """ Test __init__() method """ + default_conf.update({"api_server": {"enabled": True, + "listen_ip_address": "127.0.0.1", + "listen_port": 8080, + "username": "TestUser", + "password": "testPass", + }}) mocker.patch('freqtrade.rpc.telegram.Updater', MagicMock()) mocker.patch('freqtrade.rpc.api_server.ApiServer.run', MagicMock()) From 306eae6da348da4b785300a92a5cfaa527890020 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:10:48 +0000 Subject: [PATCH 1037/1106] Bump pytest from 5.4.1 to 5.4.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.4.1 to 5.4.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.4.1...5.4.2) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 9881df083..616ca20f9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ flake8==3.7.9 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.1.0 mypy==0.770 -pytest==5.4.1 +pytest==5.4.2 pytest-asyncio==0.12.0 pytest-cov==2.8.1 pytest-mock==3.1.0 From 3849b68b8f2cce77276259f8a106e6d727f3ae78 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:11:22 +0000 Subject: [PATCH 1038/1106] Bump ta-lib from 0.4.17 to 0.4.18 Bumps [ta-lib](https://github.com/mrjbq7/ta-lib) from 0.4.17 to 0.4.18. - [Release notes](https://github.com/mrjbq7/ta-lib/releases) - [Changelog](https://github.com/mrjbq7/ta-lib/blob/master/CHANGELOG) - [Commits](https://github.com/mrjbq7/ta-lib/compare/TA_Lib-0.4.17...TA_Lib-0.4.18) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 9fb4e209b..f2361bdf5 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -9,7 +9,7 @@ requests==2.23.0 urllib3==1.25.9 wrapt==1.12.1 jsonschema==3.2.0 -TA-Lib==0.4.17 +TA-Lib==0.4.18 tabulate==0.8.7 pycoingecko==1.2.0 jinja2==2.11.2 From 43ab814f30202de82c032b428255116dd771c88c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:12:11 +0000 Subject: [PATCH 1039/1106] Bump ccxt from 1.27.20 to 1.27.49 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.20 to 1.27.49. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.27.20...1.27.49) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 9fb4e209b..e47fd41d7 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.27.20 +ccxt==1.27.49 SQLAlchemy==1.3.16 python-telegram-bot==12.7 arrow==0.15.6 From e38581c19f9f986bea16f9beab20158e5f818fcf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:12:38 +0000 Subject: [PATCH 1040/1106] Bump plotly from 4.6.0 to 4.7.1 Bumps [plotly](https://github.com/plotly/plotly.py) from 4.6.0 to 4.7.1. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v4.6.0...v4.7.1) Signed-off-by: dependabot-preview[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 3db48a201..d81239053 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==4.6.0 +plotly==4.7.1 From 96710d42f55219d5d1ac4a7c4723fd5a3e67688a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 09:13:06 +0000 Subject: [PATCH 1041/1106] Bump mkdocs-material from 5.1.5 to 5.1.6 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.5 to 5.1.6. - [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/5.1.5...5.1.6) Signed-off-by: dependabot-preview[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 e9553a8e4..c121dec64 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==5.1.5 +mkdocs-material==5.1.6 mdx_truly_sane_lists==1.2 From a379e68cf441407c9c04264714bfc7dbcc8e635d Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 11 May 2020 14:02:39 +0200 Subject: [PATCH 1042/1106] Add new ta-lib wheels --- .../TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl | Bin 684920 -> 0 bytes .../TA_Lib-0.4.17-cp38-cp38-win_amd64.whl | Bin 662134 -> 0 bytes .../TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl | Bin 0 -> 537651 bytes .../TA_Lib-0.4.18-cp38-cp38-win_amd64.whl | Bin 0 -> 555204 bytes build_helpers/install_windows.ps1 | 4 ++-- 5 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 build_helpers/TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl delete mode 100644 build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl create mode 100644 build_helpers/TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl create mode 100644 build_helpers/TA_Lib-0.4.18-cp38-cp38-win_amd64.whl diff --git a/build_helpers/TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl b/build_helpers/TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl deleted file mode 100644 index 87469a199037a6ce79f4ee4ec347f0c411b8bb49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684920 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≪c7F=`hCoL#u}a7*VA+qt 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

        e}jSYxSKLA#+4<_BX0`|L| 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

        I_c5
        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

        SDtZ;i8C_#Z`^9CH+x{5WRg57UIK} zq%!NEF4*Z|uecDt71CXDYkz9W>cK47h+AuB<5du;J(!!QhnXcik{n`lQ~#I#D((Zb zh5b9}lJor#Y-a#(3i03vu?DNR?sTi!Wa!L}129!x_PZ9w#6E+Xkoab*VG_oRPPz=m z{=LnJh3u6GZ;$}{Pv*8F(gCdh0LP!u_GmQ9rswO@=cBXF z5yps<01l91Rj-0-tlN++@8$Ce&9(a1vu5{}T-f~S6%8KLQu`o&sX7FSJavTj@Z2V6 z!i3oGXkj%Yy%(vsuaVk`joWg4UNuTs4SeLUq8Nq4a7IXDpi<033DYE>0NC4Y?imizyK;(*8& z_fL{o_H6s-GCfkyVYg2`*eX;ldi{5?Wm+Z^ccWO7{%9&6hl~sJ>UP;W{8Gt@)E$C8 z-bmtdN4%E$d56gQ!pup}*1PHzYCEUXl7p?KoaL(-ZgRLbbqn_wYaVS_Cd$%5SAf5y zlx96ve@cz5P5>7p@Q$n_`H4IDEz*mUATpbSzi&!^m=GD-{aI_trA9s@Sw}3)2%s6=k|U!#E9>>06FPcoku0vrw?32>JO=M$0sFz6`KUJZc zQ@3znXZ^eJ%+JZ|3$qUG{FDyc?yE&5BsAl@*B3w59N3YULrv^M0@5A7(eMk>c& z{-HY?9#P3M)5g7kcS}*X*wHq?-*2iiRiY==n_hZ7kMzENjS&~bs0m`SOd6sP)mmFV zq9>MAAKIy0QVcTB!tXcT+wqc02XRf=KbhiU-|@s)ur*y+ln+e~=! zt>hoAc;M%n6TVba^{hK~L;tOM>JlVH$P>qjv#B#7(q97aoasE}4%sHWXs8NmU9us- z#p5p_&)tKhI@UwrNw;owA|%u$#Qi_AYn54dtP*8e*Qq?=e9nd_$rI$zIk`aKrn(;Z zETifsD_0>GtrPEEO=tBPqVW|Zv6Yd&t7OEN$ZY?Kb@{w#>?)RIL-8|y5|!y1_$M|7 zt8uNp>ec5WTEOC9#hHC~3?B1e(ZP#zxvF40p0kwO+J{aJWI9=6!kRK>OfZ&e4So__yYjn2royT1PX{{83p;!2r}2NbC#3w& z_S{fjDSRQpZLd2xec$0iY@0t2U-2RMYpe)9jzp*Q#j!Fk>>-p-IO0w==KJcw;!~nC zQ#^{pg!WCpP>|`-59cd9VhtGknoDIibGnb`+fEm&6SKtBhX`OhM&6f6ITJy-8J=))vVo4T@iFq30n zAvCWTye}CV)4pCyx3g9C9}&(U%}8g($e#>K(h5q?wubuDV3$l4=2 z#Vff#!>7mpd)%X3XT_NxF&$AmJ@U${O5CtLdVWaum-*bgy-P9TPS+RgDJIRmo@Fwt z%7Lth#b7VGnFsg1ewM#7!~7LA@f4)mhzpk1VYrhU;J@ke-;H%*W$*^gw!-y(3xt0l z5$m@YeJ|kSUS_N*RyPj8hzwP3gLj;Cu6N*OP7h}$@3c2=0rx!Q>CohN!gA%x!yI*N z@ZQ7YgQu>?LA?0;idK4#nJ*5}!( zbaO8}!QOldThlo$OYLpZHFTW=!l_vDZZ6KALorboU-xr8Vcxo718(&90JNG}_1H&# zujA?jI?nA+i@-YCR|=*`Mb?rJHuS$ndTJ1wElBXtZ}_Jx>4d*foW}NeX1;2{+!Ec) zIacWUXT_qzkqj9qwh|e2LBczW9TxnsE%?#Z$}74Txa;wxd~;sr{s^Jq+U2%fu*sq% zGhM?t9!7h}6)6{%OrJh*BscWZ_ct3xGO4ShP~r4!Sd!ALrJ?WZRSU@|9P?b6M0`~? zJ3Ib~qG2b?75q=$E_-RpVL+6%V#9sKXuHdp`kM?smPR@MTYHKIC&s;w9$$-Om-_9Q zM|H{TGdJu2U+_~XH&WcG%y*S1xDXLQ8TfdG8|yKuJU>w{vl&oZv&;hCKYN`$+C<4S zm8;-HpfK<%y{2(|iNnm5!Ddvo8KCTb(>s>zI~UkxPBMLY;^& zTWUeMQFz0@ZuErC)$TXJb8$r>(;+Rh!<|?+QyaRcAH~?e&;cC3=1#79LikCC6d-dz zu`;AC#n;6JMf$lCBPE9qlJBS(-N!qb038QfCJPZKfTepWCefhL{&2Pe4KHOH0UP)X zzsY<(9bJ97N|y7}1NQgnM1-dQW9*_2hmjE%xwU!L*;C_QMHD`Rq2iomu80!AkM+5% z(=FTc<9BSwy3g1VM=J`PwJQx_GG8_YB6Ac}-A$*>*H+|BJXq8ZMCT^Eyllq53z|eB z8=N;*^ul6qaSMW^ABJjXkG_y^z4#~FmoCWL&TA0uymcu{T+G@DO1QH*WV1o8!oxRB zGt<=l2AAtIVBU5Bnf`g|nxNgyDlIk!JNw4bHu#s)xku`$F8Er8y5mli(0J7mO*G1> zoyJY;Xr6y}-7@7^%)RsXjiu?1e1B!u{XJPnBz(Wz^ze~l38~uo&nOc_FNeztm+6<3 zA)kdBy`IYM5M z+k?%`|J5tPthpmI2%>HLN9G@=Fi6H_T7%=C-2YGcp`N(L*l#6kQeJ{cjsK(!fB#Zr zp8xA4S^oByw&e6D&GLVLi{A*9J8BEnzcX+WGX7NzanWoy*A6nc3YwC+8lJrxX0&#= z#Nx3yT);xW)Kbu%&*{*d6I2EhiZi8N$F+w(@esL(JDvD!azx1GQGhHDoFy4p@E4}? zx#aK0lyYQjY>GS!BAH<<*{Snv&fQlz?TXo@z&($+zM7u(@IKww-+k*;m3~l^J81H` z{Bu#^%ZzR}?1T`Hk^T@?(_yjtCBLlxD;yP_!3K=_^MPfefBRE(HL=&nl|N(1 zvoW(T?NtP51&e7Bubaje+O7RJBQJw>}5UQ~~Kv?I@*?KkK_peiOGuL9!4%GQ5=4 zuv79>sWXhX zT9pTy$W_r>ty$00w|$h(HBnP-@?CBA#^NjF{CNh};Z4wV1l7ccD41F2Q zIRuV0ZCu%HRdxzvncKUIFy%q)u|>dpa}s08YZIJ@tY_VRyO9Sok5JV_utGMNog^61 zd&r9E_A`Mt!&W>ti2|t;1M+}Y<(nHB)P?Wx77d7LG?jG#`l|_cY9tX(i4B7;gMppJ#W4Z@oLWn4$QbNDO9=aDT5HL8)S^dSU4X0*g9oS7@$&cfrVaB?!NTbcgkAr6jLaRd(*?Ix z4w;`1x0gzvn>Qift$jmYlYN-HTA`295y;qa>}W;|b0{)yp|c}Aa+TY8Z;6#E%&`?z zQxsPlAs)84e#grVhT_SGcq?oM-u6JvV-Qz)cr&>n*|4|ynk!M)yM+;>^LwwHWfC_M zit>>9^=DjlH>wW(G7?<|K5H@R(qZB*nL1UP|ni7&#qGnE=D#* zdMx?;xRO4dy-7z*9xYba<;^Q+;ot3L(VYo25$8QqJr9XPe9$S>$~HDozi?rG^5a~h z^!A_0Ab^;C)W`LBBJr?t@vzct*-9iTM2H%HqE%KdV**@KtK6`11S+jhqEcpb1XugmcPH}f51W&SLEE}9Rc;p14sl{jAeDS#I@#%JI~Ga;ed7i`F`H9_guXWS8#S zk!r8Gq-<3U*5MdYzTL9`wpFf_0nj%lvhMdWtuNYH z)8tMrr&{K2d`{lmEll>aqPh0sB+wTJVvW8BZTlhBkTB(`X1*vX8`R~4({fyun@|@_ z67*l<1hc{%>N*kVi@utc^PGaGSOd~XW-y5LlToSQB~nR z8);=`InqdlsjzAF8 z+ykSZm}tm>`KI@npE;%MzSt?2W$#Rnv&JgGs+R)v3+lN1^Hgq zvmy$`lmYWg7k`FJa4m}g-sQZ0lJ&*?7eOPiOR?h^Hg2uyew&6E8M3Bsv-|7F{bgdWoyA z{blnjqTzl_vwR0I^x|=HvtD(-GV^GkY`^F#dqS-taGuL+E2o`pQ~r^|!C0_F3M_zw zz%J+YG^)RbHX7;zGdR+by; z8qE-pu46KimO6O_6})seurC07Za9~)tB3g;i=@lBAppI%8GkI0~4Tu4N;)d zNKw7`IGi+{?X|>-VwI;V$t@)@>jT!hpzp`d`rI3Ymrq^z8-|k$FA${D%n>(2>HGYi zV;P||S$%l>>Kug9MqdyO7iAzbsY0!5TFzF1gvZCMumEV%&8WS6Et^rsQ#KlAm3+{a zUZbnzTIW|mxMF+)MsXBo<9TYRytd+e4eI|`)+PBdu6?|FJy2{`XRr^FEtUN~ZF=n| z_ue9q{iNJytU#Qke1r~S<51k!L3K`Hie^c~SZwDRrCV%-Tj?mtXT1jb@{I3(q%TUw z;-1&miG%Jb%(hS%Rcx-Hq}Cehf}AC)L8EFRqg@PUyOXE0vrI!nz&O2(u<=F$!oTnBOvl`VIn6w_1py|>&zb^HY zRi3_y^9c6om z%{m*a&C%dZ*?av+Nzq$E_ZeR4FBRAsZW4+|7Dg3+tL3Nj>YnF1>Dm80%q)8~_%Z=% zxLjP;I-y=Ie3>F=?lTvhz?0xcvz+jEH4jR_Dv=QIG3{%&T|j(lr5Tv2rvEO!noM{2-6!b ze?;@^a3;!o>1+IEf{H+Y(4p;{nZ|EMKDJcENuF8t*t*l6i@NJ`BJaL^&Hu;Ndq6e0 zHQ~Yp6jYjk(u-0=sUk{mN|UZA(z^&qmtF%RO_~VOdl8Y|I|)*yH|Y?H5PGNykc8Yf zo^$?t&i(!cOI+ELo!K+bJTtqzI~7y3Z@ro7ILfFTej54GUB95Pj^$aM8C}evP{lm7 zSl7P`TQ8`i8Q<7ib*Vv4yBTkx)Pr!rA4`~y@j~GK+n5Rt=E{T91I)3Yr&L@_uNNV0#8sj ziUL?xtb4D?CECGJcY{W4!5`8K%l;JS$4M-!i{m;#mY2~bO zpBn$vlOW$62+UxePNI)j#E^b%gIkU5gGe0E5*U-rO3|T_Q)6gg#m~Mk61v_SJjY!H z8o>l-WDaFCQsCl-tEs$kZlgkvc$P`|__)2l{mHuM=$!Sr+zIY+| zKt98mXJzO!916PN+NIa7B?LY+3^#>uVY3sK1L9_*mxU1NlX0GH@k8(>07AYcK6Luv^J9`P zpfI=!+_YFT#`3k}QE7<8Mlw=OxzmaN+gbj*P4BLYB$qwx7mnkW+<_Bc7hx4}-smY- zI_x~`y5|LB-C&qQEPQM=e8HEh8AoD)nxkrl1x`zcPh$-__iDozL?d7@IEm}MB!tEp zd`ui6w!v;@)|M>%s?|PnfE*kx;R~xgn5r^DPJL=6NWXzk-*oZ9(eEtY#9NOTCowir zW~jM0w8_hz5l%D?$xlU~RlhV${=)2umAMN+WP|kD^D^S!Jl{?Zt|P)4adXGK8=-SN z*z-DIqatkyt8Ikt7bl8%wQ!cn(p4nA>D;04MLCoonCw8|MU=ax7`6e29Qid2Q(nP< zhGWxaXGr*gKrVUDtC3WBUfZ*FHJin@C#tY$uUg-m*y~nc3O*^8wWQ9`&m43wOk9Q5 z+vy&9AHi5^R@^F0?=iR0G+o92oLo7-`p-|(m8JxbC~JO;^kd-GIIwY?vKJVO>eY&I zA9FEJ`_eCQ4Cgmam}Z!Y6BVR@Qm8b&+JaLlYq|RSl_~9;3GW~Mg!Akgo7suKQ~DJD z<3t!?JBFPVpH1yoMzaK>$mFM(Pe~&&qxL>GTyS($C`95S3$Hvgxbk3enjRwBZ5=4J z%g{uY&gBO^vkn)Q8M<~g9IKBc-$~N3-VotgJ8ijF&%0>4_tSkWEbs(tmFR74*3wWi zi0)6Xr|~l0sC!p%aS0*FD-w=MnrcsE-{H7yy>@3=BD7{QOt{@Q<;~dIfL{*q*cg9O&{%=dr6VYzTZ6yqMC?l0A=`HBYQR$j!KV+1yp!W2(`%fmw&p*nh%!eM+(P2kgEh~8x7mjGuUt>k z=rI{W1&z5NPuKr=4e3q^|-V(mv4hGyYb$>2tgdlg*D@m9CnBn4(`-W9Mm?VUVC_kk(pYr&u7($#&KtGB=r%dxaJ z7~|~DPd5jqPLCrqUUobP;6|HKV=~m@jR|W6M$5H(=wS?^!+MWu|E5&65 z$=4n2LA>a-;z(3WS4a_Sjq24sN~ii=De^$O@dgbgt;FUF#i3{Fe6E{w!aB17tm>ng zYMZ7Zb&-`>Yw}ZE0!^>$g9SD`#x@5rQPHHn&Q-{rCvbxuHR!URxzjT+M4@Q7vV5S{ zSA5)7aI2M^87=5SImIK{qXA!HT<;h@CtkV7ovfazL^nhhZgq{iqyNYoU|{qU|0D_9 zH7m_E|J&=va%bXA(Lfa>v>4IF;88QL0xxsjvR)Fj8cTBC!x9cvNID}Ox@PKGtzp#Z z{=n^Xz7!VA;$k?TE^J-w+w>dY#`s0ao^bs)HmIo^8Gew*D^0P3ui5MZv|eAjXcG#) zma|p14HaZ!AFv;GBPZc(Yk13Z^MjuM?w!5?~4ppUqT2++r~BS z4A(F5ulODfxv=hfiYm%xt#Xz@RzItq8%B56^HkejKi8d-+^j6HC^N7UeKQ`-ZBfJo z4|zNg%tH0$@B*Q$&T{8~uiL1Y@pN7?QvF1YUE16cy;{&(`j zDZ*N?m3;sHW06v$BBHX5N0}UOR9WZ%y!U3Bm}6Yy!*WT3^yBA|66GnTZqf1UH#gh? z>d#xC@e(&rfT-u6kzIr?21Y8CyK86PJc`}k7tK(j{<)A`azfXiMeK3Sp9k)q@(s*Q z=@X9V$d1X4h1YjlN>%>$mbJa_lonR!F1hjj%|J(`f`Q0q1?$H>wt6UG#uwKM^WQ?G zQT4aK+Ify8k8m9&Un1e^^tx9AV-MX#yn7NBe{ERttVOJk^v#P@S+z)~1gTxoJ2Bo> zm3OKqTGXW6e!Aq6#&$geO-@mll!xd^x>kC;F^?|bNVEWZU0DNP+L00!J(ea~*O?Py zBV(And$b*x2md%d^y7bTX2;j0;sRJCYZM9*9BlsNIz{_w&mGeWCdnZtL(^P&oDJ1E&)4pqOx+YtF&VHvZq zvL#$wI2e)Ca60L!!p67U8Z7Z#u z(|6k;b{JuXlUC=RTk^08x}u9RsD)~53Y`Zm1d>A&Ts<>ymTn@#o%pq9K=gEba!=r`@xh~Ua^Eg-fNMV)Nefd-2#6)|Gh)>cfKS6?DBUCeb&jTPf6HWl>jvs z#UX!wm*SYmy~AFYr>sVEdcARR4LZtfzps|BH1SE?5bwE7O^NmYU^C8e@Nm^1@y&W# zI(aP42>xAl43@*xn?teFE_>;%zzuY8r)Aa3z2Z?d{R_7~p8aQ&=w!6M%hJ`QUc*$A z!i)o|$OF+^%3yeYlW4k|+{Wj|15bh{FjUrNZb~@(4SQx zg_v>IWE~_0yQ;10yeF|^(}mcvbW7Z3vJzIVN42tyla=x4>8jL>-PB5y7uV3Utv=WO z4Gwct8H+O|sBeS|!l|jdp0G{LEe&868jX}YQd{C|#b#LCr= zaJVkiDPWr!W?|t}?%IW;hH@~jZfyRg-RA!9={FoDO%fp)E1Jp!R~tyXW_Z+SUvdJX-!OE<*v%}8@5xTX-5WCgtk)!eN z=_O$>UVHVzwkhgO;8N0UbN!KmgFLxG9;&dVowd%HNGk}Tfnpkv|5h9MHiuGzTd!L` zLiNAN|LNcRxbn@Ee3h~7Lrj>$Ihz^h>!cwq!o1tfE9ScI@3^**Gew?w06CxsRm`;@ zUdUxp=JgZ(!S}}V^X!A}l7qI7GL&OAN1r_eZ&}>fVml#mk)+_Y(Y*rVCFO9n~2t3r8Sd zLa-j3H__2duAK3qy4<68=#7MXwn8#V-1EGWwKjkUh3GF75~Sv1F<=!)NIY^li}{m0)Qxb>m9tH@x~PtITL2lY|YclN*oiYS^girod$0Y&ca zp9`4^g&=9GAG%Ndv|UFX7v~0sWA-?kKwerk97ka9j062^tHUm#>!zooqsA%;AS3Uh zeZj$f!GPF1X;&YbexCyh{nqra`Y&CjQohF&jLdQrz4YqUfU~LRVf^vp-H;`lV z>tvl5mmf;LiMvo22Q#&D%GGm9FloQVTro zck?YVDod*7`?Bt-RVZaNSMuH{_2z12ZH~bE;f+SYh&=+I4~{9y)mmi8JEL|`svPC@ z(TxLXvaHJu{av-HQjF3pFz7tt+YhWM%6WwlO0?hz?{Tl6k@PUB^v)5J@j2=uOEuSM zsR1ZG(xuuc6CSgk-W~2gmwsh6&-&Tljs1j0GZ(akaktpp_rH|BspoOyu6`kYX485V zrJ6>c77$enIxZEqv|kqv>e!y3PqQin1?S@7d(af`7RzKgx1)a++@NIU5YlKZBuIj} z*%Sb*nkmdz+n;BnesP`)?7t3~AsL_~!rpw#Rn3^=H@$s!CBf)j{t@~hlXQnE%s%|!t^~xwn^8l=gNtGQQC;(;@1GhRx z0?SS;?HYb zbLsAWq}bz?(Si0%3%Ui+@fGO@SUUMkA*m z0ri<#O_kkgg<(TlI=}RW<(7$EV!n8323%Xq!Kfz;|7hguU!TwIIi$Eii+7}!e?Y9j zbE z{1X`WS~?Vy2#EmDOtM=q$Q!5_onzNcrV?QO(6 zbUv?H8QFFh!PGFgNRN7!pw8D})e%U~$aXGC;A;1YieGM19*NO0)qTV}p;y#wQ?!yZ zkozblNTfL7F@wibsZ`&S5SZsE@lxm78%!5Q73v+r2(Byv^|n26!sA>D$GI@tJ;EaE zGAdw(xH;A;xGxP2$bt2(NsM-mbjbF!T*6}tmxKtL?o?rc1ZBu=bN>>Hu<{Mu)B3nw z?cBJSuxE=)iVPr*x&q*8OTxjT5aVh5^6Cu}+iuMPQNp!QGBn*$abOc~hb4ES6X?C} z7E-@ao6cx-IN))W`TW@%OE4}>;9OcxHw7sSW^y*RnjOYy1tPvXqxCOtKXd-#82cCM zq*y&Qy^8tz0AT5*9ImnMV?+OOCF z1j*Lhj$P|B4!Md~^*w!GnwCBWASv-GXsLa+rI2$6WatRWB!G8Bf=rDYuza$VcfXDA zR=z6`Xvob%NUGqqSd9F4(%QqGqm0P@+=K&O-w zBPY_3!loq0lVNkihZ@lMlO}1P)VQpBd^Dp`b=v@q7P&Jn82Dol(7+VbCkhDTSf163 z10#bFT@u|!>iuP3xE_9Fg7)fP4FY0X+H11BX_nsJ-?at~H9h(O^t>JPo_K*3;L7*B zz;z#=?ZYQ8+P6P%3jR@-@{hVW&>wX-Gm;TM{+2u=ZBH=j+})8ORWE?*IeJca%E(!`AG2X2^7vJaQI zU{n7JBbs3E!Yw%wmC*u#02BK0iyX-QW+S}J&wf$wTp-Ycs|tw0aWTE4ZMM-oIu0Ke zd8qtR9vn-5U5wqB_8ybP92uW;(4{|qpO7Qy~=Z_`Bka3536P8qV-^{VIxr=`%A zSHKuN3E}m#JN=(vqzU!^BR%v(COzXx4<|asnves4wKa&_eg|-8pk48F5-peiwODw;85j|Rv;GF{Pib?(N(YICs1n!+TU2dH4Xt%9@z(YI>;h!DkrVaTB`^7 zmi@yAY({mrx6tqAUTkE^c@zRc)37ZhD+xq9Hxb-36bMGX?3Ne*(2Vm;=r=_F?h_0V zbNr5V0Ofu5nPE)8(uZg)ANZ29dxTdn9)FZS&&64Rs6B6+H@^3fWO@o9PCt-yc0Ztr z#nLm~Ka3>Cvs3$rkp5PH^6N-_U}`p?Kw)4v{tp|$LOY&m2`jk2{S%1|_V{tJD$iei z?G(TA3_x6q0}zi>Ah=U?g#2yTr35D$mv14w?&1_*PF$IJX0D(3H(G0N(ETxQIRPFK zV3PC-AQBM-WxM|b7oH6KP4}K&`$dSZ1H9!#NMSFErz5c%X@I*-DgS~4kQyij=I~vb zax9X(ElXMf?^6bLZv)1{5pA?B-nj_#JLgSCO#M$Bf=MeyKP~VBaad1y)C9=GuBO8r zfT#@+e74BH0tV3Y4kNe?KQ#r=a|*sui82*J{r_M%EF6c&@Bst}Coq8FRb1?KUm~=} z(*xPl4rmYyo|{N0b}J%qw}HCoFAM(@;JGn4<03baXRg6FaKVBkj7|XI0wDGe*1%An zF`5mN|CbNG`otiHH40!vZCWZWcTeY_xmqbx?HDb&_9G4=g5w7hlx z7+v7%nEQPQ34MH7@EKMPqnYM)6OtpJElT%|Z?uDeUU{HzKiOqJ#Dl3&sS0bi*FL=>n3 zJuY%^{kI?iT9$w1Hr|9%oZE1(r+^8)zDax$0MRbq1>}o^-ZSBo7t!RR4GrbvwyOr5k4FHSX23SlUi0&Tw+M;99r3N4w>IUKi5kj=$R230+3rv#i9smDOSlMb*-OHw{ z8_g=SN$pOTDPXTnNRA|f9;a=a0U0K|0;pd8OMAZiT0*=HsTFnYFQ8k%pRy`;LvP*@ZO}S`n&k~ z8{ypAMbsM&_-v$P2ImKGRZfUpq;{0;uO}dJ9R0hN_&aomZ_|PfJyi~_11R}u49Max zz1+o{4|m;Wp6frZG4DGVQ43cLr1^sp=YUrq!=MO~Dp@I> z{zD;X$6CA_L0&tr{>SHR?6jaEhz6j6E)iEfP~(}BOw7Oe0}-26jZS&IoxPq;4j+61 z*!1AjxCVqk^C?gXUUuF~1hO3rG}G*`a=RA>qTQuE_=G2&fAD&Oy&aqOHb}l1z?~?F z2yjb1VGlkHoj`s6saD#pn1H?ahdml#P?HltHW#3ZZ4baPI0EDXD`4kB^!)MkzZojZ zP8Mvs?tO-Su=%onT0=7M2yx%u-L{3~u6fGw1wp?f(c8W22azGXCt__0Zn1Vrn6iXr z-679$(ZF`efdH$EOZ(?6Zy*nFtoMDCy&zQ><-jA?e;BaZG|oPGA4}3NNmw(hVPYm& z&(+EStxACgmFUQ^s;5=p(%(Y#Q(2?(UpvQ=KeA&pARwA zK;)Q8d1Kyo$bUUD@Q38D#^EZfK%8c)F;D=y*z;|&g7>tr(g~Tn8+2wnn!t@s_OfzW zQx28DO!kATx-Z-PXc$RJf7+L))!jx3;-A!u+HZVBaS-!B&l^THz?TdjVJl}*3pxz< z{In5m(|)LS&*rqDOQ9i}DY59qoWW@nxLpH6dcV2P7!g zp4!iQHt^pYy7LcrWkgxxb}aS?L-{-^`B=mRX7K`9Nn8u72$~$B;i)N~J7=sOR#jVv7 z5dEM9ECrOxGgE3J3cJC%8Z)A1L$70e!lZ-u0#?!O;;vo-gSicl3+q@Zb6Q)@_Ny&t z9$IsTRgt{A$1fI4jTK&2^P4~?rezYbHmjX_Mr^}QHM$tJmLWv>r3c9^oPE5#c`eEI zV{KPtzJZ+{+&gY{sP*g3ytslSD?&y|jNf%PU@SeQtPJIJEC$;?7$hAk^o~BVF=;nS zr4x>SV#-I0-W1w%UG<%-W?4Z%l3`+fl9C}qto;Qc^1?QYQ1#TC>5Agf)%QANNkj$< z7QJnc`J7)?t6==EBs^aOwim1RZ(yD3-(iDN47{I6{)R)UOY3M{_FUB)#dCr!Lt4Zm z!e!GFI>03UcVj*;)n_E@wjGVx2vxuxD`U7=&-V&S!f>xJ^k6|BM(^w%tBuC%CxN%+ zV>>x!J)bih-$>W&XY4|$CW+hXkF3KEC_b95F;8N;`n(JnetW`%bURVT+p1&VSoXmx zopsc)r+Wock4>V$hqv4U#6#MoJ}H`#y%{eJ?|;zq;I2Do{K{Fz`Fn;0(?lh^z+h8q z%P>D3rE9SVV!cOxs*p&uT@Y!VW)CL12crSSXehus!k{rt#be)SoEJIPuk}&&eZ!wC z({E5K?}uqA>5p9q7*nrD%qn#{eaocNf|ECH?sUIYZLl+tm2%ZFQDU}=>Wa7He2hjr z`KDFC?N#!)710l38^;uNEhuL`T$C!M-5ZG?OA!N(CuDVj)dZ52s_$Rmf3xi-jm7iy zI~cG+MHH(3@sJGFbC_)?I79f;2l^Ss%M;`d;61#Q5%K$H-9{vg(+=g@Os>8MOKr?|qzuEM0a;uV}+eX4D)1j{c1X5Yp7 zFiI2dP)WRIb;16&U|q0Zc)lcQ%{^uhd=+{)>oL+-Vr*+(hw4PnKhW{0;*Ic5X^_AD z(dSCrS(vZJx>Fw15q4zj#`^5k%4LB%cA9p$elXd|`L}nZQOy;Z*B2uX6Qbpr(@OmF zGX3?JM;|sZPvfjCTP67)R5>TTQbHSsw~Jw&zRJ<*yJ^hA^!pCll4)IuyP_p(8=!PV z=p&;9(JBJhEw@e#=}#IdrU0v}JEjW$LZi!vEm6{EnCZHrVxD3dy^|lonz_`HLX9BoY!Sn;7*dqK*DXBPq7uTLZd{Vvv#g z#h$nSV5D?o%^P?iXjNfw=;2RIEJoRzwU4+7#pJPK|G=Ufn_f>aT??xap7}@k;LGXn zz3BV{Px&r}JCTQUzTd7SdxFbk>eC9%)s5+2l&DRoe5hP@B~L0MI7CbVG^{_I-?m-k z?{qggTOIWv zoYkB-tS9i#<>yUuPeze;%rUmK%a?=p!r1G(&JYB`Y-8?*KtB_S(Wa$MKjlxLLt)*h zVxzC*)BM09W{I_Sz^^xcn`?el0%4ubFPBhrH{&5$IA*)z=rKSaMr>x$JA zg|S8WWu${8oE2)U)~aF-kRh$*J{!EyAHi{RD?sh_KDfyd@ZUG|55FIL#pAO)Vv+OZ zzBWS6qEo#61yz;@FWoqU1jG`a!kK|BCS;?{;@<1j@r?IpajJ_#Y>mp!V=Sp^2kql# z2&vKl(1`EIeiCpf`bWe3-aYhQ%faqoz-lw_5XF`>Wi3HFPNCUV+nL3sA!f6ILbQy7 ze5xJnByD`uWmHDAai+B@F%QIyi$3@ztgt=>7Q(hdMs&&=Ed>$B#Y1zIPmuT^(6Co! zGnc)Lj2#z&4--&)tSiC4IENi_^SRo4q4c{>99Iu*aoTXu2e6k~=lgkV^9Z`IS~GZt z0=53Zs=~NO4tE9*0m^bUO7u|n>VThmRDDRl1bbcS?(NMn*7ry9ni5t7zN|DZJx?FZ zYCfJTvY9KzvM>#0k?zpo`?Z{hc|?0X{OwtRJRGwXTJm9TIz_}S^L>ty9_X?jy9EY| z>huc|RI!OpT7FhkGB=u(T%O_hA)T=-Jid9!dC3LsE0Ip;`AXu1!Q*jR-`y56oCBY} zU=|0L%$_t$nphpG#ZBT;0$BJRb3ZV79TXiDd-dfH%%dzhjt!k|ZxNP*$J=0H2yWApBbeH66l4Z1S-@Pu*qZycq!mWC3&OYAG1cEBBK=6CYQuVzLO!nM7`x z{xyV)A+H8$oh;QtV9lGGeXiq-Uv8V`tMqpOG$o>`Scl_vxAQCX{_KbI>zI7QvCaHH z95-6C;OQ$NO}27CTo1>UEhhGzIh8j>WGj!h`_tXw2+=yNC$>jMjLOuYcint;n&VJchdhbG z+U)jd{vLt9#j&p*3G`!Ox4v4hmd~AxNg1xm&j7x14b-qeLypVrI)*L?G@1yU=IoAr zF@CoIW>r=|H?|om*FHY7+LhiT;bJ&R4Mz}N%MzIa?0jEfJ7XS}I}*S|ec&o^(h`Lw z7wbD;FI<|ZQ?5Q+pigHQcPUfvYJ6Zz0Pj;Of8{9aJWxS-_D3J^7ud?Bv^sMj7-_7f@ba;KEdkx7h>$=M6q)x%*Ne_>+ zXY}LEPzp?e(ZJ&>-TD{~ehiUKr(Bh+uE9JvTSk#dj+@6%;kSGNe9om!z~)Enhd$d6 z<;Os7EfNvSixjrMNe72k>=C!j!a~7MX<4@T+MJEIxZNI+&@@bk5O2^n0h}SU=>N0rlAtsxGx|d8g6d3=kOO#X z0C32`Ad92m!j)4>WyiE5S&|8s$+;>#cRIkWy=}SfivdX%%&_0|2Y}DJ602K|sh(W~ zyCCI%a}Of52Pr!PY?iBHz9Boj>3NrW#T;BOB7yx;d`e!e!+x6gV02FpsU%d*jFu`F z$GOV=sVW_mcAcqknKT&!XK(d;yaF05OOqT4y1Q*7 zkDQ1$!u}+LsHsVt#-t013GDrMhUv2YEPhQR4)_G(7tq5!G6fxFi&^!I!-+2?|9ROa zOR~TGV9cQV2npP$<;1ZBUTl%g{fCxh)ud*99rD8cSBXp*{R7g4ZyYW_RXT`eszu#gKEA3oa?RlkU7Iv2!=OY7CXyxv0(cRA?TzGpYHhq*tc6o z@_IeNAkk{4Os^@?r4W1)`yj2$zOcQ4u1N}@AR||3o61=u>L6M_Q~yIenrkM?!wx3r zQX}W9y_WcNupm1*SA+MrrSYk^pz$?koXhVEI4~Vb{^P^-wwve8U~`ntIpT1PDGbEhAan8PIbc3i)n$MSOzs9$2Z7cJUPcUDt|FXsu)Xl+8 zq1#|voGU;5z3=Jri`v?KI+G?w=ZlB)uM(X|=4F4)y=eS*^B(!mxLj6rDIbJHj1TDg z-)(R$6CZ+xL+j3kn#`?Bl}mY~RNevjbc>16hAFqAa)YoC$Z$ zdp(Nmtuzm&_{V<)GE*K`gQkWZFucF}gLbk=ao?SPLi!}gaNmKWA1{#QbgxHLmp%cy z!>*8pBVP)f>FS3qo8APJ>$`AwAT}m{*!FtW^frvbt%dWyeY-pSa_GxW1EBi|~0ho1UM=0hN6Z^_%AMHurxof{HMlRl)JJ=N_s1-%dc0pT$^ zEU%*IfbcxfK7Hx13;XieiD1!mwzK>bnBX+v-imIB+J(-f`Khj=(zUGVNwS}>DD7_| zE@4S9tRpxz7o_7G-xucPOvtac-YK5eBhN>__RW}_N^fW%+aL`945;{n9hjSsC|^Ij zJc6xiT}Yq0wBw`iWVrTq;UlYgJ#cbdtIzRBQrz4FC6)4+5_ATss!u!01iiwj{zs?{ z!m-mqL@&8?T5gXt?-d58Keo&@{-TDiDCw9E`(ruu{&l4C(%$VffBM5UIm9R6Wr5v} zDhf-sS9rr9I-JbGm#%>wsww4x?K@oU|Fk14!Iu`RE5ED(&#UH2|EF(wda`;G)imnk zpg75)Zy-^5xNFRh0)M?p^PP^50BF|yr!!P23AoB@@@f^hRV2QQxDRai2XYg@CDQ-#I?xUZpcFF)5QPAx zm;Vo#>pKu2;2h~eIWX|!tA;xNMKc?Q_1TFe5GrT9&@T|0|Ej%X$`%A8(wqgfrVKn4 z{Q%Z!_z#o|mr#MhPSXHdg|mk8xkE~Mk}$<39sA{fY<_yeo$`=rAGdfXAjD7n8OoRH zKX6XKZkI2k2pH=C&73Y7b^I6XKwYpm2q~DUcZ>cV2*YdcIC2Qd1SSb99(S|{ zV#KMP>V>4i6%=E|xW5A~gZKy_Twjl>1)?>4o5c|hX6tD_b3CHEua2)Y0~~`fm4W@4PXiG1>cbX{??-eDKc8YjZ=xjUqQzGh7 zA)X;jT-B;K-a@=6hQsdp}?KJV;W*)y`H5v_l4)AIKrL%fX;k$cZ zmxd?)t~pw{W}r zGH<+%{Ao+Q44rh>-mvjXD6kddnP6BvZ&&~KW^e8ko&r;#E&v5;7~W+0@d{W?%i5ZE zhb1Ti4_zWY%=I1qf-WF7c8mVa`>D7yzV8IrV#0vtJK6gUi~oN2_fj2{^>e2Cc#3km zyh!t(w+>Ck^i*vKm<_Xa0Q{B*ZIj*lPy2a!D{MH|i4YF4LqLF;fZWe!pEMp(Y*McB zsUTiA4AvJd!x|tIX%YKobfbCMf8fw)Dc?qSZA|>hqK%L2nY=}hd&CeMa*J~Tr^(U~C2R#(McCegka($2fB(0KYE6Bssy1(DV}|khi6MJ^ z7|2gad*i(lQRs(%;DLTfTD7SUZ0(lv0XrTSia_^c{*3xzE?G)||9fhG`I%~Z*EQkh z?R{9p_LGd}tc%4F#@PtLAH==?EUm!u;!YC~*nB4?Jx;V20o35;YbGu=Uv4l@>$L6gbUJ?aOm7hJY}g z$^JH-6`BiUj{c*$wzTR^^`%?eANMgLaNxe)>)R9_XY# z^`~ab{DtxtNE0CT>1HpN9})y1qf)k?{Z$k-P-tZF?)*qO*t1tX)fTbB#cmKC#JuAH zj|an^E6KXFF(sp9yU*1o*F*ohj{un3FMdGI`bicc+U%tZ886fd|O+s-;Xtl`B$XdTV?XaIE+d+@)=d90sToWZAk$Je|X88K`^18R$DDRNr zcOcm;iwZa_)-qzOL|915q~e$kjCqIHE~jeI+i|tCW#P zdDsB6z|lGs88vxwZQtKBzV|@etL7qLKX&Gru>#=~=YJm#A!0sFTg(Jz2v20DPn+*4 z^?`*8#1mUa;A;?J-RoM5Z#|WVTD6%5CpC;XL|KK7xYkLVZKKh2)JIP{zy=|D&-$`}_<`=$?l0R+IrP4@N8tcDk zj}exe=E0l~pB3@R+S+w&N5a{>@IHijEADmkt?i%^-S39+BEde->rHt) ziC$yx>T-NRUwi%NuBSRr{g`kta3fScE;Gm&15;y{78r|XAJqIczQ*4AGG90Hm^f~c ze@t0%R&Z=e;XLT6@g9RJT2^KJ%sg)K)?xYeP3pKz!7-i0bCS!5+Fp{7HcNIE+D(_Z zn2*OqaRHp#h04?Sv}2#TDsItiK8ah8bZb<0kk#ENzP|Y`PKI|!>h_qZg3rr*Exoc; zR#LEc(-7?DrZT%m#MF2ryRpESn&Rx;F($<(<$Sc_`M0N8besL`EL58?#nj|m=koca zicL@QZ?Zew*z}0oySWL9lessRq;OvMRQ9^9Uv4s(-I!-ghrRVl{vi9py)j9JS>7=j z;8<{ekAja;KDWY_D)kiC*c!Vr@7Nn)IAgvF=gCjAZf<^h3cG>-j1}rtj#(QS;t>D``yu_pir|?u(EO>V|uNQq^f}& zFX5D~J8_eNspGtx^Edc0U_hXfCgDwQUeW0u?c<5kilv^))E zGSef>8@c6Ah)l%>cCWb+Z_W+O&DBlNx;xlxznvMQwRx>tevLnEOETvJBsu?xM}+A; z|F=SuS*1j`NhfmW^5)efDU?Vp`3 zcQQ1D{Zik|U9vy%0b z^*;|72jpy6od7f$R2; zP7@NzGBhG=(cY*U`wWrPlQ%Pux@@9$8xv>MizbIn?+9J8JH9{02E=iZJ8uQybqvqjPCiU&jgsz>y;5vTSJm!GX)Oj~F#*~u zsIahylCP%fJs5&h-EjXd2rxv(fB*4S?`uk9XMeYGDuTUB;4Cqh!o z2#cFU7VPrt?FuVGUOG~`iPYAamU|8|9Ns%CSi zNd!9ox>0yvSH0L9{0*@|{j1n4L1ai}Osw8K-R{dTLu#7>r{qN)rWD3%1sA*QHrE%~ ztR1r-M4ATEKYHk)K24BHLAy7kU+<8nI-NmV$}Gf+%*^hMI(fMtvKu1kRN=Ohk{9e1wmK}>c`TUCuGG#38kRVZbq_?d<_UxbHwpR8wIZ*7#R|bSyMBAL&N=RvtZ`T7fMZZ|SQN*eP!J z5xbSjKfKyafE>AO(N;=X=ehrJ(nC(d#;AF6L?)6_ zr@p81VT#DxqYa78rf9BaJ-xy8O6$ZHcYlbyW=I;Pzn1=rS4$(aMMuhmMbg>dp?}D5thc!@uv%jJ<1(e= zHrf8ZmN;_#||)ba#&EhE{EDSFJHiP-x=U#889Qo@W*^zm40w4HkLr z3};hk?U;zZEwts;eTh}k8yy)5SxOM0)ph!|pH#{#U3kmX32t(&uKsO|a9XNYe;)HJ z&*ap*_jQT4B;N97SYI@Y1dcy<(9LeFQ(?+8c$J`0OTO!%!EZQ%sC78edpFGG5 zx&PKcqm?wOL~ah5IE1V#^;>?Kogf!Jy+B<;{x;{vV8N`M===0+E)JSqA+GNT8~v8r zNJOlF;|7_)B(`T|(v>!=TF)r2K*2S;&9VifDeaaNY1An_T~Qls6M`(K7&uZZYRh2} zF8{pMEXIEDLRy3}-LB~N2w|yjL^WasC%Sq=D`=0xC-HhQbgD(Ebl31Y(FzX!JDxlA zrq>znZVJP=JIlNzhP$|b4JR5lb0v1P#Ha&@gW*nai89CNE>oGv4Y=-^iR1s_>8<0M ze82y3LO?`7KsuFfk#1Cw4v~_Yq;%J)(ILVl2S^!oi!gfhXb_}hbdQDsWANMS{rNtA z|Lxv=?c67x_c`afc3tN%+-xf*BJi&6Kmr~Ox`M1WrHBSsXLu4PDKa;l(+pZ~U4N|b zME%gYEY{!YoM0hDFtAanUS(=Z1u{cpm`*{R-oH3A&2lc@$tmF_o6=gSIrIpLY4`Ia zgZ@)(`b@gH*-pm(XzRYg$+NH;_j{bZ28Kpqf*?etd@y+7VzNjW78D94FMa{2p_h5= z7?i5p!ZSU@$u(|F-KNk0@=b=7+`a~6&I=(L8l0sS&Yxwwu2NUt(>4Y3-#%9kJW(-4 zCx)}hJeo@s)YisbR#Wz4Y@h>#jC1FFkqKQ0_`rxXM2`F4WT#B5?M+P87fwwD<0h^V zY87}USK}tle@g3S`KO1ND`9>s?I+~S=LQ!i`iAeyV^ebCnSVm_bh>IJ?JpeIy+=yj zJJCw)In*k$xjx2Nm?Ps}L-p>-LdO>W8(7FmdjzuDRbADeWDla}im|`Cx``>^3UBA? zVO>KkESNz(i=8(0`1D{?6~(SE>+7HFTz;mJ@$+%MZVh4pl2#%uSt-$?fbubetNedKKVkFU9;rgQ`MkDq(&-OO%W&bSIvmx8*6 zJjq_~voYl)FVH!Z!D$>beghCxQ(dimRp#!){_OIxn|DqL3T?jq~dm#ZgFL*cYnpWMB8{4z} z*rL38yxo0j*DCu%d>c*fyv3W(4fF@UOja39=vcanf}f|`0RQ%h8&28v7EYhCLKdw* zl^6u67HC_dlLt$^YzS5N{6#^Ar7(xqfBL$qF$;|ElBl1Ak|tN139|}qXGv$>1WISn zLehiJQvu#`6M&IE!yfqk zVE2Ng*Uv0PC;29(?KFsCS{2F|Vqv6FoD;k7Y+I)YHgzgcy0|hU)LV0JaC&^1xafdh zsQC1!ZW&-e3U6nTc1HHC-g|{!U6dAbv#8d~X-ZTIoH5f;LpjS#)9G} z7p0rec-KaL{r>UC*6?rHkn0Wl-Y0bS;)90nENcdqr8yIWcjnDyt-r5+zaQ;hfOvD; zRGYG-7#42c)ze{jPU+AKTYi$)9coI(3@cwq<#SFIsz9h+`I^nIhW;mpH~YNB2MY_+ z(cK%*eMp+?#^vWB{#EYj3jVU?nzGZ+q{VucZ{7`cACU5kpZMw;fi2{PKEwk*7>w>a zV2Xa6df6yM4`|L%=Q04b(<@tByAEY43b_u+#bkNq&2@(6^j3u{g-+24e+ua*Bt1h% zVB(5mWXXHg4SAZ~nz}m>0jz+$W$lmaKD|-*-0Yih`a24L23_J7DCBBY&;(`}Sei=g zikY)&a{sOVk#j{$#N8JVb0x#n^>cOl<`QGG@z#>NFXYHKeZQ{~dxLCBL=l1J*7a$QTKRUxPrLsS$42-5VENNx%9YK3q zdEMVky&G~pnAFhzfvETT4x%UV4`@UF>d0VHB5_KLDYN?1jQqbv`O~6pymiK%%;ji z<8oue8_Z49UE1l3ptMExt5^Sl%cz1^*rKlJk8;mKpKmbJsYlS1J{2I}bopzVVHzJY zkIxOEu>DrL`d8qO+;PDj5D~dEpm~)!eM!GfPxfxD-sJga`nR1l?{8QDsSkrRffhgR z^=#%rdyN+8wNKw2(9#BDYwpvAM&;OQ7dpVkrD^@u8CSV&@xu^FM)^MPj~M|fX^)q5 zWeVj|EK=K9?Rd%63pp*Zmlc>n^**!o?*Zjy6@QvDp@H8)gTZy7ZO_^VtFSiT08Yrg zYO4>FotiD3sTQ37wbUUsC07x`=}&pqp>LU5A#7n`VA<|s!J82{5a<-oCY-?Lp2#K) zW`hYu+)`a$nrh5}$*bW->eKH3761TKLj#Kq;YpODtxG%`><4c|t4Ks}LR;(0h`ZzM zYNUqBwqV9oNfg1=k+j3CcPBjohP!g zEq|*%`L{I)R3qsf?Zwxp9Qs7rD{pJ3|Ja*m*S?)xzn)EJ!f)2Z!HtPy$6Z>*XC`Kg zBgVtyZp4WYy{GC7BYR8%qI?o7{eXjw&7bGVN?Eg|um6;f@x_jfc#Cc5Wkd6xZ%Aw4 z#oko8@lm1ZwDeJUyCn9Ubf9x}o0xv+V44B>T^kmP<-vlHv8S=I)?hN#(L(EwN1g>o z+83ftEL*fh;P+qfb(EhKeMeIiNkXCYgOiO?8E*e%AJIz?@9j){n@8eomcqyo7pm4K zw&F(-Qo%$|w0BRUu4LH}&zJ>P7AJF$3cn_J?I22iwGk@QFIc(R*-rM3;uugWS*D7$?QU7 z5sCBB2;8SP{E5+8pKc18-Zo_!*z#y`>Kg|T4&DgmJq)@^QnGkNvA2>xf=FgUg_;7^ zXrjk$!#1^VMl){koOH@=`&>-2Z443u_kji;=pA19 z@lRO-0$(J5Q9~>ZayEIjs;y+A!DQDpqU)2y;!Pmc)AjFnHItLXEZcE|KLKm7niI-< zml#Q{9Blp6&2^Yi-`j6_BgayP1}p>MSO>%$H@R?LHHRV#gL=x#oO~U`DpOF?#&da) z`x0NcE)?}wF#nI0m_(Gv&e_$n0og|LYU&pJuTkov?R4av+}neOis>l){oph&P{$Z_N=6Rfz&O|905`I2IH3YYPU-7D6-KE zd3Ud_aK}kB&@qsAfD$u&OH0Fa&3|~~b0c)<&FIgcuc`YP1>%57Gn`UZ$Ml{@`U6Sg=@d-(qZ7XUV%oNg0l+ z?#v|Z(ju??^R{VnP9Q3T6aKMYU(6+g$Ag7J8ppPyg{h>9eNF;joqn6F?QPzXb!_*% zO1MiO=ML`=n~nv^bZDNd($iun>U%O0p#%{1-Y-9{xXHoq36LVEe_=oMxXyf{Sg9|^ zZc{XM0Z-TG`mym$V4%MR9kRVA;>{T#u{!JHbi$8bjyIa ze_A^J8!?6+1-xLrR4@@(7dxm)nSo>?PCm9XK*sl4H09+oKS`B`$HXpWKR{@&h(nIZ z`7GwiaZrz9W%b_Ga-*A#eBo5&_J79mu)_;NwB#*UJtEYHoqT`WciZsqM%?6dn8gV1 z-aL&5KD%9h5E)PSkM|pxi!OLugGg*akQG2cRX;Y&%GiAvj|?`rJsd>gXk{o8ZkUy> zNpXu;n*MWYa7(x<+Yz1Dk+Dzl%ly~_KxSHgpWNe1T3MHE^qKLKiiAE^lrWm&GbCTf z|7c@F8Ye2k74xa{%PfK6->Vdty(7PZGD$vqN~VtQdG}5--g@jg5jn?YtV!C80+v~5C-TxrJzR21Wi^b+1%_Iv(%K71s+d9~Q2-O=V4-4U(Vy3g2VnZ7swEW2 zkLUC!@9LXC|0+d+IaM={Er3;3F!)GllcC8=o(Yg$89Z*xbl#$g`J(IK--d(z;`VPO z(7zO1J9av*@E%}a_={{~sZxPkar$LI(Dk{}+si|9mVxv!&9hm!0Ihiz^!CtPVZc`r zv7%`;)T=zT*AjFcrJOsanZ4@pNP#zbUBopHKKZnwGXq3KHi<+Ol5H&&DzMMUT9|Iv zh(*irDem}h-w1N=yZI;BB3^yo<*~RtG-27$fKPhC-7-iHXUszVh4ME7EmemnDo&{e zx`F;xi0dS9+TpPNNMPKXEBpZe3UV)b=$OC=A7absPHi%G!TD9a7}y2zfw$t#^-m3d z=W6CMyJqLI=u(828YpVF3Q1UE1c!uv(zIflWi@Pe4sz8CVgO9b!`ecJaPKIJS{fDz z>x)B0>t9@mCLMzLmg<*sQtvZ%zoC~ix?85UPbM<1t1ue{W_?tsw)Ae9KE*O0sNdNu zTvMdveVbscXAQ^z`xN`7d+4(JVGuujtKk0O^uppt+Ul0G?rBAHx{o81(*Na zi)ex{WJwtJuwZED>3HQR$z70{PF**sA=fqQXkM3Sr)@mlyV9lQ02eojZ>bIA@**l@ zHyXV>==eynW3^EJZ0Tm;4fHcN_Gd|}8;1o5iv`?vw3(Y?Fucel4=;(&;-6&}AgCJQ zeIXkD2uq@V$^2_f20RN(!m5j#=|i(w3sNtL-o1gQ=x$4iNK&cYSy6h&XgBh{otJ3d z!(cbXj|6>y>&_KZ$rKy*2z%d5F}DB}A-rvx<#)2mNoWF#%8iPb|-eIiC0%Ef=Y=Zq&NBs0OAzw`_NWueQIdq*DDN;A%9lEBfBS zNmq8O1qH^wgNg?zqa?u>aYs87OY_>_O_9QwD&Ag}hdrh8t{K9+`NVCix0whtX_t=V z|L`P9OICGsBJ^bqZpN1f@Zt37-tR$IA za;oWv^KKGadi$8I_D^0e;lWtwjJr`e37%fDFj{PdSdF?uNu6{t_T9>J`?}Ic##rf`TiypP+)o@;JeBx5iPcy=ghX`83v_+t zDxDObJ1_tLs~qaZ)U90~@_&%*lFV_gpO413Hnc-sR@Qvj@;`}!`fs1EE#JDESV4!q z96weXA##Vfn+&V(@G5F7jjkPqF=}F~%tV)`r_BBep9qgr+GI0mGkRy%G;0S7!#hkv z{Dlb?wo+<$TzHcDo^_Ko7Yi1!Zs(GN_hE)kEq?a`x;{%jRm z3JEX*k|+X3yrso5zZoXcJ7{A)q0olLK9nFL@~MK0+0bs%#cV;;x^?9Gdxwt=Mw7i4 znXAik4MP#`gR6LdkdlB2GD1_C(L<|^>;>HLWm9d)Kh179u(ys_*Sp8_y8zD(EvXcD z)!1WARoMD=agkC)o7W=wm_)V`plrKsFDO809EgZ7}{ zHhZb;l(@P8?;w96@WvpV*Qzh_7q1wHP5II2X6j;@aa*(?8^^EAa9R}l(1dj(aBIIo zDdnp*VSvlUQf+X5deS#)qm&G1!m!1o7Ml>G0Co4XLBg?LJ!T-zm6uNR#ZzSv~I6}LO8 z+D!JyS-V)q5}Bxw+r9Z;&_zj(45iyEjTs@Bhhoi3L9YB?N-E8Ni@07aRR-tm7c$o{ zOAPf=7CZ&-a!LPvsI|8#dl>v|WVg}+i}Cv!9$(Fy^cm_O=9sA0A}K^xgU3AjA8WMO=7g5}78ZRY>p zp}fsk{9h^zLl+lXG=a+-*8GnJ1tAYIFOIPhe2{vLd2+VTprxrMmQCAw3=Uzu-T zAAR#bZUPjt9c5U>@fQwJOHB$X`@r@OR(_SI>H!wJSXv^U<{#Ui1~vW6TV5Kh+vl_O zxb$*VviuJm9LAQ_^p`UN5W?l9qZaQFBae@|Xc|U2tffN!pQVc4^AEoe1VyDDnPW8- zX};T-C^iseU$BB{m!1AZVt?Sc=yHsOBi-_U1UP2S8b7Qijhr?CkFa{qQ*HYD2y&n~ z%Jsz~#0KBAty)CnyJ1jzxe9VVlAMf`oQw~f&x%y0Cpv`Q1ZWF8`cC}xvT1%9)SM&P z)s!L?y56__Bp`W%`_mgKkias}R6=dD5%WYDdEdpFe;AYk2r^8BL{?v!(*iZPl4?Wc8#ivVXHEphC_-IMhYvqV{dv`xu zM$3~%dv`Ofy$A#)#f_Xdyi7+}@+sb>kV`Vdz>=RI*4wemlE=Tz z!clyuzfV`FAQaMCR(_phTJF88^v<5al`;f6^J%ztF7TBw*pP8E(9^Wr^9ApNXFVe9 z^JSVjf8|@(U(7wq=TU>#^TUrA6m)jEsJ_V)GBf@<2o03~FyL)X%ZDsTn7rVZF&@ph&*nDDPyVsRjLvUgv7#Yu_SDx5#l^H0-#ayYi& zEsS9>9HcrfGjcbekfE-x$W+;<(#SWReEuiK?dMgCe#50{{kDcvrMmSEfq<$ly)~I_u>O;7?!4BGT09}hnoSnXv2>A@Ptqh(1bL~G&ol2Nkg+fGEUi_-yUZw<#?T#AW??wjH(IIQA(lw(^N?**RIBNpv-O&gC9 za9g#ml#ei1>Rv_48v>ml6Q1z2V0`fN@P?8Z3Q(d~rNOYH*x`#+2#vIZ@1hX(PQ;qM zX?eMA9@{^yf}{Pm64h+$!k^bayL$R1M_z)kC&aoqxAwR*dEsf_ll3(?|ADh#CUIp9 zpx|LAM17-|D=42=l|KS+h$TheQuIAKF8cjupA5W930*TaR9))rKX`lKLQ|WaqhP^n zEo584KPL7sMbdngHE}VdwP-fx%Ws8qSIh3-=}kffKlU0QZXbQoc=70&m#7<{}&PN!xVy zuip;P%^t?IT`x^R|aa{a*M?C zI_`p&d&rjleA?}f#1V~7toi5IHTtr~`S>3>TzGRmfwnVa&#L_i1k5{U*7WqW>UOu~ zROj5Kf|FtS4^K&4wg@6|GwGN}pgu>0X0Np>nfkHomKOnmpG*Vz%jH*KuxaDgYW}l3 zy65DCWlm#apAB307NgrMDgNSa#JSn{zW%K*5?gq3@}u_jW4vo~gp6#GQP<6ZBd2w$ zmy%_W#26IboxNvDxtUrr=ddI~5ZZb}Eh1W1xx}r*uR&<|Go^3UlkNESGOS{}NrpY} zX?!+&wV_^}9^@VS69NVkI=F12Bc|*XYG*&5kZ+0s|6FA5ZSGrS>;AdCc>8y$L|0zq z%r@fUvT3H^(=nAr-`Nmb$ZnqO7yla)^AMu5(fhzYwL7Qq=oZ6p)@)VV$HSY2uh%Cd z4+7_-R1m(SDPC{$pN)Ntl=~ShYp;e*2Lw`0-mT;(UlP6j4yq0!Nricm-JmKO^P1EH zW(K_NVk#9GB2RULN#EZs0#Z*A2-Q>BNq76x5EvQKSqbgVdCkmZnNAK%?+A&L!yL0j zbKgBs+`SKXOgW?mUBs$m+7;~eWEQr{OHQG1KlS(2{ zT&`q-_pWo7;V6FLO9F@}sEO?z%%s7utjwaKTsNPteOl7Maegok;C^fZn92Wo$E|ov zSahH6pM2*o)P031uC_g$S=Kl;R!})LK5R}LKwKBw=m~W$Fs!(rcOOg=tzVi3(3mp8 zI&{0QcwNwZ`OnVNqXQxB3CxNz08FY2a37&IxDYV&jV{nUASn%+$9e5czBIbw&!ry9 zawATDLA`>JHUj~i_feGR#-0A}F(%%R&tF6Yh%l6fR+{MFde&R&y)>*h|2AGeDfBc_ z@zC%#K=iR`E7fREIIcT^f@mrmX6~9eL-7Ii%g`1@t$8R0_w?Y3;`HE#qE0dQ(sS6d z5aXCc&y~l8kuha5cr);?IBAS;*I6xZs=9tP=j7FW|CH;%2CRr5V~8=W)JDGoY499u zw~SYsPiZ=kza}avpeY_dWo(wMcuey*rccq@_U9Jk%g>gT>ge@Z@^hln{z_H92;VFi ziE+O-R5{N=x9*JL0$brvIEt{lJv`U`yHl;DQi7*Qanva=(2z5YMP%-``qnY2^-g4C3>pAeb%&vQs_ARcSQVACJ7=)y%}@X>xNX(CEN5ri*PcA_f>jg93IrpW#t#<-LoBSLoh;7d4X&-efnw3u&F#tPLG?#a1Y+G(-*fpQUV*Zx1%i&bM5Y<(^1!e z@{25t20fZgD@3~OrKVw-vaIAQ2X$Q2*R6lvP3DvkCn`2j_kk=>tC{k?Lc zIO6DQK=0U-Y*#h?-fiQjhFMPd*v1fzB0bNenBU+}NSJso9F6A-0EoeXy-8tC^BLx* z#gI@+Swn$u(HF%DNM11KE6c;i-;#kVCq3P~F=N!R1P9jYl9@-Vf)>j=bDgSDe@$tB z^f9v3e~$6^T{iW&(B`pK%jc2DPeBa%!c)gv;VgY|4Ucu?Wu#sgVTPh&m}>G%X}B+5 zW=EM|%549gT7i4!L4?w4!^R@}@4cce@)!H~OOlWH^KYEC&`LRGi2huv1l8}J6;o4A zOPM4lFUGmKzWP){${CCp8P%PHiqluZSQwwIzQI>m;&nC6_0;H7p)(^>=oX=%#@kKn zdqMGKpHu8biRd6N=gapqPZpFH{yuQ>Qm^FM4P*!WGquS&%$evSPnjGsAk)1R;10H; zQ1qClP);E=>3K4W!=*qF-G9oPQEA%4@eTNO+-$|!Byb@>R@Gf{?k-q(AE8}%zXyfm zJVo(VZ6{EvhzbAfE#>vqa6U?|zky%pJoWc#)aTz4U;paI0mB#Y)`iSYD2ca$l@DuVDU2*hlX2FcUljMe`=Rc#_?3r?Z z+>5ondn4^&$V30g#C^ZZlICa>t^`1lFW!M-&TWX#c?K1w_unBsjxsWX>7R4#9}T)uCx0<{oOOFpj#@YnGses)dbjd2$wig(t_m!pyj2F|Pij9e^F z7L%-%pPuAYO}RbT+C)P;^P5c61)YM|1M9!^KDHT)_v4siG~LzQp@&bWC7+)E@e8n! zr(3(I7Xl1iR$C60-%20A4((=O=>U%4VDzNNGKO9Pge*_;ym=$cI5_S*`|fp6$4sQd zSY8(cAO!Dm+0#gwlZU+ZIi{}}8P^wD_#J+x_K10|af~`!RnDE+E3h4v>f=eTEgdK* z$9LY$vFgU%EQ4>bf4kR-2E7kv&1>%B$5gdFM&BD=F1|oBT(RuTptc1tZcBU$palZi zB7z#{d7_=k?ML!tKCw3j`wA$C=#SeUrLf9dH^t3k$7Cor21Bjc#`jH;jr3%(LM}#h`*(!$9r&1QXb0$3bN@5Vy=*oseMT26-Ys@q zI|hF9^31awqSL9+s-1ETfMlk zO&j!Aby*8dkaY{YC3uaf{)vg*79^{&45b4lC-*B{<|miWYyY`F54ZG09!a;YJzRyF zfgWDx+ii}n(5m0{p&~84zNUjB!1%Dcl#m2&bVfQL*7wNJ=&pKkV6e{Zj8ldza1dG- zINZeQm;t_`dt>=@!$0=I*-rDlTbzdH`g03L5={l7AaR$%=@Q4O_g8Ouo8B6Vxy?uk#ud_wY$b_;S;@>`ZhG!kHtxug<&5mKH`QaQ0V1=WcQ16ZK zv(SI2*^jmkY*f_b@Iq_1M|Jt{2LpZ@GzT$N`vJA8CTEu-Un)5Np|5(aQ$E$#c<1sn zB({J52730X00xX&e?yVcF8L8;mT3n&y5gNJ&RyFWoRJ(O5Bg$y^6?i*v)gPe^PWr% zD+m89DogF->lC*3I_9iWwh2|)XV%02{LCVEI1W&tuqi6TyJ%)ug%^f2=mKHIg2 zD$4Jjz59$kRBrr@voyKP<*{L zhb>bz?x`a@Q!X=aoy5L~tpX{z=aJ#i^745216P*VxZ5{}8H&6%h`Jw6!$q@kQ@-Y> z)o*=3(~-?A+EeOO110{+yp8J>O%I{9PwWCXqKZK9ep`pX*f zoRVF;qCv`TaaVh$yq8zoaY&x=F67p6eEZkj#j~q=+fbJ~f`dUOkAA|z|J9r=$|k7ajkNyDS)?bKAFidgmvLl$9ASH5@6(_@7=PmqiUeKzhS z`*CV`5a7<)c%pVraUIw4Cy$3e#A)DI79Vbs2d-O;i9v=8NzM%DHe*ZDcV1eN_^p?( zBCj46zs8UMo)8HJHU>mXsLTqlxwKezzPviybP%9Y=O*l~RnxFnb$7^kb6p;ncG7Pt z^mISYY`-v=f>epo?`!d=xN8paF$eveOyh?OgE}^cyqQp&oVKM@HdshnIvR49alFY~ zGxqL|#5sTRx=kD93-ify|H-iju(I#V0!1+O1S3`J`j96>Q_Jo5o$J6Fwq+O>u^8{Im%q}r<7u1NDBGfx+#3=apx%l@H7|l&>7f^-{jsoGXw8XaJ%JtS+ ze*bvK@rufBG*k`v`(3uf8Kb)(+NQJi+*E2@&3Yl*i#bt#mOlTtjzqiUv!3tl%MP@aMa^~pU~}BxE@nIs@2$s!Y!*+LFe+cWVd-@V zLtQ{iG0}`KF%uPIOvRJKwy!F!;59d5wOVD&x9VIBUIy{@?TV9nXNDEi)59$Fa)`C$ z7jwc{>uSAF zMMB%uXMF$EiQI(9A3zRrcML~Gv)TDEOpwE1z8wGXF|ayWVB+gJU9H>gSGq4y@(1mK zoA8JE3n7G~-+#M=u9&R`bFutBAoq0F?A^7_U1PNz?o~)3dnWz9l8$m@_1m*-WUa05 zXIxR~mFL~M<&$NVYyl_Np}6OH`~vsox56E&Tp{lqlHzTIehr*@zk}oAIl20J+HIk% zmiFzC|I)cHw}j8^>!3@MA$iJ77Yg)@aU3xmuW=fVvkX#t)wSJqDOT)J`6V2w#GlMK zrf=c^#sc#6YB;f=cT2q${k>s3VVAr?ev{ui}psDvkoOMPoJHpXmh! z%4^^EMb4L93u@a;U3i!%E|XtK|I4Kmv0$J1IzMFU3MN{42`b;GPPsd&;|T3@2I5>f zP_2;&YEd={yGO8x<*vZj?0BjN#-uwcE!aI+t@GWpIK;#QRTgSG=oDT!`Vr(bu%ilH zNV0b4huhW~{CW|=QIUG4MC9)8h+rE2i6nZs$SmY>_JX_)C~{{XMwY=!*^PYNHiUZ8 zXlAiOV~7VO^l(IsDyOwj zTU_CAqMox#98Bgu71*6hqXIt%6;BZ4Ba2~QFY^6q*e7*Rh|*YR zW@AWs4a;@HnrA}S6%7kTH^IktPVV0G-w#oH4Xm{5cJ+^f**W@#2)~%EMl~+G(m}}v zt`57JHyM-9A%k$O)s8*e_v3pW2i+mq<5rmK71dcX9>qo@x;H` z57f{yR>*`cJR=6hTr-k>hT9MvzeETh!tu`i+l=vuZa?~(Xn__wxS`@AdD}dg-k$Z0 z2hFTV>d8)~e(C+~Uau3G^Ysi->n0(Ri)G+z0kC_g{Et@U(LAE-quEBR6yxoQb=HCO z1PbS`Uzsm6jqhqwN;eSQpu2!4?SA-|q6AZ}d8u%|{^FmMO;R|>phFf<^bdn1X4;t+ zWhC4xA9W$*K@irmBs@pn)p`&LrgNj%T1a@ahB4E#++w~GxD#q+@LQMg?lyrB#)Cv(7cB}Wb6eeUy~_74CRu#mpPE3PuqyMN)f*MRUx~x)L&&+0_XSS4 zaxLg~frk;yqgr<-IF|g0MGgM#$4cGdBY!K4StgowJF<;Pww-Uy*vE$*(WE>$bhcQL z_zp7*^=xB&0fGkgVobs@)6)e3OOJ4t_`_h;p5gCzTD3k8E#QSVGgE;Vo{#VLQH$J3 zyn@v}_BvR=()pNsC=j=w*d=Frp0J-A>$%TFvELn7&?+?0K1}ZA_d*~~m5~izh267B zt~h=+`hl2fd}x?`4LFB;CKvGG2RJNHQmCbpM2V>5NS5^}*zD=f$Nh+a#grF{DHJD- zuDJ5mVN5~BR7}7Md{%@;JPJ2d0|enj%N4-1wFOiKI^|3?5-vEM!?p{Hd)8~oPTyX7 ziYz`l-X_yFKjKNuzb#Q_!D}{6h=+HR-~LIVISW!ep5!@(_&0V`c3p8DLB22!Bgj_9 z$j8z{j8BC~&?S|vbZ)d;*LXYKI*lEI9RU^Ha?N9;NqgK@ z7V_J8P=a&Hu#nzJH;)=nxgt--0#r#@kDmH$fUSaLUs}XM5RcjRh_>3D#Gw6%>Imw$ zb9YPZ2^3W#TKd$3{;Zv;3J>f(b;H?VBRSP8AWo8-4kv3^7VPt;S!o6*EEFrDjdZZ? zH0)%l&3KsHPy7DRx>0Brbf6$mh)hKF>o%-M5B&5|F2zyAobr+ys&>xFoCdq< zJ+Dw|!(OnRg>B0Q^>`$7z@gkd9?m}U**?q0I3KPfYC<1;ylby3l{+R`4d0;${+cY>8j(1S3C^(sqXGzFPF*fw5f)zfh zzOr+@ry^q65T?7u8Q4Xi2}xMDmUf99bl&a>{!MZP@H1$=SLTku^OQeF}))-?)KD2-paeybOi%C-8s`6*vX+lQ@u#OXBFcndN#IEL= zyI;zoxH88VpBJEy_kH?==U6*$1FDR*g!jX?6V*lJ-SL=xG!G`4mD&LVYJId<;|ZTQ zk&(VuD0S?4%AM$vBTU~DXB+nM3hO;~^sH1nM&%zzE) zpoMXbAtdAN+j&o+?j)D;{>$7k39o^j@Sgp@LgN_1e&?!fhMK%Fe3;kd(G3ph3>z>1 zbL1@4XXS!C?qdAQu{R|l*dl+hX?!18R%#kiK-NIqrXp)S;_EE=wNf=x?vt}6vajAL z>~6PDZ(d!jS9!^f^Zr|yV?R8SIDkf=;!n1JdQ$1H`8pG?WDxZP%n@LFwx}$&+s$$l z>BOBtiP4BIb&PNR6#c%8E%d%9a_s zg2)jT5lg?FCcRf*Ak1YDR+^cX2WPGq#3xsy-8Z#2UmIbMXNu3Fyj=x(b-xO5s#mq)s$OWos88fo!5^`RezsuZiAwCIs`jI8^ zG67wSyWT)U(_Q%no$=fH#w-H(ho=_5zpL?Lqi4NAa|Tn~>r;b!>-64hwCV9Vs#S~p z@un*)?NBZ@zsdi4&;lu8wgLYN>8SSO3@jDT+!n@G_?Km)1xN`mvsNmhEi?LC&e$Y< zova%zngL&DUkT#n$tGCK%;JPHXvOUclVD8JXFJ{B%ch;JVW<4_g`^3qMp&=Mc{`@N z9-($%7<|6?L4TRyk2~%bTtrf;13|cRv3S7V{BhBUeeHVT)n<_@2b$ibn8ao+)F2E% z@U~}NR(B>^MC86)Px_rTqy-mAq9C*dI`hegP;^t{2zR35&@H&Zg1oisb78(k-fF|- z5;!1&0Zf`u33Qv{Hb3X;mI;#t&wH!6zh4d=B+}{TNCd7(hBKV0FK6z@18Cs{4RsjYxMaz;*gpc5eD>0P-fY~ZK~6IdIl3{+vaO3 z{(#$Nup)2W$o9pIm){LQa5dg1Pl+Ks{$6-y9a>KkaHzmtC5eMvP~h%6lSrEp;ahz( z-ma2`VePldH|#~8bziwf=DqbShb&jOJr{B(*=bs*IFUQ;yg?Ha-#vArl@{vLB)B?5 zAJIaf#6GZ#w8mDQ65}RpsCm>;xy)?|ZpINNVP8AtdjZa1r8Z5kfh}&^ScFZpsv>+a+NWMWT88qx#u#GHeTxKqS00#p95FpWw2e*{dS!0@8 zsu?%p{Rz8vw9`NT7SN57pF`3sME9{TYJBcAQ$4nQ+deY4%z?1+ zXdJp0-{&S`L&1dm0ELgg7D)SwC7Y3Ay%2vIvCVmFN4B+q949vpQr$U19#KFb4+4R^ z3L=;h{I;~Bo(sRuMpBJ~M-rt=i9PLA_|sDY=j+|Uy&ZXVFF>+7jYy(_pZI;Q^p}Zl zs6LwStvX+2$67iJm00du4}!nWqdNkZgU4dz@Cp!D2OmW48k7_)h~sCbT))=U8TVWy z=?5*WyY2GUDR*L6ZI(+$(gHZOB6ST@2^V8a_JyDuZ-PsFHMJ>?)H=$MFsYM_C*k9ok zfiVS&nG3h&A-z5;v7SMeYunxgD}G*U7m^Qs($jXj9dh~$iF)_D7&gDS(W7a3oYMkJo+yX2J&VuqFTa=5E5KG#)AyL~AB`p}v z^96pYF0#lljHvfdn1Qkspnc;*OmL4;Wg7~gaJPVC1fJ-O@2!P3{{=RQyr*ZMqUX_a z99yZ3Y)5_^z3W&W{j^>pZeM`%A+wGnda#rf^a-;8h^@(;^%p9YC})N|lcgQ+T$046 zcR!pLJ4fUENo9TO+9`)PK0mj$*`T z$myWu8V6f6B^Wnzflu!h?@?;E7o1jie3T*T88`CHYPl1eCY zC~}%Z4iR%^V_Q-VIh777hshzyIfr3mNJiL{vtd{avkk-S{M+aI{XQPQKevBgr|0v& zulssl*L|z3_LQINLLxb&{v;Om(QBROVxG;60#><_s6rMmcYZG-7sd2eYxpp779R#Eqc4oIYcFLU{tv*x#F!;GF<$T^8}Ap&i= z*9m)iS_U?yYp8~k^54cSE=Mlm^x@eSYV$RK1`eQk_6}Ss)t(et)@4lO(Cvwn)`S6hV{UEDZSJp_`oaAW{X`UM~7brIB|YP?}DDv z$vyDTcat_FnD&I#Z_zNjZ-T=kIy(G+N2fFochZ>c&DgLTldYm#4-)|a>TZbN*Yl4E z9>^<$%HyMdxw>${(#hQ{Y8bG6fvB4ouE{xM#s8<0fNJj7Dr!d6N=nrQ?BJUJzciWaR#v zT6|}yZ=%S_ze!)&)jaWT##^q7+>ja_>ktQirvhc@%>-0gtYW0d4e#D`A8NCXI?H;t zPzs8~M#IBxut_rfrK8;hM%EbLYzb!91F;9xX=cA!K|K=~hdva&hpwnwp?N6j4b(2K z2`X&s>PM{6DIhwxc2F0jWOyNnv}+|}L}i_Rt=j{AD1>|1QDn)+CjG0iBmnUuekOfl z-|bHBKm=51cxgJZQcQ4E#uo+ z78DFCZ}ise;BU)j4*GP4Ykt{gVkgi2@HRcQQ*b>F>Z_47U*>%gypcTr)%7EmnaTB6 zuqUY`$Jd+B-%K`IJ>M-ad4<2TJGo58xOFeNf%)+x;OrCL@nn9l{$}=>afd!JH=Yc- zRpC5AGgK5G7%WQ4XEKYaJu&|{0B2F9VEv|TQ?p@^@daAQ^gy#FolzGqgA^k$`^ z+@NJ9NAJyIRdfDyQ+1=#{(8iRMTWy-6Z6PEK|ZGAQ3x>79o{F(SgC)Rpq>_<^fLH~ zy&(eSG5L;_L`2;o=iD>j>NzE+X|d?PZ?RQPHHfs|2y{M)rG*|s7XO3i?V>(h7u94u zZTjDzo{j1j4ywO++LpAiA9Jw9{j1nlour>|MiALFa zP_X<)ZV+WH_dno>ov14H$UP3Tz>pXPOy15A;K(xpFQd69xlQNWq~5|gVLPUXx}2XK zyMJR>^ti4j9jvaCRD) z17P-Rt|4WM1R$$dYnasAN22s`h9t*7;?KbM$q?*8Ri8-*X>!O+sx9gC6NtE$XVi z@hVlSvkBqq=T8rdVpzp}qs?j&x%Z#qZ&4Q4FU?U-CVjgOY*sutXnA&{$v(6d-eTSco|dJ{{ZtndjHqzR zcFcfH3KEH5LzK@_XO0e7KJ>)e zy=7IC0^~~3TI95{TgJ6T{yXzzo&@#J$m`vN>m{xE$29Jcw~9NrnRdK+5gmD#Y|Gsj3~#pWiH+94#f?PHu_Xvk0O5aLmh*V7sed5WTK#CP;=sy8UF*0;t8#v2$1bvGSt2bLXbUlxhNXck{BL z=2xuxYt>N|zN2`fVUB#`xOe$r*xsJjhUYTQ$^I)7Ayj5$K8&?PN#wPZXg&IVQV#SIs+ONcA#-dSYD~$K78~*@ zZAhTODY}_NiwM#q>UIS~dSG8pb>A~~5SWQ*#Hv~nM5S}XPr5kCHdyOjaY4k7Pw%RW2lhfpi_bJF~p zn%y2;8J;V08!4%W)_*j;4!yUA8;0)m{x(1H!Yx;P+p+2Iw^3*sb`2mmT(&*DUT%vo z8~&~z)6s3Iz1;t-OOluue(sObrrfKyFN2DUK-7n!XIs7+{i(S7t)4UFc&qH_CNCZk zrFQilk!M^n;;VK7MhIg=w1oS$fv%%rd+e_)7Xj0oohx;|+920|<-8iWAGY*(&*@ub zn-{H5;tm*z#>=XzGXK&qhyImWR20m=lD(x4mVR+LLw51r z&AAwb#4wGUiQOjIHxI1KrNk|PwpS?UaZ}O~==ZgdBOgKg$0+Tm7JXyc*HiSY(2qYdzUMcJHDy6jTl?| zx~{TmYDRmvl)=#~6yz*ch333taI-ZiFnI^#O-nP{hf<&{N78{L&27-BrRARDsdLNf zfZ)eVtV>JQgfbPx{P6~CtIqS*f4h3BFlzzh4C^qSY=s%@P5WK#%g2sdvyCh4fe!{O z*$pmnJfsTWl`GW?h*k2zk5)k)?K@E_wJE+{iAp5dd%$|91+c9A3Ec>o5HwB_U%Yx z_4ghv(Vzb@Qft?{CSMwSUa-9QA>BplfOKAp*#Ksr7{GQ-g z{ZMm}9eHHIDL;zi3{RQ?Q^P<%>0TLO+w%L0cc)a;e^385T;SBzajQAK6J)9!ddQFU zI?KKe!YV&wTkxso?!_yI(^WeTp{Fl8T}lfWZa#bXLdgKhNw3PK;sU=`&r1PcNPmMZ zzNkommLH}35{*i&d(cvT`b=42PyhY{iR%9v11+*|UpJSQF2QwNRy~kwhsZ3xeQ%#! z*=LhG{yjH%5r0ti<)<^3u?K<6)=~iPGk#{D_HBY>vE-ibx#aFUP zYy{Yf{do1lccrG>Po#F|F+Ql5gXjd9I(lawd-Z~Q1D4SgeDj6zyUO93Wm`>WKS__k zIJet&SZf8Ok@mvk3mfMc==-*%Fo`qgQLlhioVa-d6C|{Z31Lk{b--B-Ru2)Y_?9K- z{}|j1)vwLheraIWGyQ5KOAZ}xL;}!t@eQS zJ>+7@+|Vak)kCAkmyW;svS05CgvZu1($fSpxu+sID~aPgTg(b$7n=XrcF@XqQsWai`}Xj~;+ICRzC7=^swPr%{~dT8YVhIOL}hfB8P2!ejllqW&)4Ww z^WMJkwZD0wUjM3Je&)UY!;j08uRI!-KVte+uOg@O=$z`8xR^hnt>QCZEWh-g)|onc zHQFTlqit1bVo9;#vs-_7L-)EW+Vp&XsffpGov!wL&=Vkgab)hz^2)i>@}wPP2qF99 zS~>4ji6&~}>glIf|9);gXP$cX&nzpg*jqJJRxX{?jeCxYI zbi-NXCW(Uo$xgRps75lh- z`0$zD62}JrwQs_-)N=|Aq-*uDkH3Z{IWs6TIsGi?mdk}0w)6m?Q}&GFK*mU$;lt35 zxewpwUlrSyZOJ9##EoH!_3&UEMTc?9+ z0FL)UAzDjfN3n8S5EB1E`E=Fo)sL`~D`VHj*H~BEq}^rkpRid9iO(`-7<@pRfNTG^>NjrTx>xIGNz$di{2oXzuj^Vo$yR^Hv>LGRqb3P1p%v$xtL4LGxm+)>3LXI;> zAU~OeKsBuSZ|#J%A(8=K9k%!1Kc&a)o)OhMK&o=E6;u-K#+lwpHDAc7ZR#1`cce<~ z=+(#HZ^c5y)EUs@2Ow__iiO#K)Qg(qOc}?Cd+uB?X6%w0DXDv0eO&VcSS6)DYi8PM z2IcNuEqL9_D zKa59+vix!8Z;+$`*td%cnjK|pMd_v&60MU#PxF?O&`ZT#b<}reQb9*0heoAi-iq05m99H5nhzyP5S}e zJV=)qzTdN8X>P~#c~1BlOJV4=^8Q;%)X|NRc#YsYx5>eu8v$Il?`2vuBnLsgl(5q9 zyU|+(r{}tSB9@>J)U3~Z_`9AN`c0qm{`i0n|0LRaLT?`{)_dLV`~mUG8wm5HoJxS1 zkv3N-wAj3|!j4@(gKDk&WVrM`&)3I8iS0qh%%k=yOiFLz!vK*r>^=E!Mb*T1?Ft7S zaRNW=0i;XnQ*-a~jteSX&ON9dRO97=p>n$Q`W$u=A}FXz)WQN?^CPNvIPJa7d2aG8 zz;9d}9PGi!uE6YER6am1{2{pb14SRr18U!pmTLCUu{Di<)gV6d@k>h_|D}Td{mb9- zJx_6N#cq0^RJV{In@bAwpSUFsKLt`3JrjsBZ-$JTu)%NTytyo!Y9Vnccn$ncy7<_i zKKS|Fg*G`schR}63V+{Zw;Y))J)+%BHhKTFCA62s3meGJi4luOy(I2KAi3A7)hueZ z@(ilhA_a$vINg#jgnzi&?TDk?#IahVaeiBdk}n^;eY-t<>F_Ey>Icto8!bVu@|0e= z94UBJkGl^)J`%4a9{V(yw=WVbiP`St-#WWOs=a(zhX%@V#J63}a7 zUV`{L$FMM?7`!}B*~;w(@7!dDUb_7+xsgBDZmW;B%O6|-Cg#)0|6QP}=7F+2`B|?q z%6aZtubM9Oc};|S9&uM{m~8;W$LtNDjD@k=YWQ5U#!n2=`FN{|E)$sT@eavPPWq4Q zC-C67){Q;%X?Ea{;6KA-(#0C5Kf!b-k;jr7r)(p_?jL$sX6Kj${`cocG9fHu;MU6& zKjQC!{`)`~aPXFL$bG6cPOS}z^qe2BP)Y5rJ>?*>j{t*=W@1SVH^{K|*2n{MdTa12 zJnYWU4RKX7A=+qK2Ww8(iDI=0X3yf4@Y#FaTK5V(7JM89sC5vVkHGrcDX8d+Jm8+N zk?M8zfZ}V{Y@Kxva7J`$LnGJwj9Ct22%qyO(~CGVpYEQ~Sj#J2V2**S-KwaAqBhNL z8_Ir_Qqs3OdhVZ-H8-yuDA;Fr@d>*jtCz-4=@KuHX$XH=dBa?ehdW9C@{GBP=CbyTYMH-nsrMH+AhXnj`$lA3)5`X;1q0NKm9u z+)ws*eY|{={7P2q&&Iku$oczj>*P?&Y8gpF?_zglb}shs2_c!bQ%dMQ`)1%iq6qxo zX<~8Wx43nSJ}BQs&gBiZU-*`9ovY8ywoK!Rrjin6%<= zSApWTN#n&@V?VQpgv{$lLNHDWgs#X);p956d*M19svHA&ykz4Gd9Xm}&rw>MZR~bC zJM}T|+CSm75dDTng{;j-&>pz*m#mntaT(#&p*~lvX+*orHDcvbTZOvg=TDn7A8-Xt zDLxOY15;MATYWRQDY`Q6QnybmyeQCjR?j$CGn#awABV~O@-pmoJ!l?pqR+Y@ltJ`` zGDpvu_0jzJuU12J7Wr)IU2|!D zstda#ay-VB1+K6>Ql_~%z69#q_rr%0yGxu9MLX=9nJID3cgq-FGka5?8 zAbCWc(#I!x%wXwjza~mKL6AgM$g3)_CI#@x&tEt9P2No5EsTxUu9SwFE3IUiZX>Y! zXjYS|hob9lz5C=5WJnVAK^&jUs^zkptfyuVR3V?QNe5F>0IwO8>%jj|T|Hkw=M+)Y zK*rk_%uzhpll^A`6})bK?uhI(+&JuF75;<<&Fbtqt4-OgNP&HUaQDNJvY~q>P^bSj zzvwg_CHp5vX)b_7V;6NekLZb;D>03bhqGkTqzem~j2QW{)2rp(6X741Qa0}qu0^ru{BmP=F9?`}Zz%_@-Tw-FRp_Ovk#Z>gW}{1cQfdV#z%ErD zF-~yGo{Gpmq<0TArE8=4rD3M^ks=zM)*l~Y*XS3nas~*qSY$$m!*vGZoTLVMT(0NE$LK2>EBV%CWfgRe6W{{5 zza{ON^7$;TgdX3>@~uzX%}crrz3W?fVqOgI)~P-U?47aiB%WMt)WR2}L@4h9Y1OpQ zehvs;tDGup@>8$XSb0RFKfq51oK?bHHs-YK3N=}klEZN#2ZS$_=g8RV>0?=q_5Sf* z*GbEIuaSuKDFmT(1~()33@JDm1?00lT=}wNINpvj?9@I8nt|&TF)hJvYdR~&wRW?c zMB1#^7HcWgrtlPta!?GNWYnbN>lqNVPy1tFM23aRm*gk_fup-m$6EbI8Ee_DS zd~JMc77i0(id%e1LJb%0Ew#-&5QH@0J#Y!ve@;SGy-HaOah0Z2VGZ_!1jh%Qha00& zlzj>s$UO!%ATqvox`UdcXt{rWw(sd4kBacAJs#VE3(v5lJ+(V{@UP1l-uOunA54v1TDjaOAHhmH(XR=? zl$V4bf+<5HfXqyJmq>kb=jqQ7?FpFKk1bfW1_t>)QLassFrhociX4%SnJ+5^zCg$e zyx)d6vVcG7)`!z-8O`l0z21Vf$gl2GiR>C_Mo)>$f>|h-ODuZWe_E!E_&GZ~(Gvbr zzYpbAe)7ZQ878gxRCfumYk?7~*2x$=CDa*b7UFlV+Uf3LUj2>KtoO0j-_K&kN7Yj9 z@0Y_m`U5t=D$~y$VxwySyMzE(#(~?fU!PywzQwpZ>gZ6ydA5;ci(~4gJ(6cfC?+2cNvdSBG`5 z2eb=2YuP&q8Lw)G5YKdrYN*R83vIzH?QqrM7JtSJ6EN_;1Ef?5;yBno0=?A30Vk{=J{uDUbmjvM6qityyoO{XW zF2n6?Yq=_CUV-4|#UsZzJVV~!EP(d!m6@z^C`$lEYBMLOgV>$>_*MVB~XK)Yn-8|Re%GwWS3Aa{(^%kTE7JE|ec;8Lgcn|aF zC;yM3j?C$5eK3a8%=KPticnG&{%XhEJb9`2TXp}O*X7-H(p3L>BKl)Q4HFiOT{n2v znjR*=p><;?AFox9f}Sz!6ZQBj)(0_t!VBHXgwS>I&Wby3;;;c{#}@DT{XL*W?iER| zlWyb@w(HZqft^}!g0&B4^hW->{PbC3zh>d`MtDq6&nM)Nl5aLwmbMFFDPQG9kdH^I zlAU)V(%LhsDZQ2^x=Q8%7KF$sk|)C*(s*MQ(8R@kmD#$^&oNq2cs%9I z5p&cbb+g0vhOT$ri^LYV(k&;JbgpRsXBce*MP7Sep`tp$Gp6NnfHLh1H+E%<>3DtW ze$Zd7q;Id&q$uT$r)8H`1&RR?a%z-w2D*@nDc;%ZCrNFAVDAaqCgmJJ#e@#%t6BSe z5!gvgw4fuR_XbQ$pWs*>6XJIeN$qq3&-5qZ0T)Z$6df-OXOoVdqVP*L{$e1 z+di%IDCW~oUu2(OMnd47yXVcx(Dl3x|CreuR@%|`IYa+IyWslcY`K%l+f%!_{284Z zZeMQI{D@^8@^{f0)7j`Vm!@pIzyBXTzdik8B?aJNI{f*uIZqwO(JVGKo$alG_bkPp zP~Wt(I6*V5JQ7Ab_EHiT|AA`F-JCd0wT^)w*f<9EqJUPFx_RgwTkF4TT?~`|TfF?t zSggu-sdhbZdT#L3Mska?MsoStlmf*o;5(Zw;_f`91gS2{E({`7k z9HB8gwRWdJmT@nmE`9Vc^I^l!v#UL4WZvJ0x@Fgp#B^STVIUgX=!{i5>FV0GMETtQ-V(+y`b3 zx+v3pxcMaX?wP&$b0tFo%TEn5K4$7s$}Q3QU*=xspEbE0M(^|h6c@Y3i_g)1!KUX= zpS|)q+>!niYBkhu>asjBg=qgPaotMbyoG6JX}o?*KK&);%*so~ZQbDg&$0M=iXI;y za|ehl+R{RL(tMAa&N2JGGR0n0josHhbMr(^;IOKc)!)jofHYJe!eC5p&m%r@1lKND z+}Fm?tY+pG!Qn*#807m?3IRZ=z%4-HEgRpS9g@N@wmV z&a{gI&%Fnz!2dD$x=mSd?O0J4TbT*#u*h<84;&Y%X=$-CU7M^%ZYl_+BfJ$9Jd~F> z8qdUM(7ph8b}n$tPQfQoZ>|(Su&*FF4%>*f9j-i~Mogy8 z7SU7XZrN=aosw8~aaq+=-XI!DLDNmPTuPZ`tVm(hk;O*U-mhGQ_{!<&zC6+%K{kpj zM^Fn!@E$ZMscAxqfGX*B7PfOa?5N;XEY?Vj$x|KUCb_oqao~;MyTf^jc8&Z`8@IkR zA1S`@hIs(JsEmp>Gb;a2jz|X{%!YbBGs((7^;(kZ;sM3Q^0^u09^I`}- z>|q9K_*N@|t-Jc3P(#H}$UVch0yds$)@)X_Nb@=oT8oE(oeL7Ja|-FSfP#$dd&0yK z%411tZ3IB}=#t&YnZSzCz*-k)0d!;kZOFb^uOB1a7e@EpSV!jfX&Fx+!{aXO?l_iG z^SM0(_qFoRUCEpx*UM#33bN$wN!}%_>>g0P2jPYF@4=cc;hv6>F`16qv*fiC{#T&C zYC=zJMjDo$##RbTv ziR?WIvr&I9HEOPN`&-dG<2jRxnCHp(oE8j)4Qc99d{elGIA&!?W+}dva{YH>N%-*I z?y~o)e=Np-cqPDsJTm;AH?Asih~g~+fAu0km>()`AYb?C)KFGbl<|HJ%6E+2xOv`r zx@Avgc{cPQxi%+XVzkT~bfy(sBm<8IKlvv1?QXJw8521(c2_Us4> z#2tr^D!bt1+$UYum#TV|bChNlRDz8ZXA5>@y>Cl{zEIndv#zr{hz`z~^)>A17js#y zG8g;>8T?fLD}YOPk;CR9q5MyRJ<6h!*=m=tI~Xbdw{M+V)9RBJ9d^g|2Zz8&Q%^I3 zwb%}I;|ApR$;AHJ%gs8NS*9D$8<5a3d*{36n;w-pna}r`kfBuL7Prw7V&4XOsw60`j=#&R{Zb97GlHh0k{WIYGFtyrF<0RpwA%wk8Dei^ z4|cqac7N7G8IkMdOZ1_LBVb#NE3+Ga*Md8=nYwE5ca%&$@ z3CeO0`fvEBt+|+24Byubx+?4C^61ve;jVALs$<(DJPjOvK`wg4Jghw*3afFxFp_5L zzrC?{-@}Us>K~8nI&dx3kZ!D)q;Q}3~z_6iwjA84N6#Jk>UZOZ)1#i!;!Km#dhySb>3g6* z70p9~GWWt>`}XbCdP~mw2e};~XVb_qB5&oGYCux>&rA9C? zqX*DmcT|*DBg={x?0Xt!#O8@+nfyBw(^|XP8&ivnkB0Ax(hcH%YjkobNL*5+H0wH& z;-aP19*mHjW_n3AIvUFhFUa^uKmyli6X zjYfZAze@iPpc;`7a^>ost;ihMSj~+KE%8DZFg%R-L3V7Leeba54Lty5l!T)r-oI_& zI&UY=XJ59n)eVl9&hC61ZLIxb=ET-&R=`k=l>4oi?;fg&Nz&A@_g6e$`LT!p0MBC5 z^CJ|UZ#t^?^R;OC(2xY^f0k zoJ1YY?nH?3&1p(=HKz#IYU!>b7HfpM#^ZTz_5u`$hyRf(Th}!krt09?6dk~l8RhweAfj`p-_hb-b#y}4v z5}B>yItWf@_BfoXtiICCo`RUiy3MumWu&&fT+Dr^lj|?bRzPh{M53hd zmk1Q+T#_x!?7VEIs2QR6km;7=xY$;20IZz9K4KIb+iPZbJaOwQ@`?NJJ4;ahefiJ4 zvyPg+PD&vHExPvBHN-Y+2G;Efrt$X6k`3`Z{SKl7S+e?%t98j2gSa?I?OU-kS z!D~s^p86e>vOVCu`;SjxdA@c)Jb?a0G2sXZ}2BKi-iPveHJw#HF1EYK&X zBV8ZEbz6UkE*nCc)pKj6g@SU(#f$4ShFMx3U&TMmKxs?>&9p#a6_LJ%$0PL)`Wn6u zsg(U~$aHxkx`n5NE=wVrT==tgIw%Sj(lyElDH4ECMxz5`7h+$!~%ZeW3-NgJ4 zU5WxIhp*Zb*7DjXODrP@Vf2#D9t@itAu@}&#(({?oEvh1{Q#q>Jc$+xvV8%#@=2KF z8kDXjY}c(q_l3DS|L-ni)6f4HO&-o8ypM=%x{Rm%t`n|9$0!hCPbftT&$Y%~C6c74 zM<3Djtp4xEs?)+#hVv=<*B)n4=T4$3wi^3cv4RUfdI!la8Jv|(aGo#rQeE$_kgeW@ zG9e?Kg5{&~M{gf`|HHTrv}m*erys#->Y+&v)q}m7U44z|BI+ zCPsAe(AzmI%1Hx3k}q1DIPaH3^PD>gj;8_QTYz$qhJaF6>1ix~O=5+uGN(s(qJ^5} zkTrB;xMX1|?olg+XZtwIlAHs|T;WD#QVjEavTEmYaAA{d#eduKE1UMvN}Y~KJsAqL zP!qqoosU#CqA;w`lX4WED@D;PkLLJ)zB*2t+Y(urn{|T_BGNnM9INi#6Jo6T^;Z+U ze?14tTnV+wVfwm1%way~li}&XSl@^$xhaOtB)<~|48@{Cu#5;+3=1}4ggrteMA4aO zN(d_~j;r^VpEul+7mljsLPq#`1AMnhBVi-S7ba{;i^=sAac9OWLDo^&2rMDI%50Kx zYl<;7Nywsa=5bqou}HO!Xi`kms2QErN{96Ed5ds*Fp$!Ol$#`6rLz*~tiyDQCQJVh z3>3-IWW~IXofYNJ-}BSYQcv9!RXO65<>VGH%|xCS+aB`21Lt`HOc^%Ow3ON za@U?QnoiKRF+iP9bUouUd7IZJ=C^dI2PQV5Rix*UE&X&3n3)3*XG5~0Acejzxsgqz zuu17!dYYC-l;UIvniVG8K6=1K!zmE;RzVn!KIy{e^AmW%#uq8$v_F2MU?qpZEQ1pg z=?;sW)1@7BQW&kVN?tcTRaLxI@XS>s){{#t9y1o00X0|q%-;C6{ECEh$pRHin9bm7 zva?>Wn<#LQelwI%h1`joQNdi|PqYvs6pc4vijN~Oz5Qhpc*M|@8}Spump4j;tUg85 z`p;1B{^*T+Ky1LeAdrZ%dcHouL~py`S3!V0|?D$UvRt{Z1gg+>FIFBDA~|D zXR{IKHGM!V!xE_gPM87}j0z}_&2cOvn}sA;7h6l6jQZp%&3DJ1;KbAJKV@aKZzV=^ z%`o%j32{VC_blcKaXd2S0P<=Smm9}|#XS7kMn314MQx~HahY%Y>X^o3(Jj5xAvX;P zM87NpLjpP;Hr)XsBBn1A)(-vXO$)&X%u*%js&r(&uTZp079NPGk)pW@x@Ds7~<8nK*#?}5-G-uQC0p(BG&vkb`PxIPqf^a8 z-fZO4x(se9!yq1p{KOn;TcZ%?|CYcF;Z1#b)3J0_+cj)j2`4#@0P@W;$Qu(dDUD1D z#0BY!pTJ{!Dx7OY>g-qQkN{A9A2oc3?A{Lg<0kN%0uEH@$1QsVbKHnV3G+NbP z?xKNN?RcH(`Swbz1hLBJ>NupD(sKpvGF(T41H-lPjWI@5q%m9xWQ1({baZeL;!@^H zkM-wfSUOen$yfhD6ow<4H1O1K4Fu${_9|NxPu3c62gZV0m}Em?hY-UnWNC7Fbi+n! z1PEzBpzBTnrpeq zJW?-=NEXKs{xwxay(XWU<~FfHrm0t1n@!{}B!i0+c9K;WA0dQ;VibcXX;X|*sT?qW zq^44hd65=75%O+)9+NFzspHk(2I>3J+e92Oa7P41jMn!NR$*)Yh5QtmnumLNUm=+b-5ky98c2>43NN^4rxSHO$kB{{-{EQ_qWj= zHTcZX79>apx(Gz=lvTV7ha*br!7yoxM87wx|`?}W0d$5 zH*6T}HnnzmJmhX&hU6H9P}9rKTSMcwy;inL10;enJkc(Sz6J~9v_o!MtNeVt2C7pJ z{z|Z@Cmp1?-HeLflJr6XweY&lb$b`N()P8kHD}2b;QAzJoP%t6INIbi}{(wbSzOYOOMEn_~eTXVP#z*G+NMN z%~q(Jf|%DqF=#Hsev(h%lUu=!K-94nXz35=j9{71x+r8&+#(HlLLSA9jy%bVM&S_M z6a1!+EQ&iMQmFm|_ld>7#eJp zH$bNz_Z3dVNWZH^i$Rg%LTGHHq#-$ae_<|e!-!TSOTVAnT!JS5KxK{3-_M~+viLsL zgq_p#Cs@tD_%KcM$CUp)$I^+jQonsI~fqq(>8D92X><^<^+ zU!<$_Q+eDo{sc_Oq=R4PjZy_6Kvr`VlZ#|rIl+YBNyMqU=oG7|fg(<4*`O!clWok8 zT)nXtH(n_+#x!s30dYP-mmEey;2`P9OXwWtdK>OQ7{vg;jp3%Tcr&e_1CcIwpUUgz zokSZp1#n;Bm^X3=u4|%Iga~3`;o$eo-);PJ1dXhgAADv5x2dM1R_HJ>pOA$T z>axPVMe$4sOwsSv28z-uEKnN{g@+q09tYLB(o?jISdvCf0U8JH5$l( zlR{pTR5zxv)3q&UBAfcP0Q5~17xpe{T3Hm5ky^z0#fCM&HiismTpNQkV0l{(;z1~B z^d$557KO+ce8n;KQ5gLJU=AoSjK#gih=s6N?E<61C~O(bdqyBr(;FDl#efThrIZvI z0{oGv=$Tu|A|a|)Wf4`E9;3W+DZ1*LeIlq)nHHufdb*W*=8Rj^RuiR3>1m0QTU0X% zC#a%~{)%*)B-|1u72{_9S~E$MyKqy4*8h*I?+j}yf5NpOh%^;7v`_@Wme8feL_h_V z;;Or7q)1svlnzoP1gTL&Q#61eMG$mdK_m(&f(Rk7L8?k`iJ_<%5~PHBhyQ(^`{91! z3rWtI-^{%8&O39GHFD2l?JBl=W+nOEszF~#FO>YR(veqa_sgO za-H`V>CfqnVfH`aV)qwwug!Ny9l{Orb;V{(l4xzw&UkcuTyn7N$3Lu}aC<4!H;Cc# z-`WNHsv2#caJOHWC|kILalc9kM;|8&_e^|^obGP7%5qT*GR~;TkR@qqbOg#T5W;mm zIs-Su+horkW1)25b8&aBNy8_f#*=?N?U^~rPe1!E}ItQnJ?Sg12@_faS?g9XfDz6^kvceT>@O*9a^^% z3)2;-NN@k6TD*@K?tyhL;L7Hw&mp~9t}_{9YH_s*akWpfrumKD2_E>Nd86zog2}dx z_+QZ^{Lr=&bkeN6w?4k)=1F|bZagvEB)D_T#=Qj2!FN-+?jZjp9D}whl_rzh7*foA zr|r2`%r$+Q$2B}_JI{{wnhvEeD;u;6T6$X$C?m&DKO(gT`3g;WTnAOkuZGoYVejcA zon4)R%(E6O_5XTL(n-?bDT#ap-?zlZ=I$WJb^&L59+xtv?}=BwerU#$<*sJKy3}r+&Nj+_K&!pEAGPM2uj>T& zk}=UtUT ztRz52V; z+@E;gg#A-;Z;8G0%H!K!h^cH4S1B^X&K+G@tL{Q--`s%0Z4lCz5&IuU@bB4;Mbl&! zZU)7FjSb3wNVC6r^6jo#sTXw89HnJ5sx2CeuaUm@wiAhabDNV+tNqD+f16etJ4vtR zc$G0dM`rR8`?))EXOzuZ&$btFwQ8?m=$Pu1$eXnDs=|U`W~NTE^vJmkYgSaW5`J~V zHn=Clr9G(O4REU>{}8H9whLn0kA<=uqk>BExGOd8W*q`zyA>-))m?TxWcgQU+5CCo z@b-}qp=ybnR+m5?vSXNizV9#|3qOv2-j=1GXZNF_)KVRlE~V&(CzynP-d=u}78+0g zG?_dfy#e{*NnYeB=dIxb=+c|d=+*L`?E+~tDc#-lYW>4S`qT1xL9Z~1SF4hie87lY^O!jyYmzkeQ%Z>K! zOE+scd=rZ=i7&M8L~5z%HY65si&MUZ6NP_goMvU^#nD`{8iKk63k5xBI%&H>J7a-N z$mhls^m-Ah7Uaf`&)2b1yjIsTe=V3dJ>eE#Ip{;K*Ok~uC#knQ=C039|Jb5*o?g9k zFMZj7-Yy7gw__>hQEB7ZAIN7|F2}wXPbM>Sn#ycg?<~Fn~quCG?q*2R~;=6W+GEhhq9f}N^Hk*uaV)Hpq1ODHH2Hu->|L& z;*0-kwbh2*Y90+S2{QrgVR_2vs^Lp^(+4)#1~)#)md#6|;V9C0Wh2Uz1_e-S?+{Ez6~>ZiRu+b+l<1TAAw(b11o3v#ZCT-WM3O6&N#tBSnfl9bg?u?Y0Ftb_o3PGH8A`FVVey-6iSSB8G2qL*n0w;a-Ht+(@`dulket)vmp*xpWe4 zp~fb3dA|pgs8maqw)UMD#R#$0UH$goX3u_z{5FA9>ZULAoqj6PtG6f+O-6m;fq(zW z!Lr$=cZa>!I3c~ExF9Q*tg?rs%M-KKgiZJy$$i0cp&t+T@pF5X0Sc}XO!g9l?%<#E z%C2?<;n>#kPcJ5uwaJO$dE8zAb787IW!f&KJhwei{JyVkD9H>maPX`x%ibJ`@{2!- z_jPK{ZWm+$c05Y`oc?Qp^Pr45_Cmo;`DVZXdQI^aL3rm&whKYH2ZC{*?J?GMls5uT zR#G5VK^+wCo5(K+`x#`J&D;1*KR>sh>)KX6wff*!m=R!?tZF*#a$i+QKGz{Hfo7JM zLtB$Z!H>V^xU>t-cYw6_>~Vu6`R$F>Jf!0kacPqHmol?4`}sJ z2yJz!v^Bob+&=v3CLk+{6HmCKikXzv-x+G@v~t&jC>5!$NsDE_{RP~}p}$w?r2U`U z!xwy?7IU@o@6v`TNANiV&Dhhd6IW_RuaD-|wqe=@yemqmaq@?Znp2@9m2X`F_p`^1 zIO

        HVL8CT^H<|o|_PeC(By|@5*gw40H&F!DvcU1Nj6i;+PmpMf@n;U1zw+Y*q3c zQFsXIUzFt$6z}crZX1?ERLekT;1-}8FTgu8$Kq%X<`RR6eyd_jdypR~zjY{d(hhH+ zW2%$yf|O-flh5zU|^K{g`_# zFP6rOQ^u3ONv!;?<5fzK=*!HgfYp5NJ~*d&OL=6S%G#khd0V^XhXMZYsr4uR~;c-l&{rLEv>Ek`UAd375>sD0Lkg*tn3o{eBi z8$O^ra#XH?!HyHV}`7t*a5GqRF_342^F70Q& z=5bc(F%+s+Mk-iaT1hEOMW{g-4G~&Qz8+vCS!JAn9nW9OQaQB>_ZiQlQjH7U)CoSa^I_-X7#q87$2=NDbp1RkntW3 z2_JWnG8Df}X4b|V;B%xm;#c=*b_t{@W!fErRvo7lMueq23UO>7N+rs;|1PcV<`L7F z2;i5)8LSL~a6wjnT$;>0@2ZE&l{pc7AURvEA1!#U^QfQu>8u@VDZ2q{!(tvgidvI? zIH9VHZwey_i4*x;88u?%F#qlO3|Tz(m-n0s-gy(0P+@P`QYiaOo2xQGc>ZY-w~UdP zMGK{P;<4_gOFL1+x@of-LgcU*kk{#!9`{HGNkiAI;MAqVjg~B-&Lf(Af*u|_{?}X( zeswdwQ?R?D@s~!j?OLk!;uRcYu@rV1Xr{octyn^D!m4uSLY zFlT&D8EyOt_mC?PpRIoeZ?)=foO1=6!5?Az?s;5yAf?(j?eI05ZcOTs5jL-e`Lk{Q zHBY#^Q%|uRUMOA_5KJVW&`C3Al#1!qa)1F?LU9Ct)#s-S9U}`Z2QxjB@&}n2VJ?dD zs%>38#j>*4ff@%_=1QxX#^7$aKb=96UCow6JK%)aMsvp&N|MRZz8? zPZg{rw@td)5ln>YKp38-+OuTyZ_#9pbd~YSQV;0a;;#7C1X0tt;kZ5cp(uUmHWc%- zXzAC>{T7y!*CaFP)uOM6CIXq(GWxOxK>C@pwo5k>9)8Kotuo;B+4rKMC>3|tl#Y7k z-|go{0chGUC;A)%_*4Pd|F)}^vkqlzKZC~NY1fvFlL^9_Qj;M`jiFQo??eN`KqxNfwjDgxGYkOvr4}B{S<2r1eec)e^fp)a%0Xn^dw`)c zjgtD{Eb~5{^QTy$Ns68iiQ!x5U4p9<`DOu)3$Cr9(!gEXrUGYj26DcKF3({x+NjXF zVEoV~^M?}XphIy$)Sl*ZlWIp^cM1G7CG~-gn+CTtj4^6QDg^k6v5@f1;I*De`8G6} zN%?Rbk5veqbR((kY8Tv=rDPK6r2jU0tK(N!w0nVRi5qkXUbowc1t?BY>JKz__Rh6}nYTm15UrBiEkAU-EpvY$$e5=#o!Eus7ctn)E_ z*?s~556KE6RP81aAxgjLAHlC~`PROXBx5{W%D&B%(iaY(aa-Un<~f;0@IMh^)og>S zXBm7`x1C!=$19mWLbywhHS0VydlIT9gS<)+Jz~|Sz=`eTEx(lywjK8H9zbiyyWwlT zT>#Q#dA5|ve%?BAv52dfmqJ5Cx3!swg<6QB+Hh&z_N-cLx{npBW+wbS{U?P%$87vQ zxuIlBBtj!f#C8BJ^ZusKah8|`0=2dcz+1$6F>^RTu9FbH#iJ`w{ae?kg~rLBXM(qC zt*O14A}yTQ&kYf}L+SmOYRu~pm~StdnXaT#GPj~!qpXy=$-loUghl2HvvB7a}pKm(ig9koGKgFbw`%C!K2xy!~39(nqhfY$Mh&Um% z>uH(_9NN@cPRB^yi~1ExQUgN1;ybQn&7xSCpw<-rAqYL5KA{FIghbRZuH{1uD%F0P z<(~eE*C|i~9%W_O>Fc;Ql4U;Z-ZXEiP{Go!JC4t}{0V55BD7&^qWTkdnE7Pa*6~fk zmuB*~3Kr8MgJvJU=k3LcK_WAy+XD6x6!WrZ%&$7#@(`)V6o9H+3RaW;((qLsx6K54 zve->{Win!18b74?A5p0K^s(i_-w^wod7in&+;B)Y2`Ks3;4^YBw#pHNBN06nq4Q=n zznsC%1<(%p)d%B$y)}B1<4j^imd(6zyv#DLN?G21xX6tEa|uYbvj~d5d^osWKy9~V zUCzs;%{$iBR8WQk3X@mv(Q^N#4i?MuW>uNU3f2_VFkYP--Z$)ikOB%apj!wnU=y*{!dPuh|UEY;@N8 zXGo*yq)ox?@y7ICWyHcC>kxqih?w?$(=h}YR}T=e6(C|@>lQlc_b|L8_iH`bf~Efk z+92U+VBK5V?X0Hny69=qNm?2|IibsvP`g;ECsy&J=2;=v4Qe&@ z*pCB@wixpGak5Mw)D%O5IzYpc`kj?yvu0?D4IF!Ku$)R(>J`ndKv@uUcHf51l9!;0 z!fjfwNSoh}KSb_qF>N1b+hyxzk71MZo!jDF26gM8glYn1&{iEq{Cuvy)8;^7rvR-k zYa==(7f2B1Ka$r%c`bqgJelisl7>O2dG+q!@Ad?KZ_6-(O$4ASUdi@4m+8vcQqN?U zlkIQX;8$ncAP#D@Vtp)G&t3QUgxKpKZjzm~hd1mVKu2x;LMQbqix)-HBIay#{=h3g zY<^P^x!^caz}=GivUHelnR=3SW*#b>FdUpWtCRGr;mo|J*>~(hmWxJ)9)2joBIel> zZh`7)1Y0IQjb^!|hsBenc4{snYc~^vwOTVWu0Zo)(p1D9u#^K|ZGJ!}9gKrc?vq+s zl^#XUVLNcWKfnjI=4PmrPp)Kw@ahBvf9l)ZVg4rI)(Y@e#V7{Z4!Qz67Ar4?b}c^v zSaqClW2tgu*u?(TFQei`kdPY`i9&Pe4(?X9d|3sK7i$0w&L;Y@E`;l-l}5&1e2$1d z!DQAt*$l5N_63Ubb$Yc5NKNLD_i6dDp#J#cvAY5F_F9{M;4N5M0{{tjwp;*e1d15< z>`7KP@YFWwD4e%~QYWS%ww%n1wZW6611Fw-o%ta$e$)bf^P}!t&^t#lMzH=7t03n* z?$!O>k<%^9BIOx0R{m|8UwnvZoKbWQ;$EmRx-K~29Y%bS5I)IIoH)NI;T>6G(F>J^YoHs9|MSe-ou8lt_me~Iq5iu{NDTt8}0DZykiI9VHS7aQjy zP)-`RJczQ##D*7eH@87+g?X0|&@R9{&ExjxB_y-mTe$;gSo&}eJdgl+mp^8=2X+WC z-R5NGHK^b&@taKVSh;LB8(;D_vEhUWu^Hy;dLAvbCbip+C1Y_Eg%bsxMHFh9LU5su&%Tp?D{U@-?dmDi|G*IRBQQGkq_!^Zv&{n)RK0+2Q%X_Q)raM@g zpiX*Zr7<7s2E=$Khw8p{2*g1WPJ#v_ zDn1a8uD%DBvGPG6KIBdY%5^X&ou>a^Z?-2IF0wj+7D**SDd;-K305Z z>QvY?soyobvf&pctY&KaYUi7(M>F+Pa6eC`_77cqhSYL)GmDXZK4r}J?l-R<3enC9 zq`=(~&F;+OJ-ctG_au)rm`$1fzyF?dpO+`qPHnZTX0@7N=Sq6`=WeAB?Ka!9w{rLm z&-YhQ#d{g&D`s&<1ITyw+R}$Bn1(gPszDk47`JRG!#~EvKqlQ*$pkEZr3Usn7fNy5K4>NoP_ zP5r|82$djQci%j-RnZm0-#8RYCzF0{E?Y`x&xyH>KXoR3zjINHA93jC>Uk#VE92{> zLB`SlxQ4lzCuX%Rqy?_{B<%H+XZGCoZo9WK=yGI(-_c!{y|l59 zu_0>~)t^H|=D#u6^hsiq%hSf_=Huoq`=^cBFatmUm-HQF9rOa+$s9$`wmH*AJlksPFhTnYA-NLsV8* zTz+D2S{XLHc_g#;PhE)^uJ_6?;@g8VG~@1rvhfEMCG@5GgC%7Sy}F#;&)t699{B{p znE!kV!}4hho~`yM7X^Gb4*UP!LR z@<>`)ICbQOeP31NogYS9J9{hH&w8%kB00#i9$v0q>vF8W7S$N^)j!vArAV?gZo}ZM zh_4M;qh|Y3?%SCDEPnJS4B}DJFy&b=LV4BZXVokIsW%dQ+c(es%YDM%Pe}_eEy=6! z+{~n0woorcnUqvius*%vBG(iYz4TVaE(ESAV`}5CDZky>UD5DM-S6dKQj`#ryYV-E z`gI%AIbwS);T>|g^S@cyLF#jt5q)VCZsU9Uz-Dn1GP4FDR65}`GUMWA*7;;XqA7o- zFRV5eV|qs>BJ+pAV6svDg|~>|<%3HowDC_h&u^{?|J@xT2|h@ zWVTCn^KeHXHjY>&sX(X_?VH#-6tEdybQp;KUMQS_)5u20QEsZa)inMn;O@NYv3WL6 zl`?l-BV$lCMSA2^sy%`ol$VNTv>n@lvKnIR-};)Ou4wXg!gG1lj5OB07{Gr=@_oXM z9pYT?5OlN`&2n_SKi`KBa)mXqO)3JF4E>(*H_tgPO|InqZhZwb>|4(8aw#PYS~?5^-IwOt*qn7Q*~ z_gg=t*99Nl;}?If?{^?MLGOi_{X*iDg_ytig-*3)`8aw`n{3PVvoHGjXSM?+EphR; zYmfAoKmOaX(nEro*qAcEaL=S;kw4?2s};Pf*pHii47!|LTCT|O4l=XUd=E-&u}6j| zw9Gg?&wjtknCTGg+<){VZ-ESYIBcBbP$>ypA4Ma~4-MXyU8*{nAGu%+3}Br=d?iPU zH7o@DXS6s(nH>qO`I{81{cFW;c=jdA=CO&p_2UD^=Z1G{J;X`b8Zh3jy*%Cp8bkKo zR6@*Kq>B`FQWcBR?fBgJ#7yI1c)hIcQRK%qb86#FnI7GaqRD?d z9e4M(W~TJWPH@B-)mWNJtoQo70q%PLV``eLt)fl0DSvZ;91d9*MbX1cC)*k9raMZw z4vIx>-GQGg)_ACiACl=KRw><>*slCG=<#H6WSGn}SBSJvFu>O+X?6-;r&>{_@%sz8 zai5RtC(%~Uo`(2WeY(V{HQzl*)gFouFN_U4fq(og-;Dok@^(=)x^a9-9*1mf#<@Gw z?UuJe2aw)=f)yQbyC|i#J}UZ~OZg!G5l8luv1v^Da(1@`h5vOh3`K9YHb}ADF-W!V zf5h)%EL_^(H5E3b++u=qaiqtJcLnY?n5>#M@%nkC@3&(Z^B&U1Y^okvny8})wRHaV zjv}h`sO;AioufCfJcvc4N|MfttIPX>I|6aPI|VOo6K4puoVQVlIz*U#h!BLfO$FSP z{M28J^togmM)3CGP3HJtYoxemkGW+oi8`;XemEL^#QgrUwdrvh3iGe~hGOBK}G zlc=~;IX^=Owq??nu^wH5be+s2!~Vmr>YqM0n>r*Kh}9p)x5leNqedlGnGp-06@bW? zNedkeD7@V%5Sb|4ym0pqbzAMhL>G}^P+ug6t@V>>KcWYN*c~s%EVr~cla$%4oKfVhoq5dhT{V0Q1DfI^0%GBV* z;eg(p#59^;G{n#b5GT`gX606t`>caJ_HYU%`0{7XS$D-w{g)ZI%X>MZlltVP>fh7Xp-SQ)@cBp>#VBIaqO@8 zI;yKEveC<4f%xC#ImeA)^R|z4lCUE&ljaxq7v5PEiI*YI%8k)}HN3wfSV{hoqC&h! z6qf4TO=dq%>lvSLQ-bLonQ68s$pAFX(5)Q;R}lEMEYp;!&s#mECv|)il=0ZLk9Uhw zXyX=*0c2){C1ClcEy4P~YVYf|*RW1LJgR2Rs&H%#Y7azy?%Y9I@E(gpH#{HHk-^Jg zOT7yxAD`iWf$p{AIrKfD<^q^8l0DE%ii3&s(ywYeHZGff>v*(~p?LBk>FxF?>GQ<% zx}85abrHgqY>K&z2j1uLB_MMwJ3M_-U>v@KgL59{@Uvllou)czL}nHbwB8^JcS4Wx z zN)Si81&Q*q)PF>&b!vV~82;yOqs$XlnyC?*A6}wch!r%k_iIjf)Kk-r#k@ zDHx5%Gk(xxbf55X$W@=IZC&K{rYmB^nq8%az87;(cR0@vDdEU4lP(>qCk| z8EMPO4mVS1xiONacP`_uTz(#a*wr4`CT3c^fUJFUdqxrE*H<`09p-m$fBb3e?%2(g z-mk&RSY?=i4b+D`=88__W$|C<>e-pbU8~!*i0ro1Lv=^h8Gl)jZ_4M+rrL+H9V+zf z3|DvlN2pRcNC>|;Yz-rAds01kWH%w7`w2#zYYFJSc@*>4OONssNm0@@!;459-SU;Z z73-QB1ri|C=7=y@ZcY9UQP^E@?~^1RyX7D>mq9MCo)v9gu)ftE7-sW|*m=W$Gaa<6 zKBs%O-F~w}kGyH-IMjTy?U7SjOGvFk-6MSz7rs{3ZLJ^gv${8?5vx?T5v$h5n~RPo zoew#41jhA<3mqG)`*WI$PA18~flE(4@WvCX_8ftTCI0nlGCwxVL}R&?x3F=#Lr@RG z^>Z}}EmT4yYZC~-lXMaWI=Jw&r&vLG52e|CmiKIt$T}4Cojzb=3Xcy5WJmfbU>#dOb2|VvK4D8GoF*}tv6xeC>c(#u7B2|hDxEx2XEl{i}t6_ zx#B)|3Y@(_OTkJ$#^YAsWOU~(<+5(%*}H#8&uu$$^b2o6v+1#Ak7G+nVPqHv#(D1A z(0K`!o_^>e04CJp+mG+PB^LsrS( zb`#Fk1mz_tNl^*j_#@r=4)pA8=O-nXeYY@Ul&Q5aZ$mqN0Bw5TS<7_xil5z)+4We0 zl?F$K()aLy&B2d~a&dvnXb)VTWthAMLWrCnYFr?ixbAQ-id=ZW@OFPI8zp(3XySLE z|6LO=>|o1dD!(m#U)DC$n<;S$_*Hi)<`$GTrD*Sp5~??wga~@UWWxZF2L)}`b?lM! z=sQs6=l}hC877Dtxvg^3Vmisc7{eBtsNu8e-ka#vy9D;#*H64M`EH(!e7hYtyS+3% znVmWN^Lg<0HO>xagpacAk$H>M_%2v$K~PKkd;Cu!bqe-gGhQ@zKq z?xpfaGMnD$t(D9BH9N4t3o8lZN~sAbW{KYDe*`06RnDK`57D(5q!& z7v^s&*s;7H>JzR`G6)meIM6U?SnGifRbl6YsSUOHyf`HePg z#O#FH03o&yLae*q%`}eEt!vjuk+}&YSCKw~aO*@N*WFbDg%j@YpSP&xIDic}2(ML9 zupwh>e|qbOGY(M961y!@X}Oex5I`Sc>j>g%p?LjZrNIbq@MguakHNK^2(<^vBay5B z8BcD&iVFzB3;Xl9<*;y~9e0VoJV*6*Sx*z934dSXNfrl&>`~%V!OG6azq5n&$ucb} z%gILOdZ?&P@~|@XiYSD%b$yR?C+)gb$bLi9ut zOw3`z(}VeM0WC1Y?u6FiLemqjJn+5lIs?M@U@!MHpDU|s!74U~QRpmp zf0sFHEe=J`p5E>FGZZ6zjwn3VR5;^*4L1`~Mz;I!NX%aR>bBFcf3d%SJ39QbwnOkm z+$>WEr5&dULLZzT5hhgsqn-AOWoeVeR6fQ!Yc!Ok?$Ieg!Pd+f2t}*J-sW9h0$-Rk zh*|DNWbu@TDIweeT4_GaV3v*vAevYq{mrmeQjiME z0OlKE?Ak>T24w`?CSxnpGRqMh=zUBsbO|;?p31-~TxkNVe7qdCD@vnjL6y(l)SSME zblJp#Aw`BYWqLYRPHU=O3_5R>O|V@h0)@Hk>E=dv=`p!pPD zk#`rS^NJ{!-x1*TwpcQZ9-GsbkT^*&;ZlaR6~8R%N_MbXjpQAeUI5Hgfif+zKC4Cl zz0@g~V8IY^NMb#r!6RChGERv`j&K3HWn|%}-)2Lu(vVPA=F+GXNU9nk9fBF8PoR-ra1PniirD2}{@w-E?&AR3zug8S}R&0iypyFd2QMp@y zXlu6Q#fJUxNlZIJH6A}^h~i1T{=dR{J^*)AP3+Ve)-|Y4-If9Xe|wl$%Q(SVM~2k} zHlCtPug|fb1H|OQK7+H^pL9~sHn^o+5nDP5OYaakf)Ug_iZrK82EcQ(eGI*q%w!(Z zgy=DWQQs~YZAn2kk!4_jb_V?L$06`awb4@z`yeo$+CVHyTZ>YAu^g#K0Sez#D$BibAOc0w?&wdl^X#S2O4ktiWg3 z!#)`qd1Jzk)JI87LpRQ-zG&esoCM6jtV*G!TWmz7EQqaRU2Gs8EB6n~ULiwg@^a9O ztO$9nL8?{MdVo4X^S&F_b}mNFq0eza~ey)5B%-NyFbEEu~QFKD=HOStUOQcD2hijB!F!BQDAO|(0H%}E1CiHpE!TIcso>Ekbtfz zKxFAdWZmyFub$mLmUM)YeB>Rhy78o>AhhV6f_xC})=1w7T@YJp;U&ZT8*)~xTv!HB zHofh0dTBbQIWeeYH49VlsQ`9m9O{6aC>$h)BO$6#`SdA^@AuJq0_j z_R)BJjR;h(8-#qzu!VDtrER%|M`7k1iQ&=B{Iu3I|!eef_+Ufr-qo$O4K|GqI-iRIMd;c%8vj7yEjV6Y- zmAzN?%3kM;upDv_F!R#($LpKzv|(}#;6tv38A=P=3>*Uk%W*Ci7F)XI!e;S}m-3?` zKI(4Wh#wLGOT@vFzrd2`U&|s7EhqcMGw6k}agk3yDf=jYI@BAG{u zxJUDnq(^p(W6STZM^y?$Rov-XPN-@U&1ij!t={VeTtYA7Bx?pDYIqBmzHEG<uv&J~KB!h(hK zP|ZtWq*@Dzr<^mYKMPMdV6j~`EQ$5CH<_bAQhx)3OC{+ucVK;Rji(Tt=YUqR(4QdI zD`>#>ps?~`elu_?M7Xp3%DOluwBQ2vxBSSd||I_kx;es zp0BGfe|jeK`Q_ik+?mYxkl+L_+*a&E4%663o8*)zQ2J8M=__0Z%3hk0c$3MW=o@jcWn z(sSyylKR!<(De!GpD*7Nh1Z@|ec^?*kk%ui!zjS1}u`nOI2<*YR;^ssAG0oN)oo7Qc<8?`2Nb;5bzeWLqcNwPc-_=g9fnEMEz z$7O3!OD8=0q98CE0$~#)P<~_hD7s5|r1C6BeSHV~gCrh(Qx%oF4bCT?(hGvR6QLt$ z^hJBg_{RbjekK|qcI^B}OKV!!%eB^Bn!0DwC*4nw$!o+F0aNN@`Er#lfDmZpidk+-ML zEcNxMTu~TIlnKl9d2hWYeLr%y=R`>M>^7z`^23+2C9@-R2NR>KE5;&!f&#y$7F5!B zEuVaMn7=#sRcWW-eLK8q$}QJqB`7)ctsD<$z|dH`tvgbyRhV)3Eh5FvMi&sGP@4f5 z!8}{EG-4KFr~4pS4p;7V=NW7_yL#Rsc1(py0i{@~wb6YZC82rX>g9wUV5+X}(nP}m zrzBgqT_A+^yu1G2CyTt8qKpTSs!rYTtWCC#Hsf=b{K6H$Z!6!w;lY&~YVH^RS)*Cs z5lU%XSV9hmYr~e@=cOKWuxJf(8$r0d1PZJRl(DU)HxJ^`;l>PjI_WB*5se?*JwW`=a!nC=#Lx5+qi+r1?pmLDC=@6)c`Ys^67 zYs7Z``fWzud5&1lkt=82($!3B{UDa28*^BY_!m2zA z(nrQl-W~czKX^V!`=;sJUA$b=MuV#>m0RIPHv-&eMIC8`q9vyK8Z==kc+^F-DW4m) znmgAjX4?9ybzbJ;Ac5uk#x`s6OdqnRaTognl?pp`TmuOH^A&-nA*%Y>S@sNMJAyQ}ptQME?*<>vSu8P)Bvc*9|%3U?!F zSGxxeIaX6W0{E_hTM@ZxR{s1y^^&r#jb&w(aGbACht?e}R7QwdTTZ>ijn^a`W#HFS_Wk+jpR)0+ zVrxS**8aPHK)o&9$FchEzYIoyljcA?f^@eg#cJf_DQ)G3<^_e)*O@_Gi>Lms_qLj1s(Efi0w zpW9LL;_`UgcvfuT7DVn|Gyi})bPoHUKN>~gkW6k-`XKq^Y>c(U0^ z8tp$W4xRiSfN=It4HrrIAf=H=?M^kU3_F)>B8^B-MOH32zfzQ`=cIJeroXGS7)ke1 zs9vc7jsr6y^V<+SEzPNmSi67tm}=pvzH@k-`rkD|t8=*_ha*mHMx!Gi!hs!XhJ!Hf zO=gZXr_m2pE99IADMqqH*=)D9a?E*0C9ST?46T_(B^L1J(`?{dIPXUcmoypYVdj{yC>z$j*We_TA;o#q0)0>oX%0FamTr?)#hjb#o zl0@Jxzy4srW;-*LiQ#q^?5x{rTi>5lH9>7Sq z<UE>oAjNuuS*z+vYrd+s?^ zhM5xU8THpCT2#?B=7E)!{^Il7WIm?ZbDT%NOdr9CmXFY&C|m=<*=rgDK2)%<#teF?6QNcF^QidsAGD61TI=+sVx zLt2QV_q!M`3Uzod#hJez>i7S+Si=oj#G-Rff2>@?(5;+3bya2~vPU)}>}4(abbr3mPPyxc zwbfVw{L`;CrPRydY=@cZIw#*GnbNXOZ9=S}?cX&pcF8js>+Zwtg{qJdlch4_mBR^N z(Vx}8SbX;{JN7+*Kcnq`v@*=>_9(jo&K+wPGRl@HbW(YaTax%Cu1qnrmPVv`2w?3$ zmbtLx&);$`sMKBf#wF0+pKot1hj2*UsvON*+#MyR9HXMv9}s{fG8jgll{pbe)?1?q zPG!%rz%V&-*XImOPW1fFpj>z1_RP>+_o}OQN#bmFann`DWu;3Ix#Wb4NhT{V3_WF) zW5&}yRfee%>liD48hS$UyyfA~-+k}BeZ+agqO@<*k^}adzsE;628tkza?ZII1@KRv zt7t2$PCCqVs?2}e`0oeKwC1ZlP{rlYIe(pZe>2KH-3bLni--|T|N1rK4~&SzT_v>h zam@fe(=O@22wSmmjLZyNeP-y{yRw++WH>f`PoeAPx>H3Fna$P6CLXPt$-C za>U5YALi7I%7asfc^8#cDgFWOkx7tUip|w4$y}d8-`cs?l{l}!(rM%B+y6E)9%;l- z^}S|n0{EYUuG$gC$!yzRAiolD@_3@@rQwsixHF2-0nV$yzosGq*{N>TfRk+m7RW`$HDk1+a|Z5mJ( z|1E$o4LKs#lzq5cymUdeJM&AM6}#rHspG&YaQQbJ2N;I|By7+r%=7tOj*6#7wuEKV z+3bNYj{4{!l3Mp|D)O5uddODu`qAk-MG8R|x;NJzOCDvX-xemjhcEAiYo-7DOg9P2 zRwvYla*ajg%4&?lj48ws&&ejMfswTrK8hR*Fp%5ijDat{yO<Re9L$)%k z?+Lu1MB~fw^}{&3m@r9nQfKS*cJFh5Lzk#jmxV(mQV2h-cm4qxm6Z$In@8BLdI^Y; z&zg%=rN5j`tuYu^^=6!y0zvIq?b?^J>Ks54yUsW&`ZimBq2;w`a(IsV zdL()}R;PN`GgkVE5tR$-dbg;hsgadccXczBl)89ZpX#QhT2}6B=D_b_5#R-08q+u3 z!%Z$FQ!h8)5&Nybe68iWi>KuM`pbZf)oJt*c0@?vus`4JULE6*^`4aaa=*X50k#S} zwjs3D!Sx-b0mI6{hoja@ZF5DyQJL@K7upk=6)+MqX|F364&EMhTWwV+M%Xut6f@QNaJq&$MePy$6ypl&$+-h6AY36x0PWu5L=U@jq!1LmRtM~S0sXT4~z(eUB%-bwdSQN3|jrr^f8Bx;#BQ0mZo znvOPiC+d^ASolKMGK@if?d4&_sR-ki?t+wfqq~ymA-lOzH+DF@R;)?aQAs_hX8fYv zJyS=_NsG$Ne{_wOvrE?^7JI9HyS!3H@H9VFPSpGdWpg8&&E5fLC=aaJu#`U^Y40_i zk>V+*KU?OHduBRv5o>RrM#hj^U6H_U-Pby3jJ9*gPIrzaCWxzZoi9kGh z+wR?XqCD|O9YY^DfrCiNT_{eKblIUNmGs@Qw_c!Y~4xCX? z`NA{76I!p~2@j`r296yWWzT9PQ_E5UjzSeGRJnfmyvHuYJm8t~UaM(L_0L!FV;R^z zLpJ}^@-D8bKdWaTb>Vcan()8?!GHG9HW-{@dvYv->i?8TqH2vOzmkEI7_=--|%*aR1tK^zIQ5JJlFh{wasm( zR3uW;4x`b1wh@htt{Ui%*b3)nE8WBQiH`tjj-$G0!LH8N;)SK@?bUIRK7V?Mp~)e) zylzsbAnb=VO&m#azzFP{S~!bUw@5Yb>7y#sBv&o*QTBU}Eof{Y4tlm?IP%p|@}eQS zh6-4s_6m{m;kNGLjvNZJc^4Xe<7NnzI`&6jvl>%i^GXRkx*I$S{f$qdy#0r6@`u?8 zcNtx5>R@FUIv_xILA_6Wy?FQs$O7a~H7vK64cJ}1}P+DiTJi1(jh(GaDH_rByjvN~}j);aH-93Q-2^!oX z!5J*b;I6@g41>Gd1Q}dT=e_s7_k8F47@q2;YpQGS+N;)HJzZ7k%5@qi!w?;fY>7`i z_*=s$o6aNGlQlj8$$5vJTR@wG8{zx>gr?l>)EU29#^>~H9Vsy`kdKLeSa5ZVuym~% zSceaU{f(0_u*3lZH5iC=MqsE}A2#P=44%mVG}L3IAF*am39KcAO$Q{%Vm9Z9LyL7Y zfYw(7w0>s-7{qSQv`?|oBl6DxM}nUY^s4B+fcR*3PtcFsU3UY(H(KX(*LBk9H{iz% zOJepahGW2zM}Q?QDF92(vT_sL&P5YvOb>AxiRPu3P>fg|Hc=VfznuCSJywW8OaR1( zlO_2{&jKQP6i4)h?ki$qSc0Sxmgx}ijeJ`#fY2Cpt;rb;Sg2W23iTz*^%;9h;BR1) zNSuLfi49P*{3epc0pMCyAdh_Q=H^BX5Fn|oH@T5%L7yAS{~6N`Fy?56Co6&JhCc)4 z$TNVq4Fb7nHXXqKN$fIauB0X(J3j=>4)%!Ag-81&VX?OWINap>2^eOtxc|k)tz4Yd zn8e@Fzi-+KVlSgwT_wJ)Z4g+Bv0IA(oe4}h8t50wF~Vh^O$hpb*w4ze(!cNPwL~K} zr3Xb)js!*kk>2cc+UDj)3e?4%iUAPZ8$j^3tjmh{@IeJKV&Y{fkuI5}f2geN{u&sQ zq((++_PK7XjS2pu&rAb8UB+ag6K50wNocN;c@xP!ux?U}h2JY6?NOnN1yBayKS@#( zdx0FsPm!XGL99kHOrC781ivN{@zHR~u<3N8q-9HGIvz@rrYx<0}v4H>} z#X@2ia5&?;HS?%+YLV1Cc_d=ogl%6clS>y-a#1vww*Vi`aqQ`jBLyG;7oV6ouWwe$#a@&~f4< z6m}B@?@c$s_8+r_u3B0SsflhzqG=R8{cDK^TE4S2ZC^(N#%q?O0qsEq$W@jLF?`I9 zsXfGe@v7b~0&GEH&D__o(rysIP9~sF0OeFY1EP(hx9)G-)oiAa+%?cElz72Z7%-!e z+#vzrB{KAHVsdI~ia+Y~ zY?E(HMfaEtWG6ztQXhbNDuAQ=Bms$gj+#3#K9T_erZPm|0Z2CgA=2Ft7FEP1S1wEq z(W>GwrUXQ{%c7ox&YJnUeeNsv+*{ZZ0f3r-XT>%*b?AYk^rW~f1i7KD;5OV;Ry?D1B@l>y>2c6 zjJW019gp>m&hJYv=)OY1h|}K4fnc==g8$ zBu(t<567L!+?t>msgoxoe#$=TrFGpvG6hm_M(QnL*GU>4VBU@tEg+^G@sLMm=Lgbc z652ykPgXrGFc;-5NCD03dAY^&prK=g_MnS0d7j%aX<`oZcqW}NVrA99{f2y zPb4)<6(?QT=so}dC_A98KERnVYOyDJN5Idm(W$}&0Dy7S(DrBi8pYU%Zu5 z)ko*0@Vg;ic5%s_`<|N7++HA1qk(B`90NcgJvsh$b7VV!E#_XKE0>ECsV2T=e~hto zbz4z90ni3eC$N%8gQ%_*xU1Ln1{Cnrx>8>@Nw_yf0xh=!EeEh~Jg#k60P=(cEjxQ| zTf|*hG>*_$^mR(=%@#M}6}4hFx0q4C`5G)ES=ZAbpj{K`w@ue}_yBFMX5V%A-b+dM z%`nm1=w2ZPsLJTFMdo@M4|LZ^25jQS%0d536pg%kLwv)m=`%2U9s*>kx`q8CKsaFX zM|8YNOj7odr}1~ieQ zVz#06#m;fqz0zQ9CLkQ+E)CW7^?L!h9-Inf0M)=`>Zw4U`+4=A;YtOE8o-%7DiiJ@NMkCQ$egc6!JGcKUX;{X;)YGSl_61i7kfTB8iSj^vTpv_Ift5C$c50l(iRhY$Fbc4F1z?C#nrBE+_r)o39j2DjhRs( z2Vg%rp!Mg}{+|!KJ^sD}(&&k#*X*((<8xo51-}0WXg1i}*64H7#2N2VGtPxQ#yD&v zEmsb2SEfGcUvR^|p|8uuxdAB;OXokumQz38X1%D|EeDXs+%pencJD!5qYr!`jeyh` z7#48dGX9!tmTFfRvAfQwYT!7q#d&_&Z;e0E9p7eABNQRG)@v#IL>+8-V$QP*yAQeM z%!u4wtM!Xk!3N}qhp_%))ey85MPOW3g-5Fp0MbFlU~e>0R;49R?x$7yML@Y+=(h$m z9L2<@IW^6urZ>Ol0AXfuNYdz@CGiOo44*Uipq+%bt8|qN`BnypteShE4(D@M- zBr-xGSGJxygW|YU^hO_O&mjUgF)ZS9?#DZ82;E@kLnzEi-)|sb94F^hoBK#f^`a*t zb)rIaa|%K&UVa+0HtR&*=(x~y)54}(CAxX8>nyezR<7zd7!_;SXySKFm?c5IMc_E! zau(Bhvy^(?7~FC*>>%JQcDPV3@z8wOVB!O9s1pxbhU~g5`5({2I(K8%AmoikLC_S# z#>(>h#f!4>Qwidy(~ymZht7L7*BVv9Ojk86wL->)q?4hG^grf{IK?e5m#3GDOTZ;9 zjDHFw`sR=ij2{Vm)wmgi{_wBi6ryt@7a-4nKK;DZ)%QO5qx}y~PO*<@j-V5t=o*Nkv7g*~|+CKi3D=|GHWV3R93fQ^nynVm0D0MlMDyuV1)Y3yO$}XOriWjN__d ztKnuPfD;Z9y5wDfchCj#sqDzU#YoF#%5BiH(SA#qP1yP>l1Mca6BB1CHz3C#dq%58 z8=kQL>O>~6=36^z3)Hy_y9MF=+sQL)=_|RHg>xOb4}o)emgk}oOr^EJd6v@0QATr8o0U)vQixwRtIZ8fRV?8yo7Cp#%N;H{D=X8c z;mhG(1}%R+`REhmQ`%Z1vIN|`_h3s_>*g}sa^>>SNrQ8v$a2p9xOcqIZVO|}`LY%v z8~Yr=f!)!mp|yuvTS*b) zLG*>poq5n$5L?i7e3HaA%9eoarj{fy)u@ zl>kES&f;P0;q)=}Q97iyvvT!V?aJm>?r!kTEEEMzubTafF zWEJFu&wKA3--!R={!U^`sm@Vx6qX|PtM&OEc{&?w)F6N=|m4lA!2O18Qu1K)rratoda7)1~l<<1&i*R_goXj}APx%ZNUg zeT)Nin%hqcA#HQWGmq2#R6j2BI4(bdACZnFq(|bD7lQLUAv2e9cXdS#rh9qpkcZpP z>Sf1+Xqie*Pa(XA+T%hgJgVD)T0)C6y7jjtl`DBpZOsfKyk?7SKieIGF?2`SFc$n8 zW_rkvvG5D58t3_Qio~WPl4j28x0x4HrAG1G7OJfyuqt5=t)TjaH+7N(PC9J-3QCkV zM-x6MQ3XMTg5!*KH3)Bt_&FjynU@ufl^nn-hD;5=-W-E7PIU^Lisw?n0S7D#8Ws7J z5Kw)Ak&Fl!Y%8}On$aNR5EopmFZ~h zIn+DR54v69bxMtbC|I{h-l`3JFE(h;I6pbQF)O6GW31XlO z?<~fLp>a;z!|s_O^_y_5~wn}BW`W^4;Iro|*@O8W2;oa`REq07WL%NW~$_Ab5#1T3BU5^A(;yL+&Q zasEpp_xik4BG=ZF36|eIHTT0if#NdnS6LMgTMNA?TM*(g2xgRD{rk?}bD8Y0J;7u% zu+316el@G;*g+KPy91rhm?|xPrLw8-`YVuag{f$veOwu{-v*4yX;Set3^lFdF_%NG zet!N0yv&E<5u+OvJDzEG?>9hAd0*3=Wp;mKb$R5zv9vKkWwqiwiRWWh$0(lW0`%p zwB~SW(_nFprj0yl>D>8KcWM3kV8eD*5A3YmG)^(oUR`==Q3WG-5SFTJQ9tt8PFRF{ zftv{$GD|Dy&y2xkhFU9HQ#^lnlshXUoD2~T;-Em2_T7oV7VBz*XkwVWv)jtq0bgZM zTLP=VQMHwF;kYy;=4Xf>tY9VO_-qiNllxOZ(Z&gS2y1J}ADE)36#ivD*Q!NEKrW|T zp=yZYUBRU5+`XYVSe<;&SFAg4Tl|OhC+UZ}FnesVcMt6}{?+!55JnIYm|0unP?%S$ zG(rda=dC2D4vYrEYO!cBZ81E6wWxuyXV4&+Aif`p?}L=oOguVI@@CUA$+fo+SfpQ3%Bb~rfTr%nM;!KpfJ zq^v{b5wC1{r7c@YZbg*#u?cP6fE0uZLIL_Q9rL-R04xFx)poLHE9O$?E4~dL)p@3{ zxCw=M!9b{`aoVODYNRE3rD?XsFxF~e4X5|#{<%WNbNTg7fyhA;Vmu@afD1Z-Z* zBRO>_MJAz5Qzoog`BPYmFv6ZDmVwL%=$COxvo0cTN9H)%R&^$@)GKG!6U?g3Q=b3F zw`5Y)K@jwcEQvSImVHt=e;KQChS$U4a%Ls`l8x8KzG23wOhb5BwCq6NBi5R1j0c>; z#|VC|;Z-rL2deQV*M8{`F*64~&^=GsFR!I7_r|Y}n7UO6K+k+uZ$0JwSx3p>on1;{ z`!i4%jp4Jwqlz_Mj!f+O=Tpk%(2iMA19)lZpZj8FS)OX^7nQq=B-`~-FxC=MRl+#1 z$?^BHSx`>77#FA!9Kh>g>*Z`zjcb=XyH^#Z4k=r?a}z9a{+{C1_v5B1L{52RRBp;`^8!`GYHJ0C&J24^7B@!Tmzc3V5QSuX0HV)K2U}_82DwbFdG_ztF#HLb1_1~gZ#2I~@mmEWI?EB{ir=rGM>tUZ-LLQm>;u1+OGeDu$y0-Nrw zHONDiMok`%k8f__Ol>)4(GcX}QBZrIa?Yjj}N3=Wqrk4&#`G|Xo0aQjMl6>7+`qO9Ao zeYVQ(;9VNnyM4S9AfmC-QN7?glb08!q@4923^jiU(uXLzpx54md|l*ey|*q`@9Cmi z;rkmVhJGb%>VekU68(*ADezZGMLrQLhPWZS%I(@b+9O{v*tithGi}oZm)vj8h>>Q2Q%#DE_cZF6Jeb zzZ39lnXI*T55x*nslkL!n+sxad9_3=!({D4mQ~9# zjaTLl;o`dUH7wfxQ7d;}Ni6hkj)OgaoW*{T<*G#QCEPW=pJryL={u>hKSKCt3e5Vu zptm<7r7*r%K0W^Sw6j3o3|53!_P&Fc|Mh+tfg{TWv;{q$*+uH*tv2*@p0YQdsZ_yA zidn`vwZ*-j*iMcbsctp`;?MlPyx-6M93m{ovV8qjft|}@p|zOoYJ9Fx$>rz$yp~H> z8{=_2*P}=PqVCKv!P-!xF;%rFW?@(uo)fy!Y&UQ^5qQlg-bS?@JMPck*}Qqu&c>d{ zb+$s1szy>a!NzqL1;_8{_mH~vzku4FT| zQW1y!8zQUq$4@C9@dK{a3(T;0r^yG2*_Dd-Tw~SrGagD!@XHq0yjnH!`yaBQQSWnoj#;BP@8RIItjr)s01+_dwF%WIzv zfr;T9-^)s96(z6umNlq&d)B?@_h=GRp5es=ZRUs5g}s-tRaKSuvYhklvBS=%*&5r6 z&JS!WIaf9qA`7o4iu`P*W<1(?__i+#hX+FBj+U#>^oih0g+Bb<0p%?-ThVasup*%q z2`@cy+C3;E!uatWJ=DnL?oY+vtP<(A`AT=I_3C%^Nk3BT5fvWpTzC9Ufjf*^+3(sk zHS zLw9-m_C24vr4H&= zo>O+I@3b)$C2fD5@#7FXV(?p3Qp`4i@rq*qVVU#kl3IthzAwZwDX0^kcV8yTSaGl- zL0fSnV$OmG_jKJ>$eSXKSkvSQcK35;&BJhh*Pu|XGr2OT?bd*qtmB-ZUt-l(^RViW z@tCpdDFe}EY8X8u&D7iPlQcZNj|u5$3~UiF5*6__AGrXVz(uPKibHfJ%hPB0+vnZ$ zH!AWwy-(G?(&999 zX*GZFMuT!!V$;UqscLZl^M=mUGadGo>>Q>_Dmf>SOIY0J4THlzNNgwdPoXN&i8Qsr zfVwt;K^w)*RqdMRm*a)kC2LvHCHU?3=K^Y*saHJOLuGspmBI#Yp(;+zfeXuvYPM{- zIuwvy!f3|X4@xT5IwF_gnc<{k`@ziy%7ESJP(qvOVG$(f(>C1>-<^h9{&Syi22mxj zY46A`)1N656=@C%o%A*~IiS2;FN5}4b7yv)-0c>RwvED;5PlX-VQQ#>aE^%q>Ypm5 zJHGzY2KS=03<&LdWjdKnY=cP_JM8Op`*y04-&xyIFx30po2t^WPNiQfF?bs^uhTA8 zaONyGqcgJ7!s?`^c6&#W!cseoc%N?$cWg7C0jV4uQ}!vYc56JIV7pZD_XqJkEj2YV z+t=-~4j$j71=hssObGLsh`a1}43!?{)j2Z9wWKhzw$C2q5yPlvGc$gxqjuYQg#)0)A>&g|<1xPdKGuacK`yevvpzN` z)ulgO+rJLym%;`o2AM8fb~X`$uC9cP@)`*V=>?Ku4vR8vQ<;+W zGbAKxWF(|lz*$c-M>}&4Gjk75cQXr5c2~bxO=E{1&euT`)lHsXpg_5L>3GrA5sfDcjZgN&Vy2x&Kx+Qp&U;MW! z)YgBzms5m1eFoHDw5a|&(Zu3iz169qA+oPtB6q*pvhwq{X_Pt9hv5{F0~+$IaV+sE z>#xbXUyD0D;wapk;)!oX% z%+tyeaEq4C3%8gnFRU_Fd64`V%NX0vnO6+%rPquG(o~hYFoj}k7s`jVm^W%nBa5$w z|AupYh#_<&jKV*k(&A&~YexE?4Mz7iXMX}3Y5_jD|7{Q$16F2EKx0lSt(ZOU@s6%o zQs2LMc8ZJ={RWdr=%odHt>YFu#gf$J?32L9ud&mkU2TDZRvOwk!AptUV=+dq32St6 zM%Yg(1lW{0&O4mh91+Se>S}4Ewb~y6C5-fOL_xRIOV7sBKTruJ7q?f(qMx|c4uhvy zgoHvawJtfLezr_7jtO^osa2?;@ughce;oAtEv@HGA3#_gEClFKGP zUdNp--dq^nd)LjvcMC{Df@4G~HFi;B<^i0~!%}SxA#`B6ZR5t@A@J`rVaZGq{QC_; zbT~rUgM;zeq{2g(!zjZe6>~JB8YVHRF~I&q*)ga^@8rG_oyxrk=G^`AP3Wes?;Y+K zO}C;sHmhV0m6_mrp#foxZ0K>-jExmnzMbORgg=F;MFg?M|aV{KM3 zwJaBCm2OleD1;(4#X`c=A(0=EUX4zD`K2QOjWSo?ni2yKpr|H=$C(CISfyD}2}PWS zzKk#n65%8I673g*>O32Id~-9uC0e2JJ6gyZ3*IC<$(1{exjt$8I*DFW@#R-64~akD zK?{fS2jw85LwAEOj`s}k-v@3MZGAmsHvG<9M>-xmq}#>Q$3 zEbkF&xrXleV@5`t_?H7+ZrI0jA+&b<`qRzGNa_&hv57XXT7v*J8tw?q+cF;fqAqdx zyHD61Sd%he$1hy0zNbEKLr3Pj-^}Yu+=_*}Nftne`SnmN*v49=5d^tgMr)#PJBTm> zN>M*IgXH4&jr8KKI@D(AYMG&@L$F_?HOGXR=~yc!6dr7-oI#sDs1~Sq>+~80=uMtu z-y%i-*&(oI5r54|E75Bld?1@AzCi2VK#w( zi@EGEH}m~6X1f~edt!$YzZ&T}QwOk77A!H?$0M^J*-D;;JZoW)FM3M(f!RR=3*R!`E&;BQ!|jz*%in7i}SVGR;TYY7cydPw;6&Q_@WcOXkUyI<&WD zcMaBHa6uX_o}Cl+npd6wKc_3ofx549(VXY62E?5oI2w0K2u@} zV46!5cJZKp`9NbWX!`1@N1PG-)ALqacgcHd2JY=2PASRe{3c~f$$+-#ddPQU<&Br+ zibM~Neox9b3InAaMNn=SFZkxn@g=d|<&V%`%*W>J8$xuA#x!Yr&KtqPPe@Pkt1D`G ztxNZoQS3!?nCuOirIV=sv&|qGW36_cS;YtNX~7hf=#77GJpN_w$(+`}UhX zjFwBu{6Jl&NU04o{hcNUQOcbR_hpeC`C!mqLOLXqq3}}S3#!!;uf-?iseyn(iF201 z9?Y_}A=|`u1~8eIg(@R#z(c7V%5;OdhMk`72TwGj>iI*1hx<}b9OQjyYaM&37>%Lc zI*BgoIHIdh5`5_C%Hu-EzWl2GIWh8c!l5lT5sHnvO$rEVuH+5Cw*!Wc=~Xgf_gOa z{DThG-PdV+b_`ieS;1^Fuiu3zib<@maJ;P*u!O)GoLy$}LIIU;=s7=HO7xB)Il5q# zbLwB2oai;hwHgvf;cu67fpIT(Dn2nM&= zR`5^gO;Ms?Xo{b{k$Nvt#ny0AcbkMWE@Pgz()59NQMI8W zR@im##TC`b?QqQ9;CQ#0%?GX4OAiUQ%jQWlNl+56m2Sjx`k@MMW2L>v;qjtJ4cNEp zPc<*2tTq_yICfaEUZAuLMqbsm7YCPM;_f>I8z!NC4og_AV70c_kV`7c3$prYiU!IZ+-+6d!UA6kaS9Ix~Q6{1)E^KX7Sl5BHVXNNbft+@iG=Je*2rtI@ zAs3ONm6G71%HwQp`>ZO2gA+2r8R_#e3^u=)^0mY7%JJ;Tkm&_?^NrZOeAbR_zg=gh z+F{{+=s~xBg^~<`_3M3a$wE@%8k?aGao^c{ha+p>l1rbh^qi&hvx}>(On?s`&K|?0 zbI?WlI{|jvb(r195S|@xcO+9=q%#oXGo)7udIZ`@G=Jq^ z#8#gi40jzgUh*0a+7ye))K+)acoY9d6xP}QNkT6265BWOds9>16sz-Vq4&gfnudSe z^yg5uCJstaD=SjN%^5G&NL~z+WO*SuEb$fCE#AFqaDn z*X6*T#AWaf!v&s`R-7a5_QMa2_>Aq!pYB^fUf}*ulJoJ8Q=l+Fr^+OdknsN}Z?H7; zGy`}}zoCkYu~6Ldu5OzO4F;Ysokkw&Og`}gv9;EV=RP;h=3O<*4O-Cf?)$5so^ifK z#6B*J(MAfo`M&Z|uWzbWm&GN5MS^bJ?;a3$=Qks1)60z|gS)Wl>GS2@@;LGPOaH6u zzbBND)EyxKw}+k&?*6|1SI(?KzJWrf?c(AqoufrC4vyVj7{_i%aA(I8Zvbw58g2E& z>V)Fv>CKLkt9W2@bFf%vcCf~v52vnU zMZCMVt+Zq-DEmsR`0wg(z$qS*VmvTJN9dawelJ}yBbTyydLPKaDOp(!C~*GgZ1AvD z53?JWr}D-YSYt>C702JrM6%b449=nwt0G52zjiqFsy7wNcVi&Al`rC`#!axmod z|38S}34eE5Ur^_fwmca%t2jG6%RFn~HyrUU>!fy{oqXI;ux_8-rDdeJ6)3Hb{=erV zV;QB4m3{g>b+L@OJo{Pe98>lGQ~ES-&!!s(9b@i zEQ2V^u7-3RIJB#A+O5jqaEhn{4%0L3YBGon=X^6eW?IWcoKPLULGmGq5Te|A*v@rd z8C$`AY;hw(%V&X^h2BNfuYlAsh%-0z^mR<}h7psB*gj~}7WF^QCv>RXYx`M89@R)5 z)sPQ~DgL>5!rT(5IEcPE#5s@Mzlbek2sI!tvWs6ip%=5)W6@_ZbeO^_*WIso6xAEC zC2LuWM?ei&)Vlx7SN`Yffp0(STB9(#^Tb1poU{F5_j!`H51Z3B>kkumW7BsmC0Y9g zBSzG3H#IhVXI5T%43l8#=FUz&A<}|lymJF^S&nYacVKT=>vV@mR5Z z1-`bhM4~QRA$;r#7)U7Ja@+TsP*$h~q`#%he2>i|wOHzgs?UllCW<1Bj9&BeQ|3ob zXsm(iA;s{(t7M!8H?)hV$rHSV@A~AkbGHMsRoLwl`rOvxTpNQ=V!ZWc3r^{>hiKNc z&i8Nu|KOv^o6=sBddfl8Kh7h*f&&jfUZXjkvWPvi*`E^`2;0Pp@v>{R+L@y{z8LvQ;6sU!`wN`OtHWiu>FU>x*B?U#d8h~l$@Td&VKJb3kYJ&cb{oGR`dA{HPcnK_xtB%K|J#sj{ldgVAjYsMHHS=!JY0!8 zb}~)#%e3x!*lQfD^!Ja8pG1It$%98Jqq;U$dwg@~z@uHp*&KGKF zk(=a`FR=_gOJZV(YbZQO%y?);3TzC}Nog1%f;qp5f(~WTa0EY(UQ8Z^4`I{9ZHs6o zu2VRRTA-jA7kI#bT7F6Amc@LoJJ$n$A@Yv$S!y>w>l0&@$aB8Xzb|lTsxEqb;e+Jx z)ISFCpZ4(FiOH}&rzbVKX2g5Fh<-<Tuw9Gw0~;tN4&dywGK3 zZ;BeO@kqkgo9+zc0kzs0^xM6XhJRuV|CoPdA!76EoXeIl;m*l@_FPOd{@d%Mb47b) z=d0);<(H&wze3Aab8*qoC`ZsU(5q$`wCwr^Y=?}}jsj#ifc-hvV)cVk3CG$nW(Ya^ ziSDvtc)OCZJW; zPsv7)XDGb5!Y~ZwK2PRtToe>J!R6_9@^co~GNpsa16v8;uYoLSC+mOzE+l?uC%Qo^ zi&ti;0LoZn*DRNM;gv2$Is1ocUlm!wg|f_uez1v=Q(VryZNOb9(Oi0M4_CTLpDsk& zKpN^*JR|V8feqTQh;o9Y9MqWqTnQ^!m&IbW!c^U>HSuO{1~aV8k2b>Ky-b4$il%Jq zR=;-q{hZDyMNp&3;5(-}E`yYcbXUUs=0A-ss$RS4~r9V8GUW@VsW^yf693$NGaL;SntwdY}D=$ zGisg%Ig_@OZJ4V!CLna89Nmm_)oRr04a1!>%;s19`wqL{fFbVl3I`XyucWj3^t;;! z`FlsW;SRVSzF1j#ED@B>17nN7jsQFHv8BlsIWtC}$L~^gd^Yn^%8!rYbU7bYXjC@S z$$Ho^C-Gb~d?gAQTkrDeWly8V-^9eBwa$=& z3>hhug$5LYFQq+wUMk4b_`Y~Lua1Ua#gKX)TJ?-zdaQhK(eD9^B$|GKvX=!FSJ0j z=A^zO3l^HAhl-mw{i>CYyLpDE+7n=&c(Rw%`+`q$1BW&)N`Z~sPRdzN^HihMn?!<} zCs~4I!!2AqFBmX9O;OuvH?8Cs0)?drSn};+J3~ZQLY^+AkmAakW?Q}}ve1OD3>T#) z`m;dDj7iz-pjS0kBGpM}dT$^C^@I+ykb)F?oBDiD?sibyON)x81#`V2nRo1F!35h@ z^_oL^8Rk#fE)~i(pXjN>)D#9Bwgt9gjp8F$%*mS4;c+M!N{Bo$#Go+4<_SJIkX_<7vGx-Gz;LSgRz7w3X9*t#b9(z zLO&`!17eM?`>pr7V{!)1(I^T3mY4bz)}YujZRt1^F}$?9-YMoQ-3}XhLpl13uDSwF zl-TcK)g=PWiz3!Z4O9_)UZrE(7=_q+~1_8z1#L&b$`z z8fCDAfqxYbBByrno7?9Sv0DR=4M}WYa>F=?S?)=QS-Z(w!Kj~-=k(ipA14*)%&Q-} z=_`%c$Wvbvrmk)k^J22LqDd+_&C+LwGxs)$P;-HP>lVG|t@7{8@mCOjK14UMoW#5^ zeUjvRAS9cep-!jeBGaz0xHT)06*kuLh`RA36=C#ST0+e+M?{_}CHFmjQx57Xs_s5V zQGQVt7H%bPC$weUWqCp(8ww~spZ#s-`*NIY6JFOmzRcsFx%#%5n!oDYqf`) z>^b*W?n)1b(zcR0-i6Ro^nR0?Ayfz+rDb(QB7R(qKl*R(nPigs+FQ@e`YohU%$4Iv z$qCcqaN8{JCAp8pahkFE7>wr5zxIA`-D$pLwzHKtrgUny#9(ddryo|w4FS_|^_yr}lVy$%F`PXr=Dxs?KO#caSRuz9+#RK=I8%ZIA)Y#zd z-W$B&sdAj4e6nu!iw&8XF}0s)pUJc%E)H6FL%o(ORH(_;5!!TRPLG-`bi1!gbBlL> zM-HHNr?)Km&6Nw2UZ3IHw~Chjk5f!*J}%>a0f{J2)>(kzakDMm*e^rTb{v z_0%x;j(Mr^Id|o(Jaq(Ixd(UDNi?scHm&a#6KQ;lkryX$mnD^;J6yX?!0*rGR}}bI z_p@|aecYC`XfssNf$|GWbe6mnS#S#YdKS$7&Q|JY?6d=A;7n+@;C1Qs)(7e^&S2yj zAF<=|<7?$I>$ah=_{_gdr3#FkT^G$b176nsp{MMZR0{nGkB6y*SXe!FZ^_~5Yyn@f zI%fqWnz>U{F`Am2h{;o)Ig=iI#@eorBfG!ykKnc`N*WjAlG2fq|K8}#6HNHS0JY`& zJb7MItf`}N7|u})n?@gu?OP`P&c{_x`^MAFFLQE0B*ir|uzZZ`4Bw}-+{^Gg%TCMa zlqHHpPgJPjinpw?rY&;+l!924 z_Wf35;eK!mGS^jptMOGX&fXvo%V|owrD9-Oi(kt-d?HLw%u@K9A3$Z{aB zq36Ep=Uhz&cg7%Q?U?qLKfasKrw??$p{J)-s|9j$6T>6%|#EZ-tDsGrv;amcD$s z`qClc8>B+RrPGyUhlzOvUavJsu=Q6)BV>bd)qHd34tIXDm(itv5Tjr!gFjec_PWTR z?uw}Mna6!f-`LIUqvzHBNE2n-8m_NI_7lSM@fZoO%1zR zohWII1TxyY#&h6B>3M4p^CuslMHdPm4qO;6^+43N@l)gd=fCJ#r2!BAS2vq-S$-WM zLY>VxMmRlT{T)ZENVT1c!2~mRS8%nbN}s~TV5Lj~RT!>7(D?o#f_iuQ5O%)5eY@EF zWOgAjK2b8bIQ?*QyK}OBmBbx1m2xG(k;jyOcQ+`J(k1aIyu7r$lAAYyTV1kvH+Tq3 zD{o%)Js1vVxkH@qVFPa`JcX4qYU#q%)OI7uHE(eacod(Y~+x z&V+0+vss>)nDP5s-v<7?FnWJK7f%)Ttbk-}8s^36uUB#JX=~|g90B>=_GMpd`CXXW z>PZ-+mf=v*c=)}$_k-7($D5SxP62Z!<40sp%xoWX+ia&{S_yyR)nje~f15re@sK{U zc=KOOI<^b5r(*~NsGE#hr$ozQ05^H3?~Pe~d136GvjiO+X^3h0h9k^{Qkx(9F)fUF zcZ5MvGo;}~vBPh%w(zP7+!>VT@REliW~2lE6rV z^iS`Qk+~>7yzgnJl_S@d9|k8l)c?-ZO~QK!C8@y7eG{jI`{JxB^aF;w`8TQ1TAJ%4 z4t~kRi4T9*e*Ddn`8d#}hNtBtPgQI|}-@CoN%!e(66X8dt7rXQG*9RN?KKs_#lppJ{cF$2Avx&>oe*B)wuvD^j zjf##P|H+a$7PdR)-)9z=J|H?3JN`n+wAzLt+BB}DQ%Z@ACSX$ww}MR+iXn+!lJLGD zAx^dT{p5`F>q^!*l}HKD=X-tgPo5~<#fK<^yA^^WUJDnuM&UD74ekZg zJ873~3iti2GKS4tP!hB-N;;ObddXt6)KXTLdu8CzHaMgRZ@+F+KMZkTo^|1FSWOLj zd1cMi{Bp6@#mwKy7*xF2S5x`WTe`*gGU}@UqbdQS@O_t^gKm= zex2XF=bkhFykF-t_xruy@B4nw`=0L?YMC}_j#$<@ck?=r8_G$(dN;oEP#4wa!t}#v8Y7Js!oqZ+Yo;}`MwS%QdoxX?o6*O#BiduPrSYbq<;CF_XY!NK-|U%Muvq;H zyiWJal(;LbE3_gXqT6v;=8ltC)&`yLX?^MeHCsF zO}BUA29~c*m~A%ou4ji3Y zY?vlwmi$9@A2H`+O-n+um;U)D=kq-@;be}nGI!k@l;H!IaR4*6cx0feVg*OD8WF~^6CypDj_j}#>n>WgF){$ zYwbdSM@kl+qYtm;tP1zJiwvipz|jT4=Rs`cKE{!as{xf0lx5mnrB1hIU~E^6u7t>i zd?@f!>~tbme+sXb?72!4Qk4>x;>>1D2SfHy`l_BUXd<^jN|rZ>bpb!7j?A6f^14ts zw0i3E6`%JWq0hVEnPe-$q~Y?o5P1dTk7q-RPtwm&3;`M6#GSY@takNpD0>a+?PO89 z!&!?rw1QdzY7DTAhbkYf&b(vRCJ<(cqBRE^dt1*~-MQl1~& zN(PX9AZ^Y;Z`aq1&S7Ia`7R)7h2#P^!V7`btrCm|aVdwk4xw<`rk^ac0(;j(JC7`7w zA3K;kaii50K6Lc4RWDP_0v5=-b$#{Sa4-L*$>kRP(O~^e`u(1;7cLSDL0MZ6d%|(z z1bwI{{0#g&kJGga25>bl`9*9zjt+gh>Dk%PGt{Hs$8_nQeyO|(Ioddu_v-=Y2-#R#DSt3 z-hzT)Qz7Pw3a68b!5Iq+jG+#@v}Y8kwWXUE$%b@35#rBLP*YF_E!0L|(Hq}wN9?zW zPt09N?x)thL=y=W@gk<0NZ=|62+BeNASov){fDF#%GFH*g|T*&a&vS-*dslV_L6R1 zZepOeX2>|%fhgA=s{Yl>Y-=I{O}u!1gSxH-1VZRLw4j7P8Nm{w?QI=p`hafP(McCw z0$4&@yjiMLUrW1LTrymW`ka0zpi`Er#csuga&j8?$%kW(DxM=}%1YSqT=tnM_PiCB zP@&wL=Y%-9Qs#p07!R$qRd2o>WS3<#l{A$+RNy-1Vy|9eeALc;%>0-->-inZOwCCRq%nVQUqbLE+4OUDqaYOC65rW+3x_3J#+-6+dS9cM=!cO@S7uAixD z^>w2$=$Q`h<)+Z9W9>Dh$-H_IOgAn9XXI)869>}U+z<=?Mq0gQ}%W`N2fj@{+U&nOLfFj=KjeoXb^#l${) z9@B6ku=0hMs+OV&!(jpqC8NFx2Iob`FH26jWlJgPshwmHxb+#m7u6)Ce|K#1?U=&bxT95|E!kq537W>68F4>M^Y4Rm;VWj^v481%S zzxhIr0KJS@k=F_S93;=s5m7B(CUpv78Jx7D^e<3SRf9*lqr+HZyIpKWfPPe#xaqs^-jvOS+o7 zDP)m1BX(u8>b9H|{4px@^DZkT?vd@oAbJr^T)v6nw2{sIW@&(@#3N-Uzhwc)atiPs zsKDiHVr=e2hn;kbo)nuJAg|@GlwA$U3M)EcyKR{UQq!%7Gd#2-#TMje4ufE>ameAzA|I9OUY?ekEv#z~Jk%v|;bYag5^>HPepCqXhd!_*3sw z=ndDgP@M~OJby;0Sb4?lysYq-u{CJTzTVc=x{4jYaWa*wN`&I0VEf(oH1e-@+7m9i zSKNX#oGtG7woQEbB_(73K9|yvK#5+f#NQv9P8`msiLbwVnd%=$Md04Af1DQrfx@8N z5D22}Iw;>8!5w$9)D$k#k&uY={pXJkBa*4i?@D? z4+nn_GWPz#;n>eULmK*{fbWcdLqG@hdpGd#V#dBc#q1aTze^hj^+!4HeZ8dhFZ!Q8 z{2<{d$F@(nVEYT<$oqJdzt|_Vq3HfUw{ftjqkP6bk`w*Ek>6d%Vbozqu#c+z4eEzK nI7~Y{$?Vh0?EiOR|4cc0V9GrUM#4lqTZmsoBsmfvLz4dhT!f~+ diff --git a/build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl b/build_helpers/TA_Lib-0.4.17-cp38-cp38-win_amd64.whl deleted file mode 100644 index 90626b183a42e55d12ddabf57d3d257aea29fbf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 662134 zcmV)1K+V5UO9KQH0000808NKSOtF7|O`iw=0OuJ101*HH0CZt&X<{#5UukY>bYEXC zaCwawYj5JX_IrMX)%gI7D4Mymx>uUjNY^9*vV@pT49wiBic&BochUqUrY$>~|Gvj| zpx6n!i`2q-KYjeL(x-h?_N9 zhrBJ?C;27;N`;c=B+ZhCjP)f0;z^c1DB-loD^wMT?-CCG*b!BSy-)=@l!8IT%9Meg ze1G5;FOQ!s1RrVtWI`FQ837URH?e{&_PS)t%AO*N&wpix6!wf1awq=xN%>gy z(fjw`U&OBqQSmv4fBAWb#!My;ame!YeZ&v@jP=@DY69iV7^foEWFhV~yYAO&3Q4t!I*K+^Gk(J)HH3E}|H+$fGM2v>9yG*uj{h~l_= zQ^$DIM~_+YkYvz{eUugJ`d6zeU|`QI`|`18i8=_aah^PhdD||aT1aJg6Q8^=b_NJ1 z;au$y{Wqoc(5u?1eNC%kJqL1kX1fP_myDJbzZC~)oezUw1|R>^ky~|+igE+n8f*~mNMUEg-Wl|pd^_JaD2W+4i;&_`v8R8y#NwW++Fwms349gMr@~VLR?29yq z9%L!(MvfMpD8KekKAn;Q;--k$`#!T#z zsE}?eQBe1GU`c=hIwoVA0UD(_{DKs{?3grs%H6&!)~u?KI7(I0_0zHeU4pOa9+XL2 zZQY)wj$(t7J*E|Gdfm(A*Arzuc@;mF#bIB`^8S#0(Xo$f$dm_(UMIXLtIlV1cOC(q z35^|l?uH(5I(-v8!I5iV1&)LUGV%hGkA`mG%!qS|zgIsyvxM&u*^AA);SY8+KOAp) z3C{3W1M~vN)p1^6fNd)4PrdWe* z*Yh=47YA^13AB8p-=3oK^nR~oq$FY9lCgmSJ>2K`vjaD&v3XHlK(ACDgi6l7al|_?E4M!BA{-F zDa8#x92`zT`NFZu(hW@_`ORxViBy^B5RXYP^1ro+xWRbgkHC8qzjR^88(+~_Q(Guw zJQoENf3h$pImAmSy(mf3mkFND8evXwFqX*;8iWwfnkobmS}`(PVd9M^D=^+bPp7!i zhc$La%odms7{KGXH+G5X4@4YL&&K|zww2%of!nCB7eHC5>$C3(h%aVIp@9JwrW}fChC!2yOQcNFi-WS~Q1R zg9tTF4?v;dhU?5>t-GP=W<*5Q`ziFA17;ytG8kwb`d@2eOIptxN|~vCxxUR)SgzX5 zghtv4X^GoTI?E!1AhVPoub+mgR?WbGX$VoYr4Ljeo~~c>u(q_ZV;s%MaM>|c{JgmqYta?;w+-l!mowyX ztc(4zD_;O0@$%Mx*U>80>7!0dz@2;RPf$w(1QY-O00;mnFHuj>{g;;s-3b5yavcC5 z0001VVQgt)FJE+FUu>NWyynf$$zgF~f+4P<23Mp7mX8pEEN7D)#c+`^S$DnK^ULK5MVN_S$=| zwf0(Thi+M6%eL8UIrNuI+H5Or@~^^n7XR!v+laA$8ew~7$c8VkvGsPCD-?OEaE?*l93`60ewn6HhLDtJ-gqZwzuHAge{5tiwy1ZhvElgiw`hE_-pBrOK z;Jc^DmiN0fn!h~8_SEI{bzY&Z=%VhPJ$-MzW|Sa= zw&!G)DJCcr@0$1R`fuB8=e=)dn6^Ip4vxwwS3&-M7;)FE(Kg!*`kp#^V7car z3#1^ok=kneJ$)}NIu+hsKf0@qt`mwjpuMeZ%xTJf=Z+szLC^@avX#;IH%=)x?aY+; z|JOg=$o<_dqix2bF8a~foYS^G^IxRW<-GA`Z>7HYy_cy(z&IK(x_!ohrZxBGugn90 z#jEhZ8=mv6wx%uGvf9D)qx?;6`OS2pM_zRG(9>Y#b=L|MZrZIaDaC`PkF+Hh;lg;) z)yGecXiG-ZjiB+m3!NNlN@`0SDAD-3%Lz`_mK-Mr?wyfLCVk~SJ}ubei#+cF-oEm; z9{7fCEOCM3J5;-txE$86(q`1dm>3F^G_-ZX?gjiXRs{*+=TO(|BSGWhpH`11)L(Hu zg*vqHKG$5oHoKXwg05L!PZO%{_i4`I*Vqef!Mg51-KQbr7(K3ZRnTYHRT3=UuSFZO zfKEri)225ja?=nc(t4U3bOjOs$KCMujZzoRdIrSC5rm&4tiSQz;)2>q-&i4RoV;b zdKPMJq4K@-y@via({(KNF8GHK(NHpM1B7svBYp)?nMkP2a+sja=YmZoR|a${vmBZD zq=9oXIA&rNVn3!L)|;3{o}{Jb!J8Nf}Db`}C^Aw$LU8fsRpt_sp8THM9J zy7b28V)}KMI?Jv#-F`Be6sRX919P zf`-zIBlxC+KEnmJ_+((`#;rUjcP3rsI23BC&?%UKhKF^+tl?+i&5>I_8)XYdukFE) zF@K;R*G2P=>Wv+rY2#mUEh1d~rAM^!_q!GZJ)h{FV}4_gzjRB`827(!9!<^2`$RWn z`1zv^cJE3Wdr93BH=c2Ib8DBl&|F`{=PJHU8|$;#Zu4q)F5y9WOgq#}za}2mt!ZqO2h{q+enpOD{8_o|;@xOh4bPo05;=3XUjoU;{tcbhh;Ra^Q8 z6e4OAP4ODdRBW=>=%Oe4yxR13`aVG4+snJOrbksd-xMd^_B#Fa+*{tqNRHm6}TR> z^Pv>;Ni2m3Zqt^2Oz`QdUt4-auHMv^9+ayc zE1#jlf0_sCPj8KFVocf_E(H7$Ac@m88FRsSCXZ`;{M%@LrE0!vHT?jYs;%-hJ54Ht zEh=<_)Hzdl;+RgeB8c7tpanE@R=pK>VBVm=9=gBBo21FR#Sy??vQ@?b<`iG~ZtYRW zXEZ3(dgC+HlBBt5{-;k~3*59|&?hY*nwy52=9ZxsG-PeT7<+-ok=tCwf`%+azDRLt zbL^YPlgX8kcw(30YWRQ!EN#8MO`Dke!iiC~`?BiK*JiH)+ur>(`pmtNZr)v_8^c>~ zpyhrs>M$M$rsb{L%+|){tTt}c>DK?*-kWIo*XfOr5epazpRv|ww2%bgG$jB$^VZb1 z`J2{g%f3f9{pFq7^0|3f`JZ={*hK;;wqu>AW&O%LtnakoUz#T?GDK=#@W0A8o_8(d z8*gh%&Z8UDl}lVJ?7S+YeVxZg(Y<`1tLnb<8Za~FE=`zs;uv|o+QYks(Og8$4pUj} z;q}8rj(9=jh&SkG@0OF0BWN`bHv1w=ToBd$ z7<1e8G-*bjaV@~DXw^x`KNToNLPQxa`+Z)|e|E7%^oq+(cN*W%!bHq7tkLK9{HKlE z`H?pMb>;(aawCZn%UO0I;bRT`c!C+sc%LqxcfBm4i7*T1_>2EUwD1Au3VG!tA7Fvq zh(h%)z5JLKy`Ol=X!EqQJhG1w`xi_`xTn``Z0ya^lPw|R&6eJ*kkJt`HUvF8f}W0` zXA><6o082wqdPibsW!I4*0iPJJf6CSCV0}KxoU4b*m%M&VoG=jkJGRtK}+|EtcFQ4 zIbo33FOCO8ywLqNodp;$+&v5>At z@lLwf08H>>P3#~dA*1_L(HW*V3zzl;KDWBquh*>(kznH4M7>H~+7U21bWew8ug};@q!!tP zXc5jQDsGE=f#z_&3E8p09-jmpzs{n`5GLLAu}~Rqt`vd1I`z{ zG3hVw*P`!$R}JG+#%@)hu03FE)054>&a)$hpx?8drkI9eR5#C_U=aWneH)xJns9xG z`R~VG2vZQ~=H+8eD5BLMjPfKM+vBxf$W=EACqg*D11U-Lody}wda1{3SeS2Cy~T}H z>Xn!OZ4}KgTM6j6f1*o& z>F!97gb-sHD+k6ZYBCK+oy4oTx@U91SRDzwTy&F$^b%2<=+XROG-nghhi*ROYQ|0U z>80EHAgj^y1$wk#8)h#etL|yhqdBW>>eVtTIx|{O9HeQ!f-c;+aMMMZZnWdNgbK`v zPAHxky|ipbG>?|2RzN2#XW_jW(W0`Tapez#qe(ujv(Jc5bwdDr*pmOWiL13oa#;L3 zi7uw~q3Jm#;T1u&4HpeUmqE%S@$VNb{rPFpX0dnbAiw5*lPDG5K|)HmpLp>$pEhZ$ zwzQrmFkHUNix!D{s~QtT=NjDh69SkzkNJUtk5PCJ^M2DI9s>`5s>H5`Q5gvV;Vke0 z=@&eE#nzw{7${%y*K}YRt42lOoKhYLgLuAhn=GhQD>pcTgoX~hL}iFAVqaw;YA*{E zJJAk6(VB)Z;_i-Eb`mn2T}EAau;7xNAdP?|o5?JxX0cr8V?4Qt5?b&8EJ$xuX3La0 z0#ywm!21Xxs!N&+P|y(G1#y1?K?MNo(PDR-szP&b?ANN>2;f@6auw!K7T+EkjN)3& zb^=)YDT~TW|7K(QgS6|JwCzmOhPwck^h)R^S(rPBwZ~K(9mUn<;l9(ArMX+s*~IqY zRZ6a3Epq*{HeR*Yr}b)5^^;Glu5?uq`r)_G@dp;xv!odRAxI~B(_pSPJ8q!0rBWlc zZ$Cfex^o8e6g5q&%@Z86Es^+J+)LZy!ysR~bP!LZ;%`Vl?TZ- zhUt-xH`;#_I+R)^zsfHiO~A#b7T?Qn6o|EXKuWF%#KvIbWDf-ocFp0OGR6 z7c%SJp3ZvmYKrqLAaj`~gaI)_3uI887zFRiN+Oi7>XFHgRZ5b6)m*072O@CLxWiQ@ zi*a+qgrE_2Rb&nx?)q%5*R5K*E%qEUpS|I0c)=Ys=DA8T**xv7ocM$2x!W^YUTR8X zczInwp^vi}bow}eV4uy61#maFbUO99TdJ{ECMP#?8-p@|>_QWdp@|?1H?fF$g+HD1 zYz_dK=XO|~xm-1|hUj~jYhI2c{(UrTZfX$Z47Q+Gx*hytmiZ#I6^lcQ zOb+elrApaNut>3qr3V#M!YGjHGblmCz|>__g)6`&0q3|s9~ot%1=ZN88?auz4oR3+ z02jU4#-g)czQi>jGxeiWPKZ7Ox!1sYq`5_a^g(f1As0$L(cGpC>XyZaE}k$oAQ4;X zLKZ84Ve!^20x#4b$iTWG(lKmwEG-)%K}Q^>EKXx?F5e(s=)S+1y3m5ZrF0=v2qy*S zfFBAD%gB%4L$}Mjw3%JT;%2$Lt~J@*mZ{%(E4{Nx!C|YTaolID2^l>;V@tY;6VJT0 z-Y{u6TeM|^oX{0EYs){=M3V2aDRpJ5rWBdAnzXNk6`7B;C9m;~CEU;utv*X$&_pMh zB|6E|^t1PyY}@Q4outzjSuR>Z`Pv6A0Uat7#ZXsDH__8=oN0JM3n^y7z6DAM%L>ND z?Y_~hi}dnBcoc@u9=<#d!zUJBPZLPyc>}e0UIopdJt!?>iRyFGM^>ckBf=Zw!>$GN zIgjQal5NIa@*e9UcerLzxg&aAH~px0RX`&N)$R1b=2SvINJI&{iUXuaM<2+7(9@=y zhSFW=`Di^)wmz35WOV8e#IH@WC$cFZE0JbT6s5$Tu%4Ut#Drx}Oj!2Boia%%dnwC@HnAdNQ0k(TuqCnz zO35k|@1u+LKmgh6EeC&#-@@p(N4{F+|3ejU&ZIHj}Kn z!{nS(5ITq419<0bLus?gi)u${zR8P^+A{h!Xl$1S@PB|IWlQO4A5GpYm52djWW&Kx zw$d%Uw{#0#28}0_Bu8s{bXpQ-NC<_u-KLFQ!ct2AHB{rSzu1-PJ#~+yzLR*!?Wp3 zQKq4r><83vcwZtu1p@fja5K1{G~GSa=3Sbbl%U#GstCQ`N$uVlAAt^LZGA6kr+cLm zygrC-t!1*TBjUZ#O`&b9{?3xyt+8vBnPLPhRr^_$ z+LuPxg8fviS#xiqIyx|Ph??Op6wBL3m276Z3iKVk<@5$xBUEi=s)8mz;eAETjh8o} z7$yax&suHi%VKkw)bSdu1KRYB#NS%eUYk(u9`21DARH?1V(Q(eH(YHr)iaaS`^sAc z`MmvtRs0elKUUrH5!&DgdXxj(33EdyW4(s4-bm@8_aFQmTse#^XAfntvf zxl#MMQH(?p6VtUXUI$ceW>(q5kanq}<__F0^^(}OsqtfCj*=fJ%u(|Fv%y?m61$5t=WrV4csIolN8!8J~-L<&Q;TNAr#_x(W6L%dD_SnH9XA zCJ@l;dG;P=iSd8AV4X&P+jq|OxAZ|$bwyb*|q z;QV&F{`QZ%gbk2!&y5Cm4t=^T4K6NH^R1>I)^eNGxzwxsLdKgxV|55VSm;M|Xoe4# zWmMRAu8j(D)2OgJXzbR3+E0WJE#>VHdyEj5>d~1Fukn+5X2`sqIyT+kq+*1*-q@Q% z*y}C5S*aEzoBh$EMjtacU7ThYeqTIvx?T9Pe_$8h>b-+!y$#QN*^|zf2V#(iPThu| z{6)6mEnV)d)9u4w{)PA9PXjM)Bfjh(*oapQAUp8~sqct0=fKm%s8n;&lfs_$7JIIj z*(Np9cs}uE@9@z|QGANG=e~2|?P+l+A@~7lb@5zAj~EbxCK%1z$I9JP+eoAH9AfS6 ze!A8@@6*zW&BM}Upsv+lx_f4{;AGJA5u9OUDu0DnU}E8RHW#y}Ev=mutlF6VfjqUR zX*lax!@;IB@z+A;j=X;HJ=o3ywwLsRV&x+@l^!`qvzifJrxb*ZB#Lg<9$IP__^*mC z@Bvlv5s@K|YL04;{E@5q9g|;4%nd)F{*V2eVob4li~z01$Csk>Co*5=F*Jd&#esCoIU7-EC1dr6(&l8xv`Eg+6-QCGj#b?X zxw!zHi$Qat^e}PteW3qnMH-a3KxjaPiY|(W(HGa9(ie1f;i(-0?WcgnSg%$)6jWr9 z`~rbxO0$giW)@h5ru1N|n5~*Kkj*oZ9i4`3A`{sWDP+eJvWYVwJNop<=9$P2v5*}h zuuetR@VSbCX|h?|5nCN_y%o2_HlE1J+q6f2`l(3OWwLc<6REnMrRqCas-DMEHH%Yj z7OmXNO{rQ&ErjXklra6W5~e$q@C?x|Qf5kr5U(NO@#fsSADWwUdp}HV&Y5x{$-fmh z>W%Le>&8x<=C&bGZVpw_Bzq+ylcYdL1qY+((UBJ| zzR=cDQ8?`P!+uHASfL*AI!l{7>_hQ1a=k;343jrR-lp2zR8_r4H@r^39lA1dJ_B{P zEiMC)`k^Z|o4S)6`O4T)kZtjU->;ZW5K4681Od^OWV2koMO$)$YrDhcEfJM#=M}FWsmH2b>6&Gb9%F3mEp_mNuSP>f*zwYnBfVqM*lr*-MvqLA#*#3g z>jvI62s+_WQcL3W{G7=AJhZmMmiPO-U+R(RPHg^1vS}b!5xrUtWG6=+{Sv{8Om`5# z`jF4aF5MDn>B%N?_EtCMkeIP;if5rG81=cTyv7#7s6|lyif&x%z-}~ddy}ntBxkd) z{QSGN>5;M2qqoD0$XG`R_984Oc2iRIu;7;7pY>OnL>{)%IN$8K#brRbewayRx}_Td z2g(mhj`RU(V_kA&`Ii*oi!=OLK`RG{>6|SU_3OrQ?u)H9)fa2Qrhl-P?$#q0E@{@5 z{0YDR(wQ9DOdzBBFBTmiefRCU_LpWoI(+yW*noPXW!b-@+9fS3Ul>J{DfBjeV!!KZ zf79-IZ^#%LBGl>vhL#r+wRX>)XAIs39+O}Y11T?11n?j@kH~F^^ICV3P9#q>`K)W%Er`UgQ|7C-w z1JOtpaLq1lZd-{UuQmpN*L=nnln!9Z_mwuwOM!^3VRDc<0WEd=%ddC+$gLaKQ`c>2 z7_{;c!m4eCQLyDT#;<8hAmY?~EdwFTzq5nyX845y->~2>KUeT4F#KYHzubZ!{e1Ym z_uu%Q9yHzxD#p4tOEK0ox{wONh4bq#U>1u`AA~-dPd%fnt@iuTgZC1sM2cL|>DjUWU^ij(cys~vXH_2k70@5e7F90# zn-HnGv|~`#@3RP*65|>dPi5$;*!Stp?>CoW{;3FJPBJ=;-sH%)E`&Y4SBI~`cUaF@ zUAhIc!L<+O5Gr>%jO*OQzPY*)k9%4Ug0 z8rMxof8%bv!JdYACt=HYXU_vvoe^{`Ft!FGGiknlz#THKafXcA!jLh$cuK8np(nLJ zV6@T<^!?7VfRWQYBjOuhVq9IE-Q3t|k6c|`KHGKIexK1crPjUhDs3#*D-z|p0!H4} zKs0Bop1nnn1h>NOy_mt5M4tTa~v&HFqLUV+!yvb%?`8DplI;Yf5SU64_Yctwt z@@dnv*HDG6frxL7!?@a|Ds+|CPPl7dC~~O_ZeN&=>7#;&Wl*MQ?)Y?G2++KWAV;3e z(Y5h*bF!2I6>1s-t2H=e!ov*DlfY=5W}s^qm!p>(rqjIaRI}ulMx#rvH789?eio{q zHvYLOIr8JeQ8J%caCtHrtR`N}BY5Q|-LNk%LnZZt_#u_ku}U`NM7@LBFkCOujS43X zy_UCf^z1I(n1;E~oEr>VV{aD8Knn-0bl`1YBnuM{4=ljHUN?p;o{|aQ>lOe!2Fqu; ze>A~pqVhA*}@A(-gjGVG6ep@!D9x&w=|nZhTO(%8|E(#r=Fc@TYxdbBOr*<};dDe}jBT4g z&{WXKJWY(8C8m+{Mor=|#I-6(6SpR@5Mt)kW+&mQdgbFC)a>C6!`Sn>vVD{-ejzDE zlakuQ=V`LDbmhbjM2loA&#Wr3k^XH2@4IyLHfKhRIF+4L&-BB>uUTn!QqwFA4B1Yq z%+O-zPA3Zyf81DjQX_CgY}6@dt-h4AR>Jc;cF%gvCIKX{1w#Ti_L=*wext|d`PV{w zn%9;$x!!Wz;-J<4x1Ig7PW9e`Z8hb%mGauc>g7fB2&}1ID|}=p8@kuq)V;LuksUBu z!SuEvwO$QnpyZlQZA4SnV|9My82D3jU$?%(xM_K;|dR0;VTq ze#!~jZpDr4PZ_LWxXWjQ6M!Gd1TD(1^A;L9fqxF~K0>ehcQ zV|t@SOa6N}GycUmvp1bHV`&jh|7FfRY_+UXIFmTdjA$~EG8r`8l4|ng8Nr=HzKjcB z-pawCCPQ-9{!cRG;Z!UW7*ekz&2qn9{)rj!e_7S&(e%}ZfEnh<4dBQ};ZGmnO(%G2 zC4!zEsknb?h|-Nu|m*yAQ)9o7y? zhTE9)6#nT?YZY%eIUQ-O5;k-=tmkH{tPLk;<}`UM4IJ+`Ih|?Xgc}`B>$wTe+HZ2E zGh>D;>wMmBB4%7>Gkf(~Hs|jcFtg~!*3(D)Pe0W^tK^ILX9+KgA-`WD{&gew;02?J zy(XO0>qs!u8{1AIV5N**wvGg8?&O_d&qklIh$nQrs`Mk?0Ql(} zP$9SS2EhMA*VLv!-74MF8Hi484@O-ZMBZ7hoDx^jxU+ovvpejs2;Y>u@87A(LL9(Eyb6rLBW;qWky*wUOlS_wfZU~U$oDcx*BM@OE=!C@D1*wKEr z@a~b|FnC>Q=C;95T$DGf8Tvw*ch7UguM+33Y35$n4Kg$?G?`_FS<+&c;lwU!n-i}U zSYAG|DYTo2`#A5iAk2k<&TyQXeW6Qx2$6i862Pm~^wO=Ewlr=Nn%dH6dfy!lw;PKk z*iOw~ykB;UljpCSt!9NUl$GK z1KpRNcBqC0@xJp`Cr3kZ_}MPiu(pNc(?idif!-)=J$+0cRekhqn%2>nhVN!OLMBq>#&)Al!m& zg>MQ|VTvq|*D+CMpP8+6wJRWAQ{ObX%b8bZxlT=Gw(x4Tc~cpv#TA2yc*GdS(gN87 z*(G9gv&7hf@llz^>`xzKC0Pe`--A}jlW?W8XspR`z}k0a z)1Ic1HE6sSg657Dc-CGBVZ4KoHkPWuG;7z!WwIE&$i_3H(Z_deRtgQwKo-{EDHQZ5 z)?+8Ni^SEd>T?)S-ZKe4K8+da#hX%Fuj4H@wTsLEt^J6>WcMf%3R)d{V+Z}MCUyNN zuPwgv*Oh0~RuzObOZIS_<{r)$^@%clp`IV$3#FW#lrNOZJOM41_i?T{YVPA)c{H_; zV`-`>d&1)5bZ=3^;MZXFjt`A`PhR=+rFPrhm(vU|eC$fo(9n!X(!0M*pTjTt<0#wR zqiCg?;v8*@76gn%tI#jaC!#sCPR&69dy5l>1++%5>o;~bt-1FCu_zGkD+Mt;oWtp- z<~eOP(ovU(olu@FBf>lw5t_9n<#gMtaCUeFY0Yb5tv&otPSK9Vr3q$(aku;txh0&# z@B2f_d@$}N`Vk+Ec6qf)tF(s?Dht8^?cr`s$js!0HKK!Wyv^t#PN#7{}BBBsvb{17BgbVYNTu;yoX`aE6A9!79(?ZXG8 z&#&Nu_`kInDGM47`kS^qa3Nvh&0b5dH=_gwi8r~Ho;=t`xKX_aHTQd{Ra+iqmN<)= zD{LwMbDGe55TC78PwQhZg6bJSWfhOh>RTZ`_M#AK@05Z74Fbe)A6~&N>4kde?>)x< z{{#LPrSQkwsE+VgP#k7?w5Lbf6W81yN_#f{gYD^6?dW6A>gpR3Tr0Nd%|@w+Yr?&{ z1HRbu!cf(&UWg?0xJy0$kb%<0T6vi9uJ!PMJX|&KKK?$G6cn{Im_d_@beeFWe=leP z0;Vu=u;XY|PYNVM0;Se^nNr7ye>V!LMqppUB2~a7)phBl0;N*)@tOqkniT5GAd~k@ zbfVuw0~VoHt7h`^K6Zzw?hxY9{Jl}&3hHZ5E!|?4?mVURfm2Hh9Wn}{kb2G!gwDvf zL}b2>$eg`4lt$$=BCBRN7}Tkx9tfDI{wGk~r_EXChw}lG{aa^A_6pl6{CPV1`$34$ z?S#`4zFpBoDAbwJ6Mnqqm$7;_ukveI+{x*$b`2O8Z=EGLA?hheq`hF4ZRHqe1>=-Sho(0vO7?|S$k|A$7Q$Z zo>m=xM=)h=WQD&a6rJUy+r+M0^v2$7_^48mXx?HyTJRA2OML$LPjL)gb)VIA{0}k? ztKNQdJky=-0j$K;|D#-VI_MdEWkEknmdXH}f|=2&z(5u!X17!;&fL!#;KZ;xn*$Cv zKlp&xASuw(n%!wmKIv0WUYDM19nf)@e^iZUF$tX+532nE15);cUyrh}w)8hm2D$POygB8UZcD_(XMv26jAr)kJ8JxYmYsj4Y|HOeOR=^ z@Ea}S)JrmAg7k~+UeQap^}>}3!^E>+yt()5(d!Cz&&Pr6?of7jAiIwM`Jx3)c76dP z$Q(cW34@}^CW3t?f<0+NNUPezT|uKq`OJ2wcgH|}%jgqntFTb#sl8)S$QrC$&0bHD zM~Nt#88@NR^?hP)s&);dI|o_&U8PosFN)dUK}vE7ody*X4Oqde!=oYR?-47ah?la0 zGOIG8XdR=k=*ZHLISji0yQr3LcC$&fvl>?a5TVj&d%(`(9G!DHN9O`F-Hny)CgLn@jy3d|CXw&=0jQ|qrfEcU@%8Hw|CKDX8H-DJ zTilj%pt#3=y8JVi|HRFlg9b)}fN?Z*x+I(I2T-em!X6o+yeAfqNCkr-6%DLC>;y4q zgo+NkX@uB+ip>}>--uN19r&cV*}r1qh>XavvGlWd;y)A_W=4dej^<34lr0r21}|x)(T?wX8%F_mTEO_j4dhZ(@x%i-Lm05|vV4yL7|NedTK8+iLe$d|E-gpCmQ zB6a5(!o_xD<^h zkQ--4i=JHZ-@=Zc6Tc`OG|OVgUd4`E#kpbMIb+Ae=PG~5DbSq4T^Z1vDW1f0f#x*X z@RS7dnfX4L6(6x#{hH2->(0Q6)?V_~bC^9omFpu|SLrGa7`sBou3-5NE&B9;;KldM z;Ke|6h8?@ih0Kq6o6JB)E=!G&2*y>Ac~dPpLj40(3?OFt@2hCJ^Q1Gng^ zfkC4yVTl;)+6#D<2(1ay5XUnj@C)Hw!_auIvMD~x8`7F{ z3YzK~Ch?5xl^4T01m9^(|D@s>n@TvI@neaIoa1&BDgr6Oy$tdY#>yY>(vpNiin^2i(LP zUuNE*{+}caVs2LxmsB2%8LAt<0?*+>MGUh$nQizr*M#^T=-Sz5>RRh{9z@QZNvbad zLdK>wjkQVEp7jKnyyH%XA&c7dA4MhGNp5;G5O=t@O)?h>ga4b!m}rstm- z)3Iro7M&K;v1h<^YzC(1D@=z8q*F0f4jj8AtP>6aP+0WFcDinJ1dQW6)0N8+6WXH> zfAW7ZzVmhEDDa|k6cB~Y7b!87K6Vf&>^HUH5&Z)KJ!|Kr>9+#|7AkJMS+8p)6<4pr zPQHVcTXl5Q9ng^5wB_?sdTFz^Bw$y1tRz6Kcj>IIUc%n-_ah2tYiTlQbn4~Z+G9!J zK>~_tkVDKj0;38^K!$IZ4K8Yk*9t^uI%h@;Xlxdh;2B%&Jnb{06X@2|5;oqorQ5Wp zHi;RppfPj*b($O^Qk6r?SH8E8SKDC_L8@3h$!BrInS-vcg4mHSzP_U&fmN}0ZGOPA zy)?WWl$avI7zWu=y{;qZSsPTIt=UN+TV<0IfAa0ZHzc;b&54CUCpThr zk>i~}7Doz8n~BVPpZkq|aIa+^AHwmnVtTN=BvyWjF5)Ai-sF|PU?&MqY_-L7qsXP= z@uA+v;|}d%jsl=j^x$9>Lo2smVmlH7Ricfwco@qUyMIh~vezUJc#Y29-dl-{yQDn* zeEJ7j=|9(IKK0P5nD#U8P(03&*|?s^!Gabt)stP^cSPQTxyW%uTsdtzuudPmb3J_qsA^n z+;c)kUz+nu*tGzmWcLvGS>8EqO}n*a-_520uuofFn=QOOpE>=S>OjVFlc&TJXYe83D0Ldh%{3v<1kIITljZZI2o_9fel_k(roB834s zbj;VIc^^7?TG&4$T3`=)b_PkBkLG*`o)3DOL(%I$g?}=unEOb%oEDw%f_5rJ4;*?VhqQwh zdUF2};0OO&$;(8jgO}%@LOX760h(9Wsz*n<7gHB5f5^EQZm4UM2h3I)TRBwI-~$!h zCT#pD?tSxmV!H15&(5Z7+4oVF6Xu;w@z>t6q4?CZEdIzJ?I=F{EQ?=zFdN19ojkkZ z!3m7}Z_l#$Z~7SeA}WsH9-3C`RJ3_x&jl(-;R4 z{4-`d0`&T4=8E-4KCg**NS3WMM!Idq+Yi`m&IfI_tLX1e`g@lC*3;i7^mh>r;$JP2 zac<3*#_)fR!QOk1J>x(n)5y#A-5_CBn3idLK5I-pKBF~cZ1x$)(}U#jOl2Bx)|M6U zSxOz+@?m)rBv)k@GjEw`%2urJtEcCa_pDM-y?;e83G zAWdZpZ^EYq6TXNX#N;ne$Z3i%XIOYw+B0*1F(zi__B6a<;+@NKVh5tvW^n`_jpWM$ zy@ho3HjKTTt=&il)$vGB!-~1wN1mmefBY|9rrlSBoAJw4%-r}VSS(>}uIn*2@jkEe z&X0eQB^k~({#2;$13vdinT?TmE}s~N*y9eICXhc5MCruV&B%=HA!BdQ(|y|tcJoy-cNluVvzq0_@DO;5xAu#5YggRycGJ0VsyPn18vA6F{EKd$Gg?YG+*U~aoL$YhQi|%@11Ax3) zwN=5R%fqHUL1fbFEwk!SF{{EFQFX*CM+G?)DSVs)86GH;B|RU=q}T1|rGsUxu&XLi zzE_Km5Yq7ZhRJn8668lVNkSsZJ|c^5>?cA6J@lG3)|R5rG)155#plw7<8Y{o?}mS7ju!v+g8 zWBTda8=d~_ZGLT1i%fs?8FZCs)4TZmmgy}x3UOu*d#K*|B!^x2wL@Fzg^AnPNq?!z zD|-Q^*ZY?94m|6C2eitb_-yNNnt2~^?AyE}iTF3r3m2)IRJ<9vfasN4SP(eHD4!-0 zJOb13f%q_b{7yWVp3T7#O1UGc664YJZ0XHv$kp8ISkqpQmc67>z+%fZyjiQn4j;A( z;jAwa2utg;r7=I}Oi#1dpgl0HAbapc&ZTqwzF@-)8OPMHTqN$DZnYyQ?I7gh6VZq{7senn*6Pv^0HywjEgs_P zzE0JlpD!DLOtUHswn?XbpU@r(&e8anX;p|r$Dh;Bz;>Z#AI>;|mC{L!u2`rI5mCG~ z{h`G@SPY0tu;gyRQJmV+tL=P5)Wp4123y#*vHJoI*O)wV4Z4BbkoSQ?B3=sG@U)ck zK{}SJQ&@J!M*w3$oWD@#^07;sm`}hV*$4AYl6nO%XwqWk$Ub7^0{Mt1X`OOy;Ke_gWruD3aLkn%CK0m+>@QqqZ6E^ zTl`HQN%YNpUP#&Sg5}c5#&|@6?&4+VIa}%!Tg#Ry7N4Ra@ykG&36^nZzG_>zV1(7K$5p#zwmNt1Lh?O+TA+!g7i&Ax!Es7E0Frj(aY{7p)P~5a zN{y-D##HEyhaGz3iG&sn@Yx_Fhp{C;xtiD6WQ(3e&nMfEQKkeoc$U>zDk)#i=Y&2u zgK8F0#>pa{lh_9P_@JG?QVXnKZ5{5i8vWWPd2%qAg#QB^itK5KeXfH_nF+ zp-nGu{qY+?&+eeHM)!1)o^qS%zZ$M`aAy5%hn%Gq-iDtOXnN;a9IqEH9E1bx?#`A~ zIzMNlFM7Q_kZkc9Yjw}IhSy>o3gOudFOy=bpC(|gpOlL>q&PuTO^yrxEdV#Q4Ww#n zejpGs)&)K5;B;l$8?|sXN7Kz40;{0|?I1aWZcH5lglPK5f!L$@%;{ANb1?dvnjh>G z5@OG!4{0%**3^HO&_MI$FcDw&=JfUw5_j0Rz3?**f52D~2OmTQJ<{Y+RKq(9^VvIV zPP-^3w73jQyFmiTOQAaYnSVi$=zBZS7x|V0o~{|x@aXOK6;^xh810a`A^ZWiX0%lq zT5}e4Q6)}TL)i-Y0y6^*!5kOTtTgj|3_S)T*GoNkXgr;rA+I88!46nM;2QK z-oa0#LfbGpRNTC9jipZ&Yq4M{%=y&b1<&Mq?M6d4iS;>QYb!@xufFV|taBRVE!!eZKP&)+Jjj%bC z3az|vY~p>RRd#5Vo5b~>KGtZJJ7RCz)VY)hV$aER8z{`c221TFk*Ua0w%DTeuPj4{6hv2I+Fx)gI8qM1x*0ToxV>!esZ#8=SlMe5T~-R@xI8MY>dXb44Zr;>iT zkiPqLq~8jA(3*yEW}*v8qanUWvm8Wlc9SPMKV;ImsGq&WWJ}q}*(=1sqpBx9SDjNl zEuE6ibV^!b)7-~!eRcYrV&`DTrgV>{G_R4t^m&L#qxOz0zBT=k%9J5U<@c|PV-$k~ z5WVIzPa*{X5#xEg&?RWJ{atqanz>;m&S2skSj7~9pN&?zKlZRmk}-;5nCYBh<^*&< z3c@;e97l1SiMv$!Q+W*jEQ%<~ea&W>$5d)1F7%P+-lw?59PUI_9Oah45HtwPuIE>zk*#rkSP)LIIa8vAwp_94s*T3%TxO zBTEATYdei+-lbpEGtX+$X&mz|{i2R}*)ky5^Ql$(dx4rJXr|^~mgBh0OfNx$x>HW# zGIK~7Z;E#wE`qb=ZRhY0c%>)0LYSF`BT>KF7JShMCG?DPKF zu8fcOAL?TT0rr4*VG8h;w`om(7$oO%se_63;A}2fRQBJdO?)5foy&dSEe%yxvh@*O z<#|IawTZaeGRM6u2A@NHVr%&_o8#U!qg-m%_v6GNDZ$2;;hK9RJ5S)C>J73Sf}kmv z9jp|unua+7)vr}=WP?-2*+pf8q(Jy!LJp^adG$~Nt=x%L@|ohVwD2H8(^5&R)`E;PxYtP98k|vv8nnvc|4!A%UQuKBd|r{> zW&3C4p+qdqb~}|y#`kW5O@M^+GYxDZtl@^Vs?y-b7-m7(k6=xyq?Ho~g<+M_LfPhD=(mLAAv#*KX(*7FF#x6$}_waRg~p>jT5YdD+6VFV{`y@ag{Za!j*?!U_% zMnrp?J>H}cFXhy#x6!IO2jmT@1@ED4xs&Qu+j2+Nvsv{gPw~P78{ZsgTUBqPJqNUh zzOEXvSzB7fjhMJjd*m(d{XMo+(jwy5IHKHQKCSZNe;1g!ul-0&wkR7w7rXkMe z0~%oAJBZWnWp_czk2LPeAHgU|@=(}}>~P0m8;`5f>=sTiV>d!?CW$zoR-(;aAo6gf*A6tGNW}FnE!R7eZr*pXbN$q-xsu z{ePzSrMaX808lPfCf#)BT};YfL8n2p-vvEaS>v9FfcU~W%{T%b&wJ2)Z)!`Cs+lOd zPkZDIrsyAK-({i1G&;vzaF^J&hmX07H(}ajN+3@7)Ev;ryg^_$P&; zd#PP}q?IdpoxAK))m5}&NNus$?^PG&ffn~u_uQ|#=PT$IzYI+28&H*IMMCE|F>@mR zPulDx$=67)DoV|qPq?+eSf}s(Mto`KAQ#n!gBO7U)GDM7S36{u?l-dgo_l7u0MwOJ_=k=;;z=JeMQxOQ_;}HKcI9-yyW^8nKV#F0WHXhe&v2`#6@agM7fp zAz8D`{>wWg1v7fjgze(96?(-1-&-a8qP&!?X;A$OO>)X z8P6;K-#g$_CwjiD80>3nX0fYEA2$8WHL;88>4 z;C^Ztmusk%fu`P6FL`--vrgkFN1*CdgxZqq{P7P}?yHO;lFy`}|rwb!&r z?KQ1Xdri-&y(U;!BX+2Ys1erVh`qEq7C3BfC|z|}Z79XAq^kk><&E6OTd`jR*MFpb zACOPJ;-;Iul`8l9%gPXpLc3n zErTWfJ7q&93a%&kk00>n8?_-MUyj+M4KR?+o^6>-A~DUY`mv z_LU!bpj5YxuEs`?8REmS-2k3A4Su>Y{E3!Ao8QeA!sGQ;UiH!dV&p8Q2}SW9q@75z3XBfEOpKagGBYFAoP zY^M~k!s)n;Dx7ZGfN(l9e|0*398PCN)6J9I>R0}?(1uLWP@<%7gT_X^t|MfuN@cPZ z6OCuTFO|p|E`fX!8KUUSMAjTyS7ayk`h=L`Osc78O0XDWn&RxKwyLFqa~e1NjQz@f z`JGY7YRZm67dO!l8Zd#ny#ZrK0GYN|!3%?=>Tb3!Z>pc0ll25w2d-1!1Vw8PMFf#0T>l$!D9h7O|e`umMNtE$3;3 zz)kT=avwgF51Ci6T!VCTT0nW^iq#(4Zk?-|02qQNiuwOUN?GUWx5I$}?%n;8^%(h@Q99PIO?)$EWA zQMJu%zfcrFQmD*Vg+u^FZYD0JjtZmk9=r6XxFZ6Mi_>|oVU$(SPi7K~tlWIQ;PN9X2( z`}OjD+N1xX&IBwJzY<;+5iM52(P9-GEjEjz#pZG@lm#MF*py6RQ!<53{8X?O$`OE0 zwVjO>ksVcjn=s{yUnNqGDjDl)rhGB^PmnM89P{R@PIump6J92%P4(!Du9wl6#qZ6^ z;m!4mU#QLXrsvqLvy?!o?O8Ft;=s8E} z!jH|l2Di6-{{z!~kx8Y^zQ{!Ol*^I6sNmK|xy_~Pdv6$&LrNY=h&gEdx5@&>k17Jj zL2Jt$rqk`U2!_7d2|=ZV${EL4Oev;I&(UCAyKIOrcRA@svR$uhw>Hmhd?zw?Mzo-n zH_-ctp08!u)W&&NHebBrYL<)FU7$DS(5VE&{Q-gMzecN?&<=BBGTF}TD~DI3>6a5; zcs`YHCDP7Qq8Bqt0}#!maxV|}!g1X5YE>P4GrXF!NKm1*cz8SS7zh9pR(OM1aVr;r zOe2FVRU{M2MV}AE@wq^5cYZ#U!q10N{P|Ga8Bk6GqeQ_7ZxBF9#OvI$z=9%xQL^mw z5vurng!IpcGVAl9R1Ji}>~$Jgb5qSDc0=fY^$C73ALWkgi(8@M!7%%o-WVgP?8(oP zNfL8tywxm%4;E>2(Po=?Y}0jUuGiSY7bIKH7{pi0__I@wHaV3~NN9y$&dJV?!s~-X zBEEZ%U(T4$4|UPiQNDVLjj6cm=FjK&Ez>h3s?KQ251Rf7v$#|bf4;y)9IDdj3s%|r z^2NGnsFy!qmRl9_wLreoJy$|~{JE0mLARFQ#J-L2-lco9=r`0;x|~m!J$xDE1tGsF zA-`a3;c!@MyaprAU}Tnq{+xQWqJqA=>92?Wdg-r^{t_U0!wxD)3 zmq`!0CuE$!Hd1z&P3#vp-XgmeZS<|zk?83!4n&vAfh#9xM01+igQq83bnJ0=pjhO` z>G@}!c_)e7$A~*Fn|KQ*<`!lYnlV-rpImn9Eo>I9I_`s!nYiQ!i>N*`u-3nbYOL@| zrqhupt49gjz{&54BjVMG34&P_9qSNf!Y}oelgP$>P2O5*u>h-S( zM6a_WoPl^s^LLSuPu1MCLMNGk*6q+T?g|{`obO*Iu;v30CtR*R#Ahv6ZxFcina>I4 zbC^W`wVKzD?>q-EPqFlt?|%v)mVCzDHaqtvCT7)6-d`(YKw9-a09(#QOn5KwdQ>fr z<0QVqpB9HnJAd#pU0i&H)Z}9~TOUVN(JNfhQ&N%t7T%-Ff8sN-$5nN4x8~Qp9Mt^B zvGvX|G_{_8e3JJM%9u`s`jM8 zL)OFGPiCj6I@hEs=D3Rw%vMyLYnra}{XJ4qLMr;8%A{&SQ57WZWpd7Ea?WRR&b7!n z-y&y8Iyw9LWg?(<^>Jl1hgZMPdy@|L@Dk`}z ztNv2NN*tvNk7O#D)80G&8Aw;v{)AuoK74Do#LWEpW**jaU>h9y^P5>91O5NZmmAd- z0I{eRos-)}_o0_99OOgJlMxJTy8t1<+pksc!9*S~_Ikm|)hGO%d$}6OSM5_fQMtJ{ zGb04GcM`F?W81$fb|cf|HZ9kQK$FABqc`nt82snS&|R|isxBTS&FA>BaJN>efIU5QQ zi=tKLK7rATh7HxmjC!xojBc zj*_0JYK~2Skr2QM16Lp#vV%A`mFUS1UPZoE$z~6%KiPE2;?bCYrni%5|F|pYp5AyI zJJ}-}E0H%~OVDU2(`I(*hQGpZ91dzTV>FMuj7o(3{n%Ds@6xqL7aXTbVa@H~(0sqn zR$o?3_?(VxW%U(d+AT6R8+##rv$5Biql~@9Iii?BiubYJb>Nt(cfEVewCCAjq8V@4 z*yXUH&p+o4s-odua%$dXp{kCF2Py z7GqI>f1Y)h8dgSXR`O?p2AC)tA<{9q5}eeMDVrNoy$G4Q5>+Jbh)!Oy~%H4j6K?0c0+Qjfdy{+>2()VdieO zgv!kQ&rA`U|P zpiBHd#Is0^Q-q^UqCspB6SQw{u^ydH8U!Sz;9llGFd6g*z44PQ47T490FtH?-e`rL zRS054)*w(o398E&R+&%pHxn%3AeL0C_rRfus%7|P8Hz-e!pu}8dPR`{q*)||es3lZ z@|Y#=;xLEz7|yH=1;QDEsI`qnU7c?1VChyjrCaCyxQ6CH$`?Z?MJIO{L(i|=J70OU z`=N5=t_t#`@F~l>vn=H!m{LKiK1-Fu43rOD1%fX`NRYic;S=c+f@Q)IdvhNTvQ)qc z1C*ixVVe1{I`^M~N@lq4{D%C1v7h>Qoevq6V$xM}4wE?B`^(2Kpr&@xbCz@OkrKa_ z&Rnur)Gzeq^1bPL7Sxp7*tOhZs47mD<5^+p7KH_GKV`l>u;Z5ReQKb(@{9nhG1Zk` zQC9#)l%?GN5DLW<+o`@=zBgTcVol|Gg;$T+hgDV|Rxv=)qjIYmAoXUIbY%V$dpj-l z#OY@PU#`GnMMwH@uBGY(mBM57q3v3;4?&O9b)R$Gk{Kdsr@C?NjI?g-v-CxtR7e-( zE_Col#k%-c%ziuk826iW8qWs+{&fcK`~kK-V#*}z9DeT%urqf0w$Vzzd0`>f4Zl;u z%K4KX?(EvG_#no6fy@P1#=^jQWPboa!+e?xt*RWLUcHIWWuafkmFC0KeIi)i;JAMj z=D~t8FUzF)SK+8QnWjm4*c$*Yn;7phB~&vVSovDTDwOD62fSwc%2-Jd&4lA*@rLF; z+0VWU6-xbDo%U{w?Qc-J;v@%7!NozkDDg_#{yD39|Km~CKOn|y&dc@(#8&gJE;`s1 z{Cf^5d>w*p?v;F}diZeuu4y;5FMmL3U%51m#^C^S*)3A!C{M~i(UlZ_ahz@k_;REp zFp57Z$ylbG2MIVT`UlfUU32u#tnrmNzcksk~HRiNYYpx z*jY**h-_2Z%%ZuHe?%-|5nco(w}?+HqgP~!SsntHKk`lZ6hIn_=dn;8&sE8WqL6%H zum9!y*}Rp~mBkw*kdU!KQk%Iya?1I7Dw@}g^Y#9!v(V0A{=e3Rf_IO=A$#AUUw7wF z=~LwM#`jVi9(v;{ot-csx0G+zmUG}!Q*-^j1JB4CX5|~ZyM~AC0@Qz1TKyig{wq=c zJJ(SCrItS#f&7}4s|gdJN;Ty}L?iMwjWe+^<1%$CEK|?SPZz0oIcEbKy{^B!(`Rh< z8pjc;6bB%h~~q+OE0yvEMPq+NUTuh_J% zTN9|;qL;7LqT{E!iSWtkaV%Y47*Y^ZO44 z>RL+IAO&tku&(Vk?amJZ(SkOjO3>5I+v>Mv<}2J4fF4`b4M;e`VXIW>%)+Ly9L2U? zoCQ$F9GH5xD5ok+U-?4OZgr@Rd_1ZG?UNIJi zV3CF}JcOEU61us_Cb4q&1dWSte74YrjFSs|#&JY{&n5i;5#J<9CH)e=8mQaP=QCCW zjf26uo$M`C!rnrh;bdg5kET5M1>KpY+$-AB^T4Zo$HYVi;>mY%LXB-;R^;sCq}%3E z)JVEL^E$Y>M)%%B^*;7DQ>w2dFA|ihL?H3 zy;n|+^`;KE_oj|5HuG(#A8^k(tb0`+cPR&m#L(HwRd&u#L;Fots@oWs9I*8$J_>L8SW=VYL+1HM9@ zkNnZPd2nDto(&AR+s>3Pn@`?egAv)(X5)0(clV1E1UotHQd*XkEgQ%B!ja?6eq>>g zWZ7FJCG<05Jk6QRb5||mBU;!XvlPL$EZ5ZFEbE*p?B=lm2?fl|Hml-w=v9avMU&xE zF-5XvU(8IV61CuoIG6&xZWT>dfZVUUVzbpT-h<6ksF5lAo8np19GgNHrOmV$Pmkn0 zsYps~{gSkmI0a&7n6rczs}wG8#qS16g;Ft!lrUl_<0^~a0`#ss6MANGSuxxen)qq4 zWP!Wi%=BE=f4b9&TR8tiAc@g=4BilrUZrv|VoEfYo0(85IaLZzS#FjnF}b;Erb8~< z1)S0aauqN8hD?&aNTE5=vhDKu6Q=F*XD3oVBj(gPAm5_>DdbzU*)#Gjny#r>UuJtN zX?;;%sDaZRrGsbQaIGArbMG*9l+J=-vd(bScSIeOjMXGG%se?q~lcZd~)vKP8d+uuJBB4dey0%@&L91s0Y#v&zAyF*UDNI5bVsUhhz?zVmo zVNSKo%pZBCRmySNRceSMvt?-jWtkds#%0QJ+GT2pwM^|bPlRZbb!sk61756Ca&!*& zZphfA*OA<@ntGA?66b{l;49kUqoqpuuX@w`S9isyi~p(>Frkjp7@xkdr$4!V4S6FU_rV$ZW`%>Z%fzr=}a&ow8mOCyw1aaIPQ(vBu^3^S4($g_BT2MxEyc;1XRWqYS#euqZ1ng8nPmShCu!Sa_T_2{K;B+r^PBRaL%(if*|&Z&dEuiKSwd#PIz z0cev>LU8hyuOiWnT|kF_Z$%;EP#1H8QIYOebNv5em0ol>OXT70JbnTaFoig{YpTbz|T^qJxL>~RX^U%Vjn_`+o{xM zj2w{%;l_(f<~dc=KUmp`!#fV5NsWo5*2GdPwIxkbUCrU)i$As60wHuOw}tDx3!;*(%mf_3bgH`z4D*=tbb)b?za_I!G}_VCdUc%L&EnClU8RN0khx&yKVMOCYAr<&-V~JBffKtu7B5!ykVX ziJHt#oTT$%73jA?JPLS%DH1~*&qx?VHcoo{3!C_?yVy*S-q)#jN~C;zA;|T8?)*Vk z6**iGlB#lwc3YhAf7p8$_^8S=e|#nxV8Dbk(Ga3V8@sU$3@UAC7d!fC24-{yXE0Te z#D+^Zl)4sOeio2Y#7nrv!$G>$)@^NTyY1Frx3+d`x7gd}LM{-Ja8I}h0TdHQZHyI% zi_Gu&KF|A}xg>bmvj6S=x1W!O4b*Y6{afDWazRSwZoqd2bbXWb%KF3tND z1dTXL6SupUcCKG$6jK>77qGuwMFS1f%V`ui;M5~i>fyMUag30LJVv{Ch>xiuUWxJ{ zy#x@q=F+n)nc?oi_^R($yxC%F0z&_uaqbqq#V;>49$huNCA(RLM z30gCbPj7iD1d zT&<}r@z0ZpF@#C@_8J?0=&x|W_9fBx$XK2mIB`c6Vq$pT=GE}`Szd*VK5wewt8gsjiGIlok|3LnJR z3`L6A$N$w)mSJ=bHjK+s0!&uc&?zLOX=B|nExzn` z3eKYMXwZlp4fD%QyJi-yODYER1+}(+!*rWF<~`==wU%XQ-bp3N|j#tpc6EP7(<5oKEHLfN|s2 z)OY)>>42Sb8znvdj8{hk)^vDqhUn#v%?sIMK+ai8a3a5w7QsC zpEwQ#22nh~%nL19=s_84zal;E0$D=}6YcRH0$xGPur;dIb1y~T+%5W@&S3_tDHD29F;#!y4Esy0oDxTOP%v)0a& z5SDqwU|zjq9pe|WdyLZtE$kOjoMq`A{ym|R&O(&-d%wdn`0N*1!d6KR9ut9FLldeb z1_#*>N6ujQ@i@e9@RJ9w8S98t$HUdz*@?19%y%Vh)SIMTEa1_Eh*BtEe5VWxR0*o& zW7bW*5wl~u<%);ReZnb+MCLK~N4-aa#3NrnAju*T>&U=yxL-mN)9JR8cQ(`i9m*-N z;uQU{uMgYP4~DvQK)~wgw&RFQmxJTr0Om!vokU6sejk4Em!wonnRgOH2;{QxdLUI=_~@B zp$~+QNiUOky(aG!11h^L2n+nfBIXwy&?a*ZiPOj-@ty<(bBcBZIxq{ry+Xg07ipBV zWVNaJ5nhqFR#p@r6JmT?u<;gfat&IQLDSmK<7bTg+^83N;};Qo4L37ZEm?u$#3ty2 zf2AablQ8uU7>~SzEwbiqlmVR8Mp+P59k4%Dbs}E`pi-{xn*bX)hi*Qje2_dVJD}05 z1fDuL|3D{wGj~5|$WfbX69Nr&&vz7Ke-KR`FdktI+L{5DBi9IvZ>;&IG(59|J*+!r z3ide^PNAr$q*LuZeRo0G3tjv5_yoNy*$Sd^hol^mEM%B^dMKdSIyBwdX5Sqe|3x)b^3aOHykj!7jj=qYNsM)Rood@AF@^mZf_EXy8 zZnVc^Q)DgGaQYG!#@Ngr7sy0Qn!|-6ao|3T+nGD0Th^t%K85d8DV-k}) z_oyOOkFgd^pV~<5UAyKLr`kx5h!JHR!T`o~s%@0}gO9PZ#^eszS32P(j}1gcwxn;J zE%G%spt%E%)yMtMGaF}2+X=_-GiF23m{$LGcfd#U@(rf|mDMvx>sLug9%N72YybEg z^>8Qg7Hb3)>)Jp0&3gaysikjK9AKoQhyCmQBH;qKPx^wL6Ex->Lh}cVwI6Xhv|rww zIw@#4*|&Wja&7=CE1{JFbDE^U>%4yEy+ePUHrC?C#_`Y!NH}=!unW&o41_4#z-24@ zP*;<&_Lp22Oz7wpJ@|oo;1{>5Wfh^^p5L_&x=_zZFM-F;4- zAy}mOojA2SbOEvLV3KkjA5A$s9DH^F(uL0sEEqUf+Q-MG=lJ-@ZM$l$qc8s)3{gN6 zD)%S0Os#eOqdun@wpN`}o&|^1QA&L%~>Ou+r@oo<^7qHM#|StS#W9^hC<&)N?xS?9t(%lXFhLSM$)XiQ6u?U}*MO za&!VxmgpZeI(hLc@QiAy=m z(4>7Ksi!!u3S&Q#ufX336(;H$Ro1;(EUWggrr>B4Dioj+U83#5cp)+{YnV0< zha9@s*zoh=kUu2@E^MjjF6&7)3|AK6n&F}WD{?Bq^xokjHkLS5K8()~7mIM2ScGq- zKYMRa$0(8{1Fx*QUZ>biT7;*hS%g(jOzBB_$0O$DFE58k+62j&9iM8SQ^^8;$3Rnl zZ;hQ+Psx=!EAaT4#fxoZqWMbtTp$=lSKV2}7)6VU%Q&}Qb$_@T0xstp9*+#XzPAi( zILp9aS9yNoQS(s9%6TJfo&`d(36GVq_guu=7GdwChWt?ACvgGv1u)i+()ElBVQ zjAgXqR@L9*{X!DNJD=?y1+i~od|r9P z-1(gCV&H*ubX87)thI`rpg`X}T8z+%@Aol#cAGrz=$pYlLU0iZJnm5Rqe0<5{5zhN z1!Hkry%@V09pUL(Ak(#=02ksZWlxw`c>@$;ROyBiemtKN`6$17- z0xcYhMWqGYhc0;4H=K$V3ZOh2mGZ~3PbzkDz8c5Hw(+$f*@DK*N0+PeNARK+%>0`z z7rgQFQM1B?=lSA_|hqTBOW}JG^nK945|K8wUJ`?ZL>Hx zby36=V^7%Z3spBD>kQ{)AFZtlMgF;SBD?S}riFlsi0%(tS@pLK?7db7jk;V@9}ynl*%w}-ul!ilIhb6RS0{3KjIAPGu zk`AiY&DFY-r9HP;Tz6!+$C~cKN1kv^lWWk29{$jS4>>b|-^eQ~4Ao35cA7gS8wKo9 zaIh<6t5ei>`hnZR-d97_+rr+nwD!+NL60tW;q&B_1gxpf%+c@_3N_*+?jPc;+c=97 za#!tOGe#r(>BIQs0d69aY!#~fTA1$&d!SF}(W4Fp z4%}j!;=b+R+!(%yc`)KV60V75hwEcm;Y1^~|2@eshVTfw{-J%jH=B40-1#OzDazs; ztTc5;>Z_iB<%d0v4#mEJF|{G}U9a_7nB&UaR9)tG-Sk~HKB%cz_PCgHX-&kp`+*58 z#O-wq>H~2&Q|ln^Gz82#D!FPOEp?Y#CQK(##-l0IZdeUUKQ)^O)1E?@U3~sqdPS^f{3ET_b%5`fM9S zpYePt?ithtkf&aerxoPsN+nH%PNG7;S?_I5G-cO^Yg*_4f!IjvvW~ME3O8EESQP+# znB+I>sBm+3J&J(R_G>zWhQs{n_YD{u?|DbASL`g3FBfwnH=IS2Z~#rgxmN}=XegvE zv*hM8bBZ(epP)s268X%`W}5fD3Fp|Aslj;I$AAzWG}^vN33Z>Qe5ubg{kMHSN%q84 zdp+_e(sdd}SkjKP{E74UF8w*~(t2aVk5&4_a?ajft4;L}au`|w*JvF{lWBPp7i1|9 z22RZ4YcrzzgQZ)2-K##r#$V;0Kvf1*HpGA;05u(|-W@T!L%toxqi5y1y=v3NxNaNl zMY^8vTF}yRDL=DjT=blBvnXN}@9l+@<2?bpeql7bhwt$j*7YRZ0PS_p;wXGoZ^rL2>*aYU1RdT7C7k5eAD$Y2DEa(&(jJQyu(%!5Byt3DG&S` zM~U5^5y@+R$h)3z-@h59uI|f5Nt9;4LtW}4M+s-lE=MR4A1N2LNAxXy^k?sl=^ps# zH9YV?jibVmrf+d)c;E{*y7VNq-?+cQVh62?1oSLV^Y@?p!WRo!-GcMSZ^jWtz@GDF zT-)#i-anvu?;qG{AkoP-dSiBiBf#eS%_AKCRn97zGFv4xiTy~Aj8`U0zmj5 zw7-1|Z{ZHi$~SCx`<8HZr+7F=%)R2_95vgM39GD}4tBR+H-wAx?h6_YhQxmF+r=4h zu@yUPwCDi9YmYiEOhgzuk}@v0(jBFZ%boOe9;yAM!@A_VRwr)D?(;f0r-DW6Sg^F< zD{*k%C1=G#?ciMN(9?=oFu*W3rNTsSAucb)zgh6KCC&BjnBT^UX5{RAXY5+^P5hEZ z4rsJ!=Rit!1ZQTiBr_w615bvkCFOCbnhvrf;CQUNvuuusm*I9S!;L!sUBui?Cs!Pf z^=3Qr--XRRG=j|hcQdSU-`vD14}UWM9S`9`CBWn9g3{v#TZ$W$0FM($R#n)`utzOJ z#Jp7;?K|Q~$$=*^c3C>c4y({PptHH9#n@#H?uI=k$%a^!N{LFO>W-&W=i%x+Db;zjK&jvB>O6LJsX>X71@E|MHt#}SZY)Ar|721n{oUS- z(mh^YrjHJKg>AL{=@4B?_&9RUj>47yEwQ|mJVB)Lpv5rzn__Nc^afzH`7kUTp ziEwpG>8^-*L(At2>Ce}rR(`YJd{k7`(-KrwH?LGzbHG~mB($gNQheB3j7K_H&Dbg$ zIUpU3gH;Yrzz5k)z;9H3PZGU)CPJG%Ns^K^D+79?7|_3{RI}^S!ymi2@|}ESKYCW$ zSOHUP3Ff*2dhmmNzfsFhK%&_TdR$TLVbRGE{RHFzv3~MiS%pfp=`FvA&BV8=Fh#d0 z=H_;@4swdv5=-2+iLXeOWv*`J5Jzd& z{72HIy_NN9LNpcD$rX6!yBPw*_B#OCy6>HAlx$;i&O=xy+tim8NjN7^yV*ZvnL$5a ze;#^TzcH;NmQ}hn(OjGJO*P38YpPS5-$b!Ef!QTmWf#jF(jr|U);A&FG%mwLW}RSu z>~q@q<`FVu&p>(5e@iSL8z6Gortzy;aOjeCDzf(f&4;v4) z?GUb{I@taxhgj9Xa@9`KY+FdFgV?Wp#!0OP4V+A>L2ZUj%V&QH{^c9O|7HH=Ww+hV z!si>J%XRbU=86_~kyEs|3)q^uq_~6!7S;~4WlojzhdJ&~I7QW4M8|q5UG%N2sZFp{ znDo8=wL?V4!W4ZIE3CpS{^ir&8#f8>AQgr=Ed)Kfep1-1XA}cl__MCpvR_T6K19}~ z>pG&Czh5(+usvNwmjGixoWFY>^P6BPVL-fy9@tq(;BR^oGR1=AY~N=LY_{ ziGM!EKcC>APx8;F_~#G#C+~+%Kjoj#^3Uh^=Vt!-JN{Y6Kew=u(-^AWT03+7qEZpy zsDCT7@zfmlPj`?kQ@zy;tY4IZA4Brr9gzR(&M*JXW@CFVi+`tvjKAhoI`dTg^&hqL zcS1>jJxcns(L5SQDYN@;l=LUoc9Q=7uaf>sv>W&nqtdMHwW9{dUprFcuiwquu6kms zo+P`iT>|`O9b`W?X`0;#zi#CZuAW<2X!{GKn%k9?-S1rk@+og{vAK)AJ!xi-RCkMw zJ!-xguI@)7da<^%MR~7dtRvz(Y*_a*=iO{)p5DjZvJkHqvTlk;%zbw1=_KpTsi$oh zWR-ea+2b|)=2YxkS8VDaes|Ib;CID{217Yj{h6diq|7axw}t05lgABkn1Zs( z3I|g1@(2&EGLJ809{jMRpiZ0Ky*#~O#5V8lF#6eHGsvKDQ4nhsfu$^jm0k?nWyu@*@T{Q7_0 zDjayPRVWiuZm+_AwF+5id!z5=3%v>lF7PURGo^QhvaHg2SD0LkjzZnLLcRVnCYsma zfULng^%~sd$e7mmUW4O2N?tk=yD=%oxK(ImDY`eoUVR?*Qs=Gm*g}jWZG-SCe3Mt< zHz5x)ScY{=oK*xM=bCPq+nZd0EA#5n0O`Q4ni34@}}8EbH3 zqBj$-gbmJETcpI=-`9y)o4_DXuefz-ISmpA6%BHjQL;N0!q{@u*o>;Zk_EU}9$-X* z+=DJ6^Amh$s@gNg1;?2#Rj&?Ic#}u=CoE~J)v0~5NyM3pz?mjSIluRQ=~ea8&#$Rl zVxT7?w4o<2sAvY{=0d~l;N5=jbcu@&qMfUxuuXUBB6}|j?t9fs)X<^W@7Mzy-9-4t z5q$R}ru;vb)+L&zGWL(A2n(Z^vU~@hv`e*k2Y=9)V=K|Y%Txy;r14@HcO^@9SH|X` zY6zn_Y>RMRr=&H{rK+$*KaW%&=_HvrA1}3Kx=U@D?#gt}YPB{8RA%6q>TN#v7Aa$^ zI4v8ta~E&vuiCxM=iZK+qSoa!)>2fVx3{GBRw-%=ZIz>5#uC(BI5^6AiqxftlAh|y zFR8A=DTqZlwgSE*#>T1?_Z$*IFPwLdcEW_8p7zq|R#GZ>!`c$fUb1xhGdt?}hbd9d znxRa}2b;4UY4${tRi|)n(tx=?6}NE;OLRZO4eQ%&Z1|Cq)+Vt?x1QPKt;XsH@VI7W z@qA*1zswJJ8LRJdicI~WX0I#hL2nH+$-q(U4)_j;MR74in@O5I4iqo9d1G{dW!LY3=*yU!geD?;|;oF-{LHCk1-bP zM*11{EL(?;|3;yTb@kl`Qz+`z^7<58Sf8Tixa>A%FOHh~No3D78H?aPTDe~h&$2ZV zG>^U7sp^O`)nvTWnQAg_R12d#O^mmc!_|#%7Nm*uCCUO^rp5U*3ouN&Z2GnBz9i1m zzmp5Kgipn1Sa>zDkZrxLViNQtrmOh8!oJKY-)_ij2k+8~oE*U+#(|s{mLM%da1utx z2P9&2CTzM0Tddqog~SNuVzvi~^SB6CsH+(%wTPu@wA-%5omxwZnRbCT)1J>lTL%3> zNc0CJUPZmYUTmgyygN;Wpfudvnp=fT+I_N>3cGBRY)F&}cd|Z6twLG_X&x{5!_hUNUyln2W{neEksGQY6UlWArYrA(u(uhDwIrnVL6O?)i>I@4ZZ785#gdw#e~Fma z7l%YUv_z)32va;IT;0ejqDG}6;`t3^AJF1Ph0+m8BleW`FkS};=?=)zQpT{TG7ONac zZ41$3Z=+I~7#|+2FR?K=*#sumu0i%eS~*$oV(c17u~NPdITZknJvJa1tdz%WDV1*5 zEP?TI3~67K_Zj9zj`>bQJw2{#gS^SFJ!uwLj|i&>BG(q~kS;iAXvw+?rAT2~T}nbl zT`2;p6wI^<7D)s;<$t-#N6g z(vdcQnFezSjpu{l+iahVyh^K&dczjVYw3@uc%upqG zq&M}eDmY`)@Q7B$Zs8XP{z!UV`3@`!Exy-5RlDM?s68s2E>tX-kUIQ zu9&@a7ReJ!MCchcpb@if@-?aa+EgK|PS+L2N+tO)du|o7Tr~&gK=|aTA}kE%5P=bk zy+?_-sC$rQ@$m!r#BG1?k?ddne(;WNyB+qq`DmJR27`^+X1Lua_j5x+%~vC-Bv?aTdRrxJL+3t_MgHw?PkiwJ*TzY*y#ea-KC zW7S7(?`;<0*q~A(_J9XdI)IH^ZrzqJ8*mYo89#5da^_$-#?QC${Zq6sVBFJ&1aDg- z)%zA2_w;Z6*Pr}kg7Nb<#AUsWbfuqs;pGAcRZw!SzW2k~;6u+*IpW=R@+R^l0NtpH zM}0euM}O&%7{v7sL8slsxBY3L9eU$@2TqdwHN6FnaQ(~K5pN=z9S?hVg{-@r5%Vq4 z?=$rMF0*mX!6kn~49#a~VKCe4PPD=iS2^J#Lwq+abR@Xj=NE+v^c+yCwDkUJVgZgu zV8iE)Kw64$&FjvkKjI}cNn33pAFo$8{!_Bph$L8GWmsV4V#PflaW!isf8?h8k-`7` zMc8wn@cx(Ca|JJdrhgUZovCSxcY@~b#u_%hF#?`X4ge(r5lKGAmN}{1uc+7 zX*T%1O#yRaaiR|43N!(e4+nkw467zf)Cq>)Y|m~F0%xa%{qbLR4D!eS7l-)cTQ?PE zI^?_9AwR|bT(063b^^Q$9`?K0AHQ7U6>i*>`f5*rgahyh9Iuf6Zm;;`mrJ}t`n%oq zT{b>Q^T&tYC*o^-U_9&Ang?~Go~mhpPkvp%+(89bb?Mm)(y3^zQ}GES6hS&PK~4-N z$oJokAnEZ_phq{~q|^~aWE`;R0nD_WsjrTy_ynRyFAZ;7>bqBx^ytp~?tsK6+?W}k zkV1=$E`S#GiWaR*3#Oi;$4#~QMgBx{ur{X{2y0th$q)tKE5^oOt6LFEIzTtyd^1w) z!ZGDZRTnAG0nT@^I3Tyf;Dt}UdBb@4s~lvo7m=NdCCH%Jcz78H8MGTE&3#`=2{KS0 z>V2>Nl=IEpsW$Eyk_1Qi3LU@Uz^Mmum}NI4Z&MGw?)`LO@{PJ#B_AUI+XSv{2dADK zmRqC}G18c`Ma-Lmcq#K}$lOpIaVu633yUOU29bH!wsJ|-iUX6_p`XJ~)l zp2gLL&216$Sk$`R9Wl?5d>r<^9`&A!TKNr8?+I(#+4|nBM4h=KM3Y-)xmf!W$nN!a zm!8!2E{JFo;vti>-%XE)vg?Qkt%!_;25#X@r{;d!`rNu66<>mpVqRIU}HNTh=;(U`G2WHz9woUv$AH3r*@ zYA`4NKi5`df}8HbEFKOW2@M?H8}fC9j2Q#exQxzi%xDE#v#%?N)TGS;W5)iWyAfd} zae6TpWqJRsIcRKrL3?`2^Vx{6U42ur}L5BGD*QIRS$IBsFiw+P4_*s$yr~ zALZKR*?g8~^BFafm_jBM)n0Nw63Orx+pr{|mp-h5ICuH@XVV}~WSzxXCvi^R3k%0f zl5366S{|sK(zn}=*KgDD`h8nZDFmCOJ~xHmHxD4%xj&uZ7k%zQWBoRSA|Eg|H0V&} zpS%aZ|A^-IAIjwS7b|{WM>fy*?S2nlU+HQWDPDgG@%q2Dd41yXp|C9pnr+PJBbf*! z*3$tm=fd)Yt6N|%lpaK^e6S9*xb}ps#m;E_fy_a4FzPs;-P&~sL6fh45yxn3DB7VN>>OzO& zjE80KDR78ch#BSly#;i6x24#JKE0P&XV1h|qvV~yb?ZS@W6e^S-Im|!6qriDFwEX% z?q-(yTe$yg>O7il4qG{`0kclA&E6e>?Cyoo*MGiWp%AgZ0PsY1#9U$q_WZrzcvfv0 z;@y?+@|pWQpTV3NhB$=p_(5SzN3g^doHccc#uJ zpE$eGWBP6jo{PdbFF-Hva5B9j)y-jFt6|-YKS>6btft0>7^@M9ez$u#V@y7B>bL^d zZ3$(34_f1DklmCwz%IP!6`2A9fRf! zM3+jbs+FxoS>h8P_$pQDH+P~|)CT?+w!sc6PM0B9DOGnECGpHUlLJbb>l~TuVQ?GF zVa5C0E%vnTb?nPk$hH!Hg8CAui8ir6 zK~|ynrh46QekQ0D| zGhvPa3O|m5LLJ2M?<2&oV3GuJ{Fwgiot6sVFY*8IFYw_CE=mjHC~*#*MDN+menTh4 zxQOCnfLjX&md$)Zeezo$gNwm);`GPC7fL^fOJuR%yLOXP#dOT)2##_aHL;AHjz7^^ z09S-?_1UobCdYM5;((4KHd5b{;e^o2P6!(}4B>>JeC4}T$aJO?!XOWXJr}@N9>}Ew zAHW5H4o>!z-|lDBiHbKQIo<_wl;_@DI6wJ=0~gRuez)>MP+s!)XfFiIVNa-dAt*2T zmMBup4faAvjnvq4K_WGF>r}21GOYtKLkZ+;@Lc_yHaNw1GFs(#+n^!c5it)!^~mNs z%k^gIYmoN~*#qn~k_jT-!$I>bE^%y3YnGGlhjTj2I%0N)fL+-U^1cagzgpFr$$rP< zE*iLzNPTIX7=boij-2kEn)bsZV$OD$wd>f=+*o_1I2{~kK9(IliLN=~!tnQQ+Y@x< zMNk?1Q9MD7H8D}%ylkvJD!-jE)^^EnFBogv9qjQA9mKo_@mohoHSRUu$J#l+aYg0Q z*?x2F24`lLuRXCFC1V+O6-OK9j}(`ME9H^O?WH^rssODZ@Q<-vOa@#Qlvn;AHrOr; z?L1Qe@2&jC6FkJKKc*-7+Cu-o3bsVySMD&@P2_vOjY){GXa#p(Z>+s)5b20A9!1dTZj3h}&oXp-H&bY>dKkUJcZ3EN}SY?9@S z5~9#aL?pXH9$}dK9S>9uVLdbM({v*YRD z>+ICgU-5s$$M-Mk`jO<2?k}&Ata5l2bqcnn!WLY%a*|>%}8t^D(m9 zs227$<%m={XsIeGt^7A~E>hoV$9(MM;dZ>saCXecejZ^v<^yNo_&|DQ-cX|HH=>b5 zdfwkj7TAp&mBTx3!GHqFVPE$m_I01czV2o0>n>dRd}h`cvo;I&8?;&C@cx_<(VkOI zAaX@&4?txAw&&7lb8#62SIBh>{BW|`T=DI(dqyLT#8 zZuZhfxE}990XWD|*??7@(ACiG#UJ?LpN4!@=63vD)O%vJ(}8c7d?IXiCdT{&b;WE_ z>7Re9z)aNy=+$IT6;1TDR}|7(ZG=NqameJbMt}EIMgQbTvgP>CV|W2jgb9Y`SNeaQMY&5 zMbIG;*FC!~c9C%1s1}@e-f-`^B`aAKV#neA>7 zXzB$sxgw{N1Ol`}^>*sEqP4?gd8utNEFSJ`IFS50>58RYu86eaG{YdUp2QgUC9M5; z?3~_r-#n-HT?%z`caB56Hm>pW#B1Nq`LbIbDqnX0;COB3lB?!Qy!I*`uf0^oYYXG7 zM0)ImTSuuK79J(6w?nh~Q&haRTeJEfQ}NnG!s-_e5wDF6X2)xL(pde%3|7A`Rk@Jt zHg-SGK>_O$pEgG4()eCiKl338*v1l7$+Gzj94}!q#_WWhFZ=gs)XzDx10)A<8f*r> zCrO~(2JB)P;PPu43k0xh5&*lP0_P;zE7Fr>cRSCQBs&GQtCJb9W-wS9wQDW>j|b<; zK6pX%WFOIxB=0Xzb{cfoL4oeNFnO{wu(tmE?8Gv%3z#SSh=%XloslQ|5r;j&8o#TB zCNct)M8@w5y*GZBLNy!`zbg&CYwCO9cSWiNMd2tDus)HR%n#Ye_Ef(m5FrOHMRWVxOE!e|6SLo0L#%TJm2~pIpq3u zr?1cB9}HSfV|witOs}Jk3kEHB?7~9J9lP+*a>tUnvyo8KGI?!UGR1)PYG+l$7MA2> zUJnMGu=6WD!#Jmki&)2k+AALN5?$EClQ=fO`SXuu)ge!!1PW$B#lH&@XpKt z>`XkbUFX5``i{c$nhZRzBEHVkfTbe<2-i^+OEJTJd*p9+L8;y~Rgv4`~* z$iVX|8jR;PWngGLuhW@$UVdMP!t*K;Jg+I|!}BT{3eRiG(0E?I&$mS~Q8w&kq7{j# zxrp(+Ldr-14(EW4=LK*3Kj}1I9q8RuYOUkJ@%)MH~+AophnY)r2V zQp*P#9BV?7?D+d)dreQUYv*HP3^@}z)zGtK7iX2@95!Sg)e|E_FY4Ii` z)_v&J#jK7UcJky{af@6dKt7CVz@Cu5hk_QaU%%SHitYR9|6mVs&qc{Jw%>7Mxf<&? z(Z2}FUhh`o*6Ta4YK*^SxG=yfn{8hKRPnV}1k5u5?J3mX9-1001wTzsVIrUP26VUcMRRY=``Q>-TJNTE9Q`j`fkB983 z63yhuy$6oPuE|^~vie+wD3Kkx1*xbk4>i(E5E zA(iJXDxQxfKyi|$i;dYQ>ESb*%$4v`#!$4~Q<#Zoa&H7uxSo@QAGcHO%}wB<+QmuI=;a{Rg( zKORKYM^L(sdzg3kd@d2i>-elwj@1$kyHuBc+ z*^n14qF%S~e@FKb9bK+@BQ(bZO70>Z%-%r~D`s}Ke#hidD=wL?^o*}kkRF3)GFZnYj;GBLq zr1>%RCtHXotCHI@@B%)Gyg=72W|S9PfR>1|0?x#0@h~-chJ)Q`6rUBT53pe0k$g+o zMpRXiUCm-$%}V;!sES}wQ1|XMN|2im-gs|CeElmgp{JknC$@xYn$elDi1Oh!rueNg zSdivC7_x45vO`_otOsQf)Orv;FlXRQTS>$S*0Ii;Ixr;!^-cw}A(eZ0m2++7(qrld z*4NAz$|V}#6I@SxA393nNEWQ!#mhrRa6im1SYfoslfGoL)c1PlSwB(Pz;o zJC1B7@6kEWY68}20)}h?mZTD}l?jMld%rB6DX59&vGN7{f>2{*kX=ICoBliiRklhW zi@DyxA)J)~S(dOyPxI9s#6$by z)mL$eT+Vod>l-g{owG6?Mmk*ku^dUtGfY?})8g3u((S#)w@X~YvsuhZf&W2V0#t?> zcoOg&TOO(&V9&7~0z;EytJ_s1<|kZWUEee|jORld?x2X?80AV)pbzpxeKk9&nP$%b zB-OE|C7@HpBDdja4zHT1lZceQCT0ib6-%J=dqSz(sZG@(_>Gn75B%OY!)AM+w$QrW zsXvTVH^7ao))TI73|sjPy*u9=cK5Ipt;p#JV^ZIwjgXVS)2!*FW?P?XJ*A?+446E0nO#Mo^@)Kq)-;P>SJyGx5 z0V|pvu6f;ci{*-k>tD~JXvYYwBJ6jMrHiz)>o| zcl7h=Gy%mpgy2p$zmMxze)`le-&Q(O%5y20lW;}!b0Fu2fT;j0Aq#|jUH6YSTf7Z{ zY}RE@+=X02iFzHN>e>}TdZ~(jD!B4+xOyw{-1|C=NB1%h-wf{}?P3~HetKmgYcedd zj~c{xr&!~^z6=coOb8Dem)1PfFB00x4h~7IJJ-^&$Ebg z<-MBx09m`{#l>LDP+@Q31F(Rc!LE3S`ahgfnhvtOQCz#5Yj^9~b=7XV3yLzUcf+Mg zv^Liy_zWR}aUgBjxAlSl6RK`X0OahR9wOdu*hoTFeiKu-dP_KaZ`5)%ATv*Wb}zec zL6`+w-UN5~k_M*BHgq7w4rHFfu(%B?kIJhc zSfpXUQGfK}kD&U)!56KEf0ps}UBSOE1{(oxB)S=>Of7+8_b5<>et`(@pnr?>16)FQ z09y_I4Q0!}5mm5U7o6_`IRI8fe=Hw{KY|ao1UEq*Z3#Zc)dZj5T7plH;D3I~bp)T4 zhjniLXNx>+9mfB3kK}(2$-^Fb*e@UaNgl?BvCikBRii{Fz~{=E4+(*fISXlNx{BGF z=rQsh#H4|HAptLMy;AEDUr29ycohej#aZ94-;~jtxcUYR(|UzcPqd^r9;bW*p=W)O zezTa~z~YW?z{;*y8S10!=|vfT5(GcGzFa+jik?^S2SJEp>+e+0H`DXQQXW#&`UlnX z9rS#?l!t(~{t5NGm!3Z*<@@pcS@oR6rUy6k?|JK?x`>SrRoBx23AgAv2T{o5+K!%Y zCkm}@Z52swL#r%e;%7Wy5)#pDFb5c=W($D->`3PSneSBgM7{3Co_M>B|NO>~_C&_L zo2%@J9onAQG$j7>Nn`a7Mky2fKPmHJkv1Q$SAftZPGxbtFCG8+&I^zKJa=w7{`2pK z!hcSTWs4{{8x1sS<3RhpYdH6h_dD~QDM^?~gx@L<(W!vYup0`X5y{q3^Gvup4q0EI zq1kt9+rJbzU~*xvvsD>xh5Nae7SaoZI1`I@D~y`k;Z_(z7LR6eD^&V^8`}t-a_D?4 zRh*BdLK3FmoZ^cYXJ5Q{iZ7m+Z=7-az4pb6+rD_o^sxH{V)Ff_WNFsG&>iTA07GlA zqd&{xac3qXw0l5uvi$7_&&iS;*M;+0+@FC6y&wba2s2DmdpHVAjC?xB%*9YY}Ty3;zw2Ar56@oGG1>e}O3D#%DJ#uMz4lr$?=iCJ-f2u_iE zs2KGeW<}UYGt7$cMi1~Rr(cG!DIShRhq8H3`A^uq?b&+|qhgBDyIC6*?NxcS4;TxB zjou&sAVzO{U8a};-8wyb>{CNq72O$D#gXoJt1rdqJ>@@P^i~T%EQ`m5N1e+tPczkl z^bJ{_m}*&`+rt3nXi6S8-ZO#hu7GILGc1gU#Sa$7?{SQ!HqH_IM5cw2-=!NE{b^Xy z_6j}D&@BHH8^+zE1&B=(v2qTxa_}cl5hs>lt>B|i!NPcg#A96j5%0-xbwjZ9;0!DO zoCc5%d0!7$4=muUd&oQ#%zVD`U*@r zt$uSy-yOqgnbySJ_gzGP(X+lVJ+Naw;VW9Gl4b+%>mS(1Q9&nb&0<$qggAUG4QtQnVDTevd(yt`9m;lE^;ZqzG@dc%z|IG^?j^(OhIe; z49bYp#zNzsHy0XiCHydl^Wo#so z!dQ1)sS@2zrApjI56m5AXRmiyTHFxkH0V2KJo-(B$=c#KW^4f(?xX9nMfiBiAz(Ee zr&ueQsDkD|z}p|Lem#_E@>?^UwGpVWau^{jG3G0MW5C8d!$Jg+zdSK!Aw4SH6|LSA zwB|ZPW`7VM8Stj}BbM=D=nracc%pl(Bg@$E9}Z}0ns2dkx+0cq?KI2v(NJ}3*m8A- zeEs*0jQZ-0ns4)o-uBQ@>g0p>k4S8-*?JZU+8e#~Ve1x8q`Gdpm9w+7Zs8`w?{}Gvv0=UzQ@NEr5H2^e)CbfC2L6bc{Sj|(#60IWKa6;` z?>fY3oY4@?HuEtROU5qIQ{W#RU23Sn6l2p zH7zbA(gx0z?;T^~G=?LOV1c%upfziDB*tvvUsiMQ0KF<>pbC+ZIiTHCJHeElpphU$ zHp-tm7wEKI98#GSp_`nadcLSeD|Dl`q%^8gC8R~axg}=mR|;;Dk8?m_$7;ox@vuH$ z?FQ2QKmIt@j&IB!0xwX2uq1!n>SC6`%~QZ^f^H^k_F_^i#P1_QBMPA)c07*ODRi`! z@U#ZkB$Ba^EYHvL&lSMI=QtL!%h>R*ZaGWr>{OfFN|CY7ErAqePNm{l=2l?tce9HK zovjP#m)@&cbrGl2D;}s_Sv)b|JH4tHfW_kQp%fRYh17oF054+UzXfMFE-Z#m{vlHq z$9cb~Dt`I;SPpaSQK||oXS%#^`0_Ujps7$nj;nPls|}*jg%N#|C@l_#5agI(4F$4W zy*6OvEr8vCxc^gpc&?EkxL|M8Y(oYhS_2RQyzL?Uw>M&TMZCL}z9C5b$Vbyv0aZ?M zoYQHcjG0IJ*7I3Pe97elf~8!=k^o~FSK$K`jD5im=H&JiEkGLZvM!%=m(>zJ7$fCl zHAu*JitIabAV@MVLUUA@ol2MLV^mpC0D9S3j}C0BT!*9DhM@Sw~&s?=}Rz1@vs|Edz*{0PehyqmH#%;^SCetgBzxX zXD0}cDxlsNb~`l|!$uo+J$Emi?g8W4o_oKn2t_kCZ=dnVK_=8*MX0rWn?QDJC!+U! zO^DvVDTC-FzHPsEf}bNAk?jyQ?^|{$p7$@i7^`()*+uxL(^$7nj?P5mv|86U{iel> za;vfCw=ySx2bwRK0PEiki>WH9L1Q0o|lL{*UEm`*$;6`RzQ z+@hz%WlzUsH64?wOy9K$X6X~gn!ke$l)61&teuTt13-*f8^N#C{e8w-zxwr*vG!B= z>PvMC_;Xv+xPVs;{S-`fFWfqKI8)>HYxWhrHO@j8?>H8^ToPmGxnVi=N$Y(pMVB@{ zjzm9ENe)c1Th-_|`=ySCj*XKLW3!IuCj4<-LLHu;joa?Tqmw$egKQwBllE0=3li>S zAm9YF!&)DMt_mzl&Nx)46}pB83yTC>KMT1cTOt!L(_RU?T)oyN<%wL0vqtiW6Gw{X z^0TSDM^nkK!Z!06UkC-nOE!m-kFqi&Egsz?g6RRAJ@YrxRSAC{l>#@>;OC>1$~Uql zkFSF1R4U+m+1MC94K|E;iGYb4UE`xHVc~QU3#UKS!s(MLb7aY5%7##)FW?fnlG!gr z$*nz#A(NY3ZhA0klax2Dglg(s6jMlSt$$mKt-pRdDYhoL2k0QL`U7n-!Xu0>I>yNNpAPs29I-iRPo?4nYo|E68SfqrgZV zGB&uCWvIw0k!Bbn^HDF2RQ%JSk;0soX;!OkqzLgLr_LQZQgK+npkI26Q`1x&Uo}zl zREP;p+L%y5|Ddjcp(tNnG&iyIx9Rq!=$k-R=?+mgJXInhLq&*@QE~f)`>u zT)kbc`5;_A1KL?~37Dxg>lqfsTG0?!Ef;i`i1c z%FZ}mFX)KlayYABH>uaIPCRyX=;zO5Gaq-4B^epsVhnns&ztn{nl_bxP~|en<>Rbs zFJ?YA!`H}1@yw21P_ex?c0KO65_u#yaim@R^V0Z%+^X6FICp^;7|E$E{eUl!R!~JY zw5BwK$CW{QL3^)gSCKXcjxlrV869nHEQ|YoO`B@Oc;qQ&3BDy<*p~)4U*AkP9)9xW z^~?}l^~d#a%iRYaggf4y;f~K~}bdTcOH7jQhKTkw=ij9+(|xM0D8< z?nt$;Ai*sxIM>U%e%%874KDJX)D~u*;}!ymUR^-R#&{r{zASRXAG^MyW5}IaEIi8>+IJBRKs{6LOHgH<|}mzGZWmx%ya#Gw&@n=Z|-Vp3lT0V zuRH<#6z(sg%Vx5FRh(=0OmZ;7CU?X$2E*PFdfBPLh$*@=t_$eF*zOVS@xg;xkci7X z#WUuKx&3$2S~w>yB;vY&o+q2*e93PIIZ_3pe_H8pZ zUUN#bt{0wb)ixCdE`d&vxl{m)++zoSEl3IeN@2)S_)(1DX&M3XSqqJ8wqUPT(w{4` zmgFG(@IHheHr#g^z1yyy?Y|E{x7|0KdG^eVG=R1(Wc|mt^NuJ|H7i^Tg zy$m`AVj4@{5Im9H0zlFRz!0{Qivm3PM+qDa(O&P@-#M3HF{-Q-NVxR@^MK#@M&p{g zCDTGGqOdj(zi|ihuu>j$h#Vu%r%c!q5LP3OKD341tAKQ;M-ea^Le*`xg?{*iv((qg z`@JI`V{2tTF3t$=#p2G0C2z-dXdmV)+5G=D`zX(kc(;bkhAXTV?aZU`wB37+-%e@VK!YP{@yRi-Rn#8{5{WcHkI~WxCkcS%%A;i$b8rG+ z)LQ(Ekc~j02KlD4Ireb`xZZm`UF58vnbY9s8RQ1&qdBbth?LR*;?krnu7&p4r(rKo zYi##<8j~-#)1sQkO1Rcgq7LR1W6j&=lq>Rly-EVLKqI-$MkA@zXe51ioKxu5>_6!5 z9&7s#hW_e5IF$e36oWQ0W$FC$7yoyBc zm*1Oz-u_qq`Tytq^Y;IN{PU8(^3VTU_~#{mk^J-aRQ`Fw-8TPh-2LbA&oKQH+o%Reu9Km7B9&cDR?o9+Jt_~#`<@z1KWIl8l#rgS!*-r3Q~ z&W@+f#?RB)ONZ`kj_&M8yR)OEuECvE?DOvPvd_oBKCl08XP~r(Gv(MXgHnryg zYLJpm?OGLsllL1S4fwVh(VgbDzR`ZC!w$yD(NE)a+GsNo$J@-h9UkTAf2jI&7(91x zz}%V2aO2%PkKESV~;JLuVUdqX4?ztyp>C(A6N5gaJ#> z+&VGgwI08DKx{66vk~)|cRyRUTwg2zr(VaLdRdUx=|bb4I)IYlz-P{#+49TV78bxf zhO_A&;KbAcO&%aJ6q;i!0SNSffyNkdndHzq_D0vBgt{f$qmi@jKT`q2}Ck8lC7X#ulkQZ1e zseHjmx2hdE)42L2%(T6)`mZ=o{mfPA20Xd}kKKUh&u_q^fXNsTXAkpKs=kBj0=8=r zKI>kV0BCw2;`6Cp*sCUBVl%WiO(F69+3*mZ2>x&qri=Lb>mAA2x_qeFnyTrU(i`}! zowqm0?gQYx>fK1fqxB<=zWf`46l0Nu!0!tY`Aa^?0v)ALG3; zZM^3ltMCJGs`azO#)6Bm6INanXM9G_5(7Kok39e9pXyQZ58N1wEyeKiy8a?*YO;}R z>AbsQ)CX>lYAeH>}$sQ zgB+*&M`HsbTEQjka4J;cUuP@s;AblMwa2NrgYRT#=B>FT8HW2{wnQ~f3a!~{tiCr} zf_wpVY<)Em@FnO%PaxK;IN*C{l~1&B;uQ^@oRmasJ9xMoWZ0$Kdv^_Eu%IW{d3^31 zhT*$^#OAzwYQClB%oVFX9I9?3d5wYJ5@V+QYz$S?8iETd-SXM7e~wr*Q?X%i$1P#D zi2a?rz!7m2nzxH@S3E5}39a5@r_$=d<(xraU!SW$V4>WPRKHAJShXlzy)9bZf(($K z51a4MQALvPIbuq@ha=wlVD^sme9vH^F9}&8l4L7@QtuiIzkYf=my@cy>iyP@PU=9| zw>@CY=r66KUqZ%=dd>n`kC3er+849|uKxHu#;Iqv!r2R^p6P7pvVK0<$26eId!E-=UQiuZ@rKrE4Zu7^ml#!mk!vt!wnJPqW;Q{O!|@sw-6(-$ zY@4L#)TQ=QDY?V?oJ*fWcUaDGp*vEFU!!Mm)I7G(xaP!)tR-&x_wb4l@W(uX(4)EV zH3j_X+~d$Jgsq#Mp+pm1$d|x_EsvIZq6G>L2r%i>hwK5q?Ga6V0Pa}>F2Po)5H75h0NTnUnSjV>~uag zb*@a$H68DY!>U9bP3t)zqYt^Mmh-Q1L~K0B2i7)@T@RS`$UZe6u^AQgOIb3x)Rq{+%u3RVcbxcNcu7t1N=~PGAuX1@w zt!5fS(GGfae@-Fdg;re54%ox~i8!(xPO(DtJ5rr@c4(VKj~E~7_~24cpG-y-JmpXT?6|eq;?R8uGK=RQvgSf7!}~Ok3vz=2i}t7Mm{khakd@_6{+G7k}3`%;ToXvgu-3E z?fZ^HM~$p;q(zMkiq`dL)uIj?aSsS!G)IltF}pgGC^V%GTmQ;hRaWUAQvoANubP$A zt2#ul%7@}>ez?)oFE42YW}^g+bf4o$SkPEU`hxhZc|RWV?Ki9kng6c0HSb+cI{^^Q zLJ!d!anKPjeXx(}B-xMThR$$(EGr@t;_VD4NHQGvZ95^5&JDUR77(@eR5rG-F+i)e z({qC+tu0g2a@Dw$tA9loE%DQ=%%|crJt$G`<|b|y1@%;kyO}C!Y?Q*A9!5|Wl%ATA zx^-%L8XIW|5jx3M?8u|^Ry^{pC#@Ba%+pjA^P}T?rlx1N8LAaKF>QJ)h4O7-S}Q8m z>(q=?uTnC-6>S7MEel~DE(^>zn-x>%_b|^dBzl_8BQ%|uS2|j~je0^QtWg<)^n{LM z5{~o4O3}ZhA*fKj)P|r!+Ypqr1H7PD=^184z6mA!B)Z>%<{D0#Wu0WIG7TT`$*uRR>(jt2$wKIjjJ7C2I~M&*>$C z$~$|4-~xgYjM5#XqByS)8f$-=twP3?v&)NU>?Pxom$|W{qC#hH2o(pM3`^?l)<15ks~k=aKTGS0yC=kv06(=aJm->PIZ_% z#;F2KIuOpoZphEL6N1lT^vEH7h&&B~#&E5hznDyeL`WA+B(rnv93_{Ilt~lg)oAk?Ww11YUIZ$No{z z1IG|~IAVin({Iy8mjrFtN>H(*Z;s5v-WW`DjN8s3<;EI6Pee!G^(hlk)h^b?&UkF9 zo(PVm;0PaiuO~feYwQ$Tqlc#(%`n*f+(SBYJ@?65Rpff^!?za5+T(DF&bUND#gz2j zrwG<-tUcfm^n~r3Rd%C#4oGiQj~h}RCnW3)vN9ad$8{p#uKmT=92{2FK-*^C(E-lx z>qk=fl{|HGIoNqAR#p{~jgUYk&Y0U+>-xGnPJq+#F?9;yXg#4013ori z?orM^`}!=sNiSC$5QSgTdle~&sC4Wu-mg_@`xR&NiL?zX8<-D1PeAHWTbFBnxrbNP zR9aRq>zeH?hb{dA7M0p<11TXqe11rnRHq8GO0F&mz@lybsq}4Lm9owEC%1W(z0D=i z>IDwqq3$g>*$dh%cv}LkZV^BMym+e@ouwDCPos&C^I+cY3&i*RWgA^#JgB6>l-txIQcEs|A3a0EVCG6OgQ(4gIrJA;F;!inZ^ zVhaiM{^y;J6hMI~0pCnWt25#vtyY+#@RFDq5fwNfON56KEl!j?roxs>w4_lY@(0A) zeus#)4kgwWDn(C`5^q@!7WjbqfMbFN4bo6w!+@4(HxDG0XG&(ukVlczxQOxTX4$9# zQDkyXda31QpaCd>v))hw=Vn9P)cTbs+ZLphqy*3$$dYRfr4GB_5Uu7U?X|YZ5OHsc zmP0>h$W1GLYeAJ%auW|1$P?7g}Om5BVSrA`2JN02mmRJ)(vnSyFexVXoIdev0JBy^7 z6i=5sKcW&U$?_Us#jbJ-is!>gjy>ecZQnS~O;x+3xCmK6tksh6R^_`r&bkYg?$+BJ z(%Ei_S%%vYWTEz`cOPRKbc8wEtu=1#!el;Cq`1qoeUJ8Q-=nFLE)=*V&UD`+?8dyf zE}+kwyd*A(Gr9M>lfFk_z4Hd(dxXuMr+kmNb=&u-Ui%(xMOVc42;@%+X(}aas*sk) zHu|Y)2}RTMwz}AlBIzr{U6%xoPIt=KLjL)J+{v-IGsc!uqep5?_denp?E-d< zo@9+lsiQl?`>2ZbXSs8JFxFwGzLmKq0hcr1HqoR;VR(Y)PE+{2nQwOzKgS+3Q#ti5 zlW`h&teJQ?ifByP>B`IFZ`lR)iDqiQglgl(Utq z=dbTVuFhD}H!is>d4B&}m*p$6EJM|@EJM|a|Hs_7z(-Zx`OoA50|f2_6Qve3ZDTt) zsIifjcCco`49?(8jct^qO@MBw%WhGrO^{Mb(U3^E3}V%)Tid$3wspJiYPTe#LQuPPcmMrVa_8Q2&pqdNe&_LfeSZPH--nFM z%b6{+e|DAllSs_m0lr+11FWCii8}!S6L5Azd!*cnH^ZG6TuJQdk2iifH2G=rBQBJ_ zm+VKpSNRba8h*s~WItk%+7>gOOH$hmKVthZt~^10#D(lqSw;yZ12*YLTqu1RS$RlY zIcVm}<0e1iLghznSAN7Gt!)I&7HdF;^H9{(FY+U{C;Jf>vY)1UuKH#85!;8Ym?up2 zksq-=*^ij&vm4J=H~M=UrJSgAa+caS4N_pmj_r+1p%hz)gM2fJwU zOlD1=g|jdZR|ndX)Pa`a49U8qC>e&H_37z9e(oy4W7CExAv53#1Nu5TFnROegVBII z{+(?eeHAV4&I2B)Klg{S4&Z2r(^mdza_zix)|G(GA-|k_aSf=VicLOet3NceIS|U- z!KWau->+{HvoD}PEmK>4sXefj<^)m)@7;j-2hp;7wfi47YpLqBwHHW9aaw7qp0#jB z)5&mdf#=^|c0Me9wnsjh2|@pQ&2c8mS&n){q2og4J)zak<0$)!jN_#Q_j;~WL-&*IXN>_C7N;y9ZNZ&>*W%CH7~pqZIJ>Nj0%h6T zT&>t-jw)#|3b~J(d{19Z$Ru9}r{b5!D%H@k(eZFR=l@Pj^I%k@RgKCW;q>CtPYKFILL%~hNRr=O|BZ{nYCS|r5} zg=@|225X_9Q*t0iC-?fuH_`5r58y+7Ptkptx zErkDE-6H&$TQ6+ye5?Eh49x1>`idgj58pl!`!k z=Ds2|1N9cx1Q0U3&ax%UrR+AO00tdOx+T}#n~p2xz;(wj0dFa9GW>BN^PBu}z0x0d z^dGObBtha&Q(mifZ+^Y2L%VY;K=Hl59AZ%X@y4ysid&bO#L0gLs)y=#7l@W`Bq4Nf zP#@6W@#x1B+K1{*3(!9JvA_%GW=I0AquM&!lMGONc3LJS16Bva=Y~3CcDsGYLfH2p zqyc$P9Wz1RLv8=?5Is!GKOGrUJ!I1!{k2IAK&lFSP~Qys9Uio9XLG#XSJCQgIFuUC zKDHJiaAy*|K+dIU=oPn>cw~9S`yWSJeen@;@Z&EPbYgKwb<5On;>-6OD{yV|&Q;xX^ z0B4)HzOK*3V6Q)R8R$KS9-2x15T6reI_14L9>S8_{?I3t)AKlQ{ua015zhZPIO44B zAsc>O_w$jMLHy5?&__uZZovy?p9kD>v*Y%yX%>rMuXWR9f&>P&;S8kEx{$Mg;E6RB z_Um3ne=BpB5z-?eI})ozQWHMfb~jPNQ@4%=A&F_4QprT{TZPFze&-j7KF2|;KYfwt zll?vZn;!XspcA>o3=&q*0qxQ1R64~(wMW03D$#}rDoDHWESHQ?$$st8(o}^ibZ08% zUBJxFk8`$#ae7M~-;v1{oT;pmB79MF=;~CS|AeUyh|MvntU|OY@9`M&*}C4VO84uh zBiTXM(aP}wSER}o)Zg~$ry`@oKLP!4(DjzKdIx;wT&J|vn^G8He}Kri5O|^RsFskN z_>o7RbAnq5Qvcx>hT?SUB4v{X@3!xf6!j#-)96fMax5<(cd=j2xYDAhe1R7-t>&jR zeuA$(dOh)lU*GM~xA^rP1K&K4_8+dC7_1mA?jn1vPv181#P_p7&NFU(w6^v-EVeb* zTG?zisIA>jwKmi7MO%;PJD>A}&lw3gPni9uuAoH18P||;1}W%~eK|7?n6#N$*NCIH z&F#8vMOS`(A-5Lg#d zbuPoQuu3iqYvdZPz^$HO!a34i+=O@r{Ga=TyN#XZ=o#nJgO;^vE~p0iZS8{~`suT5%qxz_MQ8JsBcA=WI{3u~pW@b6f^=%UZSxx;)m(eC_3srFiyP-C7 zi>R9&MmH0!Y7@283=#Fi)dm{U%AsVxQa7u{eRXBI_PJs=$_wblxl8Rc?&@YcT0o0LS=pyonHGS3{x+@OGE6^LUkmb0wmm3O089^+k+RH%SzCVmWIDds; z>-!IG{P$n|>UvRT3yk__!h%@Wow-HKvqsHvvSHxb)OK;_q$t=ZBw9)$td#;ubkOHI zp*;q3p}(TRryuY+dwdOtQ~l0fUur)>6@h!Nw`+6zw7I+7dV{xSOXbaTLK#<(`=)6= zv4^8A-l_sW#0TKa*&}wvLxQIWShG~@F{Kbp5X;fV(P$XVc`&VKPW01xN=U*Rh%%Tt zIdIA>koJ#DXvA4<6Tj(F?SJBT;`{+DISR{<(Q$*leF?J+!wVN)SC_V~hmIKt)x{A1 zNiC!QW#ud##x6R6&k)97KW^n_l+ZFi6VzXi{87+|jmM>P64 zw%nq8F-*to^+jO6q}N(uRekWx;flUvN#QAD*aisL#9t z6Wmw*o>i+E6_;M3SXjlm2;N^r)jUqX!YSAV0VNonctjjRKZz~qDsdjNy^07dy`d@O zj^Fw-9EeiIj}cBR1%iFxA?*w5gZf#)Kw}gG5&wk2Ki%58LyBW|Ca(@E&P#qpd-P?i zM8*CEEi7lo{SDf(t@ z?iRl(*9Ec2$e!hP0=L_Bai!M)C#57&lvryLR$WR( zzYy7|#His!yGovDF{G5P-Zc2mmUz88b+fNxz}N7WScZ0pZ>txq4c1u zCI4terq$v`o7wYUjruYmRu18##0%)0g9`t}h6>8dkjQ+VlNK}cVg2f3{~3QLdN0jqhM2+gGG*Djw1V~+(gH^^@|>H zA`XZ>89V6VbjDU-M>(;)tKk^$-k55U_XuS{)%WYf);>lo#Gs4Z-=D_j`-PV{)@*fM zI_K6|rcUe2@F^jeBh09sr{REm0}fH*8%r>5g9A5<-|p0AafosaXn_GiHfa7`M_1lv zk%t6y9F8+6*WPh0&fG|9DB zTm8@Ar{)$9F_y*c+-%Z;N4|rVlu`^4Hg&7VbyR!oE35#$Zpw96TD+mzR)0maKlH$) zV8wm_b_wybWi_1>@V~&+72@-uC02}==Z;WTf1vJ3){}_=TILHa-aIT`bfVieq=jH? zAv}ib2i(XK+A5YoKa?5+bo^}c5t;+bMgK;NY1Z{Yy))qK@>jo;3a1V7)yVh}RxHzg zQaGqN;2<7bnyNYAo!zQ8kc6W-y0zIY<|pkQA!|Uk(H#9AZFar+Sx?BFLXwQA%{}Z{ zYv{YF+U!_$gUp#K7Q|YgE;@^S!V`3D`@v^OXxV;gOGFDGzBK4DQEVlQ?C|0}6ZwQ+ z-v+b&g7EjmK>#m3I1vxUoPoASye|ZxlW42kbwCS^m$43BLAwJc+8w);c1W}<=mzV= zC8XOx^b+4`h4Xv;(ln3eKu;Sa$zb%;W;Z22Y*bW(RgK7&^tee84%NCZdE5{x6}0Oy z(N3#bO7e-Be%BNIc8=IG(I6&a4@d||s=-Jml@cV=_j?FOo~R0v5pyGga}^yU8le0< zj`>vJ4;5OM+sJI)5Sd7`C@MX~5Zlp=I}6+_X%cU{I>qUc4hIjHo6Cv(6v|!T^tG$DcEPK}t#SQbK zK4^Hm4!1OlBXyO2Ma{0t2e6!A>5Fg0@qR)67Svt>v^q*RKxgEnPb?Lm2vnr%gT9Jl zNCN9aS z`So?9>r(aRaPK*_vG<%yZ0zR6ahQEc?~of$wogyL{kvCL{s@(wUa&ac8cHi_GVEV= z@z^0A8&9O}r{Jp;z)PkkU<>WN6k7<-=EF|8OI!2cD2Xlf52M&7MMw_fFD>J+)yy6x zZ8Wz^gdZc9+B9s0Pm=s+7+UYj{G-tFx*Ks@f zdM~|}z=JX~a=qe|vHo9Z#c2yTn*z>lp49exlj7gMP5Nedc*F^zCW8V`w^8k4v2D>D zLzv8)mu65Npi$(0kjeRh#$pj&n#Litj!ucRR@Q+~D5M&thQfmo(YD>OLX8gGBrfaT*m-_v?kN|9#;E(mwFbyERG>gs%>7|L% zbvJoZcd2}3;ypigNH*oH=GYzw+R;2HS+m6LGidrL+`;WKH2N%Fo2>lj4pC2|)YAjp z(>>JFF6t?wZ>Mh;?R3lhqPgfcQaNd5S-GgPfx2zuZlTlYJg3gsEL$?agA-(lTkn7r zqV}UpN5dum)I)`$$>i%bZ->H1*^YlUQF_vnc4`TgjXp$4Bi%?X%-X=xO>my57qoip zIBYnAmqladHP&p=)_aqQmt_#I!^96BI6Yy7HPdg4K|lNZ(9ix?&~M%3_oLqj(2Nc( zb_hVZBap9Db8MoT=WQku5>Y@yLiQ`^Fq7{FR0j)C3oI?npNx%FPp^1jG6O*s5g+Rl zR1H?BfEF>rqkMXIz}2FK?j+MUIo$$X;T@cd(M@}D|L3RzX%qnql#L`AiKRM*|lSfWJ1?2QoL`XRc2q|X??Z&I* zZoEP6#?M>Wb>tukG4SfS)z}B~P5Yo)!IS)L?h!&cB>{y^(?*-tJl?FZC%c-ob#!!q zZGd2Hf@*8=(21fl*GIe4=SZ+y0Xtl0ejLa#t{&~NRN|Q?<81gxI;Ahpo#YFpA?Gq6 zuE<^ioU1Q~vMhnnSTNv_>z4gs+FcqWph-f zn}7uZcUug*f=qkj|+KfOy3wgEb^*D z;)NG+d>UP!u0?FPJG=}6gst7oQW%X z{1xp1{V<0~alD#D@K~7Z@BvY7H3J43@DY8~_RwqOT|GM%(0e6(L{RT$_y{0Q13n@V zlEUy28x*E5!EM8BcDHgEcT@a=+w3szPRiG6H5|s>mpY7N+36LP-^QpK*!l}>jLCs* z%*WuxDF7-c0m=bwtMIViF8-s0fP2HoE$r~mWeM23tjuCl8Kn)#?-ZLVU?6tbjHpe^ zFkk&XQ;iB~#8jhQp@1k{^UGp@j9B9&u5ps7#z|b`BvrtuaZ;kjNtgQn_c4S7#YXY#Az4kK#Mq0i25t)qM;4(QUlZM!6g5z3&}2#xECFW9(Jz@Cm|q8Ix+yvEWieqQ zV~`X$W`sacq!`A9^Rr_{dZf$jt8qSQ+izGk5vhT9(Rq6zUDxZc$#B`{XeA4|Q{X=a z|0v*7b`yT!iY`jxo6(Jbv%17ae@2_tih$Cs+AJZpiY1i{A%uz{gBu7HB~&MoC#1oAMyg$uCPOG$^xp}$+= zP~Zy+_<1w21OPJZ|ItGSfddjKqF;hy?*oE>R{O5>csr=A{XNRnyu$7L22g}S?_FrA zo6sFf_Yjt!3BCeg1dUqlFRilU^;T2IwY7~@<7>o#HLp=zMb!gBQVRdt!amsJsqYjm z)D`(BH2y~FI?iv%LR{Vhfi&@Dey}6#mrxUbGl@GT ziP49VNZd-k^Q9D8AztmmxwJ!jvl=2kmCKo0P0b~olX8H11AcKc*9c&?$V)~{M4tl2c#4|* z1dt#aXVs-uCq`r{Eq>hyanzG`o|}&-k+)<)+odWnWrpz_iK)~u#YZ^lDLm`njwL(KONNii z47EnC)v|8Y16o_}P~&fq+?;H+i!&QgW2t~#{=1DRxh_+boRQA8pVPS>z$e~Jd}85# z%IA6@=@SR|6a6t&Kz^d%$me<>kJB4YVA1cU6|qZh6mrg#(VUsw6}bf;a?;-4 zO~t#2>=s4gj4mn{HKSVesJgTIX$v_(YmrfR@qU_*2h4T%Q*oq|_UyM9u_Onm+_0ks zKoJ0C(M!=+ZsekEBp8Gya>goY3i*Zz2EpNR?bOykE5jQIv`q&1a-{r+k8-%I64DG^ zebB-#v&rEOc6BWE;Jh8KGN8!6b!vFLLwVEog1gdn5eR+T>eq+ZUpIAN;$7K*&r7?;7y7!5k}?cHU?_q~uYf!r@g<+9E{`25 za@=({sTR@`c6XF_l$)b`JpLOC0Z<5it^PPxa|uwG(j@T+-Ni!MAU|S3IA9O@^|Jw` zqSXf!IH5$_P(vIWdnEt^myx*flX`0cM$iBb zG(ZDo`XUDS5I=SqD1uTHc|l1qZw4x2{)+7erl1K#(1Q~XeB(0%xijzwh(f@UAxuHB zK?YoBwa{V+WGa1(cQB~8%?YK&pvHk_Y=_UeC*a&nn1cNqyfwS3zG$5BWLlvFo**aN zDY9$D%|H|M0OT7G3V;rR{O(4q^)1oM!wD8MCLj*&#>?S<RotPP{< z9*Lk<+C>^joShk^?Xfh`M=v2E8GT&5BZkx8exr~7n8t_5V-nG_TpZ~Ho8@V157F_u z&qA5YYlt6kR2ARYqZMaAFpAWmZ3N}l7UTG7YQd&N3&y80m2=yS22}2#OyO@E4G56wqEkyvoL&&?o9PbK%#GLlR&BpfbX0w2j2TGRe^Cp%iXoc4Z2+ zu|7Ok3WirG4n;fgt=*A3h?tak=`)H`q3AE$ehH)UYmsY>ZgfYk;A>tRIulhvV63OL zp;4t>Lc2Rb?k??-^-@smU%sU3enA;0*)POLcTie16IDH0*2?enz-=U9(Ml?wv4jmtp1~v)Cf&|KL;8`RbhPjq0#?7M{|XWqhX|9d_~PI&+_pI1 zA2J~6MBxAxwu{2Fam5D>+_sCVbdreDP3y4)ZWBA!Hn~wJI!A)yju<-UPjrs%wi%#w zI1eT8=+#>SXGbCaQDFPZ8o5kq3!|U3u ztsj4y1G5(3R9JK=BH~L*+W%Xi5nq#eQCNyoFo=oJz?}U0@Non7;D`zKz>o$L{=a(q z&36lVc@>VU)%7{U{f8)ciXCe2@r7Q>eIE9Lhu`ItQt7k5D6@~$Y$WmXcdsaM`ga>i zgnq+US2ZXkf;w-H5o{R#7aPDu-qhASX+zY@VQrmmlQ~7cXOq(JgEl&Nq^~}oZ5h~9 zkWJo`PoJm16GUaJsP0)l@sg9qKNeJihM8O;)M%P9N} ze@0YWcdZaeAp>uK*Z+CvSrTURs7JvbUq!bV;fj`c3yHQlDbloNPoV~7Vap_kp64jL zibp03?G>*GUf4oXEmD)v`<$%=;tJWxd#F%pddoTVqhu>ZE4L1Ryh+>^dt@I6AB&Gs zYp@Mc$~%0H@H(^CP&K7njY^Dy+o(D^6p6xR9k$EXh1aQw{ex?n^ue{{Bs!F+fSx!| zj}Vi@tKR(g(DTglMfk@Ce<<iP3p=1(xS zFhg%?Fd9SA^C(aMyuvNWAEziWKejbrfsE3`IbmKRZZ{i1LtH-3mj!Ou1?{nvbYih7cb(-~^08PpnZus} zenDs^<%BC@?w$U-GufoWDM*po9R{V}>vg{oPXZN9`F$kE9+bClI4N%XD$a-rJfQMx zWgOQW7X_7XU4Y6cBpqjZtb--DJ}K@IRXl9HEGx@hfc1B@zq-Z71b1`1e)i2M3W|_` zTH01{xUC|c|JYEqWC=eeA z(FZb%_ZQ#*k>5vr0=tP%^CBT&F%CwVmH5|Qi7LQ;qAe&+S|Vx{PD5Cyg3q97#8%&Y zCj2=?*%C$764mAxIT}6lZgEi-e4c6NeV$4$xeV!+sFydQ!!Mj-(rrWquQ27juZYL1 z_Y>dFP5-acCfYenv|G2I5&gL~L_4S7b1FeTpCVr?$T#zpB%e?1)R}lieCB!n%pFYM zC+Roof_T0O(iIWuiimVRgLFj(=^SR#wG-(uJl_Ojz!|qpF+lEoLi#BIFaxHq_<2(N z9F&QCkua#8jcTPW#My#BOE}`6a*Q0TBlYkYusbOil<`{_JfPF)NDku-58Ay6qdJ1bI05Xn}-L5o!?FpXw z^?ujjiVSyrvzXhNqx{v)5ZI^B6i*4nV#=>h;v9v*U zpQ3=LszEw39kj|L)1Z})Ls-3V94boTj)A35~(!7Jy@rw6!2k-fw zx*Ktl!dW1a!N5W3d|c8)bg0SSKJd`9DRj(&bzGdHaQJc0V|QzD3^{%WAk$Wn!C?(N zjXbUfkG=+nIDG>rqy2J&$F)`b+3IzPJ?+j`v9z%{g8ZMp%BQP`--XUTs2>mN2laCV z!EuGMGvEn*^6O1Cacxa;mc`;audNGYvFDQ!B71X|JU=d1Q|G9a|;-g9$87 zYV~F##48CS#0#vH)#kqGtLUN4O&T342|juSdq~}y8l`n(G20zzMa^76xm-yD%;+{a z4HuCve9f>7JG<#bzK+O?Xv0D2uL2EuQ1A334@+lIZw5*#0um82;@ll{Zt}+)=Y%Fd zVfaZ|rJq!Hq>#Z#-3p8}MS+pRoN0|J$C@NC(v&3G6U)>)go!Gx42F}GHQ^*xY&DYA z;5a&v@GdP0hk+`|;G=E>%rqq#%+xSo7+|K5uB--_X-dLDigE)O)sdrA%&B##U~*;T79|03wVL~f;+)ZHh9B6dKPJ|E z@-ljL$T@0rrvmzu-;~ zk=XNT*+5^#kRO=R)?sU8Of;B{xM?xwK7;cpF0os?)*{+UOaJ6EtRe3PYX^pQ?L#sxr#9C)Z}4syp6)s%}s?+l-Q3MAV7+4gBb0!r3mi z#}pS5L^f1o5^mcPQ(cq=FXidR4~?=-Q?_1C*?#imGpj#bcZ@ z<#tBqW8KIyw^o{dXY=Yo51`(m1}bxF<1jn%#|%61?#Otvow!R;T{T(MH%)w^6k%&` zNiN&1)jlPy#3zwku9r;3TPiiQ&5Kti!xeKsxqNU-wbFi8YCzRHZ!gAdX))L>yfnz% z2pE9Ir3IWN&V^=Vb4_k(^oAaNU*u)1%9zW@(tH5LU@hJed0NsRvh0&24ZGtF?z*%e z$~8r;dgNq`N!Uvkva)x0g6`uSX73Kl@Yw$F25J4jM$KcCKB}fOl|D8YxeuJOfEc`Y zP);j)VIRNnE}MX7Y4Zd71{3QNA5GpFG`x>dPM%VZs>-8gi1FPlcG(w`wYXERIP4e& z*+{V}sGo_8iuTJjgQi5jd*Cs`!-87|f5*roacK66BU#?9t( zJct{g!NK$bnZLP`To%+B#_+K|M`wr&wCc&)-DEGv?YOEP=MRb!%(_4) zkRij#`T`dmF1;%+Ya=6~vZRU+Unjc-zpf~E4wdAdL>EEd@FS8Rua;dw$qyA%i{jH;oEqoun7`$rt3{X6%!%DldNYAZiFZQ8gr4XABqqeLO0_zpwYln|$%j zKK$F_i#Pk?jVipjq)DBwT1f^{l!UP$eJ=T6fYom@g=14T&1kU8ylt|!ZOc8t5$_WEMF+U`bCBBldRE{RXgZ%2< zK!mJ*x5OvG7=wBkc#!W91vN#%5_kE0iT4jXI^ZB*w6Y^P_yO^vgaQO|)>tL({|YMy z2Y^3F1^g|r)o%%HP@?&deqF+7%vLZOw_7C$$CpsJZ2)+(u9y~xxh}4}+9#3u^50{4 zCTPKd&J?*7uI$fP7$C67qhItm68s+sbvXlNe~QQT0da~PPe>|Nq6PZqNNxUm z?$Di9akiKVe}OZ-KuGHfR5S~r3MedkIN)pwrZ(TZffnIOSZC9&=96J&D!}1@zk8Uf z{N(l77WMhM8D@fnC&$&~L5gO@N3vJaeJpj`Y(;eu%iX`o5F|R_N$I zqa{gDpdsL#5tjq^{ui7*20|HLOkx6j zcDqim94%9;!3tOz8*qdz$ z1+DjL_c!=L%pEwUW1*PgcAg@3@CXJ80q96?A%H@+-lYTIc90ByIRk(AF97`joBu1A zEftJ54}z_BlkTOBzkd^bpZK@H=jyK<L4Hyr4O{(?mGT#V($$ZMg7 zgP`(Ni>a0F&^>X&R`f8|r2thxs=p(kH^HJ!P0T_Q2hc?520U^eAgW|FO_~ZZ9ai23 zmwUb2FBO62N0%j^eOlm^i*)S=Q9cJ z)&sd7cWN8&5F2@D#R#T@9gR1yP;ZX?45nK6$dLKzsZWcW&EZ`J?ED);iHV^|ljL8d zkNpPoI`NxHn9Dy-s5W28{OKS^=?TASb{V5*Vq zX?IhI54J-B6ga3$MElGnoWC-xwSC%}`zA_A`-Kx3-LG9OrT&RBY^PviA{8yIx;IT^ z(SWj$0o?wYiEK|RV0)S-eh%cs4WN6V&~n%MR(@9D1SV{1Gm>m-FDd*0qnXNj=7vd) zvuL>W6IhO0>GFI)pZl?^uR!cBR@ttnx>ugN> z{W7bJ>5)(Z>*NV!YH{uo@;iRBE1Qu878u9^MG2c4qw2jEtmq@V8t?>86MQ^ryQ)$~ zGDWO6={L7ZGZ|s3bs~k}Wz1x(-y|)tq2Jsk4y9*h=JymjY8P8#ky}h!cB$V)n7m27 z$pwv5X)62Gmb{@1W(k!uM-BNT41l5Dgj*D)UfnAG>*dfNBw%CpCaLXMLwD0~+X%-K zji{hAnxXnsmSO-CeC|@a20tHW)-d4`q$0wWlCB!n8K?xGGbuM^SP?%rs=EY~AeG}} zIO8hoHvbVB1m#qq;jXoqh8N0B&Lar5X3)9&GMdd@ky#1NCh2M@ujL4uO-mBttVx7Z zip@7jvH4HZFy^3Ut&}^QW0KCTrW-KEdv;#E)c+=#9)t5St@; zEin_ZS@0vK#B+n#u>`SWNn>~7uj9x;Ge;i(=r}U^(Q@R8kDen>By3}BV6m8n7My4# zwS0ejSZ~Ceu!j*dPPRrqJCZ%jGJ-wKYHk;?;|aFb`YH}6)6e%W!;BrwjFtZlW|aA< z|Hs$Icix{HRYaxY#sSHVFeH?ODX8)z;l_79T5gOaNTdQflSm}ZzKq>sSbY^ACNDw6 zi_()|@i1Pj{J-W!={X>?Wx4fue47Wx+3&#_y2C6mNK*DdpiA_28q<>@RnxUk2(ChldomUC*mVHO+1X_R@pfmwmV zO^md)W4O?z4KezK09P>L7?>dw`O(p#u{KpeapKqnCyq(x#6DAnyfBWjn=0gmaja3m zs4%fIjxn!{oPWBH^H2Ys;6@DgdJ9|P>G-N|mg6f1(O1!e6(y9hiIPxna`t;<4r;e4 z2lcLqn{!Yb#IuPxd``__&Ov<%?QFy5NrMVL7X0{}M=%>0GQUqA9lZJV6#4eVHgYSp zk6*qm+gLJ#6+59*aNN5AwwqeRcB9?cqOC<}o>tRgp~djKWM=Ls-6r&-yOam!k5oF< zTl&dZv5z7{%l1ptN-vvMejx2wwQRzBOPcWB<}bCw!!J?3*3K@+8 zn(qCU$Rn7y)5*@=PxfSb1g)&pinAV)@hgZ{6zdnDn9)QeX}hRKtNAPknAV4HkfDIX zzjh0o4*4dV4mV2^Pk_F_ro-{7>Mk}wy`Hcfa=ahYOIZ&2)kD&z^M+RYb!kGYWm{ht z(`f!4&}jJ=t7Zt=NK4;z4)lWsohsQI`4pO%nYhzS#v0M0ernNvPAL3(rO~2RY7y`( zOMkjbjvxVg5TMUqHtHb)lUlTaY#rsN6mu;9cGUx-IqP_+vWPVOF}8T{GF4(CBtO_6 z6Gu}O%@*iqIGBCxEwMkAFlVUJ2A3Oj?UZy~HzHl1p*GHIH!3WHX>#zvM5bP!)Drtc zMOF%Cd|1wr0Mh0PCcjQHInvj*FsqX~dlNH!ac_8yMft}_76HXKD^4N1#%4?8n~Zfe z0((MbzG-A8Md=npkG{zWzu&B?HOwWW02uD*mvbd5Gv2;I>i$Fr;-(HO0flipso0~apefw<9u3q}Vns%l5*K&7bzQI)cnY^syb$o6BWK54YSMz(*7YQJdy zDWmyVxeD3YP&e8C88zsz(&k9QhFu-zB}{s6u+tQQ2t zQ`YH@H&TumKO*vAdGW^^0y^#Zy&l(-WC79E_nc*e%M3QSu*a~YlJI#J6Fv{e>XnfR zhN4LvN&(_nZDb)PEsBG+Dgmh~g@(J;!e@ETO3aEH&d`yktSpYBN*{L3(P6ONWyA1F z|9`NrtRC|}h|iPWFd6ZNP^4DZ-}XWAhN~`6yy2=eiZ|@Cs(8b8a{d2Zdn&~n`t+Kf zR2*dv2I{Jo=}}*u*P-vNE6(*Lq7ET>Kt&F#j_ZWB?$;BfmhYzuXb12;(4cKhgSxC9 z8nh*8IEloeh(6ayMDb3dAdRW3bBog0GaUv#ubuuSm>Ms^3VUrHz`=VcM{%l+0~d!H zDRA*GA4lNgyjFb;QK8{B8MIiMzJos!6w_iJ0?WJzK&dKl9awq0r|!1=dT-sAz=CKN zSP(5G9xWpJgg_MpEHp3TfQ9-rVl+@s1uQ@xxF8LiNih(4r;4owmFOot&g0}dpO=R7 zRkJp?ukKp6m{AqYuclaJw3rOZK43k!BlEjGrG;Emt+wrBcMgnUumESp>|O|Q3MZB0b*d}-3;6QwjcHrrQgHaBu5p@{#m9_D=D4qs|Via#kRVE4ztLd{JrXt&isOUlahpB1O zhp8#&!_?$Rs%fNZ@?H!4>wW}8ZcmxdsC}<=wdwXnv&r{(X z_H4HA2kGC9 z9wOU2}nu#uL5vh<2flG43z-t`v>i9Ea zRGY-2U*r!lUNg)%uh0UOR!=^vIat;72o|d;t>V34#So<)A@>kCZl6SS;riD&qLsMD zt(9PbnchI3De3Sa35wvDs#W5n77oP7^sW-0#ev}+@u>8M^4GGNi9o%o83?H?adXCB zuwmv)dx%v|HzP@l6kk@q2ZFjog%s^tsAaCB8{k)e^+hPYy&L?YAVs_irt)ascE7$E zL7}Mez766a6kLPchSOx+<{GY*2F8fpe4Ar8cklN}LgmTW{_)-q#+?WXE z+!(&Yp!z{cAL_tCQwLh3oQ5IuK6t|h>m^z1`L)>lkTqti1%dPFp+7QN;UFGtmt<|{ zifG2nP5-Aq4T~u@k=1TZ)OQf|-TKD_Sr;g>4uGtm`lBT40_7=&b%8$Q;1AvWCq-6= zH4z#+K=fQh^jt*rTwu_1QPdn&Y|wKs%J_VuUxV~9L?d6f^;L>FJxbxVOE85x5vYVY z`!YYG_}BJrr{)T3mp_JbN?C z7erOStjuXZA-8ZhMZA4*(ejka8Ti#BE^ea0^?6MLi-xi&R5m6SdrFyvCE~iLUgf3b z)JD=i%{z!N)t-$;;Owc5iNIO6R=!C^&R*OoBWFj6CE;LX0##;zl`1Je6!mJQhq3DW z^j^1q9xKKI5G5tztBQJmh3E+RRUR{K*cfh5dBl8eTHYeZchc#w;3;Q(t-{|t(H zwVMbfg6MPWMp_@|aWL1?G59myj$$6|rtw#a3wf`Yx@z}=wW@ISeJC1B8wLh0WYIAk zpK2#1iXhA{{=o6h1p`~eW8SvCHZcN0y#=1tV%M!6N?UPfX!eDMffRozkUJQ!pA*VB ztG9bX88XvC8vPA8>yz`JmE47M+g&)}W#R(+Qx2y+@VMH(f0f>K2a-KHk=i9wJmY+h zQ87jt_iFbyvo>sAJ36?VF=O01BG&KA(Hy;^(Nh|J4_=}e>i_&bP2#(A$Oln$e-e4* zXWlo7R{^XNCFS-g2^`wIDZdcqmyUvi{&&V>Ox{@f6~KBw7;x(++bfx|W|)J<`}cCZDbEm4-qH(Aw;JdLIVG>f=87G9Uc{pn z-|*n?nJaGC``c^_ko*uGo*Qs|zi7pkK0WAg#~T3jkXwf=r)j>rATq`}kWx&PTjr-= z^Setp&HDEj#7Ucc_aa~Q*_-JQ(1cob1o7YSytvf9jHPVK_}{D3#dW*HU7z;l4w7%C z{0@Sf*yzOyF%8~lba?Q%gsiKr-*^T|1|59JfcwTPB#n8OQB3+lmW2$Vh$Sa-?zE># zpU%8A>C*{W3@<@K<4h;xqe^u!IVx2L;fdlZf#37(@f3ef@#bsT$prD|P0#79MQw@ zPocQ^I;kl^4mMKK2#PIAh~qzmINqnN`O+2ezS*y>n|_6bGG4b^+10VfDnr>PULjrB z#$3UEtbad!h9?Ds>yr3eD#%$v$i zwr>5Rvz8om=brXBe`=wX`Az3fm+=zK9yy#wY#jybldWUvZ?YM6sEGY?I3C{s(#^BV zfc9sC74MP2ZRb0uv5Wkc0HVbj@dEh~iHp~A`5=|an9@-XqtOts8USrx$~~x__eiDE z5_qT;1!M+tziYD=LYi-VJ;gm&*AE5t?S8glI@|o5gF)Zp52ZB+oW;3CmxgUp`i!y? zgl%HUhTF_uQ`n}oVoLm1!=#In9JV<(dKvSuQQQRos*Jw`gj@7}_TSOsUvY*zAdmBk zWF_a>d@Iv1Fad)VeE~6DN`iu2L(9miX|rEh?!iUM>1DP}&|(f;n&8Z|U50E1l-*v^ z%O7vNlcTGLTkJbNGK+mzROU(fa2ERpWh>o+RWWv2ti7=9SWs{@D30*FeF~jK9M`W?@QWpE(gvDOY5E|&mENWoy2&ElBx>mi# zoOi@8*nR|urjC!op{dJ&Xl92d*{%RH;sR=4%`isXON_{V2FR82p&3#6k0i(XcSPKO ztG`B9RJzr@Z>T@zuHj@o#D)hY8xp+Qq40o3h5CO4E+52=ADv6w@al{#J&Ec##-HN- zDJzkxZc=nulAcsvjLaT(D%M{t)->WzSdvG0_Z*J&|6k|IHxgVa+UBe1_v=IO^?*;NDQ8bK`o1}P=o_aKbTD>Y<@9qC?;5{L>qg%YU@EBoq?~_ITUKW`aHcHGqh62ZAf!PSY7QZ7}txI0^ zYPC4G3PIpUG9r7|z1odk%NJMuqh2fHu{9ZzT87zth+}3c_HN-ZLbhG_-e9BvM#ImN zYr!$3PDY?r`5O|w5DK8A%%D(u^Y)0bFKKx4(z1Odj z?jfQxjFd(w@mopotW8g0mN}@^p0g6c{&NHS?7S!F^zQPztG=qdGAi#f+FZ#zQYm<3 zCIkB#JOUd)c{GVfDh(bv9vLr=!sL2!TD0L5uRu6hr+a_N-bB-_7xw;9LWjHh0X+*H7Mo8KZ!MHLc(7>ivJ^Syu*G}*_01wD8@5iDLW zBd?WflUFM{hO$DI4pWj*t@dFH+JEEGh`u6V2$4OcVkL#eF{~1%`S16%7+#Ka4NKaR*k3GJ5q^6=`mMc!Z3d_BfQ>V$q!856v0!=)Y&crHq{(og8WW&PIsZ&r>~Fn<32k zk+QJm%c04(Kq$ij(GG%PAe3hJ!Npd{GrrI*n_28@#+oWbS&}7F2Yjh9Uud#Df0wuB zbX6Y7V9}pLWjDAxyyEzwtPmy?=(HF-}N!(Lc)Ce0d4 zo6$J=Se=%~8K>nj#tFcvCN~2EkUN#5Y;WKON#DfW4C!QtIQ??+uOm3^tf>^FnhH<~ z^u+OVOi>CPelAOjgnZ$xiC29}_7CZ6RVT}`CddwUkf1I*2)ciS9i-F;c$lS$Bc(*E z&wx~s1u$n(5AVPk6R1q`ky0z`<+RtLPXnq?lo_e|9h=Vok$ccFib4+4i$>^m*r)>MuMSxe6U?60ZL9<(fc(wsRwU`>>J6G)A!sVdlH4e% zn=k9-&4-fL8)4Q3D)e6*3us3^PCG;yZxjp9#0(Z+Z!v}b<2g#7iK&$VrBBJsX&m~` z6?&*9d+`}|7D~JaKOf+wA2X^j=T18wGZ5mB#}rE!pW;yXQPj=1qY6`fpB~6{_~MOp zx{5bIT|$(GNZ?zMymg zcBwuQQ;83H9x)rHg&(9a?sXhFCvK3kPx==9RwV)B6CNr1@~kqFTLye9<&J~(KIF!+ z#LDWwRaSO2!X{Z~#R(E$qPSCQetmfMdrBub^F5^#EPRi2f<8U_8)vVy=#Su4eJ$0j zKk_1J1?xTfT5bj6>9)A_dU3TyUrQ^2tJSUDDUNz8GsLA=T)IOADNTl+a0LGxs0-U! zUHGK~hPu#UWp!ZziKStzv3aB}j6q#E!%!FY5FrmiT{tM!g#%JuSORrnLEV$INnENi z?6?{l!+qMi)~ngj3w0!7;h>8oMd8n{mI}h>u4WgloD```)UW1Mz>y*Y`IcWTHHP07 z7Xz;kC1u$PcwC29dXqJVc$+>bm7hN8Mh%VOonF=$+8HOboi&CMCv^OlGstMNiIV%0 z!f+qu_a!CaK2GsV*B6`*FJN_Ey~p`11?cG~ozF@|q4U)j>Eg8W*Q{2Ia|&QqEOHiL ztAT|19I+ITFiGis&Cjygkw<>uO%g(+lJU1n$#@!i#WzVNk(x#lKbgDPM<9p)I4F8G zkC4q^ILoYLCxRE`L=zV_`OfOxm{dKkqd7tHkwnRUiL#Y(DZ9KX#=H!OEnD!)8Vjq0 z+exn6#2LUmdR>{7b&-C(Er`Q{5P5e7oh^Q6w-Ac`p|qBO^GSNyE5ys0QmlmlXkp|s zLjz_pG+<5QKY}fXZ}f5TqcaRoa?*k1MNN6Ygy0GJk(E}A{a4J%x9H9AkNGWe9)BnG9;ljq3NRBU+n}l zBu=!05=ZhJ3#|KSrwp(=NpY@&JX3g3X@E)d$-&P-G4n{S7xd@As@uiP-oYw}&3?Vh zJO)8$r`M3|Erw)oF(msYCE0h9hcA(NN>r)=h}NtIK(AS_2TiN)F(iA?)Rd0b!jip3 zk%(S~W^!b~emIDqml`8;@p>p3FUT`Pg7`_cW< zNcEzbRDupK5c|v;!rTp|H4USenSBZk`V2^7tG-3g1BZVSUZUp)caZK|;N*AmucIkShtfXHD=~s*V zMF(i8bPh??rI=$Y4kywgUiaKnteCmsU!Njxg)>s`*f?6^6&_0HE-Mcc;@|;Us-AXOQ~?hm#<3t*p(V2TlFh<})qCvyU2w3eCtk z=sY9oVo2t_;ntrfA^RL_Rd&$GY)68{m!X<+v!BQ&nd+_?WN6kN`N=3w>~~bF{oyET z{*CS0+MT3(L@ZRzF3MSsK}Qy5a&K@wNm{DyvPzXbujyV&o_7b=c>kkjtj&6D?P02u zGNbB`vW{2d#3V*e_|7l}n}Zl3{=G#~Uh$DwWDUCYIi^XB~?_KS*ykP%$%idXa_0qm{>Hn#N{XiWo(#k!K_0L`@gO zto1_eE~o1jPEOgrA)AaTS%>h6jKid+_G+aUNh_`ur$7BTdljBVRYTyK*wRl%8Hkb; zrC}uHj1syb!LK|?%NVK3gH?AhUTjk4J)UF>k4T8Y>4`}u)~WI%MlZOKvGj~5H3v&! z^WLKM_fs2qA-;9&hQvrPswe!vfO@wJ{lNJ3XvNvvHb|$)GH_0#_9$E?#8p(Qz0Jz2 zYP0N`R(p$;S0@}K-$9GQfPxhpn&^)Kn}H+VTa-#~@)5S6<}mwXY!T*G-m50SgmIXew-@VellEv(yc}7;vA)=vn4c=eKx{@EKB?XnymSWdk~27$ zV1ede1gi~3GC(3o(t@2%;>Aa4^{jODwiOH_b0i8QIf8Basv`P%v*wJ82o5A(s+SUz9Og zI|z?;0_*$7L>0O!)FfClgP}#%cr&y%q|K_#UBdCKY9*XP;ev;F?LIt6T8l;NF|EZh zr(~qn-2~lvh|_2u9+bA>@PqE8&vf!$Ng?q|18q8 z<13v!ZWhHS8J%2m7?+?=%c6u-`lv+D<*qIJZwwysDUaIWm|7ha-yBw@lljINyuCa| zeU}X0etyuOGd25*KUZY~X8?qT|Hg18HL@NzFVcngOO z-a%vV+hrb_p0Zr{=Eis^qa&kA-KFqs~FJP?W<`?6XLa3 z|HBL9d(r6C|FX`?IDSRG(3~L{iw?4_ahu7qD5~5fgqc7n%|UX-Dhqp$LX#{_jsy+~ zeUPX%$BO4h1`@KZVbMZ7+ix~N^*|<1WK4RPH)F|hIg_SWe9m@6@CPtg;5rOI& zCdPaMKU=|YknPeuuu+;A!5UIbBE=x=Z;K48+o3_Wy75-QJJiAxg9b_dLt5Q#M6QJr z*im4`;6;TtoQ0?O)g%1snZfX*7IuTVPws}7yjgsLcP#S`xi_&xnyXAQ$qgn8S$1VBi<@y#M_{Zc+X2C-Ye3GSFenC0p(pzM!es=rHpw0_Lef@ zz5JHp*l)JC&Gl8B_3L|sdV9^5?`AL{fMBSc`Gg1XZ=!xzx3=z|t?arzi2x}du}X;F z?^+ocpuh(M*teKIY3Bp_PEroVe07U+?fLHoDteKm=dr0)iAdJsi`TOTa*Ks;h3>H7 zcIY0vuX-R=tdD1XfPoUrTf9CrjiYBm8IML8<4K$YJC?$|+8v9G6F;^tO&9Fo7W++R zA%VeX*y!#kQN$V(_yBkTV77prz z9(}7vZ!iOv;u%5@n!Ghzv^95*C4;TDZuVG?nRrDS$Ve}TVgA%uY2UnhEIZZ=T4adC zn6bQX!5YUw6k`~<6oxm8wmK|+4$OXiC=PqE7O3~s$sByHhLvB$9)RhTKrXde6Ue2g zmccQ&CFXX+#*SUp8!Cyz*83v8KmB*TR~j(IZaoI{1;V}6W3WeJkM%fT$LF1|6DE0l zCo=XeVXG%{$?E;$A^`Y~sl^0Bx{FXs$%SXiO^=Ydb75`{Y@J>pUp+u;vVn8fh85vQ z+b!y*zhYdxL48xu>{J`dXp7goLz72>IO{Y+oQ+{;eA{Iq&c+ObII~>} zaklIIAn{6n^?E0(*AH3D5N8sBYh;MCG4BJ@MGZ0ai=AO@wxoVR>miZO#whEW zUzL2{>ewOQW>2aP8hVLyHb&Vq{iE^1 z7jvDAE6pBfpI1Vg6`G*UIu*28p|qJ~SrxQdp#g1HXfmsfi4J#ASI;k( z=WiGuuG>iVl`^99zj~f*E0W3n-UkmCOo;Oe4=MsjD92aQYU0y7N4DmeT=Z3ruMu7J zFPGzM1SDLK&O8_lWekxc?93I}mi*JCa{Yw3^gEB@_=Y_o=zQB>(UQL_px=7co-4)A zqrp&Cv$Re5LbKwcsva^^r8Rp(OP@tP9F z8p1^L$Oci?3`; z;rD=|2sJ9B?#GUc99OOW#&?<;} z4G$dH@Olg%xNM@5OC!tC@v9~IW>Fa;GNGSkMZOLa6e(jebMEyCGE1sc(iwZ&^$C)r z;6#-a+(ViEt8WB@k_m|z36_7jFM^@!XJC##W|MFn}h z@Ri(*$TzUe-}AnsHcM8|&Y4q9BZwQBhCs^VBpRQg+!p)E2#9PkO_-bh>PGQjgUzp# zG5xSdtQhNmeSv|>C_VBzny>^;mP6oVc?3=dxH3BLIK=S>X=9c^##m)xKqyK!ppp^j zeB`RjQ^z)+%nL$+#a}+HI43`jsS&R;NTfDAAUM+CQ>w0VD zWWpND--3(;p4>%fcH*0q^49I#4f&<$Rmz!Bw<5R1t-tGbh9MbF5~qA^Zhf#~pIg6x zlqGgwsKgow&1@ED{rx1ZIO_wUTk-1*64t~4XD14^;-=5W+g2>N5^;}S=>Ge0!H;asf1#W{W{}`4T7_LgPNnA;^7gg z0tv$d^^)Be6N0oyo84f3wkhK?)rDdj#if=|H_jrrHy2a)L+Fp~} zbx~WtpB%@;An6&o(1X~aJmy3Ny#E9S;!^hhc7?)FZxc{`F^YbeR!mYgKS z$Vud;(U*)LA$|47axOsoG#nVWi_W(#ox?Yg&Qm;o`XctnG=#SV%#8p4$Rwe(JWVDO@dtc zg%8Szp>%8998=pNR&rvDddR^C=~U38a%8~F#N&QLVEdJp;VChUgcmZuJZF^u39EmS zQebfA3z8}Oz9VHyN`C=d1MzL~GWrrw$uRtS#9tBfa$LX6hY@h~t0V+1{t;9C-Y!o5 z-A1%-n>_gkRHomZ@Tn9cs&ei^^G3=)&=q2g5)`ajrO3_6GIdfU8>z{UpWk z7$i0vBqwtu5fW!0*i*=RHk7f`tv^+%Shh)Y!dE?zCOQITbfPEmdT(fQH6ROf0^&j` z?8-=CSIT@DOhE0k!mi8~i_9>f_L(uq##8|VYCn;w#WsvHPyBT{yFoK&9uL1gqR#H- zzeZ(4?FQ~)j*&FOYAl`}V}_Gc_v91~ZZ$)exRY{b zSmk1ac|LsUJV6-9&*J##@P{Ug20g_)_AO^fgL3R2v&D~T$M7S2m-r#L(O=ORbT$O_ zesBKipmT42Jm@?kn76?vI~LH}gU$}>O-q0x)av-bCE2L!hq-btl}u2UH4dyJgP=J> zw0QIdbnKRK^ULqNIYM{Yn8YzFJ+)PrnaJq+k3CjR*+C-bAGzR6}>|6Eus_BW0 z<)1|p$H6gIv>?M8`6Sw>;eb!SMT@pki(08g7=u>PqRNq46p~2{s3Y@Q$=)=DrqDPn zI6!uH!<5#%bTp^9rhEWT(y2NSy3^{8H`k^8Q8FatE{EWdPlz!=s_xvIz$P%emwnS> z=t4qrFh2=}!6ZqL$wcePG%NVE+-Z^fF~Fs!0oLqyOLqn1U4=Y9PQJ;tDC@C!>n5f3 zxhblW=uRW0h+P?uRb57M>au-&>a3?=4t#d<=b7Qfvul{?#T@@0=l^9+aZ@2CBszUd zqzt2S=cVjvzh-0>wP$>udZW#spkiavKF@Wj{?K@~Q@drpX%mdT(bjAKAA4^DA60d& zjn9w-1_(J5O)ywg+NN!AuwnxmJJ{yHM9=6%(V`?Z1bU;E-qMy@f|QF0hJf)fXj@zD zt?jk&c zFf-?zefG!Nd#}CLv!3PD^+Q9~^%7TI#}8fC4-HkhCKe$TK<^R*W9{^qc&r@jff35-q=(L@2lhm2_L(bRqE@ZAca$0L zFzY%_nMi88sBm7?^uk^>pU#NLs5;r0y`Rs{bf|=_Y68xU*ifh5e@8wYEV~igWYk{* z(vn{`MyHInYIcR9Q*!PyzS^iLCi}v{?Z(>sxLcdUfo5fqT2>jcH-@8DUwL4o70vDn z*Y#$En|gW!H!8u5h%}Zv}9ypb}rtu;?gZ#ha;i zk5VD?fh&0d9|qKiBK?DpHCy_^8YI2H<34`>q;}?ctayQbS$>4g(VfUGYZSFuHSJ*Y zh_{%(=fD%w$jvMa2R9iH4P+|YU6W(GyBTU_O-m#?X-gj`;cXliiB8+XeN@*r44nA| z<$*WK1MijFZOgOMU+;n7EIHNHfoi-4Tw^|LEh2WT3Hsr3FF&KO+N8J*@+^JLjSCC`yt&u)&Co|E|zt~nN|p|jT3aPa7T zck}FM)fI_2vtt(y-O00q&e!K^eq?t>uaoI9kZyXsYdo}fFc3)Mty_m#HQh8VPRbN% zrYSN7+>joc7Bq8CViuGK{!HUc-T6k?ewzll(+a!;+T8++rV7mli>63tck?@`bsOp*fR3ARaGso(Fr69*x^8_qn%Q1n(;5jhg`+okLm3Qn zp46D=4vs$M_Y@)=pkgAQTj;~MFoTu!JBMK&F}waBc-O+F?uXTW0<88$K)_Ch3OOIB zrFo257e)z*bslA`S&4+wW52h0hKD<3u$ySSZ;5L@F-$9 zlXxGUETa3*O%~Au+9I+^XSCfPvG-f3-QB~S=wAoYWGcE~5yIp|w&{iNMj^!gU_@~H zUn_zskh*g(g5Bp<1iR0*2yRai!Kf!?P|qxa>2Xc(n|gG60@uVY!RU?H;jg)Kc0K|( zdKu$n;Y)l|IKH_!9toT(E8ZT7W*)$qledS!fg7XQui~tS%^~_VZzOO;rE^Q&lk4+J${;UHbW2I{j((%Q0-@s*;E#E4V>5-r$q`LPdUQ#Dr`@BerrQI>a9K$LG9*8?mmPjVjd$Plc0w%iUw>?;EaU znDMq54VjNPRS}fZXs$mjF5@6GPV`Ldn^e&Yd0i9!Meh3X6B(K_F?KtuJyV%&GP#g! zCnRLFdQ5|q)Tp_@K4O>|DTTQ~N?>ABQlLRfo06-Vp{wd2vZ^CoRV_+e)r_I4IwHBM zeqB|c6qZ_5)RAFHO#(>*JSome6uU#g1ID@m1xtc9WUuA<#^#?1Z2pcr3*7FmEO8U8jO2Uk3DADQ`TYP@xpphPNp^>zL^>>yZaoJ;>gXDwBk2vPX z|2fuUuY^I={uV4^!Di#e<`$Peed}!wvZL3nP8)7yN41I-_>+zm`0Xf_S3#+y?OL1u z&L|ZL@Zc!LmgZGa1m9G_14SC?F@IDNrlXR+_FRwC%V11L$(b=7Toau@)2Ve5q~kda z>45$(7?8_W{>NBO(+D|qK{><(3ANb_)E6W{IUEE>0=VHoHOlRGlb{;dIi?=FIp4#c zL%5@sreHR9ihDdy^spq%hGJOX6-lpNll-Ldj~_Uf{_(wM;U9P5HCnZQd@Cv<{_%5y z*XT<2Xuof~hP3P4;WhSZ6(^P+uYu9MUi1C8Mv~NmhY06pS!@yu z&1szC2hNF8e6I^n1gCf`i>pWCm&Y#2>;votfBuGiPb9$n!xuI3=VP?-!@*P>57#u8 z74N?>ns>?y9MPGSH8>B^cn&ZRfMx7834NSBv`#>PX?(KDcyJRQuLlm3z2l||XoeQJ z%M@Or%I{84_}xi}3BHiTZ^S$P8olBe4c04o%~9jQ-}7sp z_PD*{Uonchd;eXDCLd5ayg4r?wi?6#NtVoP9dDeQB$zoa&v#gxgNe0a!lN`=3Dm#VvFc4_88Z2>Qkqz*-eF~=%9 z#kk1s@k93nxf8%)1hRHI0_31Flc3Q;_1$ao=>^TCNB6LI9waHoX##Bp7WSDw!g zn4HTG&i9JvV;vAGC-&h0?)nvOh&=^me|kgakCbfD;9jBz7lZ)_3t$+;g)+`0-%BwH z<8%l4$6u=Y8L7<2#;PzPH>HjUeZ4Tvu)su~r=8oQ93ShYQdW|WwF?bM_^us)Fjsaw zR~Ag&qVFRl;Q;;js(6IQNe7xvTs&8{Fef%g^nF)l<;>w9r*0PS?@0BKD_R@j`ic=D zyI+SPjt880#K>?*nlJcX|?z-v&obgn9L# zJ`EiBi#`qP_)D_?w>rhbOlQ-q5-Z=cbl9TvN%aG${GJQxZ`R@K@;&$XEj#O$CrF*< z>}c`E7Cr#GOMpK8x!cTJkz<@S>Z4(MPl)}=PVg-*m~*NHVLom+*oWzO;U6xsw@-LP zuYQIXu|=$8(t^n7^Fvum$KIPICm^;}K-X^164jdXN

        $U6w?tKT@c&g@Lvze-5=` z>6qHlyrxdRHs2Gw5X3|M#+o%*Lavm5f_^pDEXfkh9DPKZ`IoYoA*i|Mc~=g!;OooF z(B06x6I%H}PeLol=*~m6o^hSncx)%Q`vH3SQ@jptz(HyWeAxEX-XB3PM?lI%9G+@U znv(fURP7L}+HBhve*JG>3-dK?YF|y!uR9W!!*H~8V32-ox%BH)!pjdRe-S3MQmM}> zeUa$YlD!Bj^~;`fn!L!-gx`PitA0mIKWB-H9G!Y$vQDkchBI`=qKML~6}jaQ*i$EC z(R4nHOjlvdX|Sh>)5!GHFy>u~?pTngKY*n$I0Kf#&keAp@M8LMeKhZc72ighNhEOC z3cOub+)-xlv;r~GNZz#{R}t$n!^)!n0do^%$% z*|oPOSqPELcLz5#L{CXl1WtG`QMSyF0PT~*ySK0;8gtk8D~pqm7G}ddIKqLxC9H$n zcyn)eSqI^|M7&@Z#FUx3Oct1I$252|vofF!bp!F*kJ6XCoW zal$5N##?Bgekjqbi`71DI{UP2(|GOP*g~{(tZJv9cT;Z7_)C!>Xjtv_iES@OS-cWk zv}0>CogG?l&~*P;F2>oOhf~k+gsJK_eWyNz|zPRSm3P!_rfZ*H_! z!H_i*zR`s+;4HzwW5o+K6zCN+1b1lf#uIv{YCMtHshpK^Gwmb8c^{$8W69OQu4Plp zNqM?76@fI`K_K0e!$cC`q^~#V5*IEuq88=@Sybqs4Lp)n(;sXP*`hj@iGEzxAFgRagmDD9>{{+JzPdXc&8Fk(o=9L1=aEX-->1`Kd&BX@crzzr zsv-%f=8>cTV?dn00&~4kSt7yK<$I*l=rHUTIu36BsoC*WxI8kUg$1N#^ zJ)_<^8HX@FCa-?Sw1-0omp}=CoC6wL9Jk-8Z(RN*;MFd?hO3rA@9w*2bWf;`ZKWBp z467j+Zw2De3|_hHh1j%WDt7smXvJ&OsESVhYCJhWPmZdS+|;yy&u&B!@iuw-Gt2g3 zKCbYHTb}B|nN6U)unBe{CT}TsKL6(MuedH~qwD+>zycHK%;sdcb#KrDaH70sk1d%f zAjr)axYBrI#6D`(3?QnDb}cYEto1l(8BCx%NkaYlyEAz}nG=cTt+^}7zhna55(W&1 zT3Ojaa|l0p<$J|ZT=d}rTL$=I#ZjJLE#<-Pd&jcQzY7L?d7zJeUG{po<|xd+>wc?- zcVRd>?UbdMmk=_$>s`(k&Y|m7?I4EBax0z z3tA;0u$a0d!-PY}X4B1>6pQ{jp#z*%?Y%!ioTIm^hXL6aZaGss@W>M zIpy|lm>R*iqG&GSjiAkmj$bYLMF$h-be%)u9O$zr=pDhcvNPhb0aItYMK(RAD|z3n zIb4f#Mw*ja+WX_o*`=0|6JlRnpeb`6@<`B44^NwIdUU~4Qq!WCa~Nba6mw43`)AJC zrRerJD@pASkx;beq_%#qNU?tJ@g^z^)*RDbTgX8We6-kI&b;}+BG8c$v^faEcTwkj z=PsS^cF63@=KJN(VbgWUpE1+z-%6w7z)hM3ZlbFbj*dT|X9#U$OsSLKI|YGXd)ef@ zg+J4>*ji?vEGvGq_|0&1N-K2I2_T&a?6Cmxv?ccybcn#INT4$;4T9PgX;`aHn&nt<6^UO%PM)W$ymKqJ{>adUnt7! zf=~M-wuLhctp2=LH^!Y!(|B+{wypY|ys@k*RCzV;rROUJA?3y3?(Ka}E!4cEj33AT zw%p$HU?gW3l_^B3q(;egK}zI04!2y09}qRYhfaax=Kv1SFEYgs% zPJya%Qioi>P^B^*Eeo~ZbZ(G0-JAev<%+0}!ApEX0}YCw=L!?KJGb*eT@8|oe~s>MtVFdKuq;908uo@s|v4*eMty&hUjYNVNI8FrS5nxfb$uSbv#X1_A3I` ztJqSVBYFOG8Cn$jg`4!D}S+TDCx@iPQ@?Q6~ClEDM2Bae%i$1pyRB1P04+NwJsEtNGN07rD;ij&W7&i zCl1|@3ypkb`%_c`>{E?tz- z+!8h8*Zd0(%VX%;yAO<2KPMf6OFyRxgDT4Hm&)xPd!KzY0rjq1U%`|vx3?gZ-#V&J z@Bkf)hl$S3uxdpC3B7$LW4fz{DHHjv!$h-x!lU%=5V8qA#|rbxxSZ?%gzCm}qSr}P zjWxnZ>$1EX!$fa*$|E=w$*V{jPlLy7@b{McRXX-WpN)yqT(&4jMhn#-ECFcIQAVKsFedcw+{lkgTScGUEB0@6F>R-zE0e zfcQ%2>4@DIZ?dAR)b|azVKPVnLv-@N8>H+BRCdT7AmP6Tm#mPzjqeOazZg$E-O5jx zNE1bmoAzco#<#o~mxmWk3ENxa`8QBSOyrDzT1n4y4or)Qb{Wr<7%m#|k!!|!LN=Z0 zkP+IRxu|~oqG?u5TPT|OX)NSB==As^j5p8}>EHdVUok})@{7P!Ia2hy>P^^8U!lWb zxrd3D0tXgVglp({T<%LM$x`&&R$ymzhButCONuRZ`Gb?n=YvA^CMuZUR2TEszNk}l zHe8WNp~)R^{jxk7|6Yu@OpD{E^t4DcJ24;fsRu@^*7IQnWX?S$K19mKa=4og*N;tH z=GG-mkkVUc^C|UVbxOtlAGVK!eb?>@*nK(f1GuFPGnIPt2f$qpu zu?~%yf~V@#N7rA{547lGomqK8=Ev{V{Ftuihn=Y=)BPxh4w~$Qw=eoo{a8-Qi5~kS zni1T!JUe99p=F_r=2%9EBuyDk%YvO{Mx?X2qb%6H{QL%{3dgd|>keGE&UqAvQ8|ga zXiaX0qR679XUqK)`$z{Im3Z zE+P~m+xCV0+x(T_Y5Zy>xOc;1I$=?ZPA;(;drCHk?Of@rMu-ruH3S)W4(Sx zt=D3+aM+EUftLe#8EJ+!%|N#CcGma$iF-VlhZ7|b>? zfCLxDx@G*54dt|I1==EkZJ~@##FP2I?vrU*^=iDGRbzZ+a_DJ3h9$p>_BSma#ax1! zFsvIzyH%3+orrHYkx!*eaa*-2cRcmv+)nxrac{l#jrV<52@g%~ejqDC8Lh^uXFWXR zVS5*cgJ!pJ2tiv}MyIw1hJaR9_TH+4Cd&q&8h6u&Xn1n-qC)MnVPN3d`ozu*b0vQeo45DgY9ShLACG<1amDjlY%}|0!4F@qlzdYU8=7r)e0o#kECm$A{vNwMWJK8gQ4tCrSYDvn66bMDx?NRR0v^5U7WQ0amEDI`eOck;KVeC)TQZ-{ zT8J1gvs(~c7HG0J)xDd!tc=?8Ubv-r{miWhm=Xr|21BF9HJLd|fc zW6exfVn%5t=ANs}l>=(NJ~Lj;*HW#R1veTub(z7=ka1J9X}9;B=sOw50IV;P^?^Sn z;tOzm5k~@N`mnS9;R`Cac?g`APZus>)a`L-lPkR9VyHQU)AmAk?#-fB!6yMnQc+ob zTxT!88@PBn#XN97dm3Id)_!x8C|rzwY7kI8t8KSwk3%`*?W|fq4DMN;Ww+3tQ2%D_ zm{72BxsPP#S*&^up+_t$-rN>iTf$OYcOv879D6}wslBLh8cm{-*i-b44mum?hlst4 zglDF`sb}{|EPVsC@C}p&-&=mA_)SW@qD*NtSt2U-wNaF7pea7-TgaK5las<>Po{4((oR@qcQ?&CTHK^@3zIytTS3c2IW zaLu+52m2zCIs~M|3U(RMLtMQk2q`8OXNz_%`9a{kR z2zK2&pSI_4G_#BPwmi^;ex=0;=Y39%st&o{$XThIU?t`kC%=%6 zpZ`U|Rb~{u7HFlv+u|Uhh}f^6%kig9yraN1{`6r%!GI#0ol?Mc#yVf}H;w;6Ue-&} zkN;+Q`Pq#BL8-$Kw0$MZ#v^Y;>_c34l(}vg^BTh zF|dLDw(35`6?uV z(?v&|7mh3*TQtbPWG_y094n|J8+sxpGpNtbb$i zQC7S2c#=uAoWk4!aUKgo?nIFb0UYYmAQ)Ba5jSJhBXb<1=@&vQib5PY%gM%+iAarFrZ3)vIQD3U!xH7!sj9YE;d}2 z4p$cbtA>kJ^q@x>B|kn~Owz*V@}{vWe|Qp~%W(SIW5wfcs15f`@b%@vGx52onkXn) zQoS{!OPT!wjG%0Th|W0$yDMiqpZ#*go;vWgv24+tr{Og-*+lv51^J#bp>i?nVuGzH z6&@GTlac5lx&V%g7BkS|;%nh_MI3uwvx%=o?41bS3+$%DG}ixUc6+(q774Tgg*m0} zuA%TWo#!+W6%qiQEuIEb9ASGfoFe$>rE`{r${l0p;;-oS}>T9o3mffH+71;Y|Q z5E|y^Y~yn8C7gw49P_%Kk1QXH;lA&6LF%z8@!>SyI)kD0PLBY1c^OcFzKNWk18PDxpf6-}t@ak3J#i|Gmn zg#QT_2tTo!yY{cY3;u|UZ~GwmBfjt@@JB3R{s=_M20M)#JMER0e7vc-C3QcC#Y-_t zu+KhC{z(R5RGU@8DG|`gLOzlsJNiLSBH0F;u;OFXj(%*6Y~TpLb7gu?iBF%NQ$n-KI&8D9dMB|;Jk9f5B?{?O+DIcmdCf=Xk4>K-#G#ll z18Xd%m-v?@DfANT0{Xp?HbDqyF>_ca#4a@8$__$;Q^c^he@Y35+vRmKorP2ACbl@) z7zQN=lyJDx)8+?3M3;p2d(!ev$n_Mu36A*sfbxU5Li7glO`Ik~FEu|%QjA?1zKJu% z*rnzN!To+IFD>7MTu;F`>R7w8%MbF9P7_$pX#yijX#&rjA4HO*`_l7Gc+&7q`1;Qx zKgc&U;x;KS$U}<~lIY|GIgKPDFUbEDDLi}DlccO5`-S!7;5n1R*AuasJ|$M^vVuS- za3uxN@;78@=THV!eCA!rc|mw!&qfB*=LONRnQ8Na3>BMsHhDoFO96iOYuXd!1u^YM zLoAQkTbcG`C)1v+chR0C8j(VKl5~C=DldpnM04bj+$X-Y+$SUdy1XD&e1@tVloy0$ z^Js5R(kV&=Z)AGz6JOFPYUE&fa^(f_$s##&$h;uFwCAXiL*@mk@`;F!^t(zF5gp~+ z;FOq<(UD0qD*PvJ%W0}AiT_0S2OkPKg1SZ4oWy#Q!ha$OYqYdZcP6-BSa8}-n7nD1n|;@}u3RC1D6LQ;j&rD>qK_^@OH+04je z;RW1l-2a3+fUS{?7djir8|pRB@@sz0UA{&#U(|jL*+8E3XucDZ2`)fWCwwQ9oulbQ zeNAmWoHf%Fu(>eP_1-GfCVLWjPZ@gsX`KsXs>66C+$*A2ZPViBcJu&uSR4qps7@4@SJtYaqMygE6nP19bMf{#o4k?XYpuJoGmSqOE%8YLvIILjdkrGL;?>vAmK#5$1@avOQ$}N z-|gh@n4g-z1BbDc^XF}R{1krhqeJt9S1W$-Uus6fe;egyU~%z-*Nsxg(4{J5^Pn~# ze`%B)5BaQ%A1X#A*^|Qv-7JXyZT#S>CMo>j)hYboI%d=12j>hRVuPmh=l`kH6yXVe zaEaPnBSD*d>Xd^dvYCPz9Q1`9VqxZ;=PIv@zHm{>d2+jG@ruKD@OjdL_Sc%8zA){1 za$oHFH2j5E{`LHY8OrIn>8urbCMkurc_Zr4&qU$pB4UnxVjIs{#GJJ1oJGvNp!N7o zDf#^xJkHPxJ={)>_f5-P=;-m=-5e`Ew`z2@`TfvmS~c1zv2rfr!iQ2c_`_O*7vjQ4 zIh&s*E`$b8)t01wTTe?|2)>`e`uo0EBpr9*Reu9_p&q-Iv!*U=)-jxr$n6rtd2XB_ zJ0*(qTtyWRD(?L`L3V1ry;=13JCgMF?<5YGBA8obl^K$^(5<&`*9=b6^?dg0`JB+( zr>D;6)Y>_5oTRot?vNHfD*5iS55Of~^ll!h>A-#E&?m5gKQ4AeQqwhM;j59ru~77j zUW@hir+ME8O9vbN$b%lxP#z{y5n7ly_ zv{9J63ni$s<@YM`Z-*J&Vbouz^!P_bk3R@?6)tCb{Z8Y--|*{y=~m;7RlG9=*Vopv z{N=F5+RLL9+@S(#g@dTKT7^_{tYh{>j%`!InlqS`hx)ts@;Cx2cM3P2Lu5FXe|@z# zm$iD*;h8XSPP;CNQ(!B#d5lrCg&%KMTC=F|S>QQhcOZ0Tt-$Mtt2eTPWlcBl#+o_s z(aoyg*C+aYhB!PD?19^{YV=+RE`$^D+Gh0S&!jKAsV`rqYIagzzOuBec81f3i%QXd zV_f|g`=oO=!7rdd2W%b)fy^}R+U#x@NKP1;ui7OYD)|77)t6D9eYyFL-cMlEX@JJ5 z0h*CuPcoT4>GMKy$RnluCY9sR8LJtNcgLYPoWWoRGnGSWCoO{s?Vbq^H)?HJ_2)$0 zpW}3Y#+IOi+*QpyfbT38NU}NGk$+@l!LeUYqPi~yfdmMiE5`% ze(%xxv6H=h-HmA}zvZlA2I@sK{^2}t3KRI>!u@^XFL?>&d5C=N>6GWqXHuR~ssEq< z`+o`lcS48$Tll} zxv~Fd8+a;Tx7ff*nI4M&+n1t6k322^_c^eD@70?0;dHsN6$5yc_kA&db7m-$De4C? zfJ@e>Bm!_VJwyE<25?82h7n@lTdYmPCH|+kpiaN42*62$PB4HwwBLavq3C^gXtlbO z)#{Mq`*!qc;rrgo8f`l(cD3K^*Vf@=zHip1>C&`pRKW`axXEZBX8hhNiq&_N=KPC! zUd{Loxa(YmRDQD8c#t`L>wm?4USH+al;2&wKl8Xu;F_+p&Q1B9P-)UB$xP`zD?R1+ z)td5qN|FIwy+q~0=Hl6>BNlK?392mM3BvE4s^+PL-!OgW2sb8UaDO_VwY$n4it@XA z@i(~>^gF;?N?Pw2ROoVT^EQQ16fdsa?BuU51@d=*p-kWr6_)bzjG~REXv3`KZ;G`t z_zLyJqg!y(FS&xha1nni!jiKi{vJXrP9pw38?89+%v!OV_`Axb7dyn?shF7}J#_da(`iy14>Ez6?|&yN$IU8>W!OIm41DH%YG*%1s^mc7#>p z{l=mpvFP7(#478-E%7#ALD~PiR;pl9Cc}?r}(Y)>9y2fFa{g-f{KVt7i z_Ee-!wc@QeMKjyVqEmib9?koen@^GiWo93pR=b22v?-RWLSU;g^^gj5J!u@dnfv+9 zfkAf;q~00YFX6fFJN*(sn|h=F#%Q*b>x-J1;kuU0LB;#rPjQrnY2=y(2rjkTB^~P3 z94@{H8{W?Qt_#<+Mrsg1jNst&ILtaxx z$ndE^R5g4KO{feeKCtBB+us*{@b{N}fcU|z51YXMBl%mrvBlxnR3!PB#A!+Lals+U z@79q2jl<>W$!kEv(+T?7pAA=M(H{*LFeg?S?iD_mJ}_Jkiavb~y+`5xC&)Q;K5+jt zlX3qzTmtvcC_#VHIkdo=oOw#~Z9JJ$cbt~{c(>nxgD7wR;+=VdpSUKgRLC_YG-G0@ zaG`<*&O#Q~HI3q$3D=wq+c7?Nmh!QaPnI8h;k!WTNCYBX!;>aFgH{-mp z{f1?~YXy3&zyKXAIVRw+)gYykDi1bVux;)^eDee|dYd=F=RC!TMDsYO;rNee(EI^o zMl%xzGV+05ADQR_r%2>#pT2UX(#`**(on{sjt(rXsJ+d!*Qn%=iaviA_gfkCs%)h# z;cz%b)8~(55>?Hf-|8F-B{pCTBSsW|{%%#cR+l$&cWy$5|E!%42_)5A>Zq-Pi*Vhk z-v5zQZ#?%1tIyxY8YebAjvfg8(4!iK4Br!&JC6s00Th|6N#oB1s_pai-^-Gk1`}W$ zqf9bbo#Z^1g+&_X0M!$H%jbB%DARJYqdUt}?$k7y4l08_snj$@$*2r;5h4h59?F*A zt0;n4@M(728|$7_Q3M5S|Mp>Jb%+kO_dM=$bfCN1F}axm9$4blVYpon%GhkcfDb(oyQwi8<6yvz_dqN_SD{z zu?URA#>x12I}QsjpX4V>Qb}X>vA}9LRsw(QRF+)7S6OmB+IHKQu-!hwL(41G9S2Eq zeyqIatq=-(Lhd<6O3;GB61pK5S!ImeI|?oOyNGvP#b-xDGcN+Z^Kfv35zSzcStk(Y z8wbMnK3e0N02qbe`2|K0?gC=eet}7tJY}>%e?p0Q6)a2sN*#U1-d@@G_VqG^77O!(y&2 zR*It1v6GGx^C9eA6-P{_)J61{>KniWK*Mx}P*$O7t4N;dMXm2$CCPII`xlN>}H_K^y>bB9dCQ@x7q~a(SuqhQWT+6>cbEfQoaH$%=FQzWNLm{@pe+-nDm2nV!BQ`dy%D> zBg=|A=$ywqAcFL4!BY!)6+9A--pcWC({??}p>bvOW4HMy>NaprEP+1lU0o0N^~9Ew^f}SuLk5L9odZBS%nqY zQU!n6kReU^5&K|gcc3-~=_G*Pm&B8AIS>1|kv?4;SxXfuqh+9F` zowJQCWz>QQT2Rp*^MT!rs=i4|!y{B&cMLN#-?u-H7oY!Hp_G)u-6jVIRyGM@6=by4 z%|e;HV;I+!ZkyA_6*V6GDO(T!Mf(10RN?}((x3m-J{i_$_T@2uC6!Fw4y)yxBns@y z?!nmh7^~rbLTO#bgWX&ju)j3rz5zMO6r6FGs!8<$2Sn97G}-!l|A5|yVnIK@LDgJ9 z-LV>NL##fCRH_zm`(v^5Y3Y{1i_vwXevTvoy67UQVty7^v8A^HrbyPB!7B3>idgif zCw3iIpq*~QU|%kkqIbN*e%-fVLhdsqwfEdM^^lUBqp=HV0gpk?t?uVyR_>GTCh1n9 z(*n_9gzPaYg}o4QS@x@ekUv2^f67?>MJS3S>jzj==}oUK4cA^Lg0U@j9Xi5L_2H3M zsR(%?%6!Wd%kZ4`glKpKyGx@P8wndF3kV*`fLcdSO?peqf#i{NiNQXPstk?foPnjw zYL`+)J{w~EwLj~(dpJzOk9U+Al}J-xb)5cGGiSnE#_AvNGC2^holV7M@4jbFZ-W}k zF(HWRwbFoJqc#_!#6?shsAbd@UhZR$WB;UKEmQSgg*&gOJ7f2oD60fI=qrn_pm!`Q ztO(m1o`tQ}GOlG_kjz#HUuKJG%-9w)cxYbbx6D3Z4UvXB z3M-~JWIsS9hV0*plk|po$o`}3x7nK__QzT#kM%IZONb64isChFH`5wPhmVp-bi6+j z%`Or<2CbXXDMA7Z?zC0B9$V4zCD^}M70MW}qLci^+a(^pto~T-C-CTe-d9JnzKo5S zIj$XWLhlnEVU^yjx;NRaG!?zZr@`#eYJW~RmJlU7DvfJt7s@%0x&9nX{&-*PYLqou zs-!e(M)+j=Udd0caKKcY_{ zqP(&ZoN-}AqTiyF30^UNm#W%WUIA0j^olVY8nqDTJ|$N76<%cvU-)Nz1i9em z(0s)|$xN``@&V>M!dDCj!H|5#U(lp;Vc5`?rvf_O2kYvUGr4B7wzwFL)$ck^L&zh|Govu75-<2tR#c;!2;^m$}Y{krfbhdoO?aWu)&V0pt z6MV%x6kqXXeyipy-bw#$NyAqR;Ys2vW@)hF%r0RD_*oyhcg6$t{#Z-EsErbS(N}Ol-6E)E?Rpnwf0lGwP>nhCr-~y96L=*(lHZ% z)+PHS;gbs4jO1rC(gfxtKH_i^`%k9icVtdtNza(fUmCLa$;#+Z3>USOA>Y9=uUZqo z!3XbU$~APGSMz=1=elKuGd;#ClQ#xB7g;d=6!W)bg$sG%{1|=fxu3lsok;wMW$Yu$ z??Z)Zn+|CljzI@?;52_Ym?DLNY43w`s8l9t{;1+;F2nZTaFVrPUbd*6pJxuaOB#f)Zg}tt;9c$Gq!Ub{*^HYk8@g- z@1bhXD&WD^SOXX3IJ**_E|)*=bL`5(XpP{}5(n0=+3CC8SoAkhr5fmny#|q{h{D?m7SB_kcynEg#ImVgy(5dVS#D)n}MS=9+8@jOn*Gg zn?irAID=^b{o&|se#p=SQh$X(IB>+OX|>=lj!t71;c(!Tl@YTt-Yt)2HmY(Ge958c zcxH1pGu{S$@LdjnF!Rck_K}{()X9+x_~eBISGm_SH{J#K4i6-p5s^=`c4_&9b1&DG z0Q6Vr{|OjbKe&^x3fHulBmmJoBt{}#zlF(^Lm5~^GLajU%N72$++ji-+_C(S%I!%V z(rl06`G-R4I0o4PZF>2M9qzxRaV>> z8%}2@-#z)J-D%n#J)fIO>p{Dj(L5BBu>5b3efT!TEF7{Ak*WhDD_w|`GpBcmQ>8fi z6qD5o>B`H-1Hs{trdN%%pBgTTkB1i#Nk|+~{!g|Pk77DC5?AkVG3~O_$^6AwZem$X z5DX2}AqdX$BohR;WeGv>OtyrRCZKy_jQI>YiGNF?3jS^uVw`nX+Pl%J*vPsQK4Z;N z>uDzKVzP>HQ9qus$%mS*i!Tj-pJSKRa%vFyRhS*$P7JScmXl4dl^$45a zBcyj$MC@k3M)tSodCCLLR?UX;ninl9cAf<-%I6VFYO~84B259lSbMHy}$+md+7j@HD9~S zeWf!LHDOaG75G5NxVG7SZBO)OEI*~B^KCVaYde!ljD9`CxVFEpDH9%A=0IDmJF`5v z={}Ae%G@}p9!gOcAD1MB{+f3>z#9ox4^!;^Ki+u-@(;J z7~n!iHFKh776wlm(YKX)e{YX{(%pYM2lwB%rT@a5)-I*{RF7?=SGJ+11K8u79@}kP zyW4%GIniS;svdK$wIq6Mo9eMdiP3LTkDW;Bu|!X88uWhZsW$1Ufux>_f#$63?mW|u z)2$)c{?K>aH7wz#oa`6ENY;c&6~P(BpB`MK)k5rov91^#;dbKS&3ss)!iX8YIgSH3mJgV-l9EtFF!yiTILRb$ChG?sbQk81C?r>Nyf! z@<$zA@|#ft?ctn)4Z`roh@NkcQV0EpQF20@pdFM;Qlm@0m>gY#VCc3U;F5zLC%A-}zwFDd7@sz{BoReo2I^rHFatkKCHy+un38{MamAD@ zOF{qa=E_C$yhFs42*5jiOv(R-c#@Yru6PneKU9q$HW+qpI*}0x+_^-R3>5+LcOFsl z4=E8P7~j7=qJ*8Q<2~skN_=S|O48u<|N4lMq`>TR7*Udl${r%3WGpZo;GW za5^!+Qu_E3=2wEv7oL%;#Si$RiY__8)`|PqdZql|NGvg;OODadzk=5sH6HvuzvgM~ z{(9xh{)$o5-TUtz9bCfUwGg=+;aAeZCCY`An;U#5;zg|aZXJdv{BA?PrD!63F;%{&#&>P-b zdTZ_H>Khm3pfZ#CmEUYHgYFdTPbI_!R=>SaVi%VPbdH_4%yEk_l#O%?4MD~8u?{AB z(wtHUaM!OG$oG^htVD4son2Uo>L5+Hi=d6F@ne(2N}Lf%iYiGAOPa6}lT9sLR@$%< zcewT0hm|;$o#?7;PI6d@yRzeksBB7DiK!Tks>bIGuI$-`m3-@i2rCgSE`2x&R6Ta- zyy%3J>`VzKsh*Q!u#tFcc)Xa));^v#-Wu1;xhmdzhSrEbJxUBR&nSb;lUgIbV3ZCz z8I@q?XWPfgky2I8HHACg7@34~e}TUC_`A|*gKUf9I>~FD!jWqy(&D2HDsq|4RNvk z4Pp&B4ci~{Opxeqr; zetrvRY28FZx^TX(G&#`p?3 zV-=&DmEgy;5=^zbM}*K(g13nfsu+I=p#}8*8HDgg=REeo$l<=fRu1>L<#4ZPyE^Vc z*P8z2jb{{5v>J4$&8TBibwz_(7HU^C!Rmm83uvlBc4T>@BYHs92 z8ZXi@3gsupEFgc=ddVnN1(dEt{&s-}XE$pP-9pj%$3!-UM%EwU2&(*^z(qB{4(sX* z>|tEJOB%9hoKLsJ^uZ#_4nd>-cOFgkBY08-YjevQy{?wsP#dO}J?CIZH^oe9Q8v%Y ztLdE^=_ttBF#jOxFdFlU02txyuGoyGY~!XNe^EO%1qBXj%DQ&e<&gWeVhdI3=wieZ zS5mVo(4+%*ClWs}-RC2Tnq3SHm!pLX0S;$I$`7L}=)YHDOR35ncQO8Ij^^N@U;@jk zLKRCajFcpw%_y7EP5XF=s{f=^E!^;p#^8(Lh8fR!< zy+(=}As8d{MB=DBsxgg}Qj$ zv^!`JdTztVjC4tcOCdhN zo(!6@2s*VN;b}8eBfg@9!fE|TPZAQMT=%R6e!Gb3S|mCz)?#SY?_c!sh~3tp#cNZ8 zywkL|1HH458`AqRkA%`M)ZiOxoHM=L33(VA@wwYn;2b88VpF44&J0Q-D!AL6>}qxY zp64;jNx3aQ8nRD>?3buQ`Oz6(lYO{fZB$9c`(n_zr~cu|JkS527Z}W0e~fOu7Pk(# zZXMuTulWzU^^fRP>Ld(x&$m{_`#Y!I4Q1Bof#SfMRUt4|=It+*T;{5=n ztYSS3fS%s&Opn7&%=ur|Yvx~A1~{h-DQKaLo^Z{ZR?{mPmc1pO|I2sIr(PStdU$dA zlB3sU^v+|v!xo*3E}p;S9W0}Lck9}vnXNa^tnA3hcH?d(6eceRKtlM<2cJ^3%L- zk$&Bm@w(RD0KMsI;d?gfj}GH6tXI~*j2wIm3QL0$`f1d6gApY7rcu9f7>c&LX`5V! z$yj&NXWah?eTbIDY3~Y0Gq;l7z0C>^+%vK~*lN@*fz)hS`O*lQRrijFchq$Z#G7bO zvReX8RGA3vcY$qI^g91t4;y}~54a{|4E2Y+B(hcQFp?X&Rv(jWRCTh;$;kE7t$w*2 z@=l=Z_+bM7kZVn#gG6b0uxZ&ZgFEjnwrZN0OqDas*&71QcBgASbwcxUy}}&+I`|@L z6cjq}9yTy`kjC4}YuYS(D;(6oc=miccD|ks(Ocu#j3wl@1KVr~tpZWgTik)Eq{k6c z%GsgzXfcBKA2=3IB2M(BSq)o3k~A=(y+=54fsofx9sM%|BCv@^HzFOlFbqfXp%9Vw$m z`(?!59%w>01hz$L_LK*9hiT+=e*%nQ(%@lhf)}(8A&N3e9@EH;4C`Y$0vX3rKmC+9 z3?Yd!aQ@N>d=p=%PqT*cK!$_+m;GB=u<72b!!?cJz&l~QGrNuIVg?#%Sdq;$93${W0T# zywTKw?-*;dM=M;#@lgs-(KiZq+D2?KGczG9xn+H2#lYET1^+dV{bBx0hP%a|lW=ChZJE~$hf^MstZ$^7`mZx8vRmn=itP*% z@@KODmrmc6SvSy|aXpWJ>f|C_x8P}`vRQu1#&1=d@SAB=$d6T=XQ6{`LQHGb^?e8y zlmc{FRUP_m&3p^I)=g5Lb4zk5qt0B2?~H|9?>}=X1!pd0!kJ4cN-8By8Ix5RRUJ}L z9E1M(g-$6_FzzflbA?LJTp{bsrOZ5YDHW-uuuP>XYhI#xBxCrkayws`&o+N+Wi!@L z#PW7ob-iAr{(C3mafHGcxug;!O4!K#4VKg5?U;g-%Zm5o-=|o;T4EF(!MA5Z>cff< zlWyn!hL4sUPM2GYkic3LSo;9}wBygixT%phiQL+GTv!GF<(oV4=P}%}N8Pf7FUpOG zc(2`qKTq)Y`TVzp|4!z=MYwnnf1ad;sgSWAMsEEI>)_)Y z3scb*LXOxz25sg-5{!-kHp=Fz2<+fujG{CpAea{~{IUzdT zYs@Bb&yAeqnS>$sm#wg(H+gX~w(8=;=;Ey_j50XHBZW&WI!sZ2a+p26YY7)q!evyv z1S{b|Hl$W=<1$NF^r*y#v6y}GaV7%0lfG1yKY)B(wBkR&CCoHtXMOgE3?wZcG5yS-PF%~^bQ!!Uy!y}5 zkElm^qw2>-E=SzH<8r-ntT6Q^=1Y4CK`%I z=soT7p0(25kMMW)yi<=d)Ql(UGW?~UtZ;gAp3{>>Nj-V6Uz4KTiJCJMN&1azg7b zt8ZLB25t*&r|3lLGQ)r8fN)S<)PNdMRlmvq=H5EMG)p9deN1+dd#9)-EVLDKpzM{= zpX!UgPWM~ETHmtsOo333m&F`7YOKKDdK9`DmMi~7C+S`@T87UbYkCxmHk8Ty9Qrxl zV$-r^fvf5G6(QqBQnAbYw5a22#JKTzkaTTh-Lex1?!LExW2#qVsF>=9GZd%;i#o1g z_2(dK=yM!{s&%{~QT;f~x-&zCSwmSYYq+F$u>Y?Xa$I@u^sx^}Yn+jIkiU_DT4;7&hWjgg z`j#rM(YGXGcUyr2 zeA2>pRUYW(qt+Ar;M;t{Vxy$}1}URu(YsvyeP*AI`V39%GmRPR&ER^Y{+Gi<-@17~ ze6aMfYT^KBOuBIoyOix=Ook!}CaIQ0qw3cx+) zkIleRN?N{7x>A+H+hmvKz&2Kk!dgzy0FaP)mjHF5!!G?ctHv5QD&4l5yUjt4;`&u835^;WCfLgH z(a@X#>Q{b~B$$yLpSaDF2B!I2G%&gRhS99IOwjL;F~KCxihheBFn8qm+}#EKgOG9g zfyGl1?A^ckll0r$i;L**i;F)ZEMR@O(!4ki_w8OhhAy34oN%twhBv(-^LI)NsQ2Ky zs^k!fi31Gtu$-m|cAX?5HU)JHpso|4C7A=xW#M6S;wEwu`1I$g@bhsWYJ0G;ydUYXT3vuVSs1gss|jF8Zv_$ zLJKkIS;oUJUJ$z+FZ#GZL>2QKIOez&xf+(8lhlS>!2$pqI#FOBT<-N!F8ka4x`Rw` zwwXF55HR_QRc0c)>vPiA{arl_9M3V)$F;w~Zgvd>U&--l`WoSV!$jfb7nhlPCNfdo z*zabaNsNTR?fDHmV>9IqYAgiil%v^tcr0W?qB3Xbm#DGOH>bA8uQGH(%Aa3HduW`A zzMJTygFJ}0f;LofxCIv!78&cle*y+^#LwB-@L^(|$-vloj6qn)%FqgrQic>S%_AyI zsc5a{rIA%1$`o@e7Co)9?dUCEsQ?On3Ing;WJPh%DuxQKwn7aPiW}VuhPp16(Zugb zVP*8);frR_!pb-B&T_lA+=Zfb;+r{2x7t*JWjhT8qup$X>#R>{ESf4(+DZDyWHx&K zz)(nrZyRE#o~)Ixm4>uiI5gwNs)dH^RT5}M$_tJg*LZ1MmX4_%%~pf;YiU)w5Q|6L zSW{{+>)Pel{3uFm;+iWA!Q@s5Cif!-Z)R;hlQ$$qs=-nLT&@L0(@MhS&UE2&b;O`X zNjTi282HKVZn5k!-+d+DQx>f_rS&@~nM{Lk_a%ba1_J+$f&$NCVC#+y(@}Z$0UhdG zW*-a%eq5kUDXb60H#^bIj5ZqSRQ%XfhFlX9_N(u~Rom)qN{nifgG4xZ3xc54`L?$%IXf0^A) zy)9takt%$qD`q-@E$o)e^U9_qVAzow{^fPLZ+a57HM)<+sI!&G@FW z;9(tLIkoaoK19$AtY^900lEBM9^Z-|!!?`FD41q+{3@1A;A?XSOXhS5yqrE*GFcfJ z&^KtnYVLpoSWS`47)z$2I;~>T(@3t8On!N?WcIivv)3h=)197mBojTG+pp77CwJ{& z$$Z__GC`}SNTwoNRW~>-OTg7rBs1nJP>{kYlF0=+H#h|*pu%Y+GnSCdgh=w>{=XE- z*F_|)8WBmWCLXb0w1V#%(Qk-Iw!WB8|Fl?vHi4RNf=sS^4~H<0{Ou-vZ6FfZU9OSl zJ5}T_B$7o_kmiqa*za_;>`B<~UY&*+7-^A7PjVV&#!wHa>kfuGA(EbCk$jt@epS}r zDvyH^ud-zHeNNObi)5c$B#-uje&U<}-}}!cYQ6v5q1H9b{B1YPoJ0{O1{u>EIGl2K z%F1Hd-RW{Lce!&gdjvL~J_oZWsl$9Jk|_A{e$D%z^|=@FNw_ARvT8^%v+7z-MeMb# z$(0qqsi{Y(Rv~)@FX(|?AzN4r!_hp3mP3mwKE?r+)Z~2lhIP{ z7GMm|LtiOQ{cq`%xl=Agorb|r23li<7JrFOe}|0K4-aD!x0OzmCzt;`mk%Vly)sV> z5X)JtFGP=i9*2azy?@g7CK;Ad+~eoPR=}7<%NNFl5zS2XeV!T@byvST8uKPTJnweG zCOgF(HAP2bUaq1sWf_#?NY#11n0gU7)>t+#^ywS4a9)^Lc+ZoCcMJ(9zvu;e(Vn_z z^BhFFPG(?KexJivRf$Fwr{&p;nG9kT2~Czu0Ryb8rOr`frgLHcHR=>-C+E5Idm(yEtU^S-ejwFK5#I7^@ThKc~xK-d`AGTs^eus>092=CKIPa?7eyXdXyhFO+BG2t7(YtCKd+?ISb@e*|Oe zq0fHCjjgv==Xn!h0Eem8AJy{+uegL~6aBeB)wrv7rAN4F$0vl{pJynM=gD(HY#wTT zYpUR9U*eW~Jrh{`{h5Yq63~MeC>b-PL`TA;+Pm%5@3DDPj1Vz&wp5#S9 z9LvxKb~LN5jsDx@_^VN}Y@J5Dv7~B5~a4${ftZd<6*L_p0nzl$_V?EBX7Gt2>Tq$aYvA;gA5Kd7ew#IAM|1Xe4C!0H4=U@4&Iw~_=-;6U%!0VsEvkLuP> zFz1+6i1U8ac;LEWu=e!~Qx-69&}nhnP6#`2oyP5V6z zvfqkUcxg0gRAulZfyPL5%4F(GCU!OhP4I3mj5ou_*^pNV`KNBp32rf>5IcMsVQ-1% zjfmKr!lcYT^dc*CEp8Ee+#_6N(d!B#fo>OB*^SZc?>yWOfU{B5$-5nCq}YtRLQGv} z4H!jxLdLaC?rVFa*TW6xGl~wH#g(UzdN}V7AKZHQ_t3t_p8LSs z=kSc4M`y3y+wv9vdg(GIUsrKB1t4D^LpS`EZjfujBkX2g*LY$q=4dVAV>mXarauf? ziXJz|a4%wo(0OA)rb*h|+A&#fTDCWhRsEWFy;sq$V<+dWWlyG%eX?QM33GZTM=fWi zdO3S4Q=khT4PE#bMZw<4V{=i@)_guKE%(_sEHg9OV_DA*QwDH0a0k0WMx-kg+_ikF z4&B1bB!}wbO4E=U13%1pbL=nE!u*Y*uzh%Li_ZLH%-*llJHa&F;1~MN2A!6*lJcYVjrXmPT2gXh2=ktsF1DjzjsolIVBLH zI)t%2l+h)8pCKe=g)%9Cuqs-lH^({UNi)MEjH0(t*IxVr%p{_}i#S-laF}u#zQj#? zotyT8G_8x9wv(H72pOJr(>AI6KaJc@(0h*`rP|eQ6oHF``=7w1S%j==SdSlL;1WsY>EdS-B6q6=sE!W`cT>)9)yB*W2UvR)O~9p>jl zi$r0U@^NJ*M`6$7DC~uNP+8#-ujj++z=9QmLtlD-_O3pL{PbOo4*Ngvy3t{XuP(Pc zIS$iJ|NUcV=H15H?|T)DtHGP3>FK4>(e%E=x_T9eziC~(T{Jy2Nax1L-r&CFc}!TX z6}=MF?sh=pFPgJ3&jW8n6P9>?pd0&ELA*Iq({7)z`y(|i>`C898Vl(%VY{O|*ls-3 z%nM^<*u@I|Apg`Ej!yT716`#5wNt;6F8?~|^3Ajge#^C9S$!H7*%ZU!ej|?@sb^__ z_NBi$&Ck%oSRMaCIM{w4=fTU~nC7;46J1|^5W*5hnu|)LxXV3XgyAg`247s1E@px+ zP(10_i?R3mZ*Lir?3@0l$LLuwTH8&DgeMvFW$^Y&`WC#@oak5WF4$Rl%dn5iyq4Vs z`i8haNh|??i_~m~7ZjXFiEa3w)i!(|kcz=w#@fXh;>32cpWL3I$o_B1;CNl^j843+ zqTzOuoqRGw{KP)($-anw2=-fw&Dx0c(_X*)7CmQ*6Ja0oylMMYM#fn zp0otxJ_gaBXp^UxGdZ|}KI{VSOM~lh^ zNYgGPjsTbr#CAL7{Llm2H*P;JH@4x%1GsT-zfkkBS7WU?WNo zA~tFtxXbuzb2+MGOGgyPVFxX*+5i7B_a*RAmFM0wnFN9a&jb=1da=eD+re>(4Yr|! zH7CsI8Ju8L#H5DB8)~t7ZE6WnK4mckjE6zmYpdScO7CZvTU)hX?X9)7&7MG5!X6eQ z;?fD@5`tn_lKI~M^StNGnFSC@?)UwE8qS>MU7z=TpY{Kg=zU(`b@tpG%-TzvB{vaZ zZf9!Y1%BX9;Ft}axsh<8+bbKnozug?XB!)Ahm1fe3(<(UsL`SzA7JsQpfT`W7kfUk zu+OGc?CD}^yAW=Qx8CHJoAL6ycp1L&6>sC^w{iaDNpEiHQCGg1H*0Y?Fuy`=Zs7hA zf(h^t+l-e)cV}emn>q>9gj{Vegd}Go<&*uQE8q+kizT7Y{7mnhd#ymt=4c^6l1) z=kqeyIfwAx1=H^$-k2l?i^6~?MK7tF#eA;T_#C1>;*W|4s1^P|>0e!cLnY>wI zCYR`KjM24~xc0UvP#k%cal&*=Y$J+j%b)FU$p zv=;N{LBF3RxCrNUfq4WZ*Bb~<_>i6XH2n>jA@mRZ?!82jy_!1|pu~#qdSAi&NMlxT z3~9{(-m2AcHEQqyP@xG(0k@Z;?%%oQG&CfvrF zeldrClXt^0cYnoqA9#*VBf-JF4cOs>OXgJ1LXylib~7#V7{|OUBRBCj*s}wi^-`5k zj+sW%Sh^vTAvZ|i;Zc27aO6(Yehr`CF~6 zlt-Sj8>3Kf9R=mFKT;V4EF>Bz0q4F22x^obKL9`Hw4bLP0Ad9JdAfwX8Z6^L&JK6+ z?Y5q8N@s`j7+rAHJB>zz-Yf3TN;0}@@;H8jBM6w(#8`UC$)V0B2Xo1{tG`uSzd%8o z$n~3Z#d3D)y>OxsH_Irc;{FF`5=~P?fpSw@*pEstl^=;lA1BtC@HxQFQ~Y3C_|I6_ zrccHJeDe!>@N=|%{oE{x*Gn;J!I^Lf;5Y>)8!%{rEiLe-?JV zig98S61#cN({k=E4@jSFGKNL_1(ib97sx7pN%$eO?rl{xy8et6e)t4phAeq<4atFi9(7PPjP;}-Z z>J~c={3|;SoVi2P2ekYmvnNiY4`Yo!ToC6tkZ$w=%?;>%uaZp-miPwJWC8b@Hg2(B zMlJCj(h{%5SmGa&g7>-F<71P}z%GB#X0^vlmOa)kUu4+j`;Qs|(g#Q5?DBIYD3>@7 z(qW(}B21x9t@5}PqO52RsmCfs8J;#}&0Q&MaVeA5Ya}X6k?M^rQX~QxCC-~5Euo9a zmUCeW%OU6-2|ojNHucQc^gRW~0z&xk^ed0cwVjj~iyNXvsd;`! zBMd(2I0JLY@YzV3IrPM7F^_A(tktBQ3Qi(BdGvf_C92pj;5Au>yvSv#3TYUWOtqKJ zO9g(G2+x@JShg-VBuvmy!iKa zyQ8m922PgQsBQc=g@YHleI~}#PS75M34uh&I#24|{FN$>GZ!?0Fl z0gPkO{0RvTZQ(bKJK-EUxmWKS4I;TFEpQhi zN;ZvVvHmwK*1slxh8pL_M3c<5iuF&$i1q93v3ZZEKf3HswDSS|;+cQUCIej+adHSF zkr}9kOkYR>Ot0$xW2aPAxHx=-P=Zjq-s^M!krG+oNl~UYQfqHvxE?46KVY~X7W%g{ zFpty=UjD~#W=Vt|miC$Gq+HLisfpJ z?6EIrxkTTDbcRSdvsHrF`H_^U&HcJJiO2peqLPZ6B@UywBV~pL@61VyelRavlYOaB7^pK{-gx z@ix)l!vp~j`E(v4K%5g`5SvH&wkFuab5ux)w@2ef@POZxzK(YDqk~4rD(Gg}p*{nt zx!9Uo$4-+lLQI07-q~athTt8w8c?n6INic&ku5YHSjzUU*lEsp-M7o7FA z=;#w)0As-V=AXf%m~x6BJs6++3oMT10L++7p}ZO1<`xX+S5H&TtF$3oua zD#$Ed4(S)z>dn|gDf9FrBZ)7ZgOL7N1LD>RWz|PE8h;G!CK}pS7K|Sx`5=Wj`4sFO zFuLa7o<-GV;J!02MS`>gucul1kT8yJnMRR_$`0yh=I1eS83PC)>yZcJ2Od zG+cl@wX+;y9lb5!8dXU6#j;K0TrIY!Vr5PSx6xtjQayLkEbWpp@>(Co$U}_&I?vM^ zJ+K3S0a!z9ggt#Fom!Xrv`>GWJ;*myPb7CHD|u6&N#g)$_5;|YdVXn;7`Jk=}Q#q{p8|DbFlqt`xUGfY_nAWD>@$`0YFrW<9*wv1;s) zv6o5mfe$oT*TO!DJbxt_-(wdKO}&G`;AKyD5)=q#=u7y(1pFm>>7dS{a2NG-s+e;ZS7V+`PU_??D#|Ft6pXLbq_-kej+jZJ zpm{ckz!mdc>E>jvv02>ICyc}w^BkN%koq+*H9dSEIyN`D2vSFyrO$AYXT2z1eh6=M zlR_sL6iPn#URyK}g*3*5y+4CQA9KzqFkZuyi7N6qySMZ5=Woffi33&Niv+KwDr7yR zAc1Hh^2>&VY%rRx=Zt`OiJMNqL54Ve&=9A4r8rIO zt?Ol}M>TX4%pF6VCT>}04w}u4Pq83B*AS|gd}IjKRUbu#YJ&;qd{Q$dwsnbqBxyb= z!cd(p^GUsEzjTB z+u?$|DnjIDU~e`V(kZRFp9NS9n*#$#r}`GBQ{6yL8I(>n`_Ac>bgB#D(y4AI@!@fq z<|QVbD%oYoldm;-I@O|N`Be8Aft9K?pQ<&mQvG!KR1N8&<5QMp}Dvr)!YM$@Q19+yV-EqhEF)hA=psO}Q4 ziDn~>Dm+ThltvZ#q!Q)XeM2wLHl10XWdZM2lOpRSMFRA+tfA-4p_6ADhgP1o7Uz`m zX-sj>s8~D72uk!DZ^lcEM3arISDP1;L-pU8FrztCH}fuY+8nCImJDIrjSOMM#(H)p z21*ylujlyIF>N-IH~TYY0@Ww6Rw#k0;=E4NvTOvpdi~WJvZsC^&NXrmcYk1}PklGw zKIRR6+m4i}I0xx`6#JsZA1hv*`j{B*4{hZ6MiwdR$wVoxZwHqz*y|^aU|q^RIi4^I zD>}%IBd7^EMU+*S*ooh6dR6kQL(wU!e@A)jPgMPjEJ`ty zn6i>iCQoy9HPIiChcYJi&@2(=59ky(vnKY;hO~1+MyX~@B&c0UtQT7K2NO-s{2Ixb zQ~FCYvFb&1_uZaMlAclo_a$p4^s9EZ3Zd&|?Qp!>OrMJ(n7v7@`3IU!@K>#vO>(F* zAjwei>~poY7XCmA`IOa%g}|drY?~O+APyixPp9)lXPjLwM)A>_}=W2<>T2K*`(_d zV|HKTyq+&gXtD8fg3z0bcnn|)x+45dPPs}mWfT;jbJd(HFt=C4rd(x{50z!GvEWj7 ziEU8!zE37x-AD;nqk}rJ&ysMJ1~t4GqhxLBh0&%?6iw|vO;g7wZ|cO@gsW4f9id{v z#Q3J3HQj0>(yiVmb6SCi6a1>=g=diADL{rN!FfgT{7LO?V{JF5NoJmoJxbZC#H<~0 zy&ss!n{QiEsu~QT#lIFP_#E?-1B*iy>FZ^fote8TN1cO6s5u;HcexR0Hz7qT=u^%T zXm`la*YCB*$Jl)#X^fp&VX`Q@1=c7#rzOhnBLvu$1Si!S;dEvsUDW=A34a3tb*d!x z5eTRo5zw0`pl+`%A)xLjHW^TNV?sb(>c3m!>DrArHX%K1w8YbGus-XEiKmNsw8#!7Wi#2R&fJ6!%!aS%&~q7T^9uQ2#pgtpo1QYB=}syi1EZn zf77Kg`T5p#Qe+>z9f>!D#C?z@?h^f=E=gdlA#fk0jY_S!tEqOs@@Vl`Nd%L}vZPJ9 zpJDF%!dNM3XOCscH`gu&>r}eIPEte;M>AQ{E@DahZSgbog>MfUq~WdOz&X%Ifsv&; zDrpzSx$3sZw-bs0#<>#Rzv|&9v&o3pMQqPeO~T}<`bmh|B+=_9z3$gwrF7S_;clz@ zHPq?mbo3KBgEnk&>upAM=aq(&u90_Jh}`7RpZ)eXq(eX8;P#XEF2we?H4@bCCq%gS zODgx16K_5N1{0<<5OE-(%RP@ayxq{C1R3?no0ndqZ)CjS9e#Z``A@b$PA_q9qJ7Z4 zv&7vjcEf2xLceF7A)m8!UD{9lvt~jBr7+s2t>1tMBH6m1#dOwKOUFRtMJpT4&}`=> zogcJH=Wkl1bJFpuR@kGcbk5+#l9^YN!X6zmk&03nAkLOlI_Kwc!nvB5H2SS*actPL zC6&(kd7N;rCI>!x%L05P7XnQ;93qVAO+7%)lbgj9iuo*Y@ALzQm?dA~0E&x=aVOJbEHSbtFHN8?>dH&RIKggB_8fKPwIy-owOgAN>rCFQ=|`zy z)u$oGjYNzKJ_9ih|Gs$m%v5MWZf`UY3QZkRPb?hV`B35Ep{2rbbcmditYU`9$;5~u zGW0{5)1<%Hy(iwM+(Ls3{$JCe^d^_l`>Gy^ba(+wxQsk+RCgQE-vN7+snMJCAH(?+ z&qAsG%B@3GzAxiAB?uUDa62*1jP@}l+9}X1P{j9Ns{|#n5NJ2hi0E*3oCt1v- zR@sK_B$(0cN2FD=`wheSMzuKKY`4H=^4O&t&Nr$RE;Ie~ie3{gbDx3W`h-kS$XtUE zqA0TT=>m@DAG5q5%iJwXDz`$7;4<}*$^*4llse_H?W7MR-Pnfeg`~oHgY2vaSaUPxk-5Dyz&6y_gB0wkpuTJHvfD^4y>hg8m@O(_?h)C*V9DxyoTjndnLQhFM#X( zA8ke)4UE0rWDtGb7G8z5JBif;q}=JI=Lbw<@B#UzF;vJP-*am`ZXmg8e2rZI>U+K- zT{YtBDqyE{x<_8@b6Oy!iKhW7pS|hhp!Qz7(jK3=UW`+rbj{!o-;_Z7hm=(TJC6-3 z6L<62%-KaqfnTe>POp`^!~*v8hkgtryf^$sG|p+>*eBX@ARe>uwFPEd+Nmwbz4o)^ zvMs6jt`UfZgjTq!LDIoG(%;Sc*hDO>s(wJPl|dc^!#CrNej1|#yf2lpn+uHI-TdJ7 ze!++uZY}|O+bP~A(|>orF;{^D#@i-cn}fN72Xjrb!K6?Rgl0@t%EZT_^}8R8A_5{Q zO%a_FrFP0wu!7eE+;?F$xLndQjPvZzLnJey*;Mncl%zMoBnRh&R)eg>KNT&ua3$!l zED0Ur<>utnNE#qgPvTLtsh@0>g<2Jqd&Ergf-qF6hs5Yx+a9sB{Zwq*`(xWaXl?rd z+TMTqwx2qE+aqS%Pnm5Wl!Yd?-KqxeGjIVZs%pX~vgtUEKQfzM6W4T{%Eyd0U=#n? z#$gF}CTTie{^&HDfHUJ0Ln)l`kyM{JQ;*3q6I;H<((=Q|25rzhhJCA~d>Z#nX5;H* z<1dab1LuS-26iaFAQsKCkBqf92> zq1SM&lz1Uh`{8=o#N@A+s&2;Se^~+_vhsz~=jI!(AGd#CD8c<7M3vxCoz4F*cwVjF z8_s;VM^eE;&NAdKOsU)*n+={^w|^lzVz~G_;=7c8|i*9@@EO zqhkW;tKe~8Bu-CHNC|`t)tV=?^ebnJqBo=G&Bnp|1^zaAi;an_67{S+8*GDL$B5f88YDB0s+$We322!%;wppK4ymzl5COI5<-&CAg!fR zE+?|1ZK%G%6v~o>Bv(*Kav5ZvCd1pML;Sy=y+y{TwbY$5I}LBU5NHo}1<6M9a&GmKW#uat|3z#HuJEClg!j z!BL=UM474J6LJgQUqP zDbSNSLuAaA3{Ks-x0UcjYMY`~IAMW!0N>kUAFw<>;Tvs_p!9K@NU@ ztgLFZbC8Sp55B+sViSCCS+;HAO#E6f%DJ#au%pY@8Dfd5T-~TVHjcc`$Jp6s{|~aQ z$QVZ;pzT*V^W;;KN$di=m#A+1_ZJXQ40GIl?5QH|w<@bV%!0>PbOBYADl7W$Ggd^# z8`R~*%I{$RYQ(1ySE{~-Fjwkg337Aa6jJqO%wSKZorUNO#dQF3Q_nY~8^sm0ja)#t zopx((DTzt8i+s?>u>`Y^SY`^bB`1phLAu@Cb94~JS<1iZ+{&MjynK5^mVZi=54O6d z-r@BeT&DVJ-(Nc3AV5*F>Lk?fuKq>;A|CzVQsdYsr`Imfjp|%Dx}Y9|AqX#=N<8}Z z>Mx3KN${Egr|612!UDt+dVCDz~xUW1t&a6rn3S-?}9lSQ9Gpsr{{ zIK5JKkk;TKGtUQCF~Ma?zeTc4>InH%`Y6NgU+RTimc2`PHWW2BCr$3mHvrVi32K_u}N$fg8_G+IEXkv z)V;~8zh3ZuK}0O*Rt#w_=|4XSxcmL?j{@$4h~mr-=!e8*H2>h0*ZPC0qiE#wG4d_S zs%|+Id04S?#e&@|Z#>;pa!ns^1$c_CjODW`F&mY@2vsW846-YL!*% zS&)1rW}PlkUY*sQ7;;$3(=D z=BrU@v6*HE>+?S>8^Hl=1WL`{Y#e1GHiMnExXqyH|I@b9#uCP~J$M=T%|hB)XcBmP zA#X?CTUx?*8^mNT&aP!QV{zuhE>2#XW3e`o56-(!F3C#@_P2>IK{?_XMd`na`jlH5 zRYwcs?!Qb-AVKc`UF_UnS&}U{S2;#sCfqq0K~|BK8CAbx5$~Wyyh2J$*{Hqox zd6R{<;&Y|_VlgHJF6K4$H^jmFk$*?d9W(D#X9~G0_`AG%bZW(WML?p})Bbx_woNN& z*6M24k%i??NHpx%k867EQ^4Ir*0kzEuYN+S^Y!a{19d)^kUF#|eqS9CPDFY1)(i+6 zCzUl?h7={P0~8k|vnx3SIIZUkS;XR3r9x-V;!{X zk5YdcZt(0?0(+6Q`K>Qdh;T_S@-hq2beO4*gI2!x76 z2y`R0l_BaxC%Z2eofOZf(5-$UkBSds-a-LNc_ZJ;z`cqv?x{*y8{MpEAp?>`zN`2S zC$**mjIt^=8x=OvE3lsOii*AxTgnw@FC_h}g?z_(_EK`rUP|uSOL4`NlBA4$Sw_WX zE(lpBo!_i7OW}g?X5rZzRCM+RX=g8`^z5aS#g{^4m87h>(e4Q{`w+2rC+NX^ymwq% z(MWlneM-du&>NN7pA1AIzJl#yX;tJcR_=s!k{Kj<j6n%vakuH|Yi$LC7 z{->1Q>Y~5v>6L!t-KWfV=kq^h^wvT8`y0Mh#Q#+BKZX2HKD`m5zb_$fR>`a-*$ZCh z;$D&XO+craC1v8WlP{~pWr!{*b5)?u8K^5w7ymo8U{R6yw@dsl7_-ul_`g^D-%kLU zd&G;P_YHVi^?af{{_qIe6)*1ie3sZ}k@ET~ZG09%*E~8ti@d59r(z2}tW`FN?Kj6C zT;-IGNcpMcH(yT(0!Z>sg5{<7tnyuQj(t~*?@>Vy*S(iRS&I7@b+}A08)et!jweG= z*>Q1N5vb(-d5cB8Hb$k$1o%arFQ2j*E9Kd*iV}!a#Oa&)#QPiowoyFUTy(4zIpqvC zf1oH>Y*+3?IBI5KfL4XSCIU|s-=qHEEp|BC2{KZAoqoMd)N{w9nmG8ynOw4*M&E_J z7ry0ORv8LX$^;)@{w{mWZRT>zh_*$UPhrEHl|!e(x1K^V>i~Qvide@*R4I3+{TmHw znK(h5n0J(-ly`GURYpncQPMaXD8#ga+LUr&kpA0m;5~T!a}u1Qlp^yAQN?;xv2x&1 zS|Vv9$5RHf%qIpoUwT<5&1mMV-vkujaZ%(9L6l17{rKy=ALU@NIzg&}xp54iG=Vp8(i{=9LZPst5@V#iG#U@o*9L} zFEVWm_w`%A>?vuN|p;wIZx=`M07ez;Pt}&_yF{=OjA~~va zX;jf!Ul&&t;)?$8Ib&2qa#S&-2WdFx({RqG;hbv@=X`TG^R2@f>f==}`W2$e1Z|do z00o8E5mcodjCvSr@oUtka^Q@Yzt;!6KZ3MsLJ&K`mqF8=6q%3-KR=}$$%)%l`4+y~ zB$m_>ULL&bl=TvaFB*$VTWMK}4F|$SMLT0($uCh9gpdv3a&niXESQ8W=10VZn**+A zw}!&s1h-V~>&0dbo#(~WV&}yVXVa1<0U~>DHU=GSN_&_tx5(uW=4TEjC#_c8XLxDr6B8JwzOh zt1+9sslqDGAEzap%v}&)Fm()Gr)`f6{ckC1lIAABhWjZ>zZU zBH}jS`Bu(D<2BvauSOcYQ0ZgRX@ezB8gaeB5<6OWN3NX9%kLhSWg|x9svE?WKhlhe z{aqHqesL;1I1XvCk6()!{`)v!H02rymX|(|g25nx~7+)UzN@Q`R0i zPAKtwMnDqDPi3#%#l$W93Mn#py+cL@GtcTWxL6l6w-gZE>yQD#;D|}c0k4d&!9Fv5 zeDy~F$#9Ojbu7_VyYk2jgOLbEa^u1aX?&g)&F*CG!boAR=$Q`K-YTN z&Q{{NWI6hkoh?U;$u{y7eFE!{%o`Oz-l)4-lFq(GUzxyI z)sND6MN|3!O&}NAEf@6BMaV=|WMrb+5pXwYCJL6Bj4CCHg2kN1>{$G(eS~8`_A|~( zHJ^-bUZkbsxs9={<=6r2r+hh8|d|HCdL z8bA%QBcD{Yf!`66x49}Z3+i9d}IVQe1xC|zZukkaDrYxf*PJD!vdj~ zb^9wD0`4yH=77K9Ek}uaUx1<;#5a*-5f0bfEF&DwCB9)Zvm^2G4b2?i&?e&>b|uC) ztVDPf1-4X?VLBT0!hsG6Lum#&7(!5k24Ss4Zvy5|5rHb$3;-aV^-cJZkCVpb zE7)MD^g>%IsTcE`j72lwTr=~zXRjcIf~AvWbyjDJZi@Pjka^j(z-#Jkw!puh!WQ^l zz$GLVGy|}U&Gh*css8!T6h3N}+oY}ehba;o&L(3;mZz|Z8G~R`R(?vFVitUz z=kU^eqkj_PLsSzrG-D7O(|b$Y-D1PqCQf3%e!%bUw#M@~kwMRCCvGV~KAEE_Z9>-Qh1ZJ*Qg_n`8c{H9iF1!eDsH9v~_2U73yH~lXKK%9IO%AW8ec4sM+WMtq z`}p;#$~E5I{fn~1y&q(e|4X$26`+0GPc&?1c#%qTjtrc4wJjJL`?l!$$L zZ^3>T{0feF_16s)iW2v`oWCfhKezO8r!I9Z^P)@R=#vbyPub|x6-J*#>EhYK&r_$wlUGsNE3A6%R2`k+l!EPbGyY_Y zG-;7mmHk>of9Vacry_5@vi8~t>t{g*0AnP8MjRQ16dV<$81_P0C%1~KI#-lj=p~7x zct7DN(rsgr(2v;luaCL568R8F>Hb4#ianiz2jc_@;_{Zpm=B_OCOKrgIZ~1g&jim* zJd-v>;+gziVLTHuB#D11xdPVKPZjCN@gs$OZA$GD&t!$dtFFv0S6!9Di>!+MIPO+} zXA+wb0X;GCOy+Dx!SmM%G{s@`U#MOe*Q5uVMr%UlTSZ6)y4PoY&p zILv&Aq{{`Y_wnYrC{cpgQ!50Kz*FFVB}YWbvKwjU6A)2$CrLAZixF={uwzD|d1c1y z;hU4>ng5z4yruZl<(Zde$g-27jzR-{JO#Cn?An+-&i*4S+GdknC8(<20PIFt?{qH)CTJS`iB zBsp(U^Qz-0aSK!8mFG^0{{wV*^jzq$*QCQEJqImxnB}y>%UBUSXh@Tz%dm5jHNt90 zsPO2}Q=yEodSFoEM;6jFueF)e`e~?;ae0&(yTaZmERT&zD|~G-SRPx7P)$o#}E$Cda#=S2uGMM=?iZ6?3@DS51(SK&A|LF|a<3aF^oPa2L~Mtx;6+ zbsC3Eig%$hWV{OqGn3<8K$uWENXjH=9w1Db4kKB1HaLqhK4FY;W?v#&YH>`kOSBo5 zZl!Z$(_^|Nv3ZK6v!8*@Q!L|LPG24(7>haBrO*=Wf`T&57YqW;j1uUm7y{*Jm!>E_ zk31fU27b&Wx<-K}W*){<6RN%m;E!@X2 ztk*qj%d)W&?fRAC5=aI`WWS}9sFh7*Cjt50vySk1a$+68C^cLy;$TEimJ&Kj5JKFqI4)yiPAIGXx1BRe9HKZ7QQVp{)UBsYPEr;XBflxN>N0G;=2m;lOq$Uu+QzL=OA7BFol;3zH`8I>-} z4l#}|JOk0;hlZs??^-(a4mxxq zS%==Wbm-kPcIcgGhu(>H=$*t4Eg&za1M<)X2f_!uwIkx6d9NECfn#O2?8pk)ksR)b zXjQk_7V$-R9=dU7!d}!ZyTR|DrWa5Kyl%$ca>x$Z@?KBqglIm*{(3*~a+-mPqf>&c zCPRMnJVQYc%G#@CNXvY7(PAml^$1OR(W5A!X*a?#c ziK4ETW%fQpXk{T*li5Y#Tm(7S%OIyFy6Ns-!+^1=H|n@$2+Er_nfcB~QlfKcBW05F zY)v1t`?hSGb4L`U@YPX*u zO`=xQTm^?GQrNwjX0v$)l{I_QSfgMj68XEhvEn2*=&uQi?)7P`UZ}T8^}^$6EY3sa zA`V{+3QWj)2W0#8wrJ*5U!CHs%g76jfj+NS3G{kCS@xxxllE$tdl0@WZED@u0+nr= z5Mvq+I{ZO#=G0Be3mw0HoJ|bk^LAEPmwNSXue*ytPm44??a#MnBbhn&qqMg^f!%H* zyKy+jeAGWqob(+O8v?$@nf>|Wycb>BuDAxgleNW4?K14Ti{}e=rpN;r z3LY28)&81#XK?B%!OBvUcDq-v52ljg#og(3bQ$`yyL;Jl8u_)lkXE`vuq@K*eQ!UR zdn=lgJiGJ^pQWGXGjM5s*k4xHZeN-YR>rXp2}a0mTB!h5@I>*=0s3YqeY1(Q^BZfo zFWYyI@<0=7=x4VRk3xRY$Psl2XUIlNe$uzXf`grn^rq!+!ccDG)ZJds8%zCSt_tcg zorHvzPe^D*#xet>qs|n8$tR7r{yP&AErt}m?)_qAi?d#Fb;xo5C2?pSJnW+7DM(I% z(cfYn`WStzG5&4lV6{`nJClxo^jX6AM<4xwa%d&_>@4H|Px0?$bNn~aH#=j-KTJv} zSaSN1pM!%Tn0K3?Fns>hveYI7-+IG5P(?4agT1{iF z@hVF)zSWN%*lFHn zX!|`|m;Q)OwSs!FAh8^K?muN5Hg)8y%*)MCUh|rZvtPxZKZ)dJOUH^`_SOLW ziLtLo+8yEq!aiW0Lu7x?_2bm(^6J~H#`jz{zPAE<(6e1x^I8fU-wVkc_H2qYzW*cz z<~DC$sk)-y#>TN%jFYFxNaX#!lxQ@kva<t?c=*;FEP;oCeqb*Uj08Z(OQ)^~Yba zF^-|5J?!uTP1c)N=JRaxDS>ST8@!(FOLG~|a4!B41woxnrHJNn)3wU&-a4l!Z`oph zWuq3swmhLJ5KL{NL!?RbG(P-Vz`Z}9Z_wPG%AIdBeh2ucGRmqp!;#Kd?G?KSBEi8z zloJV!b}k$t{&p^M0F|Iv$;{f~4c=<^M;cUpqvqaK{g<9OVt9S-ZP+cGqJG3Q3Q~m` zy-ArkB@f;)qO3_x7^B+yrMHxbGZ&e^I~jh?vVJS>W-Z4kGSiCR-4Sx&nly^`Kj)>Q zC2uUefEE(yaz}0bvJE_fSob09RYI8fwrB-<&u}|l$F^vH=Ncf_vcKJt4b(WB49dx+ z8a_ugWD-r!Zjtii4y5ijZwRsB#ga;R0bCRi!}}dEynrD0yE~_eeh0r}zh_;vKjY2* zP;bUtd-Eyk5|uc~{{~vG|B^s@VqnFJa@M(e-W|XK64YQ=N^_&`1-Vi80-5hRke7ak zMCmLIR34|aS|PC(6k{!v0%4Jjr8VS?vPW67#Lm{zLSm)L?95a?Ws~O6o9rB(yx6b5 zK|U++9Lc8`=DvVn-X8yij?`8re+wSwf7!?zlrp;o^bZ2=@busmnYpdmAABg!S>itB zuX*30Ia>S;@23PD0|EV@Khknza1z3K#K#k!kIBb&L+J05C<6K>O2Fow(jWT0yusPl zri6aRzen=(^iWVfPuGIW#EJR7z4}jHz?VjO1Brs~>0WlFzp_=0wEBZnn)O!D7Tm6c za1hc&A%fjUxuTeK@$S-hmeRU68hMgW76DjW*lPP~%?Q=j} z6*E~@qQ6<9hr9qk#Kv}^F_~om%WU!i`S4Q2E_n7SYjRShfz6&O=dT|wQaWcKJd^hb ze6c8(8HQU~+2BBlv{S+HxXS0*vGh{ItjRE}>?a_hKDjY4vq7YJl@VBx5>cnjdzz{r zCJK>otc8NhMY5=1H8~;Wi;aarH1$3)=-0jWz8LY~V!OX`UrBIMD>i@zzuxS3x4@x5 zOlAgqHA(jbL0FdxRzlS~1Zk=6janVw_vc9sz4HEw~Y_G2I5@mXJEc-GABkhcDhv4su8zT)uuGKrm zYfJaS(Mya0EA1yESU>m-Yk-_H1tGTZ$k33yn>ZxT@{ss}n;t(RapM7io<_6-nzyFt zcpUO6#qHK-&EB9Y2jsAL)?j_sVi}Nq@gFvc4;}czIwC7D7}Dl%i*JSAAO^6WhC{IY z7?0gFfP!I*w744$OkC05Cb$|IG$>t;pf$-%E%ev4rHfHiJx7(b>jx|j0Ri?Q%7s@z zet^z-d{^%L%X{XPvs1 zRc;l>GnnZIqH@JUeq0A{x5^ZTo8pzLAx^~ki%mla(lpo(0V+N%9V|Qf6uyO$vxq-; zgv6ta4#7u*-#)5UwiRp-RJLHEoPyH~xVwlGx&#`vvW&g{NPVP{vl9a_i=7Ao=pFF1 zE+y*?h01x2DS&dX9f+woE>m{WWH2E8YV`Bu<2+`DcjTtdRa1*BJR{zC`(F zcxQ(~gib8*uZ|1k8F6A%RHH=r+dZRLr9=)DxY0F=PX{OaYit+=e~qq~OqY~D((u=? z#rSKa$M|c=mgur2(PrcHIB1jkXMRTt8_GXpq|SL+9@*F3Sj2uBSSL`(RI!JKmrytA zRre}RLGyFQl9?DFjN1+DgfRojXu|%=5W#fh6Cej^W-f34=Qvxy^STmTNL+qPoVk0g zOhwZlkm=+taE^PBT`);1ngl?Ooko%f^)n}Z*~7NPPmjkzxhw0fxhorb5V|mAd1DCk zu4%~f#v~M%L&fD-iZk&zjOVd{94IcQFCJF3$(n}dbw=WdnO62?WD7|CC7D)Ch?2nI@j&2hF{f*Cy&ne)P%5R5h#L^OAIz&+>_hok#laUy;YhqvVo zeizd>X*{WGq;mLURhimC=`~k#6vMpnFu|7t>ftT(*?rQEy2_HQrftbx)#a+biohZ3 ztH+Shw_+D;JC5yJPZEhK=8mog^z#ULqm5`JXO z-%$Y@LpPE!v;*p|pO9T1s=^9U$n0&=G?V|3x{6g+B+Dgps%MF|o-*6I6Q)mUYYE!Q zo*0+1f5qhVa3NazCGy0$G@WA9X6+=M!ki}gN*}qeTid%$w)a%h_7cn*>6n`=?d^OJ zF0|o=W5nNg7e?U=k(S2$V_S51zW|LB=SLYY${+-qOd}CvcnSLOdGax1q)Hm~36lw7 zZ*ur9^ro~=qKQ%|8RI1&Mb>!v8K;$WrpgKHlj$Tg4PSy$T$s7iM+lk~U6-TUCzC5S ziMC#bD7*2T_z)Qm3A>fn%1+9`3WfmSV~~e#W$g}$?~u;MLz(k%9_33U zhQ&p0B(4D2IY?gw4#>sq5O6UJ#m0KM1YfeT(F42{=Yg>qcEJaZ8LHZO$D(#YgCUE` z2drQ9>78DEpT5`7)&4ckR(Riv6NV&^#!rf+7WdYuR`pefjYAHkR&~*Jh5(V~E7%Yo zAsD3eMVI=77^ZI*5`D-%R>(OWUcD>ywUGl6)zKuiU@{bfwO}SR-JPWWTJav)Qze*% z4|=eAwEVa=c?4-h=5T)b{mP>^q>x=nS@YEtwnma(s7?-R-8=+h)hjD6jLBj1T7n+s z15DfRXxdf`@G!kbgK=TdXQ+`0ADp+y6@&cF-yQtUjmA5_B1fXP)fEvrHu|aX1!_$s zU0JO|sG9s7ZOk0)gI^S_xbnNCuH%GYKD`ao4z6C`4XsO+z8UlZ=FeC6C2!qjq34`% zmftMccQQBY^`Y%)8030SzY^$IJtvobjo$?0{)~hQS%7dTIX=2Ub{HS)n8NwF?i=nl zF=5Cv9jVtU+qH%_9g*yHSB$f{r9Bo6VheXbKd3*!X4|b4HKGN%QTXA~g5JD&xXKNE zPc%^P7mK}WGQY6k+XhLCGgF_DH&^gMc(n|kA)Gh~KTD$pA_ECRR=fzpfI1U#BADXb z&^R$5eo;(+B)fOwI9qL`dhBG+f(r?0O5BfR@0$o)uv#~w&Y`#U{L>5!JUkd(KhaUJ z#OJ_!;i|0tV(tx!zZiKsz=~x*Cj1Bj$rKdnwx2nf=0Eni<4wU;MA)ddbM@G$BBSF->W8^bqr~ zC6&gyLs{LN%8p!&%7YBnjZ4z2M?e}4Uqm2D%Ifv0jQZ51tp2flog*ah`e6{qKlX^K z#Ajk#f1f`aP*&e7KMO0XXQxtApQA7e(Y`~}F4sF@jQA;K^*6XZZz-!M$qJq$4-ixU zC!Fhk60P7}u0VX1E-Mh94M@y}m&tPlpY_StKjzm5mDPJ4{Q6PRe+RW^B{^T+gFaJx zTBtpu$1gZI4WP36Ia%;Cd5dMi`((l0T<}R{^>SJ8er0vFLt5*N_>p-I-qnB{^;gi9 zr$Z^(>*+>FfNHDd=eez*|) zhL(rkyzLZ-Ong&CWx8`Y89{&Lj zFZU-D`ZAY1Wp5Lo1l(PI!6E4zP5pUE@HW8=zemn)7xe?JKos-Mew7lrui!mz(}OpI zvM`{;=65ikIj0>vlS~d@5APLmjpz5%*#rS=bl6n*~? z(1LlraGd;;1IAJI>w)M|X3|EYzW7}7vpr##skwB!)F?h^KeIjRHoJ^w_S-p{`FPK% zq0Y~C1g;YP(}psy-ad{(ncp))ncs`e&jt}NMETi(Co#PF*~rU;KsgvQAAY@=DQ1ZB zvqPMMP1DofyaN6fa1m@W;%_-08}<&r-a`?CZ(12@lCEZ}6>MOxO`|le%9@AL*x_O^ zH2GC@=*~%#8~e;O<{`1Ukxtr|#+qkJoCZ3Xl*XE8Y-NJKylGaJ&`(uvU)6($>DWs7+dJhMx zv;;VRv^7x07o4(M3r?s>k~g}`nm3yBuvCmXZQkhgqa;nd(=Bl+YHVCelF~TQR;j82bB89gdV z%4o_)7Ls|=XrdwhsCtkm7Fs)TS|VV|3_%IF_xl_tO%&&JskQ6k9BDDpj@O=3w4= zL0Dz1`JrpgcofPH{TE_+kQPOd%e^?`p^V-K#8)>o_l1D=aEL*6`%)Cr<+@P{1FBx&f(J01{aqAO=^C)3^kP)HBq|jOsf(o zS{)I3VXOuS6z}4atQw$Q4Ai#?PT;QkM4RTk7}kzi3u5@u_gq8b>vNQh+Kon zRZeiHEp#GpP*wtzSE~_Qso0NSk_O(z^yEM7tbsBexqm2bgq}S$XqbHAMnaIH%cUlv zFlr^lg0kW!5NJZFs_%m(xC|%A+=62`L*@fFVP0Mld5-uiH;REAq$A!N{C1?o-R=!8 zv%^u^>VJmW9i;{D#nKw3>N{~`-l%k+4sWeH!0qi-m8pA>6vwAbZBsp+)s=W>!6>H+ zSUBgsPN}nQ_Im28Z(@~fBc$|&U#B0l@FTSFD&p+sz(b*RVJ`icMKM7O$Elt@)%UT4 zF$Wmk+ZI(7Y*6bm{+p6xfZ^Q?9%=0@5 z9QjT;e#pW7b5R$h8q~LO;kx@a&I<@u3k+_~&}KE+CH%;%#0VZ&mB8_W4W1KAv)JrUUXVrLLs11LJeOwI zt4Dn9EtVoMKHHXv+4d_Oj*+O1_$a`V*PW;3RW9yL)cix|YlbRbIYTG~eQ zK=cMGlkTa4#CT$eXy{^$yom8X1d|BmYd>>{lp|dFC@2P#h-Y(Vv5P{>Xz8Nxx6vHH z0nH@r{Ra*1@9EK!QCv5g{SrAP$lII=1WIm7JAyYJh)oSL2dP1_AB}NQaN5~Lq3~?k zL1asG*%GtWU>9-7`GRGGPz@9EvECbyDSUmnw$L2 z=l(PMD*TxQt(p%~NL_*bGqQ!070dZeiYU##yltGQubW&Ks>pR=u20Ax6risn|6eOD zhi$}jKDo(e-1S#(fjdm3p+w&$I86k~!o0XA;BE`Jw+e=IYouNcPFVFR(*6~H>a>4x zanKH!>0}u6Ii&rox2FAT=y_{M_|4sxz~v!eIOB>t|D=E2Ny4CUGz8b!%$Y6GH*1wm zC3>@%K{1bF65GgMpv~(BS7)UBn}Cjwr&N?vjg)^As1p;?IfC3|Y*I(@Gs9Lq%Cr@y zTN{>cI#X2t2W-VyReHA?>43Kz$v=YVBqg%+^W-U;ys3Q(LKJkk?tg+1H=dagEn-ij z;jdt3LftTwgt&1C^G|lO&%#g%Kf4V=+!#lQkJ-$L{gi|_l({E&8)UeVb5ClOPY@aU z^%kH0IH_gbZRDcxFAd|M4j>1wNc}j{#cJFI!P zAEya{B`3 zP->C%gaS&OoYB=ui?Rob8uDq&loAw--i1Aj5R1+j0dTxhWS;yIh(UqV1; ze!4LW*+DtJuTcCQ;26fg5YD19b%W~JP`!wlGbdTdU=K+Z+s@R6n*K;NB6LEFegLjy z4e>UBJ5eJoLXLhqpkM6yT()34^i50<)ic4axvUgH`gYQg=F=&Pz-pVgIz%&9b39W0 z9M`QkL@QQ34b?%CZC2mc@Jx6mO>iEug4S7%mR-crKt&sp~U$g*)|>?yL%S`p&24gaM>5UINr*So4-BYi;*7``BGysky(t%Bi&L^=48 z%PU0;10Y2}P?zHUQrcvRs+@V`z)_J;2Z-p~cR^wE%u)kU`ckF0RfW^|P^tnX#Z{OT z*Ja?~$l`s zro3>wI)nT*2v|}-PQK?cN@el_o`W=u5Ih|trBeCC2zJh3r{EkUMV zfx7v3(oyHCMdPCG%uzRH_ElEhwHU%cWtYG5lwS`gcrB0pE4-H9P=eo&gGcHh)+_io z+A@lIqaa-YeT(TZ+R6^29U7tIO0Q+*5?d0-<@3)Z2#v9se*Sch%k0Bj%8tvNe;!_< zFn0BD((fTkBS@_ox-5do?_|kBpTo~{V%nC&zRPHvp+wY-7h~Hdak>siak>IV@<2JK zT5zhE)7_@a@)ia-##~0T2gZ7f-k6w*z95;ms0oLWkcyr?j~~67kpKi{qZ%4*61sU1l+G9UW){7_vV6QKK&!42NZ1Nam_@z z5CXz3%^lXDs9X~m?=(N1&i<(0&!sbu^bP5Q`dU3RNjRae?q5<-{Y_P`MI+d;6X^tY zvlA+t$cu^Tr36$KC)A8ls^Ao*dr^z$FXjm&R@10Zk@39 z&Iau?F_QcvKq=xTR#$&tv~8lLZ4x8@koW{JCkNnh(edCMcK`flV!OAZYM0S&YOrj6 zpOGm*wqLaUS21nJm+J^=Xf5khC^;)IHd0@X4%{VuoYl}tY)b`sn$qbE|I)X^%g`kD zFC9g1QMRoKWGKih49`U+w?n5(2kR(4ii-`8)w~=!iIJ*HrcCRz0KcTVOhR{=Y(=37 z`+`)2G)8Kq)zH;zK*BEzdp&$gDr>(#5cSrC!v37yHTe|KEEp9yE4)!ZO;+ju$8qDl zU3WZs-bN3Zxbs!2Vn_W25m`Ys(qzWdr{Y&Ue9NYy+wXvBmrMzj`}}an3RxqI@L={V zK7%);+H9V^%9@5$jwh@0x z%4aJ9(*$pecs445jh>FBml+YKxsv}dGdxF|rWrV{f*YU|z4{R&eW};oXJjx{?mT8D zG3BTsGmkHyxK%QzmQ3Nx342w2&|kS*{C=BL_XhNRfyxc!PL@x;E4g*)e$O`cXYuO| zRxJKZc`GR$$X0ejmdG`271tIY9qi>>88l%wGGA5f4Sns{SjvcW?8R}M-XxqVUOb>x?jgxeRFrv%=Gmb< zewCf|+Qf3YKPahuS99<4N1DO>VQuTj1HmhIYlw}_Bh;-KSJBB#_#Lz8QV7EvgWp4z zqK&{$^VhV1n<;POp{BX0=#-FYV1TUVTz@k=*N^tGZ3WjIi{>} zNJmE#ej#LWHy`<0LVWFp6c*9y4e{rd6dpu!q}~iVV+je)ECmsHtgxlHFtl*hV8pA3 zf*C&SIgWPE5hZX$^&DF|QjF6Uam&5MkXY2BGJ0)L2nXza|dw^x#d7o~Lol z`0V5?1J{G+em_oZz?_h1%1L_Dt6Ft&!{kaU*!6gAC@z;R<47DUF=p zc$6(uL8vfBtEf$CaApMU@&ddCO$+F41si1BTr_&rIGk7Fyu){JSsP_%b7X8`k&Wal z8ZD~TEb8@I(ajJ_`jaiDBsh2nD(S009{$&Sj&@@TRfjkgYqu{&s;ca-|8ATZj`otu z2Csf1;BEkb8KTF68JjWU0Y{q<4FZlW`bNXvnL6GdOr;ncq%1Ap$a^cXp`%5+Mr$=q z>9nzKrxAVg1crD^B)f|)n8duW4EFqlycWbeuNm*WEH3nxo`;PG&lwMXDlSyLwWrc} z@)+K1?YZ4_q^~p`>7z5l_;PR=x7wsHG(8RT4a4-P6gEuTjeHM>&tjO~XqOA8AYged`SNY3obQ=~nx+|1|b#{^HE`>D+TLO7_-5YtLa1n2*PT1c^(*ADAzcM~Fd&OXcPV!(@QRo*72O^HfxDB4-jqbRUpmwTM z8DDh5N|gY*nnQ-}i1O%F!ii7frRu~ZEf`XzY~hUXdw4JoD; zcyX;r3#RjK3>Mk@lRN!O5#iSI5 z4RTZ}Ge-k_!K1$(hqEFe;Vo46DI61GTjXORe%n;_J?vw@)i@lGMi8+&zZQdlNFb$l zgcyp+k_T9M+$MKlnl9DdB8nFM2*8lT@8Ix3(FGf*WLYkidAnKW|FK!h{G~0~j_z}R z9Ji%6iK4lrf(@aOvaIUw$Z{6kt;uL7d?`*P3bdnnr1GeV)F46RvXLmL`_)0QlsfcK zB>OJGT-Cl`J$mvr3vfsa?jusLL2s#3>MrbABAv&KX~CRyM6zAt6TPjcVlWB_!jln2 zWScW5E}w|0pH=UW9=|2}Hm|;+L=WkWR(B3OQrY46L1Z&VuAzGk5TaXCr4P53%7G0W zeig_|*WfMol~mGNqq*iy=dNz86oan8S zI&M$<(k~hVZBTu?r21%+1458Xr%XH?L81QD04-Xq>ie-EswDczd?6ds>J#!HRz_J# z@LO~Ml=}1|Lbk+a0CS+&2WVd?(Hl$LE#QTUD9-Db05htx`zw!^1oN69F6LwFatiq~ zz`<=9gp#GX8>R=ROq3``3|ZuEtV_+iXC0>}S3TWIaI~~W1#&~G-W|+v!F?F1TYG4X z+B6|q8Yj-LiQCz8b1*eG;NI=8IqZPGmv8|xeiDm^B90fv1=_e!a7_Re+NWytwgjYo)lJznL;M(eY~!CO;E1uIHZl^Z)_N(`1elpFV%P&|k2)vJ(IikLFb zR>mjF+L+Le2Ia;k0P-~GUE(#uCnEiA#kTNR1YkWV8q%qgUnL1Vvk8*<5+8=EUrN*7 zypS(uxb`Iu*N=I){4iz5kCq&vF4+3eGIV-}IYI|j9wPJ6&gc+@f&U~mYpXa*ux;@Z%l8pGq|@!8Ge6INhyd@$3izb?dA)&auIxtqL&5fLJ2 zRUE^6_!xd8JXX_Z5E8L72nGd->BTuc;p>1pGA7Z( z+AL*lK&r*+qwFjsx_t2CbcU1bVi}zfi|J8p9rANLIWmUtOc31mk7U)?L7P;4Z5#=5OuO$mat6R;^ootufn<#{)NIm9 zSNFNPJ7k+xM}q}U$yN8cf_m{xGxTFR7i2-(;nw3I-m`ujaEpx?2vy%_VC=ZNV&HXH zXU_&H(*SjUp3{p^)nDZbKPX(Jfz5tawc#lWHfi+-Zx%vWeF|Irpgk-Jrq)Xpqa_pPgc@IP zlGGzgJiAih7v2lYb05W`Z5CH5JX$v@Gd>dkbj!iP4w|HM9b(L>b2OY)gkUT>27@3a zodv zaDsKCUJlNihhQQ>9Y3{6BFJbmwaQ{e5i(^abdo-?p0Ka?VbE3NO&6^S?7*ZS=Amj; z1Zyi+k87`NXgEnj!=k6u&>l4OedzHhJVA?~n`IyL@y&852AOczE{RY}ktkb;em4ZC zM(ReY@b0#WQ}^*d3$g}?W~82o*#U7ztb*W8Iig5N6g3SgcrGYd5U>yncSPz-f*Bop zyP#ybb%<_ygQa$pp6^AkZ$sBUruaup26i+o4mfO%VbOutfwyj$d~^F0{GZ*#_WEB$=B<)=)%jfwP3-AiY3?*aa`plnbE zA=+0qx{r#jHqz>^+%5LAHh(a+LlF56t#Y^5v7O9$VjmFYAEBKKy7{7hJ}Y=gTt}iU z-I1iFJ79)QCFQkB>D?lgwfVd?m=!*B4PJ$R#pok~X&dexXS3o(6l%Jfx|;6Q_c0oZ zrVEZlLSi7|lOZv_@rP4TOB6RSA_Br#_rdPav=cb zm*|?4>JoQ^R8y4B)!p#LK~z`P6jQ#IynN(NMp?3O7fF_);6l-l&~-LyxYk7YGIIm^ ztxlidVMPi0J`|_wJ7go*$wroPF`B9uJ5f{-+K5K0dJ05nv^`0apSgMf70opi{GxED zUh34-d%hx`NPL@8?t!cyjS=QmE=`bv^lSuZntu+)*2eXD#nAJZK2SDb zCB97@FP?s701`x9tC}hfi7hUv$RtE|j!N6{aLsc<--B_g6%{KDYJReNiNCeV*I*)Bk%Q?)xF8 zpE2_WlhV(hDhDH-f7XEsrhI}p-&%ON1mpctmqRvP-vQEcrf<2}UmbJexU_aEPHP7Qs3 zihhuA{A}tO{e!{tIq%L?-}2*0>T^2=hO54p+7s7D&&{`<*Li-X`tpw_(nrt9{$Z=H z>ggo)-Td^h)i?KrrfDww|f2CnG~mukR-rU(fr)HojHgNU}cM;JLD{bnf3 zUpJUYpF>%G@As3fx5xgc=>N#n1n$&A|NlO9aH#43;44Y!@vpB$hKoMdwI-}jG`FRM-U%xoXeBHNr*yd~f<-<#VFI|}AJo)K?VLQJ{ z`;wfO|I#;X^%ebMc*pPH50mUi&;M}P_M?MWCz-G3uO2q}er^(eyT|?5u+_IdV|dRG z=Tk}g6Mpi4ihtU6SrY!q;J=_lkii+Sl_jmC6l*@a=(9Qc;&U+S;_Q2 z6~nf^mw!LWdFlE7@X1Rh$>gPyVe4P-<4N}a=N})o{ol4bvA!YY-*zS$KhMr#8^7GI zCZosehONH()@1xn>#*@Vwtpm{|Bk;8AAfppGXCe@VLRV!zfC5;{MWF}pR;~=`JcH; zlK!}r;oCo^3~zsOClBv=vi|v`^2s^aJ7=#QOlI#Sds~UVEuj0OZUV*;?$bxflJZT% zn+s4&xuH1^TTN};9%*lTIC7r$Vbh-XYGV?6UUg&Co_7xY|NB6E|Ih9F!Qyy-kn z^j+rg=Z0!uJrzIlvizH0O|&nZd-=OEPgnj=GvoLBbD7_*@$0$ge{GFFf6t-3pTCeW zU-!K*kl6pvNZ*mp)9shP>`d4%KSTK+&P^!)yvkD^O_;UwD(}UwC+v6URo>QT636qL z=6h}b`JD$_W}o|c8a?uiZmEI>L@&`N7ZrQw{*y+(qW*L#`yl98{dsN`b?ikQrrVcv z`N~DHrIsbB$t782b>k6Ry_y>k<>l9r6B;#w>R;46csduJSbwxFO)-mYlcjxCN&St` zIN7H8hL6!)*|;(zFE_Pb)u)!?Akx^!2tG$e+~}$KJZMvMx!qIQdG0@NfZq}4_(tp< zw;S`x2VQZhPoI|W6Ae)H+r)3f^{$A%p7)LTl^@ri(ld>Bltzn;UKPq-eI=U$xBY`JHzko}qo8p}aS~mT-QW>$&I*`-wAJrezz6mW@5+ z`;YSqE=2{F{6a%j{$({u%O7h0*eS{7iC=mWO;fR-k<#_IelFBqoJdZ@!yXm&_~OI zR(^b_{QEDNm|(#wb?VbPZCA@sYprO=B6x@>|^plkhtX6LH!mRN?Qmxv~ug5JVNXVLsY0 zH>M3`^i?Ufgix8M714c-?&s6}BD$YT_X}l5aX+8B8`BlNPRt2MiDMY${y}}Jf|EZm zl*-`lZ=(+i@t~BleNqfS5#4pkArN45>L#i)TE=@cy z&Z#{Qd@o-AbN2RN%2ex#AKeZ~;*=6WJzOyeM$pD5pPypfRdEb&J3C0jAq zD$|ugh66#C%FSMr!d#IQ<_e`Shrp!7vp}7kM8LDicSVWvU2bSfVJrnCiHAwn{xaGA zQmep>=H|x5#+{+Pm;N}36dfzyEPdj%@^kWd9g9r==|Xc7#ANp)5o@b78IKcf(|1-_ z6^fscf62bf8h`j%*ULW^e1`r0Q_}m?U!Oc1z1RN=ubj*Jy!zVni%0v$1w*>uY<=N$ z`o`)PBA=4qE0pt_Zy2Xc=82p9{InQBwMUB9=)s;~AprXKA%c7u|JJbjyMy)}XaitGZ7*RZEGj zy#G1pzHKJa{(gTSlR5M5JLi1wcJ8_7-gh4zg9YN_%DgMXbUL5jJ08AFJBsO=O{l`} zYLgDn(J3~qEuo(+r4u*}c#c;D9^w^4r?JNH!ezT~DWTGP2ZZDoJENu31M&Q!9(WQF zz8E>iIp zD|}(Ghg;UB%@Gy!RM@ z$`?%qqeW5lW*T&K@}8@Q&JoKC72b*UNK&+2*tZ**@FY|r#4Z?re>+lV6_1Mg@N;Gz zm0fiUkg%&B!tDTJim1KHWfP5qcudmrOM?E?_hwzfnS$a)k(x5WlWk+hmx&c_{Z2^t zj)p8IEx!)M(!f#$yTVm#5Gx0(HKoBKQ4UkvicNwpcuI@gtg@?8D=|4ttAki=vve zL7QZR*2t1vVvw^32^m$hA|j`@#~=V5&gpS>|9zV=rV^+c(vrO}LIm_7c8Z zOYeQ24plBkdwW>Zz_Bu`SKSenJ($oTPA61~+~`;EXvYI0*AEDh8%jSbc0;9NKZ_a7 zi|u*5=ElSOz**R3#_H=Hjt$#UZx=SfLmjX^pM|P_6MHNk&dIy=_d|{0p@u#1><#$6 z8*YHSH^Iwpeg1c5_F5mH3n8UkKMt;-)^dHucdV0@>nBLmP6G;_R*W5I6mph_;z6&P z>w{G)BG{1Q*B37lE^-@4TTSTFWx0gLh4e1}$mPB3H8oL8V6X?$ij8I|sjn zV*Wv-4>H=57Q=pjguhcEn`sez$+;LlAr(Ind_oCN@0$`uklqe{B&e!*Q%VUGzZD_S zo8hljVZGr`sQIyFXqV}Qa=feO@okYhoij}2rhy{WG9Scp{Q)XOY(EMT4&v`{_+1@? zriv}w!IB(ID-WYq)n*begtm{Tw!|BJdfrmuXqr%bkvF|> z{0fYl^Utnq4A>szyC#hvUV-t}^M-->@ip^qP5N5|bGd_E4((d(tLJ?WeryjSR^)-f zpl1-XOiZ3E>m@csAXB9GS@xrz*NubF9~yq|TzqlRELEs#U#G`Ls7BU?uQ$4geYD#9 zvz|tTDA%nZXJaxPyl{vY%0=$}*RigL#%2ignv^l@MXWtkTU?F23?B(`L_lGGh204U zzVFc#AKraS1nGM3Nxf7-Qa%q!zpMA4ai;!n+M!(#M>cU6e|@d`enlw25c zKk!sXqA*4SJNlZ_LeldP$gJ8VR8toiv?^tU3#M+ei z42tGMs(=iG8yDL>4fpfzrm;55QAf1Uuc6&iGONDO+YnM>w-nC;%UT-e`yLttjCNG$ zuKBULg-F$hMji&=!PMrXl`@Z6e%iY(1V>mXy9W7Zob~u;xEsL9Dq2_OYX33bO|RcJ4C6g-$0p%x#+Lk1tjD@# zmfsS>I+SqWP={S1cx5kiWI*moyJ+26g}%W3c$Pi<6uGmTuuX5G*93Xio}$BG4}ft6 z`?ZM~)kkHc>N!WLbdzdW!FG7Op=`zwM{fthSv-zgYe;lK1txm1$G8hn4FaKy)}8E- zcN}{P@P*pmHFQEgR>P6FYWi(MirCm@d zXiE~g7C=HPZU`lB@bDqtFX;^47hJP@|$IrzdeH$$)h zz@*0G0E1_)TfU!F&3ZohUVglvGTx5@c&}`!o3|9(Fz~BpC?Wxd)=4XxlB=0eS*{-j zG3p7Qi0n>#c% zwZVRn9GW7WMyCK~0u7z%yvrB?^2GKRdx@r=#bH4@M_kX$uwb2|P0wunYOddY<8N@= zV&=y3yMlBS zP_wMowEL&<*$sd%82Ijd10vu`)7jbO`gsD&XSsehP+*}csm1JJ_|#C71;^ zdd8ve?4aV07+-cUp*T?=0ZA~l_)U()_QB7CU(kL!{e7DLrqkcvFW}#n^tTKBjiJAh z^!E?Cr-uG|;qUgKGI{x zjeGb8?0)|%*G@@;&z?B+A76^3Ia$2O_1vT!B;JVkB#Uy3g?n*YoQsZAGrZl^5!|=y z&Tw)~&6qnjB9`M+ErvLXS^*sV7^H9cQ?pm4116?we*{@pLxL!Le{JzLnyKo79F2Jq zw3eVM9CG6^{FszU$F}b#Z={H(*?0mqdb;8U1>RE{bC9k`$h1~(?! z0h5VJyGMUZj6!cU_QgmY9h%4s;Uf3qMlvQAUbw|GcVE_z=FaXhzSDrX20%f8jF<42 zhl?Xoz`klDD>13Ky!aDKN)aP+xy;@=%^<~q#p&VZ)tA^WZovDsY6IdYR94_62jr*| z%TWiGqrscBIXbw3a?}y!g2>TQPK5n%XCV}kT_^L72NB;zkyAgc;O~wi5F~; zGwyS^iMQ-`JS1|@GUSlCa-0Li6QD!X0%1tP;g&b?`=w^mL$cIDG8o!=ylX*(&S8RI zaej&Vvm03hmaYWGrvM9QK?D*W0Foeb;S5LzJ58dXdmtK->s=QV8pxUY`lOy+5cE$_ z(~z7sRiCS8LkxDz zr??+YNrO}z5ZePrA188aL5zpeR*i2J-%R-DcKDp!%d`TGOWMcss+Jrs$%0PO(7&#v>cE{j!51Qed;ZZa; zce8p11&N%1rjj#mqz-e|5T)B4s$-r7+ylip4g2X1a1eW>#CCJGN3tuB4>_BoA!n~t z35#n7wF6c7 z**{d_2Nin`eFJ(Hv;wCl28LbGwUhdv$%C&0zP3c_j7g^aBr2lb2B8qI6;#fPzP40O zbu_erF!cSCU_>A#S(I!EJt#E zsR?JuezW)F6o{skA5%Z?J^=IM85N!C84@&^+7C1wKcu-jEmB9e-BRhuvk6Nw==Ceb zj_!6LDI(z*w5YtHpf8$FG&sibVkzpjS*mg`_vN zRy>WaJH`AASP&631{heQqu+tU=RupL!Wl+4z`Y964t9YDqykum$~-G#wI}Kvr=&Jy zvsC6@5K7Akzu-oEHk{IfO>kaFIA*u#!`74ihI^=*;ae$xu!U)M!JR>G3aoUrO9S5~ zp%}}Avw6VdNNnurOlN18fS%&q3kk(#k`82zWIAAs;I^zo9mQn~ydocDw)A`ddR@Ge z>*Q7aFRMZ0MWo`I0OUKANB^l4409*rZ;9YOZ95{lPYK16&lD{=N&>z?M|GHHtdSfh zZ`w7SRgk}AtkYfcE+CuPF-UQiet%YSmi&CB0iav{JPM!g@adzuhM!uM{om&A+5?oo z!m9r=f2*FA^Y>KE|D3=2b>^=N=$1b%;lsh_Ud=W9{FnI~&I^N}x0iyS=SarWxgFi{ zFZ`U>2E3Q0tI2yxz9zXY9~4FE)b|5PIsE#$NS&N%sWe!IbFV5HHnGKNpJR`Z;vvf3BaYMRnEB;iI8C`STfkK8DXe%{Bb|zuVv3 z&XhmH@&7V^CMAF8|N5Wvw|rGy`Fj`2R{p#IpSAFLO>+%D|L^>*>qPnU{h^z1Y5p+|BL>Zkctd!a01w20AP_>8KXDy&w=qKH)mP z0pv;Y-i)i^PI^63e_F!H&cK&A7L$~$Oqg9}q3eq;1+lqDWWXmAK3O8yc9r}FL`Oed z5f+RYx@hnd_-JQCUTBpN9IdM^q>+uQ_YE$(RM>^y(IU6S!=~bHeFWUX3t>2?Omk^Pb&eYJs(n>l9;m3fY@8^tG>=&J1KHg zlw6zg6N5>9%M{@V%m5ykhq0iqd5>|}r6|DoB_Q_!_aTw%MoeDph>=(zrh+?E>xZi^ zvgu8WOVCcx9XECeiq_HVsqC@Y3CB|0PsC$5QE6EypWQ>8LgUQ}Oah_6o$=L6nQoYu}^a{5KR%>R)CZHq9_{@M@fo z?9zpz(Dqb;kn!_03DURv3zzOp@HdH~Z9#vr1v_^RIL*=3d$7fKzIfTJg9?CxfiiA@ z@!g3RQ!G~(c7RIbLyjfpo-jCD@j}BByu0NI-qisLXC-B!H2|!3p$z?YkYVvUyLhsa zaA9-e*L=y3p(2+iC@pZDyR!f{37wZ*rWMAe_%-qCG-033aw4w-FYM<_ehB454%<4O zQ2jkqg!Lltv0XGZMw|P4kn_*9kYaJKyR!w@d%JV@8Tz?f?&HM}Xo%~tNL6&)hA*(3 zw?cjuD!AH0MT$Ffy2xD-SPM64q8S-(ye8tc2k06wr?_!W@B(dzu?eGl*o0|GHsL4h zczp5Yc=a6twbql^Zd+csWEH$HWf5+Q+^OYqP|cB~HpVS;urZ#1##r$uHpZ@Q))=87 zyuMs{iR=9uoZAaA>Vl{iGgJ|PD%vK@jsav8$C&e{+(`59m^FiKddH@`-J|=Gi`c8bNf9n#3+^Yi z;E8Uj1=pijtY>38h3bU{Gw33=<>ZTUTkd|5wPh9;gUO=2LjZ4$$whzgAtJWuDZrQFcHDs+x4eT{7N%o# zD;Foh0XbC5H;H0pDMAU%lPoZo?S#sqkv$-A&5#6}o2Wyp*#LemY$jXHa)T54L})oL z>R8B&#dvBRx6aykYQmWm&tNd|r>#O+YQeFb=(LIZ(?TlySW+qtc?O)S!(Et?*AXV} z){bQxI+h;2ZVf5J_Y#LxrdU!A7#8YN1Q?a_qEkE>L8+E+a=+Fj<^_vvnp^96wPC}V z3wBBP9h$X~28BvzI14n;yMf2B_cHSMCct#NFgc4}1!x!MWZb*Yc&TwsKKcp;{J@qC>Kc z)$p!ny!3|Fz~SiQrL~8xmzT1MKn56Kv=#U)ZoGB;c)u6e1dLCb4R?0oGW05F7^hE| zVKAwrT@YTm+$ryRfaAmJ36raA*iyG&=xmwZFUMulu@#n6qjdK6!PSTz3}n z!-mRza1ttCC}NHE7&g{p*jO7ZReI%E+&Cm0r#)06_rX%7Y9lcxrh-xucBC3Nuu)b| zP{zWQte%pxdTp`fWp|;n@WM}DJ1AChiBzn27E`f0L~hIy42!Q^BGthe2h1$E`=INl zAr>g2X;cF_kHF>lFEIyu>GDu^xgEX_G7~#rQ@Ek^e(ds)`VdQn`YiJ`)|B_S#k7v| z-xW10Z$UrvCmiOMkX00Q0k>$^#EsW}!!9#(vC=Bc31>WgMc&@c00^DNc+C`J^+;A`vvq7d0GN-@%2M2aKImYn-Ty6Cmt#KV*Og8TbCSkco zE%IBongKt-G^pKb9HzTl)k8D|XPjd+Q*c@sGLBs=)zFwlR6`{qw;Oppt%i^e5W104 za$X1YBmO}1RYszxEuqUryr_?Z%RV;=t~JcowI4}Xl287fH&#!JV3!^ZbxyG3lO@8D z-E1es*9(;rYMsDd1HUnktspkhWH>Jm>(}=P7#zY?g{FQAR-Ckc+lp=*0k`3%g+bAD zW4X5vwe0KCB4yx4CvBCd;ec3*tksQmy4oRzy7I@<^7kpqTXl+%4*AM9SY1Dwtl;3A z^6~x7Kn0ufpJ!B%V~EvtGt_YpRLB!l`rOAqNzuKpaxsV1pXylnxe*vLkz2Qz6-Az1 z=pSKo-Js$a5?xJu+dW*>5730}Q*Y0bZXbxZ!(}jD$9zx1jrA^KeWn6Fqa!bp9=JfA z#iY~MFAdiik7MDV@byG-@g%Mp6X$44tR8OW1#BtCt{Mq>OoBmX|F=@s_P;^A9rSvP z-=J8r{jJz@>G`8Rf%54c>#E~f`v-o-9w1YF+2E@uW@7TD!%yj)+t?9AZ>fsC2o)d_I5sMb|G zw&Hl2P4L2k92}-QC)6ZTIJoCD?nv4#v9(5bGYQwHW#OC&_nkH&v8?hjAx2KPIWJPFeoW{gC;Y$?lH`OWIiZ3j@Nxn# zC%nfJ(&dD7IpIGnAwy2ckP{ZNgiJXhQ%-n-C1lG9*>XaEN>Ca^6W;w6(Nc0JmRzJs zF480$S@LF0@@7r)pE;P!+D#fYCE;q~Thw?u$?LP!ej3Ugp8N`SSQ;%3r3#{b+V~c7(ey zpTbIf9PiEmS$q~|B!n01@$Q@$_}v3ONxT@wyR&&9)8UiNyR$NQF;#~k8 zKv5ER{~X@U%G%A!)Ge%MUz?@o=}rb`^Ui$DT;Lxa6=<7auEU{0PncI%gO>Z#5+?sN z+I^VLwaQ^bK$x^K!|mG4+?#;y4$}I639dc$0@IlWz#I?Z(!R1l5aYyEsFWNUr^bFK zjZ>ZG_^m>T!QkVxdd(q$s+C3X4`9Zi z{}_wA;23X8E%o=&A#KB4RzQM&)!fKh{<~n!U}`h!o^Pw=*9P+2lk#gE?v&i*)Y*Q` z+`k>5`~K}W;Cmf{UfKhS-R4g3;aAv)X9u==xxB1Bq{hIBT($$f_T(Pg4vUbJd(I&xx!(VbS#G1V6YD4w#|Yc!rYqLm8){guIV(P|Z*KMymPVv+AyS1rN{4 zx7N`F{|%lbh9}7n&-z(fJo{%8o{qmtbD$4q{u3Uhe3PW|Z7Eq$k-OofVos`6%t?3Y zTQYu-mQIZ?h3o8O{mVTl9Zf&X_2bAHuYmdg%(^U`f+tWjIrGkH z=A3VwqP9P37R@*2G68GBIO&n$+^zO@1M@ekww)QE%{D&_Ne$#%~yY5!9gFXR|7 z@(@F@8_*m>m|$YbW-D9-!)W1!?|E^b&9%?KTdwBr1s_7 zyLD3PH}z-GoM?Yw`y4iWgu2PF`&hqChP?1Qg{`V=!bOpb&Q_fkHZf2`2dzQl_H5EP z^Jgr*!xT9Iy_cVc$!{Ky$C_EnXLo@6il3(Y2AztM_7Sq1vFO|0v&tkIyLXdL? z@XeXZ9!U1+-@^RBt#P!=5a!dg=s}wj!B2&(kzU-rd_E-P=0?r?Ms+*%BMtlK(tadj)UlQ?=uZPd`O%j6t-yyYTq` z0Y78fAK56U+N<5AtLc7MTR$b6Ru+bpW3c1Y7%W)R4BROy@5w8ubcWCtIIRZ(b7c6c z-u!j#MYMnJzZ7+(4lM6?ni z%PCX-)0CF1ZVYXPTUcG{7S?cDUQbfDur{|U8A!qf)&t(fCq=RPica3ddJ_RJhRP{6g{~J@Hz67eTN5fFQnoI$}^^wuj1Vvo{W%Yzn=|!`Md4MY((MYI$`&)=v&I6JG> z(6nOf9eL~KT}&W@akj4d9^vQX8^|C-LGtbhyF1BXck>bcvo?L{7#6ZzLV6&7t?zaj307S4&7!39VY)-g5ox^S&g54Tm!FNy@ z+(`rWA-izY_o+62a;~^Yk}qvN*JB@PBoFg?UMTVXa@X~qTK$1-=~3b&(<$C;7cw*K zLUyKI$jQQm@V*)F$%Ic(WBg_Ctdv2E9{bYvSJvYgF!Qra|*p{Vk5X2+oER8Lhrp%_{LsUql?r!XYSMzl5(7HK0|4<+`1 z!@CvWH>|SZkbsXzcdL?%#rGs~!JYEf`IvEa`G4Qw3?tmrTb>jF$at{dffzP{G^Rej zZl|>F__Mxe7I|ffxDs^PDtLwCDdb1vfec)PSs=ha+%Z+GP*oX+bWq5?CAeQWDUnqqE(P&&E=&6eOyz7Q&D!{D`!oZjm zp)y726N3-RlvD?oc!RC3AL_Zz)l0EdmSEe;}~~`l7|wq+<*cqD0T9@ z=ZdZPSX2tSQf%?-qe;qIZ#^0seeH2*_~k&rF2Vc1~3c1tL=CX|(UTNfNlF{Ku#n%*nx?P(aS-o%UT9ncVM zuF_D@VVIi*5?#UcOy0A9-?O9NbpXJiG{CPn`*D7Cu z8+6c&`|F*NApQI#d0zDsQ1p-sZ_(ESoz7;wYhHxT@eQOMnJC}2cOu?p(I0|uXXIs5 zge}4}qIj~YOU3+?&aZv%Sa$|fB%}R`iFJmX>+G*~TClCQ3EA0bJ16k2JcG_Lniuwq z+@q6~<=RR3oEZJYB`J}+G%;`;cE&_DC|YPHb4VO+@PCeRAf`jBYy}O&#Tv$*gHhnb zBt=u>D4$T*a;aZa4LJJ)isTz$l2^OBJI~lZZ?p^01!1`K#bc*w=HY_^ zjs=0zih{y76&@rO$j7=#Z2hL7(p1R8%Qx$Yd$HfhLvWdsd5`h6Do$4&uG6e*1~g5aK>vE2813EBQeFa<_w^0U zlzl_CnMB*R6(70O(M0l*xhtSR*r)ZBP5HQ0-6r&ohOl z@oxrRiT@brVatCg%L$p0^td1%E@bssB}c*T?jLPq8$1R*P9+NVf|VwEXYqFB@uVks zS4ngcKA&Xue?Ex`3VeR8)X`YZ`}GO*w2_i?M>EhU<+^_a(o(Mb$J7eavdol#fhiq_ z@JdVt8>xbMU@Y-_BD@VQDTi6X_~3pRq2k(U8+s3^6;S75`;f!s`d>kLn^-rUO3@k9gnrTDZz%4(H$Hv5f zG1mc7Cx_>-B}H5|W$4q5P0)mg)9u`Z=|AW6nP%&5| zoG#ZfBmLfZ9Ct%7dUCgoa{oMEf-+78r&p-43t;hXh}^5A)ezbzG_oi&%B~1iNH*Z2 zoUrX20{B`Qc^hK^e=Ti}YMJ864oZcB>g=6Cr^`5F@sO={n7`(DotN&euzE%WdvCGx zN)j}aoQl!4=d&M;W)r7Gnm8qZG4#c0Sk^+a&HZRBm~!_+zGi{kb4F_dHUIV8$$vb@ zqKlS8FC(K<(ez)YDCfKwTmhBlHw_S|`yTD-bvE~7s3@tfRes)L49AuNEy5TvhQ%GL z$QOkUb!}uMofQFTokmfB*yg$(yfD^AhoI;)a0i>mSOSBf9VZ4JZeJDc328kFpKK;i z%fpS@6NT3rjH-KmUodVMO=`b6BCB0IvexspLnVJEL1a(6vkefZyb#0DlnL?l8Ia+Jz|wsD?D$s8pRQ{Av>l zD7IkHM?p!_#wfs6UxYF5dNszcM6NRxGN%b2M9}D6<7k|gxFs5B zhru`9`WdqtAi2?K<_Hbog?Mb$eRwepA2$kZA5FKwv~uf6#j$NhD}PG7;EfFC#XjQe zpt-sRuBI0J>>P}0$Jm8b13u{@9I)ciC>NNPOB!{C#_OrIV;07JZKgzPD&V{gmA zevqkjw6WGPa&>Fw`<0Fd;gu0qVM=HSI>Uye&rp7x& zPDhpP<%R4FEabURRg*Bo=x|1QyB1?@Ii5z(h??QpEU8&9%;epv_{o4zmZpp!7*X3W zwIHautgUOKZNVd?2CmtafsqjmeaIQ8z2yg7W$fAukK=xf66oDO9irW1orY6U{Blt0 z>(o&n9$u?Y)7~&{axpDUT^klDb!lVmJ7s;i-guN9Yhip5YSY;moJH&b`*CfqdO;KH zQO2Jk#Q}zhJF~~E^M;jD*+t`V(ltpDp^io>!_>wU-t&FRJZtG{N@N|I0}pEV7pV`2 zu%lmUpdU9HiE}3}EnJ*-wqhp%dEk#7*JV;XeS*DbKydX3tlRfO_&h!yEcA;IN?hkW zY)a4_H+jdPmN*Q&*ObIKLwR9#v}_|mpfw-L^su8Io|;kRn*^W7Y2Pn4i6oI5o1yeZ zt4$2Ua|YbmIhI zVz}dR$?FBzHur+BvrQ;w&;KuG&;OT5{;u6(G-UYuyI?H@6IoQJZmKfnH`3YR;Q@$a7KS7Gm%GP_S6Q1%V(64WYFq=ec z>YfbI*Omr^y?7JGiKSo#Tq+%mmu`tpo5+nD#>NZqBe*St+2mh{6uEnblTSNJ=<2m#TG~$UQTJRqGI_)&uEkwe}rK)!JU<(grEj`ulFG*8YPv)%sAnJj^Ds$HT~& z&=FBeT|;B?4#&~^6mY*Yh$^~Kg{Gn}4P+7dbatZC__AS*^*a0{OW*RRn}!bX&(wI= zOal()mhK^_Nw{Ik|CMZW_pPACnJR%Q#o(svB1{u1@r+YpU_=4rq7K^O<&ri~+JE5~NK1Lzla?i|B3Dc|9VbzB$&oTw7Ld6En76(Wn7M`#yrp8+a2g4g z4pJg)O%udAf@acgi~R!wqiov-)E#A`riOXoDH=vimTgb*0L!2Q~hF1uf~&xYpd zjZo1TaKx>+#$%u02HaQDu;Ux|eu7W_42rh9o8T-T+H{jTI)upe9LOw59qqP`bEZFO zsQSyUKYFC$k@82e0MNY%9zZ5y^d8B*nAKkz(0i0Yi^c=$YzD7>Cpm!1`By#4Z1{wM z03JxcXyA74Kx2hZMADuSWA`+vf90#v>Z%TDKZ`-y&mspZz=uu~ZrI$(5owD*xNk9`y<}Sd6U?hiL~#+fQsAPw*u-Lu~HQlhv1KD+G>Schv29;Ee?9*!d8@ z;1&o)U%1Uu$sTH3o12wz9|o8$vqzl6%Do`fx0NLFtf9f50m zqmyhX!O5Ol8B8q%?#0)zZcB31-xlKt16XjY4Y%`IPB}aCg2{&M3JU(M{&;SALGe73 z$eGfpwU`Rtr8P^C0dtooV1^C2(H!$okb+Bht=Y~S;fSr{VZP)B=KcuVpl&MogFMW$ zb_>|yQp&ItFKr-aIV7mgEYG7X&!a4_v}2Y-q%8Lk`l`1rqAV}+%kp^pzhwD3X1Rf! z<(>T?%hy?!TiT^8f2xzSEIOWGC$pY46{Mo|DLC)Qu~TKE0C2%tr%?+kcm{bqc1$>k z@sBK=GQ^48dpt{j{kFWRfOPjhk+rOK;CPY2yMrn0j-g>| zmdzc6Aql)}&4f=@?dM(PF*F1E5wy6GFgY5OVTar8Zd+F1KHK?yY6mSQ_o=-*Xs`lR zi&A?2YiMl5aCKqkGR(DSWAVYHyoGv%Vh`_t5cxO;7VNO---g?q6LC*5bkl7Hv@!?0 zeS`dN%P*d1wF`p`(3?XO&XA>xCV7%*;lQ?FM`M_oTg77KBdM*e|6gPMgwD zop44yJ{57%3?7>qP2vxDUkj3_?ebD_N-CSD$Mb%iwfj?GdxjzWrnH6{$N$3`s#uR8 z9OvCR(fCwmyP&`bX-SI4qq$4-sjVL!tD7}R5i$5srCgpPqhY=RXvCx#frk|RZD{Hi zLtZ=HV;sC4AJY9QnWh|d`VX|)djeW_d0)zq(0IvB+|Qb)_sl=+3oE%9?0IxB^aDs0 z`Iy9E|GPa;Y9L4I zGOZbI!+{8lxwC=DEd*87>!~&(`)c#whw{%s{`rQ3_Y|VNkJ0F2HGVsrnaVK{rHI)k5e{)gf>ZK?P1|wlgpS9JD zzHZ2I+@KpHKi}7g_slWS&gcQxd3VE748vLW=KhM0gF&y~+8bXJ)F;M2X#a5%UL6oq zM~nHVr}gFcZ}AbhcwxnTWT6R_Xc27D@GIB>cCgYW{s{l2`<3~S$hmv7);n9|&Prq^ zTL3(+Ze4ctl#JaPtCIIept*lV&AW=4`r>3M1lor3Qr$~^cnR)&v$r%g7@4fOezym> zwBsMR2*%u<=#QMd%N~Kpk`xP!$5{N9M1An$Tk7C_<*`WJKbf5X!7!gY2d>7iy|nYW z=wZ0?-ZMRRJHO-)DR8x-lk}iMD%6#}&khWR*U(ub(0uSa$tv8zZyx_-+1<{?@F|2( z5q#FeXES`ZVPX#c$;LmK>|`6ab31%0;8P5rowW6tx0E=sSC3B&LRa%P%jw|?$=bZr zQ*s@vAHy5mAI0VXPE&`EV)1BV??bQQbZ#Enj9Y^ub>;exUz1<)^Eyz|(n56AhaN`B z`i@l3U|w9+&`*r{o1u+^ll3TGcI&ThHB&=DN$-=SX^Nz=K+Ql&E|7%pfiP~|jZ@vA zUc`FrLzQ(7vBoQ`ZGp;0R$gWuN335k)@$#mtQKOu`l`(O8&ETm)d;NKv7aj$jieh7 zDmQ)s)NH)*=ZAvG!F0D;^^sZUt^XjcMY%pgg{eJBVV7;H!u{zeCtr~>2dH%@=LM2e z;jN61r1N9S(EvZe1nm7-72qZT$%=sPKy5$)qa^`_Ou!HOP(V8-AoML&08avf6#-XX zG3%a30nH@=edFm7rF2vZ^Nf8INc`YK%+Q|4$Z19~K_uqWS7b5o0JRCl9PbV#7Xl4M zy7AONyzyD(#(bb&!W-X&8xwoZTxixgdV#*IWpo76AU7R6)SL9Z-AmE8n#A;1#PkH} z6%;cO#E9H6i_&-T?um4FE9GtzP}}hC?r=BcYU^Ii6_}T2A7!@60tgO&KslZ(r!7-+ z+l1sD+A7QY5~w#(-Y?xCw`-?`&}#7a_#=xCq94cbN5@C#N5NkFadr@T{orH|Lo?!L zPr^8xmFt}#EtKRw3DiE6y9^lY>_HgrUKbS!woQ@S#Xtd9FNNztpem3nUE%T=H}8qk z?XHBY-r-%SLO&_M>=`ef=AcuEoY&$H;^G#wt__L%5vXG*E=U97@jL=Cfk1RqKmah3h_`&LLMH4Tw2q0OAJ(Ved?vkWzP`8S*x})o{Lh!ox{f5~98kZb7_lpv zvD|!IVAX$@Pfavz2Zq@y=m{S?JK=$5vEXxfH-5roCP^|kDl%69^#{s)i)3<(Uu0+Q z3C2Fq?!1GpGDcpCCIRm_;OIoW=|I&W?+oIlEr5%AM6xY_S+wI!Uz~`qs-Q&?54{q( z0)~?+-jli*zE8n-A$*^M?;`m2!uNXkz6jr&;rlv#Z-Z~*%>lxIL^gX<*%uG9O3IXQ z?b|Hl+6hz_n8sC~e2^7455@gk2^4ocT=jm}5sTZ7Ues9{z1W0s`#FjLfq#SZ1l*H{ zyY5oHtK!8n-fbWb-gPTH_Z+3~#x0fJpmSu4L499EeIif~qxuX5s|j-YehJUJTr=jt3iV72W8R;Vi{pC<5hv@BFlQVf*tV)%}O??U*7 zW|Ue4-#y@aJ$xs@_h$I!;d>i=(;x*)s#{$(G>nr(zAc@msY=?T1QIAc+fhsyP6_XvP zB6TtOR$4WwlA894ngg3;HJ<~Of@;3)5=7jf<()4;ODbylDNfZ=-i@?)7n2rr+7@e- zoO_rlDSk*+GFefQ0aPDUGM6bS1SLICNnccwr%^J2DVbP6O3*7T)GApZDH*LO2~w2& z^#WKmR1(RQ6oHbm&q0X|l{C{Rxt%~t9-2=|(CsYJDv6Sm)O44XyzqjoWF=7jP{}); zNy&OpG60qIMFY~ zS;lG^v^v@p3&HI7-Ke`eMTO+{@!es z-?FUdH<{)43hV6)%{p~Zq#22K^R8M0+(J;^g<#A8Y7D|y*)d4T*h=!Hxs&MrXtMKO zH9;8_YTjA$S$2EJU#9el;h1;wdLrXZz>mmjsrRy%iE|e zRZcIUchSyNgbw|*i^j({mFr!Qz8NL1zmK91_d);m9wRyAcDGzHiES5$u}x z!+_*7I1zB8GifYd0_kf4(%)J_>9`lV0-MO}fbSyGq zLwZ6$dct%{$0nHVg!Co>>7$*L4#vZ{4fX#O7lRknz+! z%zr?78Neh#ExpMv=hNdIXHof=B9dBIqKw`>o%C3}i` zu&7}C0JV4mZrMayq({h&PvR|818y12Zegb@8K1+Z*f-#oMbs3fBfyNipnrK|18#Z6 zLAPvUw~Wh%TY>^^v1QXO+u1Fj&V*ae-s6AEYcuJVopcMm1l0~EbLTy($+Uk6{mw`B z{~p}ydX^{SOY99B;Qi^|Lgjv3t`@i|*2CXei#>cn7q)M`Nvvwde)|A~UPYmu?@`TI z9mq=`xOScAO%4ybc#Q~q=9RGX2FYHpyKeXZnt zlWi09#9 z@^7}KDf}DHDLMu`C+S$bLe?>a>BwIp={SJ3{6)2-<8ue;n7o2?n1J0oLDG>;`CQC& zq^dgFz9Q+UR`PM7CFwXN=i}iVkTXiw(IJO)>}L7+X)C1NIm2}1kdCmnN*tt$CQ>5j zxu4a@*KJha?Z$Q}<^}_yn8&w_R6NJyc(vg`Hr8f)Q(CHRY8xgQrKB8hhn8#}md-D^ zRgClW73*({qCCh?!<)@0J*cHR$fx4f=z;Pe|7!~h_4J)hp`OjIC<^uDbnqX{78jXy zHX34P0o4Y$t5>(7mUZuR*#)`sEH>JG9pz!kuJAktR6FDu+eU3-@4N>%ViDa$24T-E zg0S`t7Hzs3=MUlbDzk1NiMs$)XB5|nL0B_KhA@*LBr6aq6`oIldH{L8iBTamM+or< z;aqd_`HrrpSksmrvTMN}LIg>RfPWZCnh8`QN-Bz>c4VAI;ifwd^6OTurf^eWq$&PY zf0r&^5!V(d3yQOnIBw1|*}?r5`mFc2AN|8#*H)T!8N^r(R4OtWVkDOcP(;%dU=W^% zV#=ROu_kWleHd$+D#e;|SfGi;i%v~4smp1ebH2x^ZJcrH=^@b;{xuM=@9}3o+fV)nx-tgo+H`beA&8}XnWAV0h zO`Ix6jZ=Z~(gdouX#!Q7YX_?E_)sN)6|V_w^-u#|=}8#0k|JU0JpRa(ex&1%3@MzI zLE)^_?cRxIIT|(6EQPAl%~J5HuUQIbJ!X~yT;0u5$g7iC3WBwh__MstBr4NulBf)? zp53xPHtZae$3Ud7> z0<{I}H>0H*B;ZlcR@5^tiUC3uy_t%wPuwj?FjCT!sOb5Axvb|XP_Lk#i!IcFrs@sQ z^D648;Z!}}kR!}ZQvxe6+-TKYj%8|&wUgE4C~Bqx^%|;iw@@N0qfpE1sHI4w#lf^3 z8n48N`~oW;Ny$@+k|v50Jy6?FNo)%xM)b=zQ1S*U>8Md+VoFZURia&fF`_t0i9u2F zu3J{J8K^f=$(PNQXje8Wd5h}5sjB2na-6vXbCtNAU$m>N9aDnyL8io}D6s(bHYyp_ zT#4J=dL5L!gGwIPC`n~XYQ`%ONWZwvUo$0^+8C9*k4n~Qlq_IMKAJ5g zU3oZE-y6R(!`MmoT``O;Wi44QvW%@Uc3Hk;)7ofSQ)g<)2z3Asqk*)`KQDMHs+hcBZf@0}m= zlaT6@Ja*@lzoj${+(8?9qhj_AP;+nIz5fv`V(bpz`klKGD(Vrq$9c8uK9@YLtZLU2M(O9MSu{}66sbDP%azwu5%;HJJ-259i>aB!)(U;D zUk;CS&SRAk5hn=b=uXxze?RTcZc1N41pY5HDWi0pBD z;XZm`<=Jb#Uomkz-HGY{6t3r67FI^i2x&Z|zxlso#<9Q~oBgl5uEP4iNwoSif&1`_ z5O|Y8J@58(dtS78YvI|-^Y|Ec%m|XYg)V+3Wuh^K3HA(1D~ezBvCd6hd?a$fHia?z zX$nP4(h{0)^t4n;{b2A;9*eZv(IlO^zUO!)8P=JQ+;DavL+rc3WV`MsQK#o9t;)bT zzm-Sb!;6yU$F~~H`ET)}J+x9|EC=}Q_f>e)<;2<=jR~s%@%*toFZject*7v|=mE#v zsPy$N0sVfX#qveLlOKd%xwIJBw}Ex60{2;a|4LSTvUH@L~4hY}isvY#V%7I01-a**>2LV)EyeUnl! zxJo~EI@hZNp_RMsZnHgv*bo@}B5U~=F@l@KzYNSixELZld1vWBr?q;Cz~n=TxX#^w z*YoAAD(kR!haN=N*L=nUJ)PC@X zdiWX0~X1df@Bih1YvF_W&E(xW_S@*iVl&W}@E&_Z> z&Mp}xPCK-WWX|YRkjjaTgzf)9MXtj~aL(HG~ z+MK}swK4{`7_>4i|IP{~&l04RjODn|!Ui;IPT%s1QrF&^M$6Yvnm_iMF}hZTYul2C zzlb$6j^#2T8@4<`pJrs-l#bmMkSIcT)GR5Q1vf8Bpw6*K4NXdyA1ABv&ZuYTMEjFO zQFDz93$HWbmrI+f_{p*D|1vOD(SNl;QxoR;FDwRZ$lsaw*zf89P1s{9PntJi{?dt0 znrsUt0@DJ}x)yo*Bf>I23 ztc(sHftLC^dB*ZoFOeGqT+ho-V-slCNL22IAU?m5W{LYdwu}BGz+YT{)&FP1 z7QEOaVsiKXtjmy*!ERpz`l=A=iK!zewhQ|`N!nsOL^Sl?k5VU1)4oJDy8g$3*`m#Ann1QTW_|(GNyBle|96ABsseE`%<>ljBgU`(@eR&_fd+#< zB4oTG^Q;j=wev;%sk9RyTh=qIAj7EFh>tOgXOGT!RMv01GdMLa6|Z4D;R$mR-%CVZk`7Uzvl^VFjMAU zvO-?XInQ5jBIZ3jyUQ!!b#M5AB@k3KV8IUf!vBQ5ejSOGgl-dr*(=3a3Jx02d5>nJ zYtA96qY3Q3J#dERQhfPa!@)JtC!qpZRQqmJEh`!U%RC8HonRmfAcz~f3eOi?VR*Nb z#j5&)s?wn+u}s*K^UnZRti_=6KW+;Bnmq90u?0ic08wm0dMF-Ak?n;+UzpJ;u!vi{ zun1RYzHQx;09J|+ajo2Giw~oNq+*B>qac2{BOS(p0=G)=sqc&i9ry-A!Cd3PUJiK( z&9Ke^-&K4J)Lg+A9DV^fm>H_mNt_H$zdxe~Sg9A$8yMt+E&}X#-Rt(U6kA|JX7D9z zfFQO}GC-C?az+?fSAfsA17(68gO(bn!ThIi;Ghp#7=5PgmAP#3kJvgq?jltRrKaH^jef+}~6;!7A2^5n~)4uYcw z#l`Ftp+f7%XZP^ln)X1;u?4T9ue++)cNsMwkytpq?jF8L2r6dBHVLp({-wZyr8NCw zW&Eq-gu3J8h7>YneN-n5i8kSBku$=LzEHJ02o5;>9#9#1$1S(?3gdra~LtFPvpa;)P&ycr!t2DaeEG6pc}7-jGW1DXh1`_Kl2 zaxttkV4|2k&zbs*ViDH!0MeIyrFfhaX#L)p5zBO?LEXk%hl?ud8CU=dp&;-`DaaJ* zyNQLbx0xYlGk0NhfJ*OiRhpU3YeB{@sJ-`CD2uTwkT*m75EfRQ=U62F$^$Q)^ve96 z9Vo_4Im=M}CkVbic??dS2t<-GlF*oRja<9`OW8dx>LYXw4?@kK$WFel0T(WWmzcaN zs`45{&>4NuTwflVQUEBn3?ZxhFyUrEJ%;WEVR2ygfZvm*KWIUiXYkiBi_(1nD9yNMD3b{bfq`-HvQ9js0X{D8Fkd!ANXIb%9Zz!0yF6$|pytOq z-^VSefQIFvra-^H0g0=$F@37LtaR@vk^{$ z$tkd@{SbjlKN#YMV$Cw6ba-G5ZtgHOqT`C4WdlNrgobHFm+g&k=CRHuo9?79dz+{(JdPPlWF;p%4#~gj1!`bU2r$pKs>9V1VZsd$V8_>C_^_uPhxcBoN~?2` zgDYw8SSV)-v*(y8Zz5PBqh>AB%a+KJ<4#4sfKn6^STX^f*s)UpJS1Ef5u&OFV3`OJ z0Xa_D|4GtqzfnnJr%ZO*MznroZZCoFsjb+cZ*M9_vjGLIi-87^Yofm_>QHWf|k0OYxk+?Yjj{&J5IW z&(Ry^jO#cUu*(CBx|0bQodGvU{~3;h;7wC`u1dw<^n9%|riZQWMaW+7ODQNbf-ybL zF@?4CY|E?q*jG#H_~kzc=qWQg3nu@X2db(#4W7S?01oBBIb_aOPSGzV#$@x^~|6W*p!;cM+eAW2xa{P$QDY*eZJ- zQGFo`^u`(F?4_sdzLRPUYOajbWXC8cm4#cNy7AyK4ye}!Kp%%Os)9U15MTd=)%Oqp zdRey9!$#eu8}A>B8-M?K5qnVxdlsg}Qvk?I4_dR9ijnQ<`_bZA$&BziCRq1=5+Jr< zf)`HqHZ(DngvzDWc|8M97OP*(3Eg^5&0?n?*m>kXZ!A# zP(I3j;Wj7&*Shrta1w&LN*!6c`x$|VC!`*vlLKa68aj?Gxtcs$aRC`#SK7&5VWMhFR}XowhNOniN>EaolkqzU002ycVa#c7vv@d z4x43i$bvWIp$ZYH|F0;$YTunw=fiR_P(@%-Hy#2t-guQtA!r>0lT7C&(>Js*bcE`e z|@qh!z)Ty#~HZ#aVO0IGTxsb23a%D#w9V#hPlJn z)Bi+=urR1)k#zBurv4(3Oab*Hd-{yE5M@x7JKd%T@Hcw`dU>*9| zj*nsz4*2rJb7EqF+&M!$F3$@ujD%OF+e)>wY7!3eeFv4m;w2%d5!r>$vM>e>Z9%Oo zIvUpAqX?>j=fOcDE13n}X$TI)9EYOWDd{tU5MvAz5K+ZF9Fx9r784~*_Gv$KKLG}2 zKA)VBX0VMgfvMedEMpCTW3PFN(K##N1mK*CR}q9^`Ra2bQQkcWC7gcdf{36gK6Z`5?jL-etR zQqMd)pvR0AL{yWNMY_Z}8PuMTHUTG;^hPwKdt$E_&?!sy3c7d!43AO3YaL%$vUsuq z$JVE3egk%I>H;Gv_#73m#}lsRR8l!~jRDxLgV9|#@bv;6I4YI2Y-Y+%f)}Vn|8t2I zN@><|y)4E=b@S|QB*D!L!M$VYT_*VGWlOwP?-hJ42+B#TvwC(*7bBt6^aCIKVkhOz z9XMS01)NoOP<7JF{%1f0uM@3~43CHu2ejhxr)XCAc)CPX^1`oGFaf)-b?L3!VQ@3> z(D+4~5nQc4fqk}hl6m%%B_o#e&8Cf`1S9=shFl0n1z@>GV45meNWar~UmmeOR0Dv4 zn0da(`EMT{F?P^V;CwP4Ug3vDTwq+kbhdIC=Qs{85q3&*!@?}PVPK;aRN@a`mqe^b zA_J&Aa9Ej4F^~SBHbIM>+(?IwB=`^6j<@nY329zKFSI zR_>y5R|~<1xloufW0pCp;l_} zblk?SU{%k9S6jY-jw%zNZUB}ELLb~1W*=eLDUl8cAh*n9Q^Hf}MDZoO$_r}ZKZe9Qb<$&gOxjpLC6SyOt$R z1Tnx_sQVQN$9aMQttTLiJY;(1AiVl(1f0CtzPlwM579M}GQ4g>0Vezfuq5!iYdgS! zD1Kvl`#ORcI(C?_^8qo(pgZ;K=*K{m-3!3k;FTfope-pqGzUph-~_0AFiS5y=ejhQ zs!3098Y@7}AdSVdR6QlR0rRw3t*%e#9B;NDJOH~Jbho~q@mBV)<>lqS6Q@qp*3*9y zel4G1$ojSXXRvr=PCRGjuv9vp31=;ihwBF+&Ukd!^20&h#8i-8>mr? z^%>KZk5n)NW-AKbY7!*B23&8ZQFAS!oyC#34+h_BgpBxpY3-sAxysjII@jRPQa&H{ zX4bTQe>Jb&-D&~{*)9lP!VV?EtIN@dvI@pLgJ;`-NofL-oG^uA)^LzKqvsn3J zUEADPTmY10E$Lc9`X*PxHaB*iBjl9;Yyd&YD`F>_;tfjJuqYm1px$1l!fDZ&STKD( z5Cx`w;HUg<1#)&VFg_1IQPc)RMv;U9!D4{Q3JNj!x^N?d->-N@j*Ec3QvbHcKMk#B zxoTpmLgfx_r?Gnkery;rahr_Ss0<+!HX*VCsmk3Kx~#)O7QuVRsZg?;*sDotfR|eA z{F?xowUYGowwT1-FEu0}%6gL0WDLx|q_4xThenz2J}8Jyj~Ky=Z%RTmfY%5=!b3Od@rD^%Q9s?wMg5A~_zwAKZpZ_-qIDamW>L{&yL^qqC{)Y3jSc996ptA7aL)sQA z8DY+*;HQzuukYN2T(1(@6;^*<{&bIZLsQXZiEs2WTvv^F5PSv z>ND4ykB0ceEX}QtrP1Kk(%FpFCF1zqMmuoMakua-D%6^n-S4UhmUfEnEy*C*ybKsn zf+=!a>jdhynaa&O6mpd5W{*y+(&P{vb`DMk$cRm2SoeQ^mr!LF`@~EWvTr~_bzV?;w1O2^V#kW^uy zo-TpUgUwDMkZS_aIL99%N4OslxX&^4{7+4SYb16(tBr<5nmrzX@6u<yW)3*Fiz^t>pB4Af*LYj`Ug8UDH2$=t%Yp2pMokF@&%SdO~y z!yCtpSbhl$pIoTC!;fV_CKknVR)v%hQc3MBb0fz%s>=}cK>K#>yWdxm3mSA{~OSuIp?*j@=})I0qvmM9T5}mDNuPZz1$~l7~b9w7hiGW%}9$ zrRpa;vH#$AQU!}`o-0qrkWg5PzBR0N`ZyF3rvzctVN?r5i|5=u|E%@nMsf7_YE2QY zR}<*o-VI5JooB_?#KYA#-@~dG&Zp7-Y^1op$x=oPq0$7=@8=Em0s!=O9DFye@X*Zp zSwV36+cz*TCTuue_&|@|3!=l%%^BwB3xRXrH_Yv{tTDIui^y6o9&A_xb&thn&`6z< z6qGKG?YHC|xW7JP$e~uOM0eNhd?2z@0Tel4Ag8dX-E;jxpr0F8cG23SmNUE^#Ml*m zv=IYETv*94^D4BTN@9+I^9XXilH(|miGWgX2MAln9M+shppVzP6>ZF&45NcEvi4)d zCvbJ(tZhat!530>KapERg7Jpl5BY)MuoVJxf$9x@L<zTh$m`juYnEEmOWhJaEAcgKLGdb|f&C}`GkzGS?i;$E_ zW$nX9*(Nw~nw&6l=--x5dtp|;kl^eORmSSX!h_6eDI+P#++cTv5fjA}u>9Bo234t2 z@caDvr097HH{ zSw~+z1?PQcnP+p0XtO!<5Jt>(m6G4lO08UoOte30cuK_yY&h7V-41}b@+EbON%eBh zjB^L|!e|}5Jz{n&6e%wceqOd39bj;7FCT4R(5Zh5`LdjfK0x7*};|1NKg>kR%%<-)zhkEv=Mbac!D^sfv0ru#q7 zVJF%nTo0M&f>F7cz7wWf<9*=s?jum|m7l>Lhnf9wz?VD*X>UsP!Uw#ECU|py(+StC zG;X4=6UY%S!JEBS%Oe=SoE0TK2?PsaA>!Z@244gIa9vxR*2ZBQl9I%wedzEvG}(K| zlGk-|m8OBnGz)}Hc}j9|R6i;Fl36Waq$!yjc?qEu5Kj+r&dto&k6zwTJe_Z=Sg3f{ zs`MfKFiYb;DRCO3Z%K}gaybJeevua&ob^#D2xEw5jaAFxXoo?vK%zXj#E34BeE0XK z36k<;iw=$<*)R@h7L`VOCy34wE^ZK-wSEB4Y3}znbG}zFl)hPC7@MQna(DvRXlMd8 zRnJiPx0r7CSwQ=X!nq&%WoK6N2iM%g_XVI1e^-s#llT%pD1Swg~$WxuPNWU*ln%w;#S9?Xf6)OZgC|41AR<4Njy2!vK{j%HWBp>?`98Bp0}}*dCZgK z{Wue~Pn3Be%s3(P`Xz@z*vONN*!VvLUEa-4fLVKauP>ustZR@BFH?EUwbPVPbqW7w za9E9!`!4+&w%>@i<=%QT2ZvhinWH@3Mj_4Ud3=)%E5_r?TR(`ZxVPvWTR^(LBoE5= zJApHu2;a|AjJ6qt7@``#QOAjH4@BJ%^Iif#yo7)0^B;s*zSQ<`4@pVT)IQ99z9C<~ z{1PqYvf}Oo36^m2c|wB1zFg+A=sC$m6~ns4I;1>1qzE`iWW;JSkZodMogVNS&!G>0 zGG!R)L)%nb03U3(e3z0F3%cb_+KoJ|~1;6@)p5 z^#XPKIc+g(C0*sJa`LdDgCRk5#1*#ogjg3Y`rX@EZyoyMc{A^Zd{^gKFM}P?yzgm* zj+t!!kNTq5H!Pv!i^6FiS}OxQ6H7j+R{=`a0efe>V7Bz6zdYBC%UV}7vO5uV(+)Af zgjEL`K7IlR7-lW-07rcQ5E$JusTaOT#_9 zL6Od9hNv3_o@lskgg6JIa)SE$>_kiaHR>_wr3^(nEYR5P9Bys z%;lG}r*1~7AD~-67Bz}>mX$+)A1_C2$blC}NZF|)Z;gf{6HkDc(cXl_$6)UF8g%&5 zl_62ylu3FXuaUc=1LS~|52g6vN~$47kH6@QNPn{iqz&XSLl@v`r_~Xzfl5l%hgqXD!G#$%8iy}o)on*{s__`o=MDU|N;`>&vQupxM*$&oZ{fmU`~A(F2?dtvZ>wN- zOcZaRh7bBCH+6GQtKYyqNDvhIzH!Og8TTgOtWo4`dM59$DnX~%ZCwxzcR1%xphgY) zbWMX80-)}i*Yt*mdQYe40|TXU;F1O8v^bLY;o6%3!$d2(OjKN`T;!)TOaLPx<}mdu zei|rC{XRLd7SPiEvAhEn*4H$*(pT*&HwmqIk6A<+ER$(Kn zAW+}HnLPbE5QC7bgU_Y136sq&j|gP*8#@uipJLDAmk)q%cn<~t8Hjgf!-k}_#lUvS zyOfVt0M^=KJZq&|JmFA&ap5-LCoF=+avTx8KTP7NMS^$u-HCw{YDs4 z3Jb-pXVBY~r{DOHW5WxIsi$+9yT&QbxhCow&cB9Pl2hqSop`nbRHAeJd00-^0HC!? zq$hD=Mm$|qpS-=Vr@T-}!Ms?DVP1CP-Pb~OmqlgdKIxQ1FvHqL@&^#aWZkM4y z(@g7W!Fsy5c4@3Oj0gjnQdO}kFjjM=Nvs`@@9BDbsfx#b^dO^UU4F1&MbwLQQ^%&B zh1=wG@N=G(+6m6J*G!W ztG7IscOZTt^_vQ3@eWoL$@=~kUZ$!#jxbn2K1D)U1wh=HM@Ao{sZavlk)19V@gFRp zyNkm2K78n3-OleF>Ju&ZV<0EYQw`Yway)YPfVtm%M{({z#{Ynw*QE*-6&@P(V})cr7y5$Q*;GdA{n%h%D3a^MD2Zf_ z7G|C+ekAOB!{{ibI=-+I-SBsQeoKpxp$O8Yt(*R$^TPsb?ZbRe=(R6DmR>CJyV`=8 zPB|7B4;y-wd`ANs=R2Z-a7N#kHhDI(+>nhvl2XK^eK@lkx_^17f!Ff)D((Iqw`mU; zpEu+v>?>i8Acim-eUo&(VSrGFQ9=MEy=E|jaW*@0!B3ZmtX{vH;jp}}eP~mSr>B(v zt83*8YcOBzYj|gKzr=f`IR$!!EIf`3fwbvtjm`r$%-TT_Ru)R)KO|*fkFH@HM8a|{ z`-H`5X{y-ToM`DQ&|fxIUrzJ$@_rtPgZf$%wMa8Kv;hc5r^gx`Z=dnfVMKpqu}yU4 zNgomo+aUQe9aX9pQQIn~l<~s;5LvMyw~LThRGSo*9;8q-GcL5vz|GwMhnEL)5wQ(_>7vz^686 zhdO!BQCE6|LAl|LD62X{?_c!NOOj6ZsT*%j$t<3)$jSV48=1nP~WZQdkw$QJ35ER|9j5MPuchhI7hj`2E6?uP%S=DwWd-XkdzAc0vd-yCo)0yGfb-Qr?DUom!{)Hv6qM?+R&-9~+vjz%Yk<7~c>r+^gQB7AU_ zS|uU+rTSE)>7x<+JTQyE6PPJbZDouv1O#da0;Bca^ubBTX9&f6@Mo2F8i6wPhZTB5 zX+C@uT-GM8UxW7`K4juDNA(Ndqw%=O4au4&m7k4Dx5}k5lzc7kXjiZ{rk5~@_7ang zK(~X`2K5=>Ul=>_T21;Xs=+uzfHcnK2W*%-Z&o9ZcL*&JX^GOviKpAlw_vejK*zm{eGn0@>~wq(?eWHKgq`%rg}L%cB<0(}QAMB?=4x&oTI=?+7Ywy6>S+QSt>mFl zMKKb|Rj!0(F8M&XT>`8D)S_e&QOR=S?`{Q2oBF`%wa@yW4ZLfVoIm@}75Ms@SVlEv z`W$`$bU~4$*Aug1L*?x^)qpsRj%*f(Q_b*qJ6S2o9!Sb+z)=z}ex*|YRlHnetAlp% z_cgvil`_i1>MLq4BJanSsAVv6Gas1g!Z5#35z27Wk!bUWSGOd^_OzyV z9j0~HFP&@aumEzREMS?Ji)}D3tkt;s7d4;Bi&-o8irc zjr%lAJx1`IaNqOzE6i9Q*zO;?#QmEN;|+O89~qrn%WcqFpC)OikgPZ*-n3YQG&EGK z7+6ROMQbt4#nh`&65&VAioGN_d(9R(^7~`wl^if`Se^f zK+ZxY)-um!R%fj<7|lpVy|F=tpWmSvyAv+hFvqDB7nzPlT^e;9aP zL?w!^(kB%-Lx(jzAQ$0T{nMmN#1J8)6X|)w&tp?}kLn4lpes-^+*YM-{W(&GayBf` z)QxGlhSf+pe1H5ic#~=>_KXuW=aiF-$$E+HujOrsS8L=zqwr%udm4UIX_^Kcdgkl@ z{%k*ldjz|bTQIBo%Iz9c+|~orkDLw$Dz6(7`>NOuaAR&-xplD%|5_Vq+6+;KV{XC^ z?X}89TF2enrWz-g3R6Dropq^CZp?n+UN`P0Y-J-eq&T^v`N1ilbwT3ShWg>h2dmpl zg*CH>3nc;j4Ud^|F&I!i{W1;sqtN6(yr$I!Bz=Q zV$3b#C)U)}0myY-=AT|0HfXFn=iR3b?E0L-OKsU02yI+q$6LcRz27jP}mtmf85EIk_< z*0n~jyJRO5rTT_j4mSH!XPHG(h+03nU%ksVHgbRbAL&C{%cXAoTE<>llC`W6O757K_{YjXq!6MM?8({z<^YQO;J@9`aTnZ!GD+2;ZiCOm;{b7sEL zX1Rm$hapbfxTM^Im>?~g=ydnI3(gFhdnqF4M4D?g?__-TV%fM;{G5pm z3Z?EmG;aD3Rd(J1Hxl&%;iZA|kDf#*WfBqYXjDl?`tv=>lDzV(S zQwAd^CpUUS-ChGH+%e#2jq9AS&+9YokbAc#Oz7unIF*>ue<8vZfq9t7bFA`b?L{_o zHVg~C>#|f~er-rP@qMi+zo6WUKPTr-$bD{X_rhmXZe=Gc69`O9B>^PqYy?L(QQbFN z+qg5tFME}6ob83JsMJ(xa=i^|O7v8XL)W3zuw3?t3+7z%`?YgYUaq!J8coeSoL|1T z7m=HaY2Ti>mhC`P=`|2*;-09|57eol=V=@aOi4qX!PIlEMg+25nNoRyTJSBJWjHs^j z+O1BM5a*mm}VQca&PFZ7Gxj%#t<#pOPUe(wvQYa_D z)NERSSlMri**2hee>L1tPAZua@2rn$H~#i4T8Klzm0iyQAGyh$P1=dZe8oDvERc%-~u{;WKXF=Ms0ZKo4OA`WBboE)la zY<5-XC;)8i`Vup=T%1un2)@)4qL1mgduc~Ts)der0-=&ojwgk<% z>?c@#gGd$`3Q#=h_HT=9b)0U8*Eon1pSWuoNP6~&?QI((+6zy*^GWBwtc*2q8TJK*f*WnA;F=0&R|ykoY;WloHh`zT z7ZY%-Gw7!o1k0X27tBKr0cEMFdY2S))D)mKUG=^-%2{jL8S_46ZjeQ4>b}Lhw`PeF z^3MJw5+QN3?gwM7VKR~FZlo+@oN6gVfM>+D(I z#ec3ERoWeTDyMoq`;Vp#?rFrzXFi&A+>#ODP0wxJ!$0!9i|!1#R^X50(YfQqpk#j(_4P? z7q@N>UwEYZB<+P_8S29wF<1}sw!xT|{)PK7ke=I9kv|gcvLw#mUR__5<4@h4Ieq^9 zMrE`9LgBwkH-|Yx>o9+J8ong*IR`jY5FPqc`Q(IA&kpB8chPV2!kfQ0zD0d|PD>ge z{r>mMzq#4PTR8;=f3|{E^V~1rHdV9Pbxdm9{l1DFXmiGT!+-81$UM4sSHOL%`@v2R zr>?P{t}$0=vOO;IEeLYPysi486m-^w{$AlTh|DfJc-VKlhH%Wy z>DT+0ZIel&6@fkR<5>aHD@K98S@V{c{rZ_?FVadYIBwD$4R@WnwtsoGP8S=-gb!2e z6nQ3(Wn8CkPC;ao#-lAP8dH9@M?8%Zds`l1&-q76Ppok4*5DLMZ?RA!wJzH7%bC69 zmVddY)iv_0u0)opB5Pj24-us zTBI^-xr}m88d1UU4P%%hG3yaEq5YSD$8ny;2z%oVeTcHaTT( z?!31%ub9PX_8cv;X+kqEYx|7R!HHCV4|&*2*nex!rghc1d$yCN>a0a)-ZuF&3N>eM zN!X~t?U}sKZ{NJ^CU{;XDr3x?zc+iH7Wru+%$-wj3XTTw5X7iwy?l2jFL z;1Xr@UCf%ZZ->rXtm{9l_rGz6zcKO3LkXN3+XVV#-l>U5=V#_gL05nG#$?_WGDG0*=e^qrLI?Y+0XXyFpXc+`%V6FACj+9vz^Zz z&rolI)laQwXK8Zt&FU_`&uVM0@>!J*NnZ`kFIak=C~c(Os-per+)}Rm$%N_Jw@!|2P$A>;uwF$@H75EA?Pa6G9<(m6h&~m<}_C(S@`5O_5 zVTLYVGQBo0N5e|@5ve9;nfxxx^B+F&WO28yW@_424Xuy4)3h|!@~Dwk-17YC_MV>E zhq!`1|kjCaZrh`8cvqD@s;Eb!HU;o}h|KH;QP4h;l{R(L|>&G0|B)^6~_5Pd*@2Shu zAl6%QsDC@@#Et5*>how{zEI$wXR3b4@^`0|bUQWbcHz4{c2TEa%R9^QsHYb>yQYPV zp1*!_s(0@SU9@*w#K~_{6_|1sPFgL;aCT`=vXwB~lzO zXHlv5XZH8pS+0Y3w8uGqP1A(uR;I^!Mh`ew*H&Lmy9-K=E2R1a9X?pNefa&;=>AH@ z&3|n(VpBb1+oo4Sr($wwQcC;Z&e#hY<;SY0=wWYY+>z?eulr2%J-lc3_DMlSy86lC z!xdcj%iG&`g05)S-09dNJe7TKC)8a({ZHM5cfe|M}D{qnw-pCFtgMz0=^VX2RwQQr8ebaO%Yodw(22)wmFjKh-()eGFUb@ z^fy^z%D8YA+W}F>e45-B5N!;5yT88NuF<`%JN8z$_WWVRxl5Go#z7{gwjV?EBZz+t zGIh1mf2kgQnmqbMTjlBz8jFbftNp@RV%sEZ#i;rBhQ6P$Is6&pnF8WNnT2}s6lTa;Q?T#lpR_j|O)Cn-CRJ6Lws< zm#)6}PVe}B7{T259E~^g>Y|$j!#9i3jX=?hzf!x?y$tRp^2o~&c5dKru1hU5eplxG zeMilt`-4eRxQ#|d#a9Ju+tjb_wl|g8Pq!UTr&#`&bsueA_5JITRpgUjwWTqyd&f-b znc)VkzY`W6{tIxA-aV_b3UlGLYlFG{qmJEt?zqDuvzc+>ESrBeQ|YjmX8l!Epm&&) zl{KRF)o&D%|FuHvNS!6e(API_<3OXK$8Ulo>EVs@d@}2-6gYbECe$xT4q0~$=;wU5 z<}q+5x}ucg7*KNY-_F&mKerTh1wMPI3dzaD1gG)3>b%M*&?wb@db`#n5#d-NRz4*z zrxCYmYW?$`N#gwW`YXG0KmNhLGMB%apwU*pv}I(9T;?{q*T*aizbzUSbI~~Md`&Ww z(oLuD<}5$3YP?MkVVpI24@HyABvSijlYiR;XUoVGZbsDQA8Q{F{C!o`GNQOZzG>RZ zOFX53`*g4Pe|x&N7K`ce;cw5xO=|#!L20a>9(IvOMZO+>R;n zcJ02)$%QMI7P1H)%Pm5=f|{A&3MTUz_0fo>rY~aW*iy&Y^AZIoj2_*1aGB>lN0QE) z!IG`$0)=Zi#WJ2XjyaYX8>|{%f2Bs-4Oy!EDYs!uhBlf*K5B#+w(HofxM0yX1@sE>>a6SO6>MiCh^+u z+YPPnl_Tyfx2lHD^qA-_@900r_3gE;agm>)o6e>740VyYdp2!st9(3q$({dx_(-&g z-F_)pl&vK6;`c(vEPIE^U$Ue2@w7;jykIX5ai`3KonnR3eM<-XrMC?#LNBsq)jBV| zC2qy=fIh}^X4Yt|ck;lL<;25xs(ZOK>#-3z+}L(U$%m4~C)VNgjwkoh99`W$lea5T zoeH|ox+0q+cXHoP1c$rbDqF*ibS~`MWe*(;HcsW5{ztrZhXu>uUv>rl;#b~3e)Rb^ z=!4ed&T!?XB8pGfa2~6HR%)RV=5$_RjodEh+@~{jiS~JqIbS5gzDyKv`Zp;s`K&SZ zyK#8#{1;F?_NcJWpJ{$YXZ5%4oods3+&WuA(r;Z+8KLLav)3DMoK@C+<|Fl9AbS0` zvH9jF|LVUhb$x3weJS?aFNb|OTpmq|WHOziZ@U9tcG5REP-O&ZCS8Zh(Y_(W>ZPyx zMnWAQ-|H`WeVWhc#tB6|=b>Xv>dirSS7;mqmRV1Rn0uDeMqQKp7A@^nusMnY(gU8C zleTxpnUZ+&r=&mqzLwJO3Xa3Si;lov6C%sX^Llmu4U|s@_qhYIdQ!U zdGm$kA7#v00n)UwNYt2rb%uNB3)g+J$kKdG%$`$x?Q-WRn+An+ImdnFj%d>3X%3?u z@X>XWc=U(DuTKR!zS+B^0&=I`o?0G(M;{h0W?_jEVMWHX6D8r;8;sbW9r`ZMX4saw zA4%P~F}dv6Qnp)=6iL$;*xH$IY_UuH7j$Flu?*_WtIIjJc{3UQN78kNv;BSlqEzj+ zMs2MRB}T2#QhT&^B8k1#id7{PMN6qhLu*qrhC;QZ7W;PD!2GtY&_M7Fqrlc1tD7gI&li@PGZq5TMm=L-d!CsI z?Y?yF!0|J;@1@<;c*m$B+5Y=36KE`}wjHn?V98$;p89;JUvdBQKA6P5ypi@*b0JOr=J)OQTmD1Snb}+K%yB#YDd6-s zbq1x^%d#I1-8nto=1;7X*Jstb?V6=4@A5r?@;Q(X7dnh zH79J-SP1q4QHsm;HW!%ncwNTQ6%4Whf?T3^8{MN*u$DFK!XQs!;j^jJ@4@Q@#VL(n^pTX88|U#mW0UjqZKAJs@glC=f6FOjVD9b4g*x})dV&)HF8(R zANbE|Ts$y(7bMi0!WTVdHIdVNXf*#|ZK)P~9S1!qxP5%GX{C|$>*d3I?1omDik_3f zO@ly8di7bdB)Y7vy+$5r-(A0L8@5-Bzj23$?c;LX33e;IsGa_#wH+fXTfGq^d$Z?a zMSHh!aG2-P>XxkiadSJ|BTSNa`N&xKy(2HR%CYx*S5^B}3&-rXv*LCZx6*bzvAuBa zw|(iI6^PRL{O1gmtQL@}s&Ic)pHR%tqVJM_wXy4)GLi2KbNsnY~^AcD#kr?E#JXTEI2?x298S}k(D zJ>Hkc|5@>b`^=+8z$9`-z>UZ$uY-{*-Z;6!fx4fzBC~%)&+*a?FFx$~SZKd>ZD&5T~`mCYw`I*x< zD4HgB&GGQ1&pghpBI}yc8=dEv&;Oyf{>`uA&ZvBUZ_saN=Y#k0fv~Bi#_&osXP!2V z%Hg)0yr?zn75e8VYMVBLGRtdIX@4C2hkB8VK_xeC=r{jV7n9o@bcO!R2s3ZFgKCMd z3grpn-OhJ4S*wufkRUP+<(`n_YW-UN+K$eU}^3kN3xLj&(!-r>E7WmPKKPY$lXSz$XB031CAqQeq9Cijb6nr zMf8S*r8%gg^Lq#nogD0A%;CAreF*YcpI`JqAK2_&pL&NsSEd*hI5)FpH@YUzxI^Vr z0&Qb&Z2vV6m33mLez^}H{~j&u*cA{iPTA)_cv(JR!W~i^EX?g1Flo;Ce(xhV?e9JC zu>q?aaqaX2)RN!Z>^PdT|5dkS(3Zv0G$Wt=d1UUpgM6&!t=s_Ng_ESH!XEuE4>YKH zdRiUnJN{zNp)O~=!dS&7TW;Y#m)VKhMY}I9a1BikiAY8fsp5uWiEx-s_LN=q(vd5o zUa9)y{HTp>!g(9(oOJBpSJUfN6^zm5i2q8Kh{#|PCL=&Z#dh+`+2(aX!J1EoB0}=o z6#uh5&XKqyqHiX!VR$n#N%i{!ja&Bjc>Ejwdw59&MVk-KQPc6E5_Uj*-mlmK#-5NraxeZEp9!nqZ&Axxl`;N1T?`L~4 zUmZ67heL2`*l(Sl*0UdHGvk+8Q^b#yA>g^9a{~TjZizv(`g0FjWYl+gjh^+mzyGQn zni2L@(7%qM;4*fQ$)P64cSv#J{(kH32 z(s1VD#h$#DMH!V=#~C|9=)6nCqL>SDG4mR6vHAUJRr82&@#4hGl$YoDn)>Qdz{%$BX9kvy$ekHl?BfGv%!QlCe3zcWTnD{({r3n3r#twC6Opw6{tArPT}^1Ks=&o|$=4D|>VQ zWArfp_OL|2&Z9yl(I*=(En>0#T5B_=nKOAS+hZnWr+33>PDiED(G5{uwaJ;#OTY{&a>pukV%anh z8kS1EL{|RG!N=TjZalv(DEQQ)RWtpLZmF}enGLpi21>?2?;2`&q^M1=G}cPw#Jc^2 zzArfde+oAzJ|8c8v$nyV-N){4_sy7dH1==MUDn5cZqtlk_+2(VE!3>F+4%QY46bgs zJ)UCb(;*efc-l}?PJJgt?rczTndY=|;q`|-n~3!Me$QVW27zZcUV}0~hmDl)!q_>sctFhI>^17$U8+crE%Gp^SO`p>_NF-8aVw@@Fv&4!=%2C}4C+q?|}uEp$xMwo(?U*eNu$X3St z{iTd$R-v)qRvE2FZ^Wwkf?r^RYUal*^X)>hlsvI~d{N<}&#T0V z{948tmyt{~uZ(709CaYC!|3+7W%+=J-k4^>-(%xT?B+Hy(dy5}yKo7E6E&2K9d7;o zmeVHblSc`Zt~2;dbsx|3z>|M_9ocs!@CdsFo*5e*18szYzP$7nNqzQ~s7uXv#=fob zq(4gJo^c6e6EmZ}oRBb__-KcXyDO@)x1(V;vv0H7<{Jbpq`fZot@^HwJw$lUJaLmP z?orw0YTT-PFVB3JNfH?Nr1Zd%v9;eZF+57dF4jrnoN`n#H5?0ATY9Waj4S z|6`qt!QSAQK^CixJmnzE6|KsF-}D8oZ-;Es-gp_m@Y3;0=E=M2!&{DZOOa^D?wcua z1?Mi354R?*ku2t+8)NjDu3;v0hhajoYB@aJvEJ6HTDXn88C}zodAYf0Ri^if{_zH5 zqA|VHAAcGD5m!yIv3noY5-QNQp6=v`^Q1j0PFXE9`=B-dxry;9Co&yxY-fkgg7IgJ!(p5^K}WFQ8RjMpZKZ1 zCGGM`>FSkUR{dkkUgObEVz>i|}t*w(aSCSJEHJ={sF>l>OGKfLEEyoa-Ai`uwI3k=}A%e@Vn& z>YFyd&F7W)%jT2cj-`_-dS6Q%vIUA?s?OM$JITE~^YPo}nfBvfDPkJ>AK4R}nm){| zMryQ&wpO&CK@-{Q9w{5Xv$>OxE#L_7FRK3N#lFUO66X^P6YU&)zc{9HK=$-gId~`d za=1~HvP zTH)%mDfu`Fv6AW>Z_o|A#Z$679d3&U=v?xJ)6Mh3jc3C}c)2|&W1Q~syA2*DDDOo5 z-NVcHq+kf#&)U}BFbJB)H4&~1Z0sk1`0->W(uRx)c)bckHnfW!O03fLo(1}+RV21z zcgJxiC=)2j6Bx-MyGD1ONv%CbGiil4l;c!GGx1C@E{u6W5Mh^GL%1- zjMB8;yjZ8~P+g1%Ro(=<02h2@fJ&3yw!Bl#57L5_B?}S&+uDeD4st*c3(x?(yIJH( zaU8%uK5bcU0v!70<*>BXp=i;3?})D;9SbhdQ6>gNglYQA((y67iBFv1_#JaMQxruR z3Z@}#5=}@Z_|A=HsHv|XM3BNvIj4|2KCLT(WTtRovXL>!iUj6D;)Ep>^Z#|8(1?3# zv-pRx03CjwnKXwn0lU7zkYQ4>ASt_O-0L$MJIylujmnNV3+A^6E~DycjEwR9r!tB+Ho?t+*9> zf51T6w5&vflQp&hj{&WVLs>5%E*06fJS`7VZ-(aic|-Jf;&)r?r{2#Up3}eLEI9G1 z99P+ZN6RAwOi?MNsp-MD^l4rZ{PE>RPmq`KmLv}VuR}WN#DJ0wNw2H6Q(OX?%*;PZ zTU%WMbRuK`@QOCLrV%^TJrUq3?R`r>NCe|koD&+0{}}^Hg6vw4!%G+E@Z3#uc*1VX z?sWzG!D*O;Ed#}YwZy5a2LDYS;U%Rm?BOjXR;Bxq>E4-7VY!Cm4IsUc`d-uN*?}sK z4>f4OMJfUHPk$Wv4YG^Y{PlhIJS9yB<@Q1!yefbPkib3ZjtBE8LO3tx5_5_V02IzM z0UvTq5SI9qr3UD(mp`Ox?II=r{@)i>cCZHa=__PKL<2oHV%7%o%ex#;tWoMp@xZR0 zD7CaabcbYoy8oLX3X4AuhnWlv)@`!I$bNFvJdBWzNU9Cn#%?hCHet`Yia(>P=-AMais z4MK}qACXcjpSCk&DEuCLZ*msT=OhMD3XNpoqBC+N+UI_p3!kS7nJ8lvO@-W%>0ycR za}-5XHt0k(5hMeP^e61o)ioriG!?I2DoG_H0SBuDvOJy^P$X556dWBI8xhx20ad#j z;yrY}f~i=ZnlTx;(~2GZX_+?39wv5wt>;R{j)MNpYbO?WVSO|tDM%!tAHMqxIjGA| z8W3k7b^6x`>BoQdUC6|a*EmA%Zp1Rn0M%t$C_;7=`(o`BHk;5-b!QLZ?fQoe-*Sy|m{mRd7HU)K%q zY{IDqzQAKY1URe!3JC5Z&}C#X;Auf$hl*72?VC=Q*osH(&ztOq$LezhUxp{oSRC@F5sqoEZg;O3GqTx(`Z}(ebZ{%9ewPh>x#!SK1{Y4~ z57ES-api1v!Idd&g%Xk_i9X)IDbEWKFP{5AkyOBCf)I(vfD#Q!DOL3;U#~QonL)#? zGcN(C3K>A`h8C&*g(G|2&H~i<@EP@X(x4gYa8VpEDMX9I1)m}3QJ;8o=RVl8hs5tn zE0|oNpZ+c}#7Z#*XM=FW?~mk39sS|z0}}>DWOJzFy$I42+(tW{9j;y>M_(u`-Sbv>T9RPdejp@$60WJL9d2P53WL*59D$WcSN5upq532Z=xu#tS61fJ;7oCydmjLRpM(GKJ(M#0&GSNK??58V+a3~6oZ88>LXs2 zzE0bjye53t=U(b8-Xr&YR1`#v8#v2QK+F#-1EgIR;DX?zvkSaUE|f4%RNU@sq(XpI zhq@%J!@m%pQQwf5qFjtuD=Dt<24+?gfD3p7#C@R5I18ASKI z3Xg}T9VGeaD7=W}qi@Le@QADM_hcy`N?NA8Bus+uf;SyMsjglRECk<;LvFg_=J!4s z>^3B6r>9l*u>HL?p}#z?DUriKSvob@wWtc@Q$Sdn?zRY)P|}01=_`t;Z&a5@wvabUgt6$@P6JD)i3%|kk6ltlhkH{{)n63oUHx?Q7 zCdlL;oE;&!-Lpj zfMT3cx5bQxad;+H{gtXO+_7+;8AzxzA?e`9@*1F~fIB45i;kkDFv7t)-6NsOKtZHu zBjd)gJBdH%D zz9%tQXY2QufEuktV4DWQH3=8C)eVOjs=$ITPEgX7NJXiCTQ0+Ah6c_IF9SQFzJ8>4 zB{@CQGJ_Amb~CtDw#o~Zu7F~_G{AqP-H2<#QrjC?jB*mN5wEzLp$9Q!4LtfH>Dz(H z?&IRBs<9b4{GC}xsa5Sl=YP%uZVsVR+YKM_{6n3yc`Q zGF!v~fJ?JMM2J|EX4R;t1dou7& z#)#a95 zbLqfE%9AY6^`2G{56RSQ6Q%aw%#H`=>YPtrxaN7v}LJQ%5ZyI}jKvLi*od667 z+NP+QRBn`G``L5sRL!Yv7*vOq5& zziO&2hTp(-XNk1DA+8i1PWR`ipdu!?)FIuf^4ME48c;HJqt-DBY9!^p!qr3Rg{}ei zg+@~FVoyaxtBNvEb;>~6_NZAjpq@LNUO&z`k{}K9%l3wrdIHrXPLe^!9&Cb*lj~{l zLmSiGV>u`nJ;FH<7p|CCeyCXw6_YPV)}bsESUi0K&_ms-)eu&A=!#^U7Rds3P_y$V z#5g=1%k(Nrs<_I^L$c2O`kMa|j3&HzW=pV^szi#7Ue@{`aV7 zCNk*@x-8Ty!AjvX&cE3pGJj@{T�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

        O_G_btw< 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 c-u=Va$x49#GO+I{BZxql@8(eq1LnQbYEXC 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 @P=lyz#M&c-Ho?CmUddCi7nP+S2o0F&2hk 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

        IPlCCYj=`Vt#Y;I&%yr}E(uKPBICs?@ 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

        gdRa>+ep+<(`?3@ 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 GjQ8h_aJB9Llx7LrH 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

        1$o_ns8 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�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

        n@Q9P#TzkJd-0T)Ne(b|%PuZ6u@ymIf|EuvR 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 literal 0 HcmV?d00001 diff --git a/build_helpers/TA_Lib-0.4.18-cp38-cp38-win_amd64.whl b/build_helpers/TA_Lib-0.4.18-cp38-cp38-win_amd64.whl new file mode 100644 index 0000000000000000000000000000000000000000..f81addb44a7c943135e3a113fe3a25987af8a23d GIT binary patch literal 555204 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%0Ap6GvR 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�Uz)P1LKJsVu9Cm{s{1?<7h zY3KWBPJu(zuh7a})X$&Q);Hg@`H)N^VRzC3Nc75peqpr4p%t!ZACB3zZU zc{@zgtJt^&S5g6`W&&{-f%M05Gg5?ElHLk$5nrxsQ=VZ#KBITS$Ebt_kZaTzKXM(O z$-CZ4nELIAy*2#r}6z=cZYrfzD6-&n`>Tbu=UWTBO6K1~i zET%%3g>%$jSf4*a_7OG<*)OV+%2-JFmrZx)8`5CnU!agfF(V#QZV!;cY*zr?NE z@T;9APYr@Whp3|{pP)HFlp_8M4FB5!8mxr!cOrr#~z^oBtRt8C3+mYbB zJHUK$_hIYBui29Vq(3iV$!pM@YoaAKG7vf}?5onY_*;6&|e}rSmlNwLU(Ob2gs}50( zL6uOOKjwLrd#RUNAwrE_(CG{{3qv2FlH`<~V^Km5k0Z^GSO-ZyPQ~{1u$KO?{*IARA#8V+ zF+K_i>Fa#8eS(b?KAgTnMBzB_eP8F-fsRE}qGI*UwI$-!&t#vEOpW3IRr}>7=qRL( zX!;J(#ef`rd3-0~?O%j_x^Pv5zV{AE{hbfGSAVhq5yK;_4&L19jxi{kSmJ8(LbN&n zzmHY28ZJI9o!4BN8h$I`TwpRAVi}oy!ivUbMN;`gWb?^w_j z%!k)2O}Om26-tnPpVl8&nS`rozp%#vE4Fb@<hZ-(#Y43puBTjxCIRMbz7SYvgesvY)R&Lp2LQk>rr)|c zIbL0(*Bh%nO%~|%eFw5^LR;iB9h(7q`5Pz#s9Nedn>zr2k9TjPH>9m$K6v+Do2}H| zMAxE!h}7;L7yfE|0C=8(47|C$UFoU}0~>!)+}T1K|M^%P1U;3!hPIU^F@(JAsJ=i3 zid$}P2zJOAPr)buvOq7ozUUYC!X9r|crI`DMP6_AAZW)Diath>l1DE)Z%Grvg(6)y z(RwiAx3*bZkOBUtm;S;^F{AP5p`LpNj(|e=NyxzK=hSC72EY?p)vDP)HV@WJP}_>3 z&rW3QF|_3r7Ai9Ogs=~({1um0{)_luHI6K{ha?i06ahib}hLkco39O!r$Y5``#g4`|3rlE7tMVO>0!m;##|5+kw_n zXF&6B8{>ZIVI~xsIQ?u)&-AfW@OJ-N#o^&C`dY>E?%lV?u@Ua%2B-k13B4vaKjRi3mGOnGPMpJMPBoLASrsTt{R-to>|b zA6BCs8=Sza7*)exR32745(bW{RUcU-RkGP8v*{I(HSnzPuX!cnr!{+Fr(r27%RW%K zXZ`3Rv}yFA*+LdXi+T?{P_!CV;~nM@yVah=LVd4FuB>q`8h#TCH2T@?DN9Lo!=cJ-G17@tR6bED)34a zmYp^JWD*~VEw>K(A%{>+rBgj5ww_$+kk5Y-XLq)Kp0Zz>o&k9m)T1<}2C%OOJz}4j zunG~qh(-aqm1ma&>MJ}oB7ofPWCLJFTFbK@&51UKey}re_Ub5Z#RMBo?B8i$AJ}>A zt@X-c#a#2;b5oXYYwU{@b+7(R-z;CwjFFgEOMPfG5YS7vw?ufAmmDQDVm*z_>ACZ3 zX*rRj$Mn&Fuaz4Yox3HWZ{)soMS3%7Vjv-Wsv zfm@;dnCG-JL$3{a`743n3-09Fl%Dra5bLEbj z=?~I9Jz{jSJ!p!0rQ&eD{8Qu(gHZ)$ULhiUeNv&be<3<DF z23}7lANs(UeBoCX2PsNk9u8(=UVK` zL3_vhODd(VwwK4G1Fg{6JMP`pB>wPCv={aP06h_(3_JYlXt1+r55;hVuVe?-ImyHR z>S$pk|M7MN(fXB3d+J(LY{Vo)S{M2jx;ok}JF|KFvBG{4-r{i0Mk^%f$BE0UGo>vg z=ID8DOj9e}XPpOt= z&hyKMPRQLU)ac{yk)sx*)N)qX3Wc1-3je^;hldt-Tqb=&eBtqSm0~7>)x&I|M!LN9 z+bvw&dW&8VHN%}MhN~wJl}C1?5Bw?g)iS7XiGo_nfUND+>&t8y)3#V+R`B<^gqrTN zgDq6Na6!LY9`R+wH-HY-h`(jnOuw_fO`sL3D@zD&)L&9H9>&E~N98Y$h!qO`+0{H1y?*)#X#G|3V-ZZYdOP+!4I z+;q4Meu-U9A;SY(lni5WA9jZecRmoHsSvp+zDC~11n z2VH+!9^$)|m-r4jznT?XV#zv6;4z)-4QNkCZ3)y;(uu#~>8Ce1i7k#=FrV)8c@Us^ z$D4`U7jKX7+8XT$qW7wK);tc-W7Mi;DEK3~5pWnG_jsmqER+4*SL;Jfq`pVR`)V>arPSio!y_DI9k$%?p)6T`E1ZF(d^TzJ}5GUo0To)t2 zCbWxPH=>Kj=5w1(aOI{QSKlPe1C9>oUE$yjKJE@HpI65CzSt`uP&E^+u(~R!CZ#c& zu-qPbLwY*eyx;3at8imMsus6;XX=yTVHGpmFWf~u>CY;@jg`bCm|dp6To9a;`envU z{hVCy^Y)`oh#gJdm#?~IJa~Z z+j_;{JBg3?n}zzWKx(`e2Z@^2*u|9t(bFFi6!RF8ff&^um-`{T-N`rK{TljQu_ST7 zsN`h`ARn3jcujDCnJ#Z5-!cc78-BGi{D2ke(!XsG!0GG4EvRm^wLC)n`HZP>X|}~8 z%B6uD`K-YmZTZXR8Q5jU06kfWzXo8b2qC8$m*2^#C+|*iew{-M@ z$QLMXMOWuD6z%YB>{QZjjU^eru7A6NBASn5(brX?b}yNZ3qxFS1&}U=6=P)5=81#c ze`y62(r>NBG=#Y7;IG#sxX3F1)$DC;@S$rvNs@GXsA=_e#jOl?b2ZEibgf1XbmgX| zy&NxPjCQ@Kz+9J;qe5uK3&qE^myb+*-iYp@ zGxs$b&T}H`5#vI^KOuzMD+F5vL!VXuG~vcgs?GUn&Oj}_63pLgyo_S-e1=9Jd0Mb} zoE%!@=l|-Zjvd2gG*QpthX1Kyy<=14*gS>{Ls)cICe*JdK!C^TnSlnFok=CiX8c`n z`bPSPxvZJ?#nY#KY+_r$6=HU?`ZN82$vU%jQXnfcW?i7tXh3caWg#*AYFYp^u@9-1 z*50aIXmUR%O==@qa+|OVx)6@u zZs1PI>cM!V*|_2sdR$bLP&OJYn3tHHkjdV4zF~nqwizsj&Yo0KkN;eS6|Z-43eT0B z_oTQS8ExA&Av!#EC)(qI+fi-%>`OX<<0a}2Bb~CruXJK>yUoo?noiGDgN=Tvb`8$r zS9aqB;}s9xM?++8tNvOPotsp=Ku~42)Uk39mBkt+4wZ$;@3;!z4wi9>X$!8b3e9w| z7V(roIY-j|(V`0nP`G(hz#AT@{1#-LS?G}3zL%Asyhiq6OFL5MyDH++&Yj4$e_G#* zA6N$R;_gGf9;e~swS^kVn+4{~3}gs+|GAq~<#E=E{9jdCe*mb(4f_ww<* z)a&j0PX3yuG2PknZ|oX|K-vgEG932|hnWi14;6`Cvzb(t(2>i07%f$d zmpnDmzZjdOgAal>h_o#>Q# zz^GC^$}n0UYpV6CzxLY5K-s&LLZEC4RmgnO*?Xr1IY(l{yt!l3G*S@f0Qxt0;7pAM z{sC&bfEg=Df2A2P0+`H#0EPjRI-@)w5?jjODWJ1vryIoFQir|%^brBjzZMR)oV(@- z=m;ZN5F!8ISKV<1ci>|Hvs^nbex?WJe!@#KDZ*&yG|*mA3Y}B=qK;quD$G8#cs7jD zfHu1{$TpU>QiK(z6o&!k*bMuq+P0=i!kc>qqX0J?L`HebwBK*vPwd8f+I{3_vGP*d z8k^+4Yv)ozgyqnq4!WU)GpNQUsbmg3=3({X;Sku5nb4ge>+PBKwHs0@*)y^{VVw+Nz~3|^a~?{^oS!jiTr_K}pPV4f62iIU z)08`8EB8pHHm%BJ<2;{_&BfaeomdgJ-7OT_1gjJ?FMgN4fFVGYakNW%&q^NP%Lm}Y z8sl;vkv#qBR7}6Hk1$-V!~hOC2@x*k$0Kg*`Id6&2|+%}mAp_hH_u!CB*!DjF{CG)NC*@DZF{;A7!Hk6*X(&Y7m-!_s?6(>lhh>4~La|Jao67-|x zVL?p$zMkUuhk3N=f_%GmA#AN{ORo~#=Hgv_eLeSQ)c36rLQn`BC1$zJ!Unn5=89=$ZddA!G3m%6uUI zr!nsw=XA=O-91kdN*8v2n7M=Ed8_%F)eh(m*gvX=@_|)e3>jx~@iDFB%>l3OX@r4V zP->afco!y%aE?6pmMWofWpV+z6>!Pv)W85+ql8YkjuR1~iiILx-kLN-$UI%i@>dM< zDc;}9NeZc1Rj3bQ_;zqj75^eZx1>$z(p>3+=9Iad)lT`DQ9{MC-U5JS3!Nz%@d zus813V2de^$#sF5_X)0VWs_M*p&6=cIQ*QJPe^qyn)~Bqjlu@lo zv%93p65iX65@!pah`D2U%flb3U8emuqrjcIr=cRD)k7RVWi4lQq10RG@X_V%gh?th zE+*9FoDTL0qS)mdMFIPCZhs`R;1c2EtI|?c{C1BL`m5^$MzM0FRDSA$SZoO*P#ITY zXxv;x4ZF4+rpcOK;2qU9V+sq!G)09a6efCD^^R((rGL8U>{7Wg5fsnVCwn zw-eCVU^gEQmD1?MxNOWf1G$hLQgjn4I4k4yXkDWhM)oIcTbseU{AzM+b8|LrOUN-% zOQIKlzVFV!?1L+>P^z}|s#aHJ2p!Isl+rG>X<{2u$G85fpfxxuZD8sx*s*E1uYq{b zUCY#yq1;y^k)opKp1u7t>n5-;Dkr_&qMz!nG@0a40Wv5%gFm=jt%koWSqggRX)De=P-DZmnJy3c;69UbLy zn*v0@t{@u|CJfUV|3O}`rD{|#`Qt4h+Aq=+@AjtixsdOy(qi(oXMCB)_>X&30$a~A zF_{eM!H1xNm|yXYSX7vaB(c&H3=XErv)69(HT8?vBe3dV^x36o=Mp4F>Oe_GJ$^|> z*BiCERp3-jl%|i~&+H$n6;r%YqhI2$r#Z^*n#Y3X1B&j*6_`;@&d{!>`GO?fEriPM zh+eVF(=0E`CrIdWU=kBPm@gYAC2`%6aOy}}KV6tl5zF9{mRqG77S%7jVwFd#)~Tjz zj=-0Tu^*{>`awX>icITjW)53uX-er=_RC|3UlHI;3zyh`THGSG1l^Li7;dz(t65Y3 z&7f*Agofvz*%Y{=WSv|#BV{RH@_q&cf$pR4)ohbT(*isdh^XqTn>syo>IgMHDa|ei z*T4NXvIjZq*OAq5*~D41iyG8x|6YAN&YAOZ0o?^E8)H&fEI~TcDAPy~2xt!qYmhPW zute%>S-lj_NK}i5`Y(mxf8CZo#mH5aaxKBBlx}%727rs_lARvZ5G6uW_15*ya1-TO z#suEC-#tKgYp_RWmGZQsluXglaoSRMZ^w|nCI=zKVM-ln8M}RqXb52)djGCq_`9ZN zxt8Zr!8}QL@82cAM6lC_T647Ssjz2DO88be-2mqPcQy>Cm2Wj!MHN z;WTeLVsh1ZN~;@xc1?HiQ=c)VsJ$wzC(EcBS?k$aB1=v^Rn{m`rum$rtFg2M5=J4qr$m7KXl)+=>xn zRMDzG(y5?-QitZlI9>F-Kq(5rCa78LTlc&uTBJW-p6|FnS1Bts{L9SFOUZkn{k_xm z^$hUPvEUt_5+iGxNfA%&=#sh|U6K*HWLVN9c;*$|S;H1o-T;ohh@F+sxTtQ&tOckz zL~n}g&b|(LMb~yT0qU!2>HsP|VksAjDr~Z6_?@_+}%U* z;_k)Wp->!B9Euf+6bhATWT?&+oaQ9RMaCkAv!iV4m?(SVI$61U>*cl`?OOq8lKB1-%W%$b*U_PoC? z6Tf91h^dH$-14>YPs~dEL+~9MVjb8!DDbFJqnF)^XE?)(0umCWm!S8b?PL<#Ga#q5 z0`8F0W_q9>5bEgLIj2j{2~J)oEGv-3vyo+9lCzuS(=jM z1lZ{iz|CJ{fWfWkt})ZfdTXws7RN^#lbLY)vRS z(_K{BtT%!ehr#CH#VWxVr6ZO(8o4c4e0Ll62An-rdJ(tFK$H8*X1!F<r@o*V=Io{5>Z>b<0n1H4_<0cG#dMsj`(D zrX1)q)+oB-SU5HX8=mIs);s9<1+urW1d6Jgq%?;*py#c;G1u{%l{8FI6kV_=#l*-r zTILe!?{B1l-;g?4)DQ^NrOUV4ar{+a9YbAqh?7neQln^(pZbv*{KMLDx~acDC8A)B za>?3}vGj%yUw#tvK?{c@bN48aIl4e_2}!O7?@2)QeEc9}%Ks0S-8t&)T9@2LQ_hD= zLr&ul9Ht!=sWtXzYCr?#b2W4;JD?$6$4sk)@y`o2*YuPm3Q@1q{qAEYHFQjWU&%GF z=g&rQ>H!xu#+rg5HN8%X)!E&mb9`Qy1A0F==+Hy76mV!wu?Z-ch)fxIX zw2K+Xdpnk|R9>v>8ODLQH`bZLvPHOfBd{{(ExZB#anqw*y~ev4wK@cy44q&3$H^Fe zc!!5Gm3*2V|C(|y9#XiCOd zD;QRJ1#M;c7=cR5;BXS0A@oPtJAfI-G~4&6+9$stdJ}{mLoVnWI*0s8O?5vg+AQQ+ii!hu}!Ow{mqJcGY34O=h2#Gs9H#3@XDnWYY8XdOSP zLkUePV{{UK_@;Blfnyr(&MR;5&ZYYc$Iy7>dC_{fKdU=FHs9{fL2v(=(7~Xi)pJTK zQX#Em$lwLi)i5pwDLAX>EX_%K|Ai;y-)9ADI9L;`L|Z=7%v{3LgkSOX_^bA@f{qP( z3NrFLh_&{+6;|$Nj2qUrS5)r_KPijxe^2jSVjZdmy~94xq64gki`G~ot6X+YoTcjs z<^=TrEfIY3WB@IQKLsxGe(ems-5VNzE!Wd)M)#%jG=~;>1HYij1Ae-odRdtrnbqj^ zY{9lB-#_L?S*7$E#vLSU?&(c7mRAwgYDxXX&-;Dp&}{x*^md>4+DLSL@L>|0CrTo0 zCt4jxo%lL(3r?VDIcNHwB*G0lVTjEWy^vh}3rW_wtRH)FGBF>($N zze=aBNaW^}t?`b{tB`oWkh38E$ahnu%R` z+_+*{#}-5JK+iH~Q-SSt!$|mJ@t037Au$27z%`!QKXhoN~McSgK68C133;k{^ z(So!T%|41a(I1}aL6JQTlS5K9&xg5#Awjw46naf_?&BoVAZ0zngwqN=L)0Ly!v;=W z%y*n9%9Cn|o|qj|x7;#ehsw=GKIXCHh41I^zQnU-OQ+eX{;@K)Jq{jSe8REFom;F_ z+XTMDwWVq8JRg&A6BYxx$-4b{kD-G!vjbvK$LetB(zYs22I1o*)U4s$ei*9H(Z(p% zpXFH#d6D>IR)oPI88!ek(^Od(3dqC%59aiO-t8P#`p#}(bI0C8;TH9xD+%buT?7UV5I zrdzGaly?>~-;lSEzAqnIzd|mu>!e^oOK6DU_Gx5iM#0+*x461;i0&&uV&3Z}4@KY8 z_VI6>B9ba-e_c% z(WfBxGHKh|&e)}VhIAPy21d1S{=6>^;N?_fW8ErUUF5Zj+h zL?Ela#CCJ4L%j{P;%@FV{dk|NlN3b9d=o*e@CG0G@4l?&E9TD`@eph72oKaxp6r^> zv`puX!&Iy8&IHhy{$F>hdvJf#$Q-z9{vjNp!ltNVnWRvTC1}fwKA|L30v?;`J|dZsPb8~*lpv<{_K|uhPMBu6n%Oi&tg%?!-e`G%VUk#1kMA!oTC%U`ThB zlFCX)s$B>8?KN-UMdB*TN0Zi^VN%)B{Ss1Jw2Xt)g-dmV64NSq4ts}`&qQ8vu{YJz z;^vDO7b@hoo_|ydYKiZfb{YP4FIZB;%9gLxsFgCHB=9+mn^Pm_rkXBtPP%JYnE>O# z*Ld);VX`L^=jU>idkxLEH=~+a>N_^Tvo8zNHuSRf!Fh|8glz4T`vJ~4ih`ap$BVea zhzzxwbAG*>CdglSTBz#x;zrqOecQO;=BWFo^xgSx@HiXd68zYK&UnbrE6=bkN9hrX z*guAa=ZzWryhdB9_mh@j^9{c5kpKK14|tAlQLKnef-dePLie6rIs}^C66XN zTkycPw%X3>609Te>!F!~t_L)p;CroGsS1~DKB}?MUi~l9 zH<-)&;eU=PTHQ*8e;El?*6xzMX{yJrvzzkFb*_qQVEINrQGP0nlqmQQ&4V>6z*O+n z`$$(G^zTuE&CY1%vH>fdU1}L>ndpOFb!d)?F2wkHqA6ke7V@fPD15^yKpw*LZvjLL zCcq(G1)>~9h)euXQe02*(4%Q+twMxl3>Q_zK+x7D7C|<*b9Ew1js3A&+?E~mm%3l9 zwg`@5&r4#)37+u#K3ev2BC&Mx(MpTUiyX<&1GlJa(CNS4Gun7r#c1HgzL56>7^DF zIsHQt*s)S@{-|L3^CbhdstrQ@{0B~fnSt{8X=*^u+hRbq>F4|T2Q7z_hQPw9g>8dx z6(hFXPh$)q<~`ov0J)?|vzseU8 zOZc9WDT+2iwYI`F7_R$oNU2PG>TuvwyJ(Nn6^46L*?kgop)VolP}^Z0AM+XF_PLc* z`p5~|iS)uEQc2{;_3Y|~pUW&Ve`yJ~P^7;16rSZftf68&4!gKN$-4ETlA>1vqYi^? zH{QJ=2Ph69P28#d4FgIM+t1U#5IrZEGH$8;9oYRo`wNw73NU}r%l8I-ZBU#7>caYS zPvOK=PGNAQCI)sEQsG~&a>qxC{#(){M<4iRT?dGU;+f45 z{M~pD-f@v|!4f7g{PvV>arU5=j*edy_jS_l9Nm^7Rmk@VKNKX#KqM4C1~``-pE4y1 z+m8aet)D2b<L2{kSUOeU33d78q!uhGNCy_G9+<;vhng1-b>UP5SCHWG zhq_2K%JGL*Hx7|U@wK-aViV~)!j%c$bjODtNij{3^@vXGa6=HHC?=vrC`It7qv^~-dHHX-gYjoRgYrCBg1A8mFnp?mi+RJuBEv%5vW8K zQLQtF{YMVf+A)Z%`=iULLd@W$ z4c(jkTZ(!br7`7#TRKW+k;6$g`9leo+1nb4)}yS!)P#wOvGAh+YeFu&PphQIGqi^K z0G<-{r_cen#I&t>p=)B6S2nr@OEsEF>0Q@4;@qsE$y6*UI77nZnPWe9X(||p%0+H` zbQPRrZ1;l0g+ACC^~a8-AmRiaNDD=z>1M|5*{`E=QZT;PR&Y8WqfTQljrbBP&2ZL{ z*IRgCzpJo~C9hvuOie9xw&1pkd)Sv+aO4%RQiH<&9H_7RW6{a+{p1ywQ8GV0 z3>yBB`Kd&-FY~idzpQG%{Bi?l|8lM$sau>@3sYAT%Pls@gH)NGsQ|h2=yP`*O!7xq zRcZ8`^vrJjN9V6PML?(i+E}=->P_N$Q2>(A=RWB;I%vEHw=uuifMgR%Ru6S0p>o`?h#&9IYoY zxNVFxlU=T>!tjglhTR7`WP|CwhBUU(WbTAzW8Zz#-wU+Nk3tj;Qz6S3$EvG%`^A!7 zSKib5o0hWxrga5FgchVJGe(tekczEY!T^`y*gxsgptV0;mRfu8pRS0dHl0Z6a_dGQ zyHnBZ@A(0|(340-)A zR(PAgJ=wu~s)#sh%8j|`Z5oe5<(XzbgZ>HMi^7`I9piYw6sU1D47RtRhx|4>W^eT| z@6E^2{>0qag{XR2R3UbWij1DkDTlDJF>0)BM3-Kc)KxiDLx zAC_vUo(t<(W=YG!S25;cNRh@fd9qNaE{QagpLVH~^SGsogVHd-7a z(lvvPE#cf`5$7 zt?%Lln`oXw+RI(t>4VZ=`KTs)=kQ{VwSOdIU90+h4{FOO9z6nvd=Cvlb{FFcd9%}Y z7yN-j99vwAo5b#pH)GH~+fWX|aVXDIQv-vQ)(}m&@}{mlY9?d+-$<7+ zqEonLLQ~M-k^2JNp06p0ybEjx2jSk(RM%3RPQ;p&3i;_lwvX5W2?d9IOxe?!JS&ZDIy2SMS-F9 z^;Vmc@_B(htdq;$bMgz_=koc1t~v2wae`fChM5~LyUj~29FZ2!^A0mQ$ITzpyJw>C z&*6c3pGR^7<*oXr9c>4uv5!C#N6s|wRv&JrD+3z}T5KueH}1X)`PFT@-LYwz-30~E z73eiaqy`GoBo+rcZURgHQ21!s{VAhZd7zDm`JJ%=d^CGphTz>VSm^P$B^X;Ts-2Xl z=7K$N_o0#7W6(&A%Dfh-Mad3_8|}05fX0dy;9zw-l&1ZJ@JXOpTWbT@+p`Nlf&KZc zb=Xc|y9B}eGYeSc?-(Pl<`IkYSP$BtyCf8Aw7is%!CvxGj6 zZOE5mgEiaN&ymRk{_e*&`!lh?8}y0UpbH^2Z{UEhAqN-6n_3wv{*GDt$pboxwpojGIGAI?0#tH%}6GwxIVaPYpT>u`wB_`Y|{hEatBJOCV7{OWF@**@l{`JwZ47jwVG~Z!Y28R!{?Cld%~}J7iF2C|Wa6 zf%12ut4vT=Y4ttKRc8S-!mGUt-E^A(Rry@Uz$$;yPRvpZy604%WlV@QVcBlLsr#RK zy>eDm2YgqmQ3Bx)v{@y_CcR?LvfXhX0uaLx0sSH2crpCkAcbLG;dm<%;SOVa|8#i0 z{Bi8_WI##|@LS^Z2vVNYH+uLkT?Cvv!pX7u(B61ia^@x&l4;hX4c z*?^@88n1NI&~ETD1bJ>c}=%Pi;#hwx=N3~2x)Tyi`~<6HldV4g4GQ3!Uk zWowTyuIV%O5#v2#n+B!$p~1#9du=&TKu@WQ2f&x|D_eokDNxlj+hc<}lpZ!*&ja86 zbZ1M$AqL;&T>v>BCBVkg1g1zSh2}paMwC`MsLlSVAv;AMh`=l^Y#5d$(eZMpcfIVB zRZ_*dBi1$ZF5B0zNa7D%DC*u8QRSUF?)EO1XkzxI#w};U59^jMHGopkm-&enf*8+C z^~8HyiOSE&#d@=Mw!6>nFsJ!npkZ5Qg5mC-@6g7&t~s@XD{tDe;-ivIs1?vg_~*TC zdfrQ$!;%`<^2l!%2@1<3TT%Pv=MtVLflY1p4`eOe+gdsqI19F& zjpq%Yyi*wk370{ab2DQl{0SKz8>Sp2jwg2j1rm<88aKA-IZV*>3oWl7lQO{O$GT#P z(+#~V+YUb>;6jI?A&jktb$62Vfe30q=71+Gm)GI*OtmH(DUW7cPx9DskkAY2bDb%7 z0uOLKw>m!aUJ{2(++HHA^b`L+(D@ntbHlxAl7!JLI&^s^DNCZ_4lz6}et8n7yo8kc zl$1V4@0`t&f+(N(YcnDw{J-SfBNnFXKpG;ugn+3}+ci54sX}U@6FXw_Eef_d;0t<4 z131tCI5aUEMc~;Lt;c+iH0hQ@1AKMs$@wI(;jZ(@n`zRsGwGFL30)36s$$jQhb~X# zAl{ZAyaZ}+qi|MYI9vyEX-RrM#w?v@g_P;4ErXu!%%RI#OrRLB7Ib?_jpzzive6d> zZM*{9&EniRD>GGG*>d{7&^|Xrcd0z_UW&)Ye7#6-mJkhyVt%QTr+}TAN#6V2uIqrI z6|fMAOw)Tt=rZi#XmSUZ_>z7YSR~;AL}0!xw{=4ds5T24KSl_RlJ)Ni4GxB|%2eLn z$%zMI=yFE69bV9%DdRo=*B2Hm#-SHf&kdN~eW2_D7+d`-?%41meyG7>3l@-c0~u`WmH{tuY zMlEO{ORKI5aK1-Wy)o7HQ;iTZakQ%_KUykoXtzNd*3(JFayLAE692_i!^&@}HOh7)_M2ud@DBK z?1rDvCJi5$DBqAdsZ`0mhyqzm)EqO>?rOU-U)bzR^kOUq01g!J|A zG>}KZb;k9(|pxp7`S(m0g}er!$!2{t@D~ z8xWYycn7-)#ca05v=*;ogf{T&tG<=4H%Pd#@Nu12Xg#w`|GLW|TZ!PhceZlN`{ zS1$rV660z@;mCq@8Y0LK?Og#ukXoYC%H?24tUqCdvd>g8{PxY8FTLN$g(PmA&(y!1 zzIdTks?YvY`ve^C7G5_pqm5^wF=IP@pHA>GLw<`irMr*%=uvACr(Njmv1@Np-gG8% zo25Ob^W1uu_I2RVHx-_scPj?*nO(==#%R?dwR2PFpQ68xIAFg#1nBY3Ji)zJWL?J)!ExJWumdt2vHM z8cQA}qi|$@njR{_O;W~O@yLa=b75ZR?Q_bh{sS33p=K^b?C7GR`7otQ*gxKNc=@(E zh{=fsYgA4~Cb!l#4X0hU+rj^hGvb80rvC$>Y2)D*WvqA$qNRs)`CvHla@Uw%{h@DK zDIg!7WHm`^Sa$vt#M*e+oi>$|K+&7C`V&YlPcrgdoYVE52%NQB*PnB~k}K}&$F$_} zMQJ*x;8p=FR?ffTVHPxz<6&xX?klgXl~V2y6OQtv zKqj>KKeUU|B#*nhPq7CHPg}iR8==Uy27=kar--^#39424FMV&;rc8v~;_A11=R1BN zd*6uRtRdYvcbb022JT_1paXx`UY^SuK&oGzmsU7$8fCJcLHgTpRv!9NTglV?@H>u! zzR#)Xd@{BokrhPcOFQpSR9ff`%zJrcxr09BctWF|ke_$-YBN)FLR~Ucy5pizNx;zN zWwj;mQ-2EZIy><>WR|+GyM{mI2Iw*R)H7}mtHA}q{o_aB&OgB7Md&Nu52I$AcoP(! z^wZs(zf3ufS02*dR|c}8#ZSVW%WE$KYjaSvKO|w1GTokn!;DX6bu3lRQ zUcI69;pG;!sQ&IuMr&fw+~BmR+Iffny{Ft| z0P=Eof`G+&CUsYj=*|%|G)?*bbaLlNn7;35`IoEZy_g|byi_s+T;&T$t9j+PWp!Sm zv}UYu8!%BEOz#gk4BR=KJXGA#ory_V(&?TrtX4#88dCgGZKz=i0ArH^m3BMS~D1+sI zvXy#K3#*!$a9Lu6H^lx4zPb=yXQb`UU86iJzu`A*{9gtGk2tytcp~x_}*IKWmI|3g71JkiHWzs@U=-*vPw<;^xZ_2 z2T~pFfMG|SuFnKr?qes4D|XhXHM2Ou72_PAHen8ZXx)0?UpfFmt;|}2(R&=TCbJt` zjIs2-I-e?Ix&`86-r!|aCetbAEtQ~kS*n|!gRP&O6(4b*gw@Z#C|q-VTKHt{>VkQZ zG3}ouXFfM6opR$j=g~Z*Az>X|0NX;r@jjIn0<-^xlSk?&Y5*|{IC`+@y4;jv%`n-l z!n^7&Lek;E@NtsOwo^{3VBBE1+%w1X5hiKLF5x+XuSbBH>kiEA6w)9FodF-67?8f)BFcWFS7t*lv z7GrghyM&wm<&dCY{R-)z4KtF9(E2vDuKJ9VoGu`UH>LNA>ZkClFI5K4J{Kfbz+o;s z4E*pqJXA5U@BR6uwPq|%^@>YxfbX4{FhYexU5BNV`63rP{{C&e7YWN64W5=5i!PQW zquY7QK=nP!JL<1EEE*#gAOn-2RJ)&2rrpoaulXtt7){ifd5_`Z{3)F{nL z-_DxQ`d=g4SVdhp^1x4_n)j;xOX{&g*$GkuZ4HyTt0C{MZvYt4Ms}aGKG~FBx6wz) z_y`4X;zobIZ-Qn81Np(9opGY$Cb8a4H;{J9i2V3#guA}?zH{C1ud-hUKhXKik{25W zTLfId$P~*yD*6`wGL1{waK_EefCE0*Z5R`sSiSqU5QU7Ak#twVm{EK2XQ`1A z`jIa$Rc=9~`S*Z_8KfJ;6oDYdjA)338VX%odMG#RC>hb+8TQwmyiKwVT(f939xzQs zRd6^NYp?evcsd|~-&N&lKhs~=sY*xvl$Lhjd{+fJQ=K>l_ z7S%Au63)1+TL9L?6PVJ3N)uZQoQp`s>hD|Lh%fxf{iwQm>*;lY;BB~aWzh%Syjg#) zUf2DxsO73h5AaG)81k>|DxK>rv3J}OUw9?Aqt8+oqiDhQdF>+9>sJl8>aids5pJC( zDTo{B0x{n5DA53AMq=>D{m%4DX!^&D47X4ecS;+t`q+nbeosU_wNPU^K&B<2Qvi$i z{xt7Z_vQ%6Bx458A7s~!s)!aHJ*m`_rjTkaujg-Kka>M57qr;6kThH za!q+1m!N`#mPp=$OA^sD@|^%!gDorm`5z@!M|mA3mAiU3byH!( zyQAQjjeK;&PBL-z?d+{!L{6KfFYh3lysPOsZv19lkGaA4989jCb}V(!aI^72uzb=A zOa7_2u7~?EZY7S`Kf`!qGpdHUHPMzN=qvEg!^aC(a@Efe%2h9>2f^m7UT7SoW)K>O zCd&69cmu(LP_DBO(O!2+8A2$By8{y+1SuY)%{Yo)cfn(gq@S1ld+YXAT&BYFEbEru z#M8%$kgCm46&Rn8?e%D#xrzxFFKs@mqn12A7W5NeYAR&yQ~`nr9t5Q-wum>&cZ(ly zozIBj$ee!1=XS_iUed@A*8*JS8SjrhV}WkKKOw7|zf;n~32$(WD^@mtYecVZF4gI% za1S1qV!)@Pfpn97zdNWWX5ZE!Vy4NewmGEbA6?z_A@!70XJYKZ5Sa*{PUK2>EB2xN zlJ4&k@sSqp3kX?I=&t@?qo7dZ#E16GhKowZ(n~|hTd{mc*+JidR`$1I38h8D)aN%^ zb>2J1g&W7{Cp)Z6euo_i0W{amJg0-t(ofcNPV6DI-qk(58&9H0{w2$#N7-};XHY&i z=hmVkAP6khe-bt1E7PrLx9<1`b3r^W#BTl1CXitA!+X~JZ~oA~6NWAGqzmnWI-gFf z4e_c(fv@!+?#9uKu^TVy_VmuNj)R{!DqvbJ8lGj8(1imVHOT*%j{{H&yZi%vYp~ zUe`t5NDR|FcT)Q^S$w!tcfE1Wx-l@{Wc&xO3``R)HQyv*L0D~ToJ$WUU-JVw16Y?I z#9SLMhc<;E91V$0mmWSEN}F%Izuy5?`?_14xsG0@y7hjVMt06NT+T|ckwbK2X>2zc zN14wc$Imz`-sfFHev3z{`z3_Ou_hf~>jMR=d;han#ZR`5n)r5(bT%RiTKvUhHyCc5 zUrq~B12fZz;Bh*gcj|=t0c`(Ik0d3I@y7o!_Yj}gk%=#pds_@j`$!)~`c};_O zmO0bs$LTd{6l$2p-92C3N4>5RBs|-}6SDR?wJq85oL&ezs8`9N_RcBbHK)!gW@q#X z;}zNuwXN{!|NrGiY-6fzjY|^o5eDXdFZ$`6ESB{cd+}lU;Zh8Bj=dWzM!BlYR-sMp z!|$)l;%!A8_e*wpYprQBqP{VVJR~kY`YfRCf^d)7rl37b{?8H*#Nf~Zrr@(xtk<6f zA5xoh_DU|lvqL@_UzuL@7ClYL1ofGkRi!kFwfM)5-V!+`kKU45iKjlciD}d#^6uo- z&p?yH4VUk`ir%t42gcgHbdfd7=pHsnj z&+V3#wT}aXSnCb~x@;bU`rERUcCr+$9Z`ZEK)SA0kzr~bkr)n|1ir6J@@n2p5E7L!&;ax73z0bFyEA#s# zc^s9Mo!L|C*{Ce2xi8?GWH_$3Ck`pzR7^yrJg1)*>e7elx3Zf_`_2w|57>K`Z7zje!~ zkhw_Y-OiZqXS)CKUCDHTd}B_Y5EI{Jb7iDr`6H$2m18pK{8qX{R7h>H5)r4hU`FuM z?5!R>Xx3%pUu1#3LJs^`;i3!KMOGi4iAL?KTb!~U{} zuugK)v^*!}7=62%8u?C#x+R~Izb=V)uvk7gwZ*LyHDGlxjuIZ_xW*_v5c}r2S&nA~ zd380pRxCi(Y#T48*mt0lnlsQz`5C{_!SsVm*dK$3?!h&vT4#3=&=|7{vZvSyS1^PL zQEtFL_8g=rJ-`l)7UmG%=_Z`5NZ%FLBzgKp&XlSvG4vQZ`Ene)ahf!S=z5`bc^dMC zK>iYxc?Ubh@`HO2Y{0*uJV<~Xt6FT5m0i0~FF}HXi)nl4Q|9ZalU6SHInp@%7GCPW z?Ji+CIv<_OC~z>EotA zM-|kc@SMmDh|mVHE~U9^TJ#E5E2cV{EWirzJo75U{;sUB$mbgjkbEJ1ZqI%ZLLR?`>j|5@Y8Wh`L{;*Z?%=;W_|Koh--V+r;E*ofvD-(uSMl zn9tZxx2xJ6;2EqS`@@a&YK`>wI{%Y)q5Gqn^r%HE8{Z~frO5bk`K)7T0MpAgMYV|Z z0cOR-*iJcbJ`<81uXNr-{p8Z#D__!h6%U$e}2VKyj)-i=yr2c)NAVVg3b zKzChBwhw2E3_ibqkKrVKK<*jYfK=@yi0(%J65)LuO=tP|VIXC{bYDcHgX)NmyxQ!a z6hqRjh%7@AUh~|+9K}1T8s^t!{LBr}nny)VQVcVVMy3PGg(I@u0(w4ugEo=EPELRj z&E_agk@S)D&q)W!vKk)98V#%q(eJ;hN>K|+dH@VOOv;}i9;&zH%asSOl6Tk@`}o8K z-YO`Dl`GDh>a&+_I^mJ@3{!fRbpDnp6&CD?idJu+QV&G1DKe`+IrVjZqH{sV zWzl$~%VpP+^3`C~((Dl>BHG55U)Pdvs~0#*Qzj9+txJd!#H)DL0k!BXY1hx*SCR*- zf1~O^7qqJfKd<@#Qxsc8z36|ic^_Y0e$Wi4rBxKn^CH=ec-#sm$okzqFE)U_X!{Bv zB;Ot9dRZKU=Y(BxEm_>3@krP96AjR6ctmy;EFTPK0WevBBm-($GBD?ju+s<7ng9I$ z${nt}6Ds>*`Q=b*<Buo z9FnhNQ~^kq#Sl;HF(=*c17mMxRMEMxq&&N%$Kok+6P{+vM>lB``iBhg=LpejDHc>n z(Bf4C+{z_e@UJE3%f920Y6eVkXKjTRxA4T{)pKZVg}y9lW;Q8>sq=Hw%4Ah&;k2vd z-~h;EhM4DMx{Rf^^z@vzxvRnITRl0vdSO)2g+Ku=4xb_ z8&H{xuljCYN;|SjMH8x`@aj#Ht|UpzUH(a{u4j!@wkwuSM3=5A#vRo1QjB+|oALQF zY88yo0cuwtAXk0c9asVQ=zT}Ikqm$(+kzqVf(ry(u;#kY@}lwNmP)TBajU_6rO+{H zB3kW+#Oq)ZJx8>;=WWE<`enPVP^h4F02emP;q?mwE=%9WHri(ht|fn%^rL%xs>m#P zP1`s!x)r+KObGamUBs%@aiW2B-PenB_W~3VhbIi)!u5sVJ*gak&m)Ly|G8!-R67%AC-mBB4U{_k5zs0U#k}|-K_P(4f=jE~kH$G*$^t{H)Gdea zO0t8CA7Cf;y$^i@bpX;pgFs537&&Lc1Of^jPhZE@NFum-4?kLu-A%|^*c3*_;!PaL znG@Xl2Gsr_XpYAcr6?cfO#qWv(L|U#`d8?YGQ|i<9B*tYs2unEtM>DO-kelVSe> zg)79NnUufhAJVt-pCZ>ZIDl4gN#WC1)w!2?+LAWbl4U~vl323B-$UqS!Wz)I<&fu~ z(jbX4q1Dhn^gN*AV=l9fL_TK;?AS*)5J&MX+h^`@y!^6@&io5+Gy+;NQTFXn#)Z-g z7h2VId{tvfZCi!8@jSVPMkWfCJz6uq%VCZGaPrs!==Ze2aVzxk41tslLzv!mpRqLBwWJ=R#Kd10 zLfVga7XMIf1f%g*z?T0=#;fD-SirVefupGiNwlgKhsTkPAQ^S?zA?$IH+R;5wk|Ll>|`NEB5SghV+t;MTtX&9VV(_#Q>1mMqi8 z``Ekto4Clh!D7vCB{Rk-Qm)>;;)5b4K@sAUY1Y0yWez#;FvwLk*R*XF4aM`KPT{+( zErg(V9;{^9d{Ar?k@{&tLA%x@a}Slh$F1Fw(sU0)v$a z5~Z~ZhCs^nA<1JeZHPuzCIcX92B86(Zk;Ntk(<)m?01kQx+rL^b{x>9&W&9%9zT_& zUH7GXI92(npT;7Z3uPN1)8fFjhS2-epSo9jLh*(c24hn%vyY((c!U59q^iwz;>TVN z-cY;HH26kY@la==tt0A&e%Q4Aj8*!-hedK=<4_!oQ8 z2@ViIfz3b>K#>eY0L5A0LXZ!Ej~!9&{j7179poMtWno?q=K%FwQLQ80V!o?jBUgUF z5+J${ojLV20OKofG@gr9zt3Ch(cRGVy02r(Cvn`j{p!|Z%F~Iz-)=GNh6=HaiKY&t z8^1LdEUmRmscoXGjL3||E7vfeWMICzerq0R$M>L%>4@83-ipv}hc-;#hCaTf{iu>e zKXDmNNQ&0>TwI62qrmqsDpc4c!Se@&rp@f-e@;~{&F5qm(iCZP;M^Ylqlm*Wx4cbE@u7g~@B zqS5YcvTh?&mIrC+sX|XMbOY%W%jo{YiG${P+Awx|%P)GGL3BqVdW0;!d#B;uja@Pk zspY*ZS}OY1W$Igz-0V9t3Y8)zt_fb67z-sy06QXln}7gJI{jJ)ZF2)6Z%bGDHv~s zD&;zuR~vBre7O}WUv!P;>_h1Xe<}*Y`}ci8z8Wjw3R)2!izfxtk9y2yOAgxo;gvE^ zaou-!5ryaSMm7Ln1mj9F@Wz?SjmtOyA3iS?jyJRg)Y=X;c?6L><}T~SfQHeHB&?wc zJE4O<_uR;jxgQZ!qPez>*OD@<#b0#uvd{pvuEWV4@Ifge+5j8ub0REz5a-=oFS$;|LJutETD7C0owEs> zKM(I0DGM9?&Sk6jmR3mJykzL=aqE`+ARrj4K?k$qb^nhxhpo_Akj6$;@=>rqISLMwwtY!_x+i*$CzpGFqZ(+GI|Eet^;3Ax#ob{g~GE?JsrD3+q$$I_G z<(~iOq>bm%thQ1()**iPgAJ+bEk!aRry_S89w|`j{vzMcv2rOw8|SO_RbPoSA>i?f zVBYm)tPC`jrgIsqd4s8`yd7$x{SZ$Oa`Bc{CIG)dr5}B_OvKT|I7roa2VK3TI6;z3 zIj-1GmoFp4+>DPGqW+&ALKq4N>2iWj^0?)%OBidIGCzQ>^M6FWc_38Z|37Yti_*0d z)fFiuktLO8j4e^fu9PjiP_~jWn3O%0Y}v~$(JBffOIad&Qcbc`mLW4^%>A9|{rY{r z|IL|u=H5H!`8bc~T6FNE3fpL?c|oiMnIWxHl5Eq|@&8DDt7#xB5& z7JI`}M2#H}B!sLfZT*I|yG?akWNU#i@7R#qd;YHPFU*b;V?({edzW+eVM^CcIgx9P z8(iTkzq<*dNFpNz7oHN6wDIOU5V+lvYLmH}u0jaIvn};F$Q=7!)XHzP>k!_M~V~%!2)j)3;u*@|*m*UIzJCH4w&I)(6 zG4daI>WyLst$63zo3EyUS&+K|k07@Xa!XOdK>Z|74-wJh2o zVTm|Gm0{cgDlLnvucJDpW$wzg%a-<1bl3Edtlm7MT_l|bx z#4W`ol7Mg7nV~(prH31$V}G4Vy_O1M>o{K|kN?Bp_Qa2&*nmHx>E{;4Z}B}y^f5?C zh`%`{l@vYIPX-g1X(h&y-GWhPQb)0>q;C;)GQY0>M#!lQ@eMbxQ-h+V&HxEkZKp6aj4Td|;gqu@~KoT?| z|B=-FJ>{mpOv(}W4zEtEz)N|rD?f^Z)83{mQ3?K8nkONOcF)T^8D?x>;5ZX#4C!eJu3(s*x)J$OD zK)_1Je84p%?S9zb3U%KD!8Uxh4sGl2LPz_G40pveFg5olJGs( zsh33(Y8#>EZC%%7<1&AkbOO>74GEUM13yz~PCM(|YSqkv8)@%5jHzAU7Spaxp02rYMa~kGt&^L*=8|nEiHHvZbIxc?4VQ9e zocKp;oOt&)8?v(mluv?}vR`6;QKbVSIgpz!CYN*9gmni$?iaY?8+VW4CJ|m8{6?hc z$PQIMxr0+Q!q=KB^X$fNdTmk)Oaw*25M2C4a)CY%c6ApEn&4Ei`ofyCZ4JaKB2{zRRVbF9{$o z;x_TrCg0~A$ihvh35RnJQSx0$WanthH;tR45k)U)@b0o@l0?AVcwf&`srH z*1E+KvI_7qbv+f$kBLXgyW=wNI7l!#6_pA~qS5>kC0`*?_bQ>OZOwmbRT$9vS-U&A z+L(+^o_XCExtrxw_>YkD@P!vtxO71K#11B>;duU=R8&XqijWawL6-&x95{v6@vk82 zM`qGwFrLFZmq-@z@ZoMQCUFu=BJ}EgBt#y3d35m11h$q_aDP!IE`6?f1?fts!GD~` zB#+)sIKRF7D3dewnL%n{Hz5GlI3l1??~)^Land$x5}TqiU6j?>Go}92yKNcC7x6!9 zEXjbZHe;$}P}1d6>bo+WhYjeLv7dsB8LWMkyfSBUWzMW1^+L4BeFhYImgTVwUlv5P zdhXNU(z==A?7DAf!1b)ebq3rDBN$96^{f_~4}{)S$uovDxR4-=k`%cx8QdiKk^~U( zgBlpSXYutuJTFaZJ;60Bei4%$e%qVZ-}`rT2a@{JyZhETeuoz{*bm_0Yv-kK6>-JT z5L)OGDc=4X;pdg>9fSazW@xLJM{ z7)TB#(O?!_$?6yJ^bw6^+zLN`c)(iQAu{KkdDJ@Gd?JK3}t^nui|`9XfjI7HKoD-yptQBQcxr$k_2C1i-zHwymS1H3jZtEy?np>K})w7BCr@+e7_7um-CTR$7KZ>iBzpW}zDU>y%4#z}1%<#RX?_SOs5A*aXXQkLm5ZZbO|*cNC(%siT%6~? z7zG>#U=aK@`8f@MA?<3H?>aPzE{4_B(`K({m&m!{TR1`kgJj-0##O! z0o9pv(inLQXbHD99#%F55Z?jFL7*IvLS%tr@tY5XfbA62M=Ho8$Bs#~%S6c>ZBMem zGvKg~MdslzC{HKB&Phd}NDBmyJ~iyN#$FP>emSChe96O*MN*?Pe@ z=9d^yc3pJor+cOKI!W%cC)Be(gnb~GC;X!ZZl)oVc#R9gbJHoPBo)Md2QZ$H9#*PY zH1+~#IQxt9WL1dDz$+F|v}At~#h;Iy7I0M5GL&eHWV>=O^gabvb1f3#3{|`%uda7JR zQZWNkj8m4rVyVzUh^#+GS73tS9Lzs(hblb?FX67o!}|<4QQU&r5^_@>+=ol)+-IE$ ztX32a)&H1mp@iaIfEWw?N;6Og!E0v)PvC64Cdxj@sA~YA**Pb&FE}L4g$B2MU_hrz zua8OOqLKZ+`U3!oe_BoV8JT`V{pG4`e)J1qf!J6!fC-K={I;;*^`$&PdNd2s7orU?Mc z&Ou51*Snp4KboN?Rt@Rs0fTh2bs91T`ru=UQ}UOf3+c= zDt%=y00T%=ihEF;92qN-2c&}_$WbBs!br>R&%p3F38VufcnPq>_T8P*n9}aH&08md zVz_n^utV&raI)>aNvu|363mwh#%+5^6g*}K4Bu6OG*tRj6Xa@=1<;$ge7LR(=!2@A zYI)mB7!U>kg1FZ`S@9za5Z{BZ1E2|}8O0b>+o$CR$HLeR(-tDvKI$R)|b_===Ehr&?oJr!&e#Bg@h8 zj}#g3D#sNo}N{`PsPFv65$QZ}n7v zpeT#tj)Iy4h&iehfZ&0ps2y7#@ymg<^%r0-ahg?dy#K$ZtIvGF-$9{K26O`qS5+F< zfU$BxH=)`#0d-1DgrDiUT>yI=Q7554NOrdg4b}ue;CmsaTsDC z4{A|n^Men0;L^nt*rv2mEn87=*D7e9{0_@#FpK3W$U<}N%M*#y*nmk^;7tF=3U9xd zO<+gj7?2x(-HZ^>!YsSuFImImr}|Tz!g67%IvA6Ju+X#bG;DnJ6q65z~D+8Y8dHRnO zW@11S6ca$aO#-bTQP2dvK6PB!Lu7agJ5oR*s6?~0dPSoZQ`QBGJVt7k>WOJ*K4nFV%S&UWv;(+{D~c5fI31p6cjv{ zoPR}BT?T6;&&NP^umPp!ZT?O|wY3z&xC|-`-!q(u-TLqcvlniFhk!|b_6mT(dDV+U zm5)Iz_O^EsQ(Lc<-;YO~)Z#MN64XEzwKE3KC}NidWrU5TTqVS_RsIu;B76?4P|1t& z&#H?-4+T+_ou}fg0|5F~M#E*0KG&B)ZmiANO@c+riN>LyilQK}V)K&RUE68dpm?o}c=Xx5q_BQNoCsgy& zU}GMZZq$4TAZ1Yf=CUpa;A4kw(oPf_e5YY!l0a z2(x^o5XO@zG0DxZtF|Zu%H2kgnG{)A%pb?vopEuex%`{?gL>d=@l@bqL@jx@ZgKW&m0%Jz z@jU^V=Wgl#Osm);%#bu5FI$r<`DElg!r0D=}`rG*q1pb}1IqD~rZPfWE5E*dvj zbJ(F;_%X-}m4@A$`rT_apExW^oK@3Mogs&0?}i@A{@m(cEZR`}ubh1N43v|66If|c zDN&%3jsY=IVUEWg2V%k!-B#pq;B*n71iP5J_xj(GY>hw_a|xsgzgq}^LB=nvPVl$5 zy0!t&t`P8~h5&%jW?*-NWC!-0BCFP9qP;-kF)g48l!nRJnfEM-Aeao&K&J*3t{n|5 z2&sGo6v9hdY1x9GHrplj-O?6Lg2z|G?01#{*D_th7gn(;#vm;tsKpfb` zFZYcZkO*X%_AZ%SKng{Gpt=aDZ9RUN#Rt*PqtPaNvA=ImunL4gZs%9Y+fb5_$k6-D zb|`R%^YOCko8drC80fUkl(Jwjb;X?uOT(2YrKm3Y1K@)y|0^Z!hR zYKi|d724bH{%0z9Ebq8c;mhIzu!-Xz7c`pdf*40KpzHi~@yP&HTLG#B%kR8k)fa0e z<{io`bwD&Itp_XXK2a@%UR_X>%uU^(fRFrVDOeX81`^aH&$!?wupdm4_B{f!Jp#xC zaW1e7N|Mi)pQXikGl?`w26Ume{+4+?|A1e~6gJ}@A#A@r%2^O{Rs$u4|HFcW_nF9Z z9~HyNhaD5pd}1P~5+}LLuM3wk?gW3TX*G*yi*n%-l#Y#za@w-G&S9R9i)QD+pmx*a zPSHGai9aK*jrFeI7H#56!0xRT;7S^~V8t#@|Kv(;F5?mcf9hRyN7O(qVJtSl`Nn~p zTX8f&8GHV6sX7Sw z{@!V`ldSjW3rG0U5st8>x*Y=jQ@OEwVmBk=@F$mu=$;kPaCX&}eN6(Nv8zMEuRL_c zv(=e;-bo`h=PQ!Binpp@vyHv^S9xQ38&6(%iU#w^Fb-{LH9WRO@W)OOwd}4a%}|FLzn&t<>!i~JGuGP{w`Vmq#L3mj=RsU0^NP8|~kZdI74zSMMBg9}%GF+J^Q^Ipl)~=( zu<#~XSd)=Ea{bbl_9DAGn>SJWA3mCAEo)vCt<}c4Yjw(8#XQs({P^*xL;)l+DR`zt`UdyG!x7Tz>zC?LysYz+1?(gPmiRN*8 znq2i0D4oUmQ}++{a%jJmh%{AZkwno9dl9={v|k!i?QDE6CQov{2fYkA_@gMTNcoxbHLxdRGTMH?xXWPkwBOj9zWvke zJ$d4 zJ|VhGXEGGHfAI6GQZ;2_hT2@0Hc9(YYt3rXx~9@wmo@yblhph~)X=V1g-=ZS{P#C5 zkVuPrIVE;}9lPh#^7ERnzHE))ZVOrCk4f^TQmT>u`q83aW6einJt}GhPhQoNEjLOE zkZX+BksbT|s);vdiGR6(|ERTH3qh^rmJ;7x$-@LO&50z@;gn|%dY^ilZoMesFN@{> zl6%4TgYilyyW}&;GlOW|NJ@c=o@P(;Eh}Lu3w`fc{>w(37V<|ff0zOvv$^CUW${pR zVpP%hLz+XcfOy%Sn2%2jok|P}L`gNLa5W@x@HEbpnH@G`afO9%5t32d=iU6V{F)r< zS1XMQ1obca?2p~`=uT2|wdK3ZYnp@SIZw|W3vTK4tz%B~r-f(THN&rzoxz|S5$8tF zMdi)mf?fsowwP@#_8CKcyT6fdj^=L9qL%#*O4`VC_|0uzpG@2raW&%;INCbo&GYiy zanJFR>HZgg2)8<@WvW)Y$xG*#EaNP%ef#xMuf^t4pdHc7$h{3f%iehG$%nqIS6 zcfqOywCeM~MmnN=SYrA91C8+#36rI(vf#(K_Vpg5-Ea~6)#yXNEK&nT3J%d#%>gkv@2v$6{ex$ zt|GA7e1Gj=F}Y4*-*P|smLlVY?0#b2J$GK}ti@e$rP+_*{T7ATJ=!Z2>g-dc!^W!W z`l*Ly5`>B>V`ZIwS_$sJS{FC(p8U1kZ)Z62PC#U;Kxk;^&0Pm&ewEnXKRdDzt{qX{ z#PiiO=0sn`A3|jHra>Rcj9|`>tay=2wuT8}b9|)7OXT12Vezjfm;2S9DVl`a@BKyf z^3J}QXKW?5Y+0fp6A@;yWwWcbRbtDq2WO9kjM~j+nTdMs@sbr0>}ILi(*2V>xAT;3 zQkVKqN^wPWL=)b1FTB;wPmUGk3|?g8Rb7pJuXEy#Su(@>6Zc$9jYR1MFR6piaPx-X zxvO%s&|SyH_>5+=N585C-?SRO&DpCt?zO8-@D8)dP=acxACUCHOsXbCP}AkKjc3d2 z(=M_X!6yPckJ%`k4_%jdlN{#DCt$Y!ZJZ$7` zB)&4QclX7TC3aLGXC$Rw)kUvrAZ@9?)z0^WGKQ;IZ8$~g#h&NlE_!rVz1)X!{BH~* zibQDkjMb)tveen84Bxtg6VGGA$3J=;rX?bjr{t3DNe|Xt_Z&lApT^~#Yxf)@cy)cd z6EiAipuT(`pV+pUZaB7SS9+l~c3(u@k-Klu=0QdNm)h|Fjlse%|1_$nEL+-_I@Evg zCz%~k_%;+*5}UVg+k>V1$JGm61-T-^G@?jmQTO*UCfJKMEE@m1?H(^#SQEhJe3p&i zJN=S_$$C(M-JuH%b?0bFEPqx$xC^u1CbQsu40x%3wFZE(%v7S)>~`_yq2>OW498|O z$BU}c23V3vMEQEELWsv(1;#4#sHN}lwKI&MJ(&t>u5Y~gj9usbxm_eArz# zn#d)*1Rkna626YAaJ}*rLquh_YRlK1+7VfQbAGn+=%kLXpQz_33fku)EdHgFIyMKR4vn_Vp2D+bbjT*g? zC{fyJ^+13~0q-PHCqBP(e5Mv9xv17Q=h)q>xo=k5+*bTt`r~z(M$^%U&1QpMvdZql zk~P6EMq&peEM#r;U1gIu0+W`eB(LDrH4CB3`ux5v4LvThns*&b7W%>U9@XrLa?#6v zd~2kWUqN5W;AuwE4+WLFdSZ8k zqz-r5Hk@RK2I$OK+@Z&palM-(DwT(+ho0^|Jq%NG?HYz6AMy znBGovkjo342$cEjNHQ~+S6s3z=ZgDuDrA(__(*+)!1+epbkD0F&-y>1yUOmOor9XU zNBw`lpb$c{kYUnXBES6 zY|I0{=dbKSThm6hJNHhZ+gllqg_jC;Jw)dZPNUl&t)HX49q>l0RsVpc-6gQJ3vPOw z#=5Y^aQm^XMmYu{zRahUZ*~qkqz;FVAFOzD+}LZM@hMp}y`12>51fv~aJ0Bm15S7T z;wLmoe@%H&EA{N{e?`{~y`qdR@ZLA)!ar?#j~PE!t}+ia6!7A@(U)ivtx-dS3jREhcqRrs%mDJ4Ky9WkYQ>D6-0B1FdFTT= z>HQ;SbogJ(eTDGm+12h zt*J|nAJJW_to7X6z=z4M?Y=qJ*bHpAuN9}?y!;6kZ=xDAuRePJa+x$Hb-G~aCs;}( zih_-7y=OGh(2Pi!E~1%(N+mD%F-~e?P;utLmaYg;C;=%-|1OER+2Uc`T4S1Hbh2oD>I2xr)k8Zj^`JuKu-@lfbW%X-!Q*MdnOI@AD|XyrOz|Vn zEAQkr6*YXt|J|{M`?`@2Z@-VJwdcr1`RTFKgv=H3JoL9&58>^Vk{y*Z2|Z}rh?48! zr5;qQ7aX{auW;jCrv2Cm|1o-7e%@MyMrqtkd6V1Wz~*!7S(YQK<6KumOZeGvnGpMJ zJr0~_qpec)b5S|^{imYzVEhv8hv!2#Uv4Jt2ZK&&#L8^msfosXIM{nqrbCRY^$+W< zP}c|bp2+Y2_0WIaVj0dnl2zgp6{I2YP3xTc5yM}Fao4sa6x*pElsuV-uA$LAXxiZ! z;=$g;2$MsDkZqVrE_zTdJAiNSK)=ZvY4M$056U|9R4pNevTcqN4avfcK$Sz=+9*9?%hP#lpI1o{5;^fh)-y%} zP+39&#*@ajMv6I}4>R9!Zsf(>$Dozz_Q>9Oxk0GrgdAPEe7Yo?F!al35X#)pDuvT> zew|x$Jn?&uNc}Zd+nXB#Zmp#D%I_N;Yb0|2SpKsU!k;0|1f#$3$_lugp0S@OLa9?i)Y7*_@~N#5?>*7uw+b zeATFDme}xS6^xP7j}?WzxrC7Wi{}#r-QweAuxKT8SllYp(&fwn8;V|-De@NVL?aCC z$}ABR>A}{M)TVJF1W~!Wl%CiKe6}w3%>nT7Z|<|1x&09F>fCgm;3j7OGD9s2v-7OG zf_z91c0PHm)yglgYLw=2bPaq=St;fk^Gk4Um3rT#bI?1_&kLKp;@xBQ)t=!``wOqE zGM=Y8E-{`rbK_NZWqs~tE5nR@Hn_^Pcm8?PvNTsxdJuYFm$8O(D+m*_IKgt5I6=182*3!Vb^ zRX$6MQK4J2_~=dtH+JF`Rc0wY$1>MQ-KG}!fEV}m5#K+n z3gEMhb89$VacGTX*RW{z`;sl9ziXl`cpkjimN3y~J-2rl>PCNZyUnD=V&w1I7Q!yy z-hi=|r{|xJynq+z<=vQM-Y&#k`)j_Kd8d(-JBx1}Q6nCEmTNDgGYqvio~%v*hwa*; ze#=&GrYAY6?rO@H%AY3+ZV{uJ4?x{VtAFq)wQSKunpU{Mca4#{Z-I*kDan{q}TvlZj?$zyOqaC<-HCO3!ze&L*VI%YMQpXv`38cg@n;H;gOh zMt4&h4~;7Eb86vxrSC^D?N2V8-@n3xpQjr%_$TS6Vie;U3^kX(7MaM)_mm#HGmqFz zk?fvQfDHD``Pi-;E_d5Y$&LB>dqJR}$9Y1Jde;rv;=!Zd0`D z=hTyP3GSQG(|KHyt2lp8!(IKS)<}$3La0f8K(m4sY`lLEx;$#kIHVhlEoExtSRt3Z zI%$q8JXNlx=dw-9;XkkM(j2eO(Ve74{7>cknasbENL7U1IL z&mOE#$t*F?Y4v4L5Yygq06L)R+mprQn-208zWP>E z^kOXCNeR-7YD&v!k~tpwZlWlL3ggL1C~v<;pxFtMDMXABx!ov-jM+cD0J$qV??Y4I4}lZ#5ZbBsBO+6Thd*f^ zmBm5FOcCGZelUz+mz=?rH%Fj)p?;2)xzJIxlB;k1?CiYrPYxTqeY;9vWBM$ME;_Ud zoDs~&{!qQtV!rrqfFU+$!7&@BEq^oA95)%yr-CqZCQ((HI_t#>fNPrF6-*M`FToD# z2Me7(XP>|&w0)-Zd~al4oz8R9pt~0A7&JaG25|6`yMzQ;Sb zmS0Bz&1&^Ya8w2yRaAdsg)oGbj-yJCs$fan@}d{^4rXKoS%<6s=;Ev2)D^?gQ5rH& zmKo2Tn2hJ{Sr|{gM{rRQrKhd{GZU#m9D40xj%+)&ot`hgvGat+g}&)L4b^#K>zT)N z>B=~L z!lsv0=80;})8MeRbN5IZQ~5{Szsn}pIyP77v1JJMx4oQ{92VmJgVJRE2lpbZN zRgz71nPaz!aYaWz8>Ml_sk9f_7^4RkAaw}-eWJ{+o6eNIw|M@6U{MMypCo3OIap;3 z54BTzl1G&6`>)cS(nSY17!VNKtltT-8DqYn^f`dQ+n3W8 zUU-g%wisB_9qrVm;Qyr*aYs|+g_%b$^rm2ksHyBA^knW7BX4#KwBO3s1T-^QO)swf z`>kG|2F>C5t4y;3MXc4@DbPAF-@(X>sKdzfv^GAbY15lR_j9{bKQl>Pd|4QIj>?2S zi5_gl`#ge;V?SizyqcvBsN==}^q@ZxThv#-^DD`06sgF<@6cUHTILkxx&OFW^&V5BZHHjb6nsWg#yfg~))> z%dTx>oQW(4DV?>8}e z;^_I3P+C^gv8*Ot_Jyj(D)^az-Gu#Fe!GD~s419{Y0l}q>k%z9507nh zC(Ta-hn8OSl{@&1Q_#e{29l;oi#=ctZ|5K7WZ9ru!5g%O2mEK>0wGHCXnFf5wOPB2 zJD2dP-Tlg$_p`*PV}S&h@0sVELIg8xr8`dllN#Q8@OvJ7-@5hubKTeK*_dk&901t% z<@jH<^c?y1cWE^$_MRcG<_2@e6@Trr0JEo6IfOLOC2_`OkvGVTt1fm9C=S1etvO<6 ziqdL5IkuAuGix4-B|VzXJHfb0&$mz{Vghctrw%!m!yPv1fC!D3Bz1!$2xSZ3Rbp%)8~jM23cZ5@kpun9MG-8z+UE0i8Z zS;~Y_%p38;i%uGMHi0^^^6)#|b;4k({`~c+`RDA^_~Ul9 zI#8+DOZ_ao{#;n>40`Z|=gt%8!l(3p$o|_lI$83ehko=^Z8Sf6FWO`c;PLWl9%#MY zi|Uj%a1BO9tT2cx4$LU?V5q!f<0A#`=v;v->oB!YYZ3!}zpxl~ab7ihQ6)3qPl>Ba1-lzoU`=NxY2OEIfblV~ZN?t4QU>zodgrOt zD8d`Fk68K5mvh8dqB{qm(DW4=i zBO>p*W{H^(MDf*~!x5n4Li!gto}T|1_s%0XpnyT-FJ=(?Dm@ITS831|v0$A6NO|Xo z14pMHM+L8w6#fl^c$h~l47~ky`;1c#kJ6mKB@?H>{c6ZIji6I%0MF3#x8ANL8PlMB zEe|5EHK(t@0SO=GUW!s+<}>@`LW~4ce1`bwG3;%>2aOCizfFPvO0DA5KqBe7SY*9R zA&v!yz=m)pY3mb{rw5bp^8r^?QSzZZDBD@nDqHgj8dP-m&Fc;aai6K@S@Mn;RL4Wv zu*=$DN^d@f!Ku${b5`ghR+_&5h6r6)P6dq=&0U|Qz_~tjCrgFLgfQbStiX(`z$D|C zZp}l2Ip3R&im@bPPa4#tfj3W@>2nmCQLYqTfm5muJgV18Xq!Fmpq|c(!Z9E{rx1tD ztMsOiAM@c?dTMp^vOQRydlQJ=mZy8H8rSYlBU?_bz&Gc&R4&|_RyvZsqyoLpY6#xW2IRJ#)QxtHX z1yBP20P%MLYO?AJK!oZWOorO+9;|#?ET%S%?A!+rhEzyDE=I9evou!S0(2rxVOYNOiwK@w#(+ z<<6+f7ri>L@?A|4l)ICNKzYx0Wi(Q6VVPa9@yH%iww7*8Dk1XxsiF3H6;yi6-9DL~ ze_3mWIQba<{&u}uAHMdp7Q-{<*M)7$q#O8IQeeKH6!d^^+Aa)0g5DDoGsS4U5BWxc zzZlMd$*mUQ}|Mo~lh#$6X?lnxRne_lkSo(9F-t*`00@FG9$UxzobRqb9; ze)CrW?qb|}3^s{O+5U$~-z-d59sH5aDKnO=Jz5zm9O#RWXvPl}mwU-8Mi=;^E zu5}Lp65zPU;4BE+ZPj@CAh_42NrcCGYktQR0FAsf07KP0*uS1VIIVUf&yEY$K7h$w zfe!%HJmRd4inq4u0Vr+fbv5+5C`hgXFEXXF(6e$$m9`Hda5u~JRf*rRt0mLfl09< zR|vm)dw8B0QGXOK;Gq8*61MybwrJhnTp2P1@!t2&BjkF_iRZmSmQ2!-N{?i-?nz|A zpgL2^03YD_XuHkLCclH4lL*^L>3{>1J!)`FevU}mIkJ(?quIaZm8?LsgeBlUp0zLB zEHp5Z1u8NG>N&@w2LKrAj|~ZT0#x7aJ}kM0i!sQD4S|^@(zA-Ye>-`e^EH1PgA=d< z)zO=Y+a1nC;fHRgyfG*_d8p_Ho`|pTdfWS2Dd8rV@|lH&A1H7GZYo+a(74j8)jO?t ziURxjboFrFrHyTky1szuGT95M74mTth`=U&4V)1m&Cc^VBQvW9Tl-{|$gYnDJ=Mw6 z&4*8>+JoAILDZR0F21@kF|-0sL~n|jaX|%V+z*KWVo-)3oi|Ky_xEy84@6rS#2Ant zy0Kc!$yL(#{oMFoIO}tp6$rn>JqB@q_|x5NgLlgSYrO&B&|T9hWgdEeCz#;?u)9r z2l{w2bK4p&Q!bUDf>7WoJti*b9$gx9+a4L~+A|293^ZCLP3_FPM@ab%Bqi?~KnyGXh=33R6&PzcH!{X5U61N(u`IkBvk!O5}J z;ouw*Ji2us$5z#-Zm2rB41CL*Vea5#O?!?ByKH9}6g%$&I0x9a*ZF~86L!_uj}~G+ zXhW;G^Lm6m!{-W#BSN^ixW*st!HDe)k1<-xOcUuG7^#{<`f zJ+{)I*uIknfP@8}r*|;q)uxc@tZFMjAEHS#Uz4sZTK7<0tezl#9NITUDev2?mthZ13^Bbdz z>io}~SU+$u%fKMu^EUfP8l>j+Su2YWKn4Yi!Dnu~IlzIo|8*vA-zg?e{YQnA&RW=i z%_#G4Jmqj$Cj~xyg$Aut%lDZFe>|T{NI9EE2sl3sohhK!tb2qpo3^gQ+}ny6#8gmg zvRCddOQb;dGJZq!|y8&o+`Ye;QtqYsMPJ@Q;4?t&kbOBd_8@Lh= zaKM#tr=~K9L5>xG`ak0Ey_t&}c(sv1=;3W38g>A2s3{9_#kQ+>bML)?9xy;FOf~2u z3*&!b#&ZRFe$4Al25}X55=tNiDGlD3`YExHX;ut?z+u<3?e7$r;!4-bO5wJvPW?Q- zalA^0cimJC3j_*c>Xp?1RHRisv_;I9LyFJo ztcWu<=0GSI-Co68(ZlR&BSrsG0Bd~mrsr#Y{(+i+u~cH6%#y3skI8-o>sUI4Pq4Ur_le@V?Ki^x)Jk-i598>xHft>_}R< zH;qtDR^TeiyJJ|Zp8vmjb1vHa-Ka?}_)Wzm;_$12PjB$zq3g`3JS70eDmY&EO6u_R zXUH|;efVRIZwhFWK|h3Rq7QUtfQ|gq$m7qeI9`cOQo;(nl8>2*kXj>s^#Xh#2<}0b zNs8IKMsjz2j17wG?1{-|!*B>~bb{04I!+~VX+@vu$9qZ}&3~3D7 zWLpLI@q>{F7y1nC_sd$tJ@NwNaLfR)T6va70M9MCx*860L-;$7?Tv9KC=*+N08|`O z>%0!2yhThM7-hhEIQO6RAorF<1qqoRAF$*m29MH*Ekk@wd^bL>z!tJ|tJfWvB<)=_ zzxegv?(*)yvbEe=P0Nl0iQ)TwFsyI8?{Tk@UM>UQIt6nrEN7M|?y+ka`WXm>l9pv- zR^R}G(?6V55R95^U~`d=yw_X3*ao1L#%<*Hfouo-Fo*K3v&Ti7T9!kh@?pa9Eq zID$sj_I$FSz!u&#=%fa|x=U)d;j1(Y2kEd94pvbWmVz zFk3u=@no*nWinny0F#DH0WX$W-01(sD%X+CpG|m zsVctY#Tz#`*pX(dlc+1X7C!PL#7TaH5nO7R6tE z8HDy=muQeC&Ml5q?Jc|b@Avl9uDL!rvYi5+rlZtT35bDX zmHq9lxBUsHk?iABKriOF|I>?Hrq&eLfyD?Gd*t#60Xp-2cgCvy-NY|P$Qts1v@rgJ zB@kk-e-i--glh`f_S#;tcmn9fDQ3&tndqhk8I`9xshPlgqCtK}jz&f6&CNrV)fUDW z)Tyx;zF2z?W49N4jHNu~lKzK-Bc=dV4lfwQ%`A+BNzhl@1RBI~;pSG*?YX^Te_@$O zWWqi&2)%?M@Ff|q1DV5vn_bB!;Sxdf*NlgQ5gHJp;jp*6;7X3TWPozxnsNu;+=c z!jn!`O~g!{0`zE(I2^l8ciNEez)Hl^AiX^(*$Bvky>IN1AS2~L=!abT3^9KK$OG~! zs2qMOZ=d57Z&)lb_OnH{5P&Ms`Z@?9bpQ>YfUQt-08IRBu!eDMs1p9<3ufDx2%bF2 zLcxxW$=AaCG)Q{|ZRNoi*`oghpPo90m8ae<094JphTn z52|M0B8DAFC9pa1YT7e#hxIRuv`r!bu^VQx;}*i>Sg~6fG2icz00<6h?WDlmUzGNn zBT75B(8*h7iDKL2!CwNkui;+v{?mzh=S#B)DP#^-_2`fblKyt^Xd&K>q3fTghW%1f z2u>shF^UiHK@)H0{yVl5IORH2@$vV^X=J7=Deg_&hw#w+6hfr@o_`?FUwqPsWwOOg z+Bxqw10bjeLD+*=ImxOWzojtUcnU_kvC@Bb`~noz_GAM5@&Lf=&x{4oDf%Ci{BZ66g1}&FfsJ>vwgKFRljD&)cNvmsp?w$FCulsti*A`v+ zpoEyYP4jQxLDOmQ9Lq!yDA)B}VQ^L+29I0lT_ZWmZ-0*8hfg8?g-0!zBw4VO#aY>T z8RW)LWd|lMI-wj+Zl2-S?7%MR;#KAV9aC@iw05M zT$!Zf>34=9ykmVt5k3E)@4Qwjq4zGhnRyp8WXnqs>(ndH7{piM%&5bkz@g+GtT{JW za(Ua=gW=hMz4qHB?%Es)RD^Z|o_b7n zXeg@b*~2DpjuB2+871>a$0UobkzRdvXgC~Yu%^AVjLICG04eLf+m? z{?%ioeHlQ(@B|vU$@67hHc9VhCaGxjSP(C0}1-= zE6s(8W4RWyb%&4npHnyeQ|qa`*3KYa{8uhypj^QDkXR*Ydm3hHgIhTS1Y3_E$%kjq z;KYB;RP%QN_RKMq3>e|k4ZsMy zd%&VM^UMAjBKH*_6iWpb^D$Zj_W%&wZ4v4bAP90nf~d~|im_*c?qsS41hYLbp;vGp zDbRf&ABUfwLL7o$gZi3fC71(=VE)d-Mhjf-+Zh^krPAYK&@@N^z7#W%H1dK}LOB98 zqqsOmc7y^TC`1QuoEm@vwWVW0?~=8Yo#%q+!wbc}qPoSt?dReP`5oH9CVJ{ofV{KPE|d!mskGIR5b*vB^4& z$^Q8|W8V}KB*rq7xF6j(l`wTnSUD>e0TECGJ0K{qdpKaGgJ6kUAnWen1%R#IN|-q! zbB({?Skr&aV?2XcTre*5I&eZRAQQsn5x2?}|9}efwh%rbm{~i#T43IBHhVe7F3@@RhU>5O#j%I6>!8;pg&t!dmrdP z9Qp#s`MdIS4E5FaY5#4>ma8Q8BY+TUz}|;7wFzW(_=bD@1;8DoRD!_!u&LcgK*TZ8 z-3$BYhS0qtzN){<#QQQI~`60|uFUj=TXtSYFxQ zfmPWP0<{GC{bwWOsG|8f-F;wbKPDs}K6Vc?)4;g`+YkT}?)=Y1xQ2k(?GDN=eWlsy zb_C4gGT_J&@$6Aq-UUq%%5c~@`LNhc-9~+v=Lc(p?4kcF2fK$IJZutiPr<~q&IS$k#LD%=k z(V)w~uz1}0eunwT;Q6|Sa@Lz4pthI#XDyy)MAM-8ZS;IW^+!+@2=8&gur4`djho*4 zkAT?kdX6bovN{suP59TkfQ;NMpE7?id?uF=aIz2%sp?z9naEeo{LTCea~ELbZL?S4 zPhRwV{{N4tFOP@nd*d$@QG_CiDTzXqHN-@=lI;63B)epdXiT<{BqSlmzVEW{*(%G} z_bu7?Wo)zE-R@+~* zdcXvbV*wZxuuU`qu1Xa^{3Lf$^X)R(s@JMu5t)u!4(P6wm4l_%?0_vopfvqzK*^gK zw09@41Kbw?zpX$7ArH)#$tVy(5Cbm2ICMFH)|i{reru8>r|}_`L9coo^a~=oq8LDc zf}!4~VG?W)Zi7Dw1B}Tg*yKzq6o2CU$8jJ&G{+|-0E{G3tXN2nCY?Gszc1%T?|9NL z=xfs=<>-BVL(<8Vq?I1>CP7(3ljL`%gyrg{a|VHuOmT1sIHvA){6d?}AS^+N)bPW~ zwWxhU6=SdOGSskvaFBT(?M5yL;0AmwtIp{z#l&EMWCT2XQ-glo#W<+-&^DF2?;0xJb5w!t2D(g7&17{aeq2s7(MWe@&k5 z>X*0{VN~Q;gs_Gj2rxhRM{UTzz1msyGd!4F*9jw}BJ2~{gtL%rV#{ySVHHe(K zW$}9qg{!#PX5oh1dpa5K%9$McsSk_53gLeP6aB7qTBYQ>4sm7wPyv(a2EvzQ5@9iSEVYRFiveOrq&BESP3$F3-#R@qaU+ zA*x5yS(&@b7+Gh)(o78eQ&#ni=|0n?gg+2GYlBW>6?&p2c%{Md3mvcS5~CsXyE zO;;^fxe>Z>elfZ3^9OHlo18eHT}M;Sx2({;f0KRr+-l15!sV2LqP)xg1v3&Bn6JLs zHNnVSHzu)Gqu%praD)2x7b@>!XI+$&cy;L6_eMfo*KPjPN%-j!4N8@k->$i@6nOh7 zC=5lHx4e6v(_PqI{t#uo<(K61jJN~+_zbzV>08Jg4xW|%GFy4bSH$U>>XiKsUE5?+ zbocs>+V2aUUth25b_w<~WoTZ%l2&1M(bq9W_i#`zz4f6QS76MacUGwu%CnWHT24E( zyw{z5S6>&{@^tQ!{)-QuicVc@m)%ZwbZND=3&jR|SW?!zx>4$z{jeIE;h0yo9a{Tc z^*G;#)2w4HT*~JT^@C{kj#LJO{=Cx7It!s$_E$|F`@tQ)0gbIb;je=b6^r#hZ6E8p z?c=QKm>W9f>nwRbaj~J!NW1^}n93zN)bwzzUv1bTmUFmiG$R%i_xHZnE5TbVO!cZZ zAX}x~+1!vOzxYi4t+(e+-(mNYsR=PJlL~pCPDRa9`-Kp(uSQZnu|{oPyVKvS5Xx%& z(D4`d)(oYUjZgcX$V+B-PHPBcYg8DAEONJCjf&Bc^Au5cB-%wTcqwhEe+;N!y<$;b zG{J9wdfL+PtCI{SB=*kSXnYlEY+Qdt8sZGG+dFxg-UqL4A+rB_FTG6PZ%(o!v-qst zon$kAgtC>PPUu%OMUhC>mZh}u5LKao7A``Poh zAl!BaEN73Mb?ysIM9#70iX&JFn?&n!-T0R(pU2;zzJBbkyv9DbK_Nb)oGLl{!nEO7 zFvR~byZl7=T}9@vQ$K4&Yg>kW*LCj^c*IK(=846bg+I8J%$gph>+v#rK22<`w;Shn zLU%m+&dSTk^@QuT8rS{Pymxc&KAAJ+@L-A<&5OAcDqmGG%cX<(_A_rU9U9NZsVAtg zBe`zdajoHLnO_?Oqkqo3-HQ|ujT{L#=OTU&b$?c**R1g6uU3J#T;fl253YJUE*1~2 zk)B*;Nr{WRS`p`@ID(kt#GZWpdH6%Y#Fncp)rAY`%ysCH$6Woxtl*tT{6%X`-gW1V zVkusScZrr$WvGw$)8D^A{NS<*dxZ)wmg>72?nHmhjw*44p8@+Zl3K}pB4;pDYwdBt z10Ij0(!9W6D;fMzBC_i_EPAxV;9!RhtBs#Ihx>J|W{;LN$JgFtI3Ha~5WIIU#XBoZ z2W}MtL= zaJ6}lC;8$EX(ZMgwGXfZdvlY;x3ki5E6>kMSmSQtaVrW+PUeT&ulBWL7kG&7$=9;b z?TPwWZT491eeLx#wYZ%2TZ89ax)q6{&s_6m5#0uW8T-MyvjL0SLK_Fk{?j_e3uIz5EPHy_h?@0`p!N| zzcVqnm$s+`gNX|8^~bEAJF>kspzfl5iYU6ls|J5zXWy$H{M02kj4YVu$Ev>pjL z?X!NownYk}>W)RfC02(!N;Kg$AKmT~IJyd>gn@~tt`FT|^}*$UDg^G#R!k@kZQhdm zIti`)C>N%!Sej@WCLWhRm!77wtECD*eWrZTgUMkm?~h>UN>%|hr(mDU{3}h3J6bjp zD;jyrG$=Gb=ZAVar`kMD?Ay-@qdSqQ;|i{&`qxdE2Gmd4ars>4XEyZGN&NZpuNZjd zdrzNFp0MDO3=F*@^`6=8G4riJX2atGsmSB?A(hyOA@wl4R4Q6l2U~pK0tS^t+&tJ3 z!r#-`DO=9UZ)78utk;Gejqx2eUWqwESksUUvXiW1@CZ`m5h8HaN27icoFcRwBLZ_T zWsh6@J9CW4T*cjDd9Q8=$IN6kpaMv-r(XYrN==!cM7-Tk8Cph#&J%??M4Pdflo~6d zpaoi5oY#;?sYZ2TYy^19NC;_f>^lv)az{3*@0;0@@Ph^GlY9IkkS>+F zVIC6dWL#e!W4}ZYI#=~(GYEXD`EKKtX9czCF?)^Y4RnwJP!MG;Bz=r{VlH+vKLi}T zqEy_AON}4XLw7Fm6ld@9K%H`@zhL-4fBQb%Hz??#J5TFfasu5TcsfdswM5QKR}NB@ zOjuBG#WsF^h!U_1v!iQ*m~f1wSZ^hW4q%i6BMRV56k7f5sOD0xR6*=RLEZ}3BHI#(gpN8oKyL7hU6z+FKkyP{qT zIa>mFxO0bZ-a}R+fKkJ@4j468ez$-QAR$6B1mBml7H6(cKMj>C7lNY7z_5HkB)r-t zVc!pP0+@kHAN5%D1bDJ$-xZUASyWEWVb@;SPe|*>JZh}X+j?;x3}BP^$Q_WmTs9B; zALD-|%8e8|MKfFg!lH}L<}zm--9G(-N~8UbxnqwJG(%aZmr#GsS7NxKurn?cS6R|3 z)8S6mhOk&L?k)*d7Xip^>w~G{l82vcH+~?{K&l>T&?%c$RzuzW#`UHp`1>(|jOaa5 zY;z4{#d=WCk}7mv)ukEoClmdv!6D%h?KnE~ZVf$c9!c`RBSWimf7a!Hokhu!6XlE$ zT^~9>6^E!ugEF$awZuUuwsbt=6&Lb>TOY*rKY&{ZS@F6`=v9X~jSz$a+`&aLD_l6l zds-4}dS3JL@4nRP9U*{kwU$x09*4DSLaKP7WfYqwwnJV7*JHSe3jK71XeUp4rzL^I zMgVyWVIsSUMAjK6>HLf!8T3>C;t7DPwv~?%e3ytqApNoJnhRN72c5~Ns)#A5 zlnpJa(-!mlS&r9CRpq?)hIoy1rV8^W-UiFSSccV;zSOzvg*2X2K?55w()`Z^lda zK~ehT8PBN{8^F>%{jkb*kwpnoH3M)KhloeXL7f_DaF%$@$md|j&oF^zGmLI%DEb#s z2&GCMd3B8`zPL$fS7HeTD)zt2ZTJOzRHGFsR<1_&5`CLxG?EiJ>l028IysLr1nF1J zrkZvY^m$j47T6lMIv9X9$JOgoMF za=2S_ZVJy$%_U#0ZtTZ-N~UdfPEArI?#6SsWg z2U4svaLbRQ>0Vf1Up@uy*3Z@Amo0eTJdi32w(dcCg;Ki*x`s=k8?QV{%L zywkYdNH~VTt|IdYfg`AchkCs~TLra|hu*nl3FQLT4^c21OMpXJ5Y&Rgc(+g~cY(>e zG4w#ClWo&`3A{@2Ni&27K41oEKf{^7q!WcYO~9P^Vi_!G@^cpTD;<7g%#QmQAsj~# zLX`?4dw&40zWxf-tO=sze`Fq{X0CS9u`+0{QQ%>*;VDH$Eq}_rtHl#+YQRHGSU>s= z$)6RX{Y?;J69WrwHx$*kj=E*O-6&wydiP5Nc>Wwb;<6oyl?f~nYVcf8v%9V*BfyILKLWRL zQ&ZOx`u2lC-)g{9zSqhbaDL})5#tW&{<|vvlWi71r5w-iQ*0ANU9?oP1_A{RnZhj@zJ&hsgh=6b^F_A@r!4eSg}zDsku;Q_<4YQQv+hDk{eB63ye%Wh zp6ZoHX6S~zHhmTJy5A(bI%?cnl12=?%s`43Y&IGghNAW`)(Ifw zNl$i0%*jTsq%lWR*pmynb;-Y3hu_Z=%Ep+G8ifUg3|ew7S1+JWBey5d?aK|tR;4g8 z<*rbIpTeW1)4m5evH-nG&k)uR_QC1F8lUxz)qt0{G}+NjWk7ugvI8?`l3`~$2A*Iw zOwC~p5@nucfZT683=%6jA|RlC=gr3ez$e?n=U9V$O0!V4%Uuz`!C-h<<>F%l0_ts* zlgY;-Kup+)`b;3+cne-m17PsHDb8b9>}mBqeqpT%!*=E$c2&TiVZP1Tt;Z$U6eme8 zfHVN$aKGXC$Kif|{=bB)_#bdsfQlsv%H$i?OR4e;i`p>UrLS%W(8nkL zGmcQQai|8!R{cHe^!rc?`N<-;6&jOwc9!4I0nP213!#v9_D8?f+N})SY{ac^p!Gf| zw-U6H@fYHtvYbK&PWh6uKZ=v=ouOTvgw9`nfjgzUtQ;k>0ulH2u#47!4~J48T(^Spgie7AA% zL@J24-^0qi5$s8f-i9q|(PB|j|Mn+_+jKZMI~%sy%vMQt8cfgH9VW=;VRJM1MXedo zECkIg4dnUUh{ovE0LH(PpyhEX*Qo)tjQ(1YFf}!@A%SzTTe1ZB=t_&Xb%JM&>^66C_pNgz z%x7RC9KRqt3OcG{>n)%qTwymG^X!t{vYX3*<}zLyd??o1|Q{9 z9>d8h^pY9rH>$Y5dQtl&%sBXrx503-tZk>6?s&~RY;!jKER;`TB&n;XLCgS{uB71L z%76AEUfvf7m~p|G+n<_(B;WOHT(D#+t@BvI4a+JR0@WZ9ZTbH-=-0OHAwMbE9NbuJ z=GrTjxbJpO;f$6h(+-M>_{ehzl4K&Hi(~}g^?$L=>$^3Oo9IeFS1P2P9HH>}Htl;; zXvy|p_LU>&7~Z)CEC^rtbs2ioJy8Cj=JE%po44cHMV$K-xV_#&dtxB_N<>#TCPQUk zj07WkWaB52iz^PvWPCbVQ_RvelshleSr@o4H7($&Z z13(q}+a5#@{_$=67486k0(jgrbEjiC0I6SPU_76p)Mt-`x%*x=`xqo^Z_1p-FWhDg zfJB0(MHni%pd~s>%vsLg-qu5vHL_kuBL3a(Kx2B1mBaC}-;}o#l^bO-?Moo@r}i5n zpD?G-7xU{D_1icK^^5W5@1riK*^i6aL%D|J8AU+@fukJfjqBPfpWokHHBhg6r;6;h zSuY5|CI1lVrA|p_cw9*Z*#t#wqm05y>VU{yRkjLU@h4%jIKRAlDT(Z@4BUjSyhl1b zr0au@Km1?W`5}s4@&EC-#~T5sy7TH3bj&Qw$`aQhyAZc`^?f5bN)^34!mCY02lPQ~ zOBO5JUx4P^pFI7Q(;3O$;eVJFj*{Pe##f0k?}k7y10GtaDGM&>7>H4-x&NW?`tA67 zW|zJ$sSL-G8BRYGS;Z^mGQ2t)bp+?9qko#sNp8M72bw{v=oIg1 z_8i&ldm(!$THTfudm?B#!?^cQUx095<)-Y>B3a;}c|?#SfpP;oreerDrwv}#-CYhC zrhE-8nFG=eMH;N3*<dhX5k?#kTM@79bowTiY6*cL4}TyM^2WgaZL#@2M!b{^Kbx zXh}m6cEQ^c(7FQ68z({Od@Sk*#4qFK#k`A>6+P%mCViSaQUYpo>Z=AJw3#?KnY>v6 z`7sJ)!YDiU!I|qc0ve~lyT0-j_FpE};EMzka{F9L((A2EJY2H%V>oaq^7*GiVwP{S z1p)e|hl_I#!-xH1cXko7-Lw;s?%KdxlVklXRvn;h|Mqd6445%U#eJC`!+V^Up{sX;&wvB;0PE6Aq~^eZl&ja;rA&tZXS9Q;(84$_%rCw zx*K+m3v3*G;sB^M1E97s7J%Bd{l;z7!4ZUq8}pGcF_1Q712dDkw+Vfid-6s1PX`b9 za-HWo6{KyBkw6W&lqz9gUWfa}z2YxaukfIh1xJ(FNrO}{gkH^;x=8Bpz+Nb>Tnysf1~!1X zD3*qU*NV*DcfJJz2V)NpQJDh-^zYJarpTB=kt|gEs|vo$AYb@Wo}4e#cRmf-oa%oN z+&~H0oCF$dQSgCr!C<>EQ$LfR^?2{xO6D=#ZH0v49DO7Gh8G8ax!vt4C*c)gMAv&o zTcKrLX*&5om`mGqITF0kS#GVo=#aHsaMdaavw1Jnty}@h`VZ))0HAwl&a_pS7wy$* zb}{hL=ppJAFOfBC75;+j1vd11dZ>X`2nn-BP~h=w`v-L!=$Kcs)Y6%KbZK~=%|MTs zOR|}(hZXlwi@*-2oVj@W!$|5DT!NyJhVVZMxLJiwgf_2hP(9z-HSAvkI*I-m9t&2~ zvWS_njwc6qLy;d$ajyyJpzx&*dCwl`@g}s+wS!_I+n(uhj63RvHftzU_GxxLa5b|i z9nU`^?FN*}fCNC?eq7U7T3XfxYwG4|tH2#0DZ%>mN|-KFGcnyiN0~R& zoEDV7AYtecYoy;l1nD=6=B0XGcwE?g?uoiFe{~C5C;y|(EwR~txJ!%~AtZCm@Rl}4 z)y8w9rEh@Kg)~XjLK}E^W5>toos?|rO!(m8l|tPc(2`Y}b;xRyktbHQ2YO^qVo(&* z4yVK?{7WgM!!|&X4|p&hH zeC*MevutnArA~X;o{wae5m<3SSsf~lA|9!ar@CI;MlFI!x=p?X%Icq3xuJj9Wa95$ z1gP$GaSQ6o#>1t}BPNIi%TV3V!z#yrJYpicwN6mUB59DGh-SSn@C&g+QctXg-;HIC zGo@O*7$U4qj;M~ET%pUsni-77Uo-+eFlTF^GMNPjq%$i4&FY1FpztUyd2}Debl7ei zzWNifM`u)(73{Rs609Exl$4qciQ`-)~W5-i8Upvn>I2$tv{SR}QjCmV4iR%;V-ybcTz$def^ zcp{HM(Tn!Yqr=$0wLc+4^#N*9lhk5HA2b#ZE*ikfUA`m}B&c*3sR8RMP$6MDvl$*I z0Y=SRFIN;Yw7Y~1bVhlj5G?~KM*pKE*cdd%z?Jltckz4e>s^9G+N8_tM-Ok%JFJ=9x)Nr1(R|IK;O1?d6V zxb;)-_{%PH_10b^b}|P(8-X58iWKrs665Vj>L85&$erUwDzrxh^7FhhNqsWuiqYlN zg7Fed=6zT=C~~0*E#dVMJy6_GGQ;K#N{I!!YJg5#p*TeVX3IV6CLuO~9Te?QiAJJ` z*(P*$5tzZy!)!hdp+nSZuqLsAE#9T~Yi+2^C5ef-V~zs-D5wk+w@9LJi112-%Fb*- zjsV8m-0{9zkoU7No8j^ouy2reKs~)C`&WmiifiUDmnCGfrt(V_+>&IoVmw{EY1itgnejOZa;<_ z-^5*=3j%gv3B<@nWHGWX&>h~ABVp3olO)Tot;HoEoXK`j!v#p{^!YS?RuX!sz4%aW9wKzm92B0UG(MJJgt!M&_1%%ZL1f+GKML_&A1iPNKW=m7 zjXbIv3|8_s=t-8n#CZlcdv+y2wGAMrLq=fkK*Dzx;1@SdJ6+{fvNxC?q??9Ta=r67fE&;RuM4ZzamX)`P9x_o^o$L;X4E2|plt;1=9~ zQ53d9w{&3d>?g<;B1pzATq%5OnX<9R@H0b8`GpL*ZXrE^NA={yDv5YyCW=%Q z^Bno+lHmT-0a$TCEwEZvY_k-Q9MZmp2KKH42LxD{+#spG`?)_?Z?I_zcIahLAq$*= z-V|gQ)8p`TfSM5qU2L6JR9LQ_GK23!H(7L;GO5}4jF=46;Zk|s{x~YKw_r5031OKa0H*KYXEV0 z%pQz<8z77#e&gYJAj95RG)qM5f`FDYz{UAd0Jk#V9D}Pgs<5-T+_G2*k%73P|VWuk_;KO-_nm3Fs5z>ugI9cX2#8e&;Kt zgPOUBnz=OJ-C{Wm_=fVxS32ZkX|1}|WRL=?rMV^jF&5_Z^vLIZl?J)7`xK?gW*48s z%3WFs_+8x$*%4`=B~9Sy!bJAzB6N&~j@~arldBenM;{JR4XBJ`IRC&Nb+rPtBu*Y& zKpO^cS@{3ahW9!|rlI4fmcC}8N$~S=9ZnYs=#aUhRPH&58@I1~0r%@-FI3&uQo78x z1#x?0L1ZHX3VfINf0f6kkj;&M%43~g0$L#$EFk=Q^2rJHirXkIkY}y@3i7P)K%R9I zJOIl-h_dxY5?MR~)&gID>+hr-U;$u#b-xHK0J;6Y)`i^Qhx-{>u8_^^9$*gPfw>*( z3na`g*f+VF0%rK!JO+fbzV7f|mJ)t?4Q#IgUHsIr0OkV;;|idHea*0ytN2@(h}zecTqEdD^5r)Z9c#E;>scZ;8b0x7(Hr#Sx+hPxvE%e3ZiXvaa( z8kqGZ0{Y6c4uN?{l$>g1RNwg@N;U3upr&^hPn{hVFw5 zFB|JFo9!P%QOl6YmIWLBGcbVO8uzLG(Ms=-yN^dk=zs@UNh8OwTGum#;e381bv=>I zTU*eZ!n^3(Kw=mN07cXK`>vg}3!fFhSNP=nn{x;X#Y!9gIm)Vo_NxCWj=OKBSj-sn z9>E!{lKuZ}2gv2nu69GmPX?$xRr_aLIBDGjsA^86yIHxXe79v8`k^TD97NzofWUAN zdc8na9J2&~a#Y>6df#+lT?_zy-u4e*&eiXDv@e%%l^of2Iy2-0;*D2T&o4nwid}Vk z)wojU(s8rCE^*LaqV53oicq`VX9YCg%4^Wq>+TxP0 ze>h0-&@DT?8sNyL0ZX5Gi!(p4@1>3gg=-qk>K{LbDO?1BO=Md-&Rq9ysO(q6b!M!b z$sZ8OGNE(TfVnT?eP_ruDHho#tKvbGiU9GlY8S(>U;A=7l9S1visT}Sl-$Py`uC8t z2%|pgW*5*oAr(lE*Fm9)I1X=27sp$fy6^*r z(C9>p$H56(WpgKRLgPK<#3S=&p5l}fdbgjZGEAQFXnAD{o17@T?tT85EAyPh+tC~J zGf@eEb|Lke!(?^phm62Xs;r8^N!%>Zp@$8W9%jza0jb&ZKslJnP5*-23Gocwp__qZ ztyz-GH`$v6jkW$$?=?v7Mk%UWhRufs^dVXZMNrsDyp`aU_k-|KF8f!Ly>}akf_74d zzqYjajb@?zmV2hFFNCSwM6RTWp%B!gkmWgI z&C)$)1@;Mp)cP2n3Pu2<_%IV$_Rn~vC5@bC@ujgAfzRtg& zmR0|(fU(GS`D|dj$lo*gTO(<{CfC>N#|^VCyzQAf^ZkK4e@ZTuPS8VLss0mUKMHeo zZx^rHytHkp4$RfkD5uMH`lEGJsWeJg&PT0xZo81<)p_Hi(B=LeZ#p5$7@K6_N&iAi zhmUZX%xQe^Ef!}=%ZGfAULY&Rn_E=A&5E56OzL|W@yCr~!P)|* z9%s1rcfrNMU$cW{5qI>KAo!VEF0sz-8tXp(d3PO!?94G0Yjf}W(Jm33g-B5?ZOu_+ z#%Mo7DWovt`$O;&LyFLdHLk}p+Es&zJMAkqGNedhX`)%O7k_H)h8W8Z{GP% zDK(>`YX)bQ|tO@TAR`x#EHCZg=#*_yz-Kn4{lJ> zQG%VeJA=64Ffx&CfV!QE`06ed$GRU8)x=RBOiY;h-sZ(!;r60PD)Q4yifI4p;zy$0 zYd=g4SWn4cf9Gkg=;C2VN2hQ2qW4K8kzKK43Kety)ycvu<#B=27Y&*99 zLFR&=tTT~e_~oAtY0^JhGBfTQ4rFAXXtm0mFkCZgX4r4=g z`SwPudG<9|2i4ks)p38Tk$5?mSKfniz|?(wauvCKW*BzFhsZXf(p^#W#7MaHA@5Ae z6kW_Eq}Yq-Ox>N5DQeHPn45B&2=-o6qia)6@e1nqZejJx_QarWdSc4PDl6 zP#U-`Zz8?-P50@ou_Bie>Q~e2aLc8{NTs#96~E(Y%ZE$I1nrf&vXVX7UgU>1{ukYE z)p_r?dwf1C;d_5Cv$eh{CeM|5>ME~*|HIxW{y6W_E(pEhP>(YEI?;?@GI;|R{5G&j zbo(h(2f?$Z@Jmlpz(2tR(yn-T)Drxmj>;xdaKJ=zaR>OhJS~-^w|keo(GVIExx4S zr!%kS>?A;AjO8=-JrL$vCT}aHn;HqqKU*SI&-(EFU$OdW*fNCvYw>z1kOWEgy3a(m z9#3!(AkQm}D0)*XEc6#J9Q1R+B}WA5>p6R04m)J~e?X!34N7`VhAf{`oKRYT~n zBSCp2NC4b!!y*R{I<9pQLnSBGun=7r|9PuSa#jK$L{_bp`r=|S{`^Doz4`*1!t&i4 z{yOzRaN}+0`s2%|+6p0bl|-Qi5sDLopo?lWA8tsY=_pK%`~gf`YDGJ%Si`>Ki%FvQAr1PVMo3Iw|%;aENB(vZ?fUjK?rmNavgn$CTjd z&1XYSxYjdI5nipng?jtb`ZG|^*{PdU(uWfAL)zI!G`hS3zmXNg)q71-JO}ujRYQdr z3Or|)G%6T>Tk}szY(3d%_Y54jQqDH55dS{ICy5)hctQQrO}!bS|8Z!4aoDv?Va7}q zKU7~lvA8>2v!QA(b^NpU1*$vUeS&fHMX;5JW+U$_G~KV4jQX5^gd9#grFm66^_yZj z&@`;9-)DE92m=xATK4sD4u*{j@h{rOSFOq$`VHKk_p`5g)t7kxh%E^gcbKql%tz(E z4oHK2w;WiGGh0h>3_810XoS7CJ}_caf8pV2v>vSwLS+3;xwd0^*|*t3@f4_X6tlZW zbh}UT4W9Q)yin0&^xVQ!^7i?Ww{+JW5{@8?aj15{;h;db)x5dT&{_ZO&Pln)fr5eO z$}H9~>lAvW)T{$b-yW@eDUT66qGg|S5#LntbedfFU{smD-q`oM3c=~Emis^=s~*31 zjAC1%|Cx4Lz`5!pUx2o@_8UtviMA*B*=O+2S|<*z_2Zx2HV9@(Z-Ry3y4$a$koJ_7 zyh#pmqo`-r%XZ#$`B=ip*$iWD?b^1F*nDH1H|fMk>q}GmJOO8w4k#VEXZaZkzpc(^ z#C|%vNZoBq(ULn~K6`aNz-Z`F{hY|`;;y;y6_vZ*C@4q#_EC$PKjOBzBQ;&ac~aES zj1XS;R14noM(vxRdM&5xVK!PXuO|$6BaBW6J%wZZE|Od?o21T-E_FWr^u;qy$_PF0 z_(vMi@^KNWp6e$w6?r(){BE^5$ei86ns$sQBNvjM3X1&ey2^- znk`P`hX;0Elq7|-JdrPzC!%)VyLY%}+w`D-W0*#0>Y>i>LWN`R68YEH5+5JGyr5M& zQ?k^DRgs+g{$R`~`H4#KXYJkVRuakUyEII*q=d(Crp(5%yipz92bmj1Y%CXLuxb>w z0p?rb0q#pZg=2SXgB)H-%Wikqp-FlzGW=^0232;P=dvxp5)Plujfm&SETsdoz%$dmT8h(+}Bx24s+#=!{cy61`jI}ZmSTaV$@1C@SIsGtLx)ue?gGZ>`8qKqPF#h;lC=#_! z;;kQMbqp@3jju-ULl$bdxW(27^+rlb}PcQg=%=n%iX*ZjA2lmow ztU#l?_)C!eyZxJnzxdS~dBs|s{F?3%hz)VQDZU#uDu$_!E>8QjSHAlrjiuiV>6jeQ z5hHQBnAkT0PD90qpTc}NU0t?@`Zm+X0ayNaef*~9E0=>@WT04$Vq;BSZTYYm%(=4S1YW#CK4Cw%jA2)irLn~`07H`NO*?(7^*;-A1D{izun^AA+vSWsIxY?_x8-6F(ea((NUMq@Hr&F?I zq?PUXzgT5vks zZ0xM3Cec*kyI<#nmqqtsqstw9gLW|bTp>A`r`r>oc|qgD)Hi2N=8Pd@arlU38V$(@ zo~K&EWe76i2Z0WEO*22_p6`n(yuIZ1r`(FDW4kyL*nE+P8eexN;h4ueA_KMM6iP1@ z(f#Je{R@n*bnOu)TDAwBYJ4NKqcAU$5& zujk#c^Ulfq(fWg@x0T))WnFZ-sWL9!KTmqSeHqp0646q|nDob%L*&fX_P6#l5=Y0lP16|nfj0kZ@F;ses)yRd`WyJ1 zr_-=X^!W6i!<2eK?07SA5d5e$DJyo0IB0^ba+#=G-^?OSM4(7xstxGN(`a^VfIb&K zrxQ_~;KYFum_5+$z}-R$cTm>ibEfLID|&1ys?fL%M`T0^=U>0cf|7Qb_L3xLzAj26 zTI?Wm8s6$uW%~fJUGzCjDEuV#NdrRb?<+c z%HPO3&1l+4Nih|vdEeAC-JyN?_dsfBOXBr4_+N`Y9X7?Vb}$4|Ytf_X1xJrCT-Dze z&xiQn*)Y)s3hSiP6)p6#tKqsEv&??pHu)(59aXd#F4Nsvv?A`}V=haV zllLD*aMa!56tbI=U@`I>V;t>JErApyq`w@MsmwBq$cAA9@{SGDtqT`zBDsmLi}oFm zB-_N=01T{P<2N2We*IUZE|hWhH*Eyl-8A zM_=z>ipW$Kc3)`|9KG|Nlq>pS@YkQ3nU8;BLKl+Y-nGhWF-7@DB851EWlrXIyHnR; zsRWqY)=8G3KCzEN3$y}r&kS$qeYjySaPu-P5e4+&YHO;Oo9tON-d_d>^pM{7%(o zLC_Q%-c1^-TTm1<;C18L)(`Vnd#V~aHh*EbwCeFtX=U!h29=d$@NUXcS~x{H$IWun zVZ~?BZCcO8b1b_RxAes-pQV;oe;G6}wH5rN)|(S0Dwmh}hbkuFC(ln!LS%>Wset@y z5^OG_m{v;`-pxsk-9qNh2_AMi;F<1G+|e!#H#6IVpXls?>0h3d=Z(}{bVxis8` zz0xCq`SZOkZb33c#$wT-&?L_57v5=|ls6(QB)9tM8&$WVJ^xmt>*B$zb1wtcm@VCh zc~t=v_U^epBVlJRMJwj(Y#0NT9!Dn(q6&_ zNHvdA#kGFiTz-3TpIy;tk+5@HcBR(Tw*TDB&LgPnQ9Ra_+P1&;&#^LVJk~~CC%VC< z&b5C+GSXt<>6!S|^qhM``zQ9EJ~zlYo1?Ov1D)HUF=roK3u#`J&kSDv9j@_tM%~)kV(qIkWfNia;q+|lJSO7D`jokmr2AJ9h%H`z{%}u3 zB|z%|RDqZodU|W5l2Oz7Rb4}#{ra%yauuq&VM+bEgK~i2I%$M;m!`aBadj-B*EjEK z(bkKe-}~WQHm)M#@;Pm`flo<7mOwHN8LZ!Yz@qEBRae zmyKp3MUHV!i9*}^998;eGisvW8`x#_3bsTnW7d40%g$Xl2?lc!SNh)Y z@Tv!V4Ly7q%lmn4!s$R~O*+a*JAW(gF64?tBt0&ZC}i%QPPKvV_zWNV*EJyQKCc-| z`fw`R9gu_v)~CMyoQ6VE4pGmxiRgzPhYxcPe<+U}qC!}ARCPa^sFgZcOMYO@A)0;q zt4NY6%-2m=k29qItGK)EoOatRec2_!bx!$ow}4{Z&)U0?`VNN#3vNI0GwB7PbDX!h>FFz6#OUHmdk^4ol~#;g-fl5o$Q6 z&@L`<_NLi93yA=mQ>2)wASMOx&(t|O!oK2f{eCgKAj=}uUze8p zBhd4Q@?S;SZh>rdEK!$HXg7d)gg5s&^1c~2t?}avvY}RS;>m_rHD}x} zFI}|SP$5fo!92#kcP zgfv}DxUX`~vghD6-ETiRZ>LBKo#rjLGrRD}L==^twa70b@POCGr*!)Eh|(~Bj$gQW zll+-cxf6dBn=0h&r6?v=o~v(^SM%8;ZUt%k1nMQpb%rb1rk!~AG5K8JpgPTq5N1mX zNrVf}i3!6ONy2xjnJbN5uH`ZAQaXKqmOrj;S2CCXXK4cKKGXT7^|I4_runO%<2VEL zs8T#Q#s#0+Ci)G^mbLafK1nnBm@I0J+|>g=Z&%E7*1(103(eKX=ZkYbN%=Kps=C~~ z+CSA3O>G=;__T_(pF2_b`mh;Wldgd7;XQ5UxC*yW%06hVhtR0Oz4Cz#_J06bK&HPP zuI-d6ROD?X2&Etu<6%VG)}%K=fhdzm_$@>f-i)A#l27kxHKP7c_%OTeL4%sb9Tt}l z1(a}h7J+0iQt1b)@W)xAC*D?hrp) zIJ`joBj|R?zUGg{KQi#YPqvGH94_;-XSXGO)?j$S_{T|h@sHSIkom*$k2{p{k8dP? z*4WJA9|acw7)AcyVHE!e|6<5baMBxQ=L-UK%r1X8j(?nJAOHA@n9GO>QvBl!iMa%C zw#7fbBIa`AmOB1%m@5A91u+*FhTu)0*Ga9+j^iI$lW)gM@sH1?CeLoN#Xr8JCcS@9 z$3Lo?v_7XM=en}^M{KgSnc^QK*^nd%7bDgDY{c7w@sA7t3qONx=+mVu+xNuMg2fj+ z&T(t9Qt!3^xa40S@rXUO-o2R+Z!HBho*T-vZi7PM4nmbp)*U1U!CV-#6fTVA+=W3N zjPk*x*Xi03Ye=~#YYop4nX`}V^t#WU+qCjBuVmywWq5(*uRo$CSC_0mUQKS2%HT4R zREBSc;sP8C|C)c^VW*X+qdqCJfIX&|M>rfyhx9aYMCEHzM5!p~vpHQ2EmhD}@e9Big=3T(&TV`v+vlgEfoo`e0Zn=_QrNo$y*{B)*$Q|z2o zD%gw_%h6yB)FityqO@V098ecN#1>Fj z^E$a7Zao#00d>t{)d6+42lIeBFHnS&V-dBbntzx}G0Yl#04X1O2P&950W}K|?;>5* zgTBg#NSizqH$|sVF%v4dv7*(e=yNPujL#>}de`p8d}K}x!rY9YGWouOBk(AzMOp_eKw zh13)r;zHy{BMX)I%6wrLiiZWM+iGr?GK#s<{s-_zpl+e!8KiD626$@1BnlXc8Vw^-wrc>AvJLRB`Rr!A;>p0Sc;Zr~GYwWMOnWKh7JKK~qWK&I@D;E> z{*V0gLv|{C<|yVQ&(Cz|pC9yCkp1(1s#>S8*7{6`{`uNei}~mO+M%p<25TM2bm*VY z%M$GT^F_AXOkfz9oSc!V@XzN({O|hbHHFD4|00N%!~N^>ayXAoKg+bUi5at0>P?d; zaz9~JT)-;tGHF$W|4pmn&?QM8X3mK$(l<8;hQV-4q zUKW~Z^Uu$Ua^Rn@#DML4M8Fm>U}yW<1AF}tfHlwjm;U+NQRJUb?JN1`y)tC~{OGtX`d(s0*Mi{+Z_RoLKn)`dHsyQcBbE^pHA9{IezGf3tBbO$~ zWdKglyz-$#{#fLJ zjXz%BsH}y&EqV7thy3yCeS7}+^miM7+<-ODJXG+YD=hRh#P zdQUb#wBwJ}@2mJ@>4!@GxCN`cen>O#_lEdmb$S+7aE?I!IH?Em$MNtV^P<%s=Z~a^ z+VRJY_X_gIMfd&{e{{O@f0aKzd+;y$Vq8x~t@m{jtf2hyR*CZd<0{k4^7M{ILhygd1KE`Hkz1w>`6_->P#*cBtE8{2R@O$x zPjWogX67vAk*`ZP1o_C<3RNvUc$vHyYt>~;T5;rS8P#G(zJ{x6eT%iWV6Atwla)ul zhEXlMBVT1#+Bhx_S@Kb=e1LP@Asyu-Uvz{^ak+GOn93t(%P`n(rY0&avJ>P9?3nlo zmQ)@D+cS#TaEltmh6B#XY*<8m?*3`VhF4zaYl>n7T`h zdk6C68To~DGY>eUN2iwc_$zC$7`Ll%^THaV%P}idY!L*|VCA=H1pmFu4T4v>K`mX-sDgbXYZ;;O{H1y;k_YE6z;9l z*T~G9!c1bixI!}1z89z{_8Tj9Lh`PeWuBefOi^qyE0#`Wipik*`YFovU}cz9xhXG$ z47&=+FZ%Tj6@_bFv)O>}N(KLBGQiv*rT|rF(a`)r@fNI`d$GB>VjYw zGH65lJCG)v8MI#*v^WK{bt-5VE(0_Vgl1sSK9QigD4^|ZPtd{`w5kedJyp=+5Sk95 z{Y5N}ts@>{iRaH)UkyqfnX z^EZkY(GfQBBI$}!yl_Sgf{>a_bhHhmrLWu$1~KgJUdbe0-W>Fk-j2M2Oi1w z5$0#&J1A{tl1ZtbB*~;T&?{cBX>wymmx^W)<9pl*8Q-8VPt7orOnQc)WHO9NCQFZi zWD@l=Nhak{9v8czP|~cQolp{Xh1m1$KAb)8zldDc6F{}Xv0lrCk~KfbLdmMjG*f;@ zRJ^)Dm~yhN5R_vk4u$+g_DA0`E>p{cq?TJ!ogbi1Yphd?w_MZKa&^}7AJM9o_nMR~ z_aP{4B`EB)B+@0jlW$#E>zTcI>&G&%UU8^rz{e?{PLJp3((zf}0Mz@M&3VNE0WD`1~@6kXaIvue$2`=@JBoaS*URKCzPZG%xBT6K_;a~IA1-4+)Xw+|EKqdYEyd-q= zX0fFpaV)~$?1D&1p1_&#M&jus*#W}2{6H%IV?|hv$%zqQ(7)>w{VmUQ{3i5!Pgr^r zSSSsemPn(Yz(Q%*Hw&dfiHB+QPO-f?5P@@AdHbA zj#0RWUHnQJ!b`ug8z*1lS&4j26Xp1oDd|MMCVr?PJm@|w zzW4&FWG?@d5OAi)8z43*H}PtT#{x}93$0rnkCP{I{E@?V`Q35ZLF`Z6O_CP z>)b1#G}cdZpfo=EQ9*NCCMRLlHJs-9hy1VJ5;D6h`7nhBM2O2Duo2?WO_i1CzA&ZJvsl7yqBiaxlzSR;5aR&Tr&iVcy?g%M&Mp6xJv5_8U z1V^!vFHbATc-ubcZ4{4|KOw}`|baQ`$6iQ{kZ*Bz8|D^P38Lsr|s;wiuVlb zDBnLgZD+r=-4C+aPx=1AX`B64c|S;pPZfnsypY5DLAvcJ$VOI$D_omH&T}?W>HY`r z2cdIziNdQ+>ia<|b+!?GYZ4LtpceLbW(+wAM8Cp)+x;N#PZ6*+ojg?cgIw-p19q4J zdlhUC>=Oj`$$i`XAX^!*9-Y(-EYWKdl?+3p8vsDSut zH$m)N0OACMSfA~~LN|$$-)V&mt_P^uRf)m14?+f4l`*(^0LVOe_P@U$qcuGUX&OBi(K_{|i#_KZ3Gcg5vOgkj*El<>pe$ z<*CjHs1tBsaX*Ngtz}o%@`|CVmKQcxw%mxIRF$B7_JPfgSN z3d8ZN8M2lXe}bCt7_Vx+l&bkX1Z6FU@}c`dcATKLL!`DV9haE?Co^OnmS6=oleFnPKSOL_%Ba~e!-3?tgT60uF-BAm#dh3;GSI+>WX8wDAWZfWYj>{ z_!L>(se8=-ag|uyzMaJ4CbuLO_g7P7anIpjbMXYbDAYE`1kK0KhLZkgfBw0hqw~+l zY3>bS()s73(%hGuW;_3UoSpgEsXqVQRCWIOC<%Ob$dDr>wV?CQfW4=N&ObwHSwWT;6IxOH{o(_$@Nwb&54A>KPeRTF79I>4Zy>gscPz%mpHrY44 z^0(9M9So+~YZ`#FS1$nHf1l~-Z0JnXQ$Kt*l-Bo*Cyfk=ohuv6^WMHftY7H~>!Ujv z)(!By(`6cNV=xZ)ktUv+r_MOsyC4;Gk7)87z{}i!4bo(2r_m8b|6BkE5t%mrUU2qdAr8%<+YagYVT1F zwHN+5wbw(@-kXcm-tFetUUz8a9<|p7QopeFe!=!~esk2`qC+2OZyb@P6KtOUdPR*N zsZ5RE+-_?;mNnj=8o$xVQ*(_PPlMDD)_5yye7wWP%g}kT0uyapU!T69c4x3b9;9ej z!`jVihV2f7*3zlnE|99q+RfPt?K(MZcU6kRc5U>#Gnzh3mEAijy(-Kfh^LIim!aZ& zJX#V-2aZC;hxlK=VDT3IH!4_sga7Rw%nC&Wi*zt42>)q>|HPUSHdZ#1ev!w`LU{VC zW(M_1Pks8np{Hgk^=TTU=G_8%<5r9W;bY}JDJVFBImL_^4T^U{5J zRtvC_v=o^#AoQ~r2>R|ogkBe5{z}j*VG5zIDXP)%BV(3>a@g@Fse&Mv&HchtvmDEQ zUKlY6@-b1YPy)zN!aY#1pUXqPRxX}~=c0nu&U~5PnLV$<8 zNr*j-FLJ?%1bAIL#6)?&=*plyyXSs`$`<_3JKDn#AoK#zF`h>8GU&T7h!zh@dL5ES z1>2m$+8j!4-UHoo1+|$0sWfb}oj1YMDmMcVm97AH6}4c1)HQ73h>jLcVK40d zX`Hkub8C(h*5ASEFQNJ+q1JCy-yKp9vHlFiP;BjPNIhbO|G^0LMqISOJdlxeF9~H?wnzsy%z;OR;Mhl6M^CYYSXG}ZKzsH z+j?@2sRBc=*N66oL2R%MQz$ZkcoD&c20c{b8?VVhY0L8alSR_5Gq7?(OXx-+L&6vk zYrGn3J)!vN{gPOMin=U?9o@^22Nr(W+;1DrbF>c{B6RVG@==mK3vxUZ%Gv>6AOrb( zYSzK^T?`N7DAFhD<)bRV zI5uwS9#hG@c{l8dPg8}y_1KD`cEjL9hwb*Kb`S5Bmt+lqbA$|157GYD2v=n#D7}ID zsfSb~)|*=xA>A?J2rXp@)d|8XsJDqAEP&J$gy3D6Z@B>B4fHyC93+EDF`t+MUg#1FyAtlO4eP@;EQC9+8fCn4(P-L=(YPNA zsrDnY&G;8$ei{jDoAr~63d~OgMt`>g8oJ&X0{)6F8=S;E3Fpi&mr$_5tnu)JF3y8!N2s?U zF$#FV^D$oV0Zf@D+0w|6dWbE`>^-vFApl5Ad9wJXS@lhmB!lO3-qF&erRM13GRY|8 zHN7rwmtY@5V_|nSPYoI%gz_NABF!jF6ttWUJ}sm1z6W6D<{wVL=I?J112x3juYjiP z1M=N&hJh&5C4dGPd9NYWP;@AFt`UN}5v?UX4;HeeidElY52H(3`o$>TvXD{S{{#-{ zBwUSG(bgAN$ysBY{+L~u%Y08Sh%Kb!JoKfXnN{+TlWJZ+|ASd~xvEtbKSeKnIlw5u zs}=6<$}pt%(n#7LD2*7zOF%z&qclRvsY#O7u8Rw%W^B(x9N8sv6klqCVM7=GgVaW5 z4L_W1oWF!vcZ{Dej%$+iP7X9#qXs&17w0M_G1Vw$n=e!BUhHJ1K#o9e1B+1?f1BJT z(7iyYkd+Q!(2|0tSKXze>AQDIG<~uUqv^W%v4Fez^0qu{)@Y($GirihNaX2#sxTTp z-XVFKQ3&&f!siYu)dN!H?m)&@l+jMk2!d2;%;-!R4djf^AXN-A0w|-boKXZ)I?VW# zGF;@0H=urbVn%hknBno~QpQb4d0+;+QIg1$~jc&RMG5;m_&9>Ff1$jo%Dj>AaR~FKy5b_A!OSJPxCQTV z?dkXKkVT8T!%4L8wCbB-JJIh^;PI~^u{(hEDST{0SpEd-ryVMmy6Bk1Qm6PKOU~3ICF!kC;GFlNNUnhx{ftxt+jFcE;5J!0sCFZ!W~vat3sS#p zz(*Ha{4T`ijYt(h=|<}3W=K7Zv>aN|RiN5!P#@c_VD;q<0q1pz%=+9KNJ`Um&mDUdbg34WUS{c6sj7ZAlnY6$(*#UIP(gs?uf3cqD-&qr$b zUO^3gw&K)ABdhm{^Fj1M(|ol>nr~hFUPdOpkI?>kTMH+A3~0goXu=0WY6ni@T_QU@ z;WLRcOpy8pGx|_QFnlIchCig1VMYjLRFgAGLux5zeC~w%pw4!_r`lU-PYvBF@2T05 z(w=$@h-THc;-0!wRa%7SAr*yy?(>7DJ)_en$Txbr2z4WG<`3Qdl*^s{d`XN+CT)y1%fQs#k+b z2U!0hbpos7G=_<({uhYtJ!ATlE`A%?i}R{Tbc57I=%OWl50eP5 z0)3L(y|4@a~etPr3uCeds{DHsH=gzmof!&GDwGs;Dx zAf{7T>)vb>=q!=WNaIIW6W!bBV64t;WDuh4A?)B8-R(0L^Na}ljA=Y0$UY;IXEd_U zXwNfZ?K8e0^#6?ZHqNM7neaaY^H2ESz=E=L=(Q2a>oFsWaC`H%x+||#5CyWWb-2HQm3B#XbBuc_WbFg?dEMef?5HT|>VK^kmq=$$(VF?pY zgn-JGfRqSr6XtP`aoe9Tk&`0ByyzBLViR1*5_^4#&Gt5yOhH1w>Nxq=KK0amN0WaV zQp0b;LJ9#kC3{|G)-G z$TwAyh5Wiq$anTeZa_ERSoSHn(}0Mutw zCkjDoEOz2E56M&{8r^}9Y?57OP}^$^)%NO5wJ%qcYM+2qEY=?GPBY_*Clke|WVdK& z5QqEV3a)Ju2U7HoH56w5rqSwJSz>;Fug9&H3cD4#UFKR)bv(JUw;q%X6N>eATj1n+ zreT=GOiopH<1b=P+siP6A@vi&{Iig%Z%fyap>-tv z=e7Zb8h?Y>&j%L{h*@8w3P?)gdz>3-Qif7-RA|kWcfyRg<7zs!n(KV(9UZ_y^RYKE z{2CB`TPjHSt$@@T#IJiHjZ!^)zZU618ivh)bdYZXKErW%u$Fk^K72j}XZ;;4Eb#;= zW7-*Soy6n1`6=*qay+(qHJRExR0Z1%fR?_eHfup@2e#P`+KfL5brz(=pVY-&pvad{ zgx(jS2RzorAr%QuVyF7j%y(v!Aq;qUc6kZf9Z2m%XoEmSh#mu#jc=%O^iW&HHFCwB za>X@}I*b)R$BIpm-@j%RYuhS*HJdJcfx2Z=g;=@nmykMvb)UK74K7cW+u-mTK@%FE zjc)vG>{$xGGY9nC94-1I)+rY8u01qFzgET}@&TxG3BDFmS0&uIs5kF>m}klU&#Dcj zYWK=X)iNM;4XeE-nLdreOK_|5x%&)Iv+A9Gm(+5CRgb|cL$DSAgdYjkOi1M-taVJq zIPHqJx*Ve}E?a}1ZnY6C-<)k&MtctW=FUv{mFc&1PCb3oo zN!XXd#84ou1J_8T^+g4lw089+(z>jynzXvDQ<7HP>F@uLNh?ftDwLm3z1agPXEfwD zbK#b4(cql`G}Wq~uofxZU5TDnN+Nn%xDvg8DFcXwlq&-8WF75XLGEbv3cRDt;zkw<3``V{w3V5-?`hh&#Rv|0i( zrEZZ8m?M~VfZy4r6sYE|Lc==;hmfpc) zxVLzC#@)m~Y&~YIc*vAEpWQo=a5f>PJLv{BRL0mfV`mZHMI_Azx#t}Ajd3-I zZGCbMJBQ(=aTlW9Lj6wym3OwLbCoOJNP5PY(w>@%)Ss_P^Zq=g!NH9dX-G6UgZ{Ld zdG{hr@)q+tw~N+Pk}t)7l$PeIGNh{GTM1pq_QuP6zrMHpMBO`9sdMgDb=c%-k=y%gsTE^egVDDJ< zX)DPSkgD+)^A16O=NY;LoHZU?>ML#oNqA5b+p4j<;MLBJ}DDcbiX5N~+Q*}lr` zg!oQ63~A!WY*FuF*G+PD1Ab>#!zGoUGxbB&`kCbj^Eev5DK^XhjCoosn5Jn*Q8cz) zk!?HQKu;;t$%YB+WW#fI!<}@pp&nUGQ*rPrE2Ce1*`;>AJhZeY9d8J-2xJ1KA?m)0 z5qMTvI>cba^H+IDfX=dz(znY6DUS83&FV@wftGx&D0iNhGhm-h(ygA)D7sO&Ik#Zw z=~Xw3`k`Ar&zdc3c<5;@WD}j8m|7l0N1R}5TtwiB!sP1e*v?JWZIPHi&!tGrQ>E;W z8a)41&?HyCDP0(VcX<{v%&x7o>FR$2->6+ezoJ6|Xm0{9 z4g(4#xK}lc8!*PA%W3=I9dxx<2>cGZ27rmBB8vY8^EdsZ^Lrs6fAS)YlfSr0oAS$T zv?)84MIw`?_teaA##q!NdW=QIG~NR=N2@Vk>yL3M7S9lhhc`EQsXAhSM++1$EYthS z2KV63!R%J&gzny<{#Lw+AA<`MqV5LcaRR*0`4Kxm5Oo5HD~_Fc>rJl4@f(ga%p=c{ zCf7P&i<+GG_cl##<5t3cK^eqe2RJk9yAz~bZ@^@nP-}91mXdC8wv^0;ca-2<_|s}C zaie%O&V@Vvt!0{=@o%k7lY6~X5;vxolDY8E5+rV1{Y))xELz67uu;6jG`TsORhrzR zE!2th(schH0EwnfG=-E7JK^HN2n>7KIt-M#Tgz0++!_Ml^*sUbkO90a?x`t?0FIGn zA~alr(s?d%^)C#-)zQQQYiu}E<_h7>HVU=DZwc4s$h}y4u|k)-wU#RnY7tkKj^-4sY34EznMmA%_rDVUjP$B z0EZut^jVyzd2^$$g9&q8o&$w6~u;J@lo`*UV0f{IyG1$pma~g{Rnq)ie zh`_Tq67b8V5O_F%97n)gK&m?e_aNZ<1Kw!-ei>67@xeucTQo2TQkG5zu@%ak1EKwx zPfU%cct>ByxU`?8QlCN!2x)*&9ZM8@sq=1!d~=Ad_K69XV=h`YO0HvAznP2p{E~E> z;w|B`9a23JpDSvAb`fj^W~W_yps>%Grudy)YZ9dTV6BRRY96jaE3k2T1Dcz#K^!P| zS_VffY+5sawo$lK8)%4jl*A#b1t4Pycm+sBBJfOCDWdl@s3SO;v5Qb$>$pT^Xqdsk zj36+XI#10+w*DdYEve_ZFH496HQ7NxE#bo;FUyRew?~17C z=fonMeiqAR^s|8nss5KuVk@AZI~PgxvqdqPem*Kn^fRc4ntpa)tfrr5&F$7J)ioc$ zZW7afA@u{|xy6MjB{Z~Sv3wW`_5UJL(L0d(5sUu9WYaP~;U0Y^(MD$I0@^r6GIXI) z#I{LG{3Nh(x`g=T&qvy5WU(HHR`RWCXXm=NP|zp@(hCdat=mn;$_S~Ih?U^1A|$I9 zlJxy+CXyvKI~{+LW~T&HT8)+JIIC7?6jTZp!!!xAiE~)>sf*;z2d&=o^3+Ub`ah($ zAb?mJ3w^4h8OuVcnN3h?8}U>pRWlxho7V(yc}+ai@ilS4L$xNhcJP(j#t8!`Kpz0Vm@05En)rvmoqmI?UsdE z2hjexmf1gx(Gck3?(!IZUHoMYcSy(2M~AdVwPr@mr#18PsckaLFQCcvPZjQZdTP#5 zL)SeSEr5plv4#xT5TZAM=C?Y)v3#wVa32QvlWZ+rIfsCc%_qQxQ-zrT?iv8LR56J{ z)t`tyLgAy?Xv6xI73+{HL_o3o)P7G}`*+q*`{X~f)BS$?k+ihBo}{JSjzcZY7e34_ zyWv&5CXg~fg<3}%STsMlh+!}h2KJQ02$WNou#=ZcXRYZ+2RdcLA8`ew(kaD$!MzJg*A3L$&L;Bd}#|k}b*pDC7$G*)}lnegxBl=k3xPtoFqLLmqeXQ5dTpv4i-H|>P z@*}BD*=5xFSh=z`)#>C6Qk|M;?Nz6UA3$|Fe%-M?W|>ET=a;eRV<*bkfYxU~A9~mW z^+cdou75-y>+z$kkJbL+Bl_5|`TtEHn>J6@$A0}$(#I}bx9MZgJ1F$Ai9bsESjKhQ z1lL#5COA?A8Fiq$r)D_mWB%@_j}2$~Sdr7(>U6S*Y%}=?Gw)&|;M+=`T@srygGCvupCw@}Dq?(_+ z{=wec_ISBUM{Bu~I#H84v8IrxrXP#{htziL#5Q+1$Qr$EP3Nf;G=XY+JuQs2BjwsX zA+-~0PiG3+!a4uV+csy8(%Tk0TcM%heSG}juO0X4F~{ED)|#3nikZ)qwWETB;~$VZ zf;gtDb(>;T$*b*4RMyDNmiN6vQ!BoL#_MlS?D1HD5kb%*A(f8Mrr9*L=VMix+BLEp z35Tg>Q@LhsNS();tyP-Zn0pR2wcoy1YHB&I5)?C}G7yThx;G(-q^ao>`2;Y>+SfDz zH9%!!ni}%{cPOb#_rFqcG`5;gFOpQXQQz_I*vo&j8C}3WzF9_nysf44Pcn9GAax(H zd#~0Q)?if@Tx((1&Ts@0DMLR5-`pTM@%s;Y)uyv1hf|XeT|71YS^PJoo?(;E$z^m} z7q?L|V9IMP zmQB&+kRJUiX!iUKMFGqy4-O_P!&M#4xm*+^O~(N88Q$<4Gs-dy-|v2o(#5(tAMAYm zuY}@A55&vt?5P<@oxcvL;>aUjK~vFq>|rB5c!QELA<}sSk1tRejtp0c@RnKsjtDC5LGx#?UtG{5L zqtb#*4=WVr^l+q`iXQfJf*PJVKA`?XttnI9uf~d%1*2;te-C|0Dxw z4JiWx_?m@RS8|oRo#M*7eXfwwVb&m}5byT6C%oIopD4O*{EpwvLu;LPJK7Z;W)0#C zd6K6_-3R7oz3!NUa@@WZp>r{9dv*bT|#3-OU zK8!qK{jFNfU=)d>#VkW&82Z0xmdrf5%j@D|S{?fZTpbOeG+Q0jA@vp3>x|uY!_X|~ zCJdC>CzP({HTyE>7rCHv%*PhUQ`0+t>SNGJn_sCTA4^*n1{lC%X31m2Yq&X@FmXFfbo$<|KG^ zrNmQC=aRlH===KZTL*f|_um%ub4~oVpg(LV{g#cDZJp`(EooGD-qTfrrdZUd&ccWJ zg%LPeaV6pX3=tA@WyjZY?)X~A9ba3y<12|fzEZg3>jZav-F4vj%7~X8UyHcoYu4xF z_)1qfzW)F8f6e-!|Ld00{}umX|JOC8|116@`j%;2L47MJT%m7SM6PdrdCj5!E1vnk zirD$Tir7>mk8#ZZ^|yz;|7!-QMnkTB!2iVnS1zLPe<^@Qk7fR^0ziL3pyRH6%>NZ{ z^MB3wnE&hB|LFgUxB0)mmGrIA*A)J*5T*a?TS?y3&jk^k#2t)?sUe?clZ zsVmdBy2haYtCdRM`u*enFKNBfy+Xdq6WQM|+A!c7`FbM&amwH7pW~k$>W}v?nKvII z)e0Gcule2%QmmRhBE_nBv`w+vvVc%uq(Rh+0m5yV{U1|TVJ34KI49RZ1TT@M*z^5Pd-;x0p;~ zty1?CaVv+XOVUR;!6G*N{w-<`<=PP>E`5}?>W9R!Ny0TiVJm%pl!XuEe^4s|k^5eY zgl7cqm@u?&#>w_gDD^&1s~Lc$hG}WQ8&Bi5cBN5oqRpsx2P6JDt8Oq&U`De`DA8A# z$`mUy>fN8sMOQoV-WjUk>jtu!?8P_mLk{{90GTL2W)vcG(?g|qocV@$$m%;3RsmGq z|AtjRZkl9sZ4A|-vD#`6l|rz9s(BTHar3wGdHEU2(&@9Sf2-!@BswrhVH_DWVlIvb z$_SX833n8eQ)QYoIXnK6C&!RSlauhbRz7`3gKep7)gPVCX2^qnfobx_Y5L;_6qeuz zn;~{$u2$2Imef~}nu2|K;4Zl_OU_Ulq{HQ+EgC5SRXKHoCM%}y zGtu$XwVrA>bze-CrVh~BlOv(E0aD*1S{2<@ljt^;CNbrjauT;sl_oJ7s?Eb{cimKz zm_CIjG5D=w63;y4lekK~x#qv)lXwJJk-6PmK8d?-DJC&usx*mD^W;gK_>?BG^E(HV zX#K{~B)<5*z$E_hMyqL0L$D4~ORz8H-DncMt@;krl#?jRMJGe*S1kI9c?kDR{`Zr( zYqD|@mrYbm;(!FllQ?~{-6W2hteC{tuO+lHA+-t7>aDf_w3tkj7?7r%#O%q^ByNFf zTd`UhwNurTs(DSyRZL>3d_IXq)cTnf6&0MsHP>Mh6Xx(qTy$MAiN8#iCb4?1Jc-BO z(aBU%WUP^yewci99S9-wCOG zSiA=5@m_OtWL|JdQpxJSP%hV6Rp67w!C&MtjKwc1I{C*WE@=rNIdUfxP}57O_4v7# zj!6{4Re{W)#}tVfWHV+Ep2&rIvQ(9p@hl9f1BmBzQn&@fL|6bP|D|%)a-v!}6Q^Ln z;EVz>j0Uct1@Q})=!(E_v*|l!0OPkWC7fa*bq;ZQ>QYcuJ2yelU{s84&F-JTUG%#6 z{v`6HWp!ezS|`FM$zcGaE`B-TX#)HrRQlQ^yeJ|Xe#DDkxQ+$`dD8L^k&D=gLocLG z?10oY>_l}3ozNEOMBaG06H7F#6LT~e@0?{MRnL90@&R$Ltl6aMU4Z4DDwyO(n?dRx zHhS2ZHA>nZwA2Q)Jk<8uB#c094~YVbPUdSfl~dp%19}4s>IniuM&lV&9xX$ z`~Tf-)&3tZ?|*>u0-=;}R_}kR1|pu=t}<*RKdXLPtZW|g_0LHa#zV~xP{}_#RTu{8 zcUSR7o}8?k?Eb{xsrVK1ceZ#Hs@6hLtsbP`^J?@Ihpl~)s_S>2MzoJ0+E(CSGTM31 zK=`@F&(tY;+Zn2f?WzIBjbI&)V>CxID(5O1PavWk@6EOC*>dTFj$G99et%pjT zc+&!;KVePdmG@r8acqFA&yWY0>fC#3t8*UGWq6&|ibiWOTuUBTj_%cQOvyh-L9Yv; zYI&&2#CL$3@RSMBNdLbh;W`(?A{Bc3m9YgC{3G<6I=W{I{iY7F`h|Y8<9*+bEvWR5 z9$U~j(0459{FZFe`Q3-1&VL;~%3w7@__lY;rHb|8OM~rnpXXx7*hT|MaL0QQJ`9|2%X2vYTsw5 zS2ePfVLBf_(PmTle8(|`&t%mH#xmXz41>L577g}yuaJ(oLa$mf|Nj%MrY!88Wc&wu zT`v+9JIph?HRd;M`Sv=33%WI`bo5og-)jFm@vj{Oqh5#Sj-Pg7ynSq7ssiWxBAdtSL~%p3bjH+?Yw$G6P?@dDBBZjsP$11St@ z$cie0!`#Za}4n4=t1V9&xvhz=n+J>F!+BS`H)D4Pqbj@q^yO+)b~p?}%@_hdpz8sAWcQf)$MoeXR-r2ar) zGw5o^)P>_&mUCLb5!9&{AA#6x)Z86apv1efr$Bm3;l<6$2V zyXY32_>N>AZvmSqox0J~%)4O)J}$m6B(?(qDs_y?xx8)$2~a;g#mVtBOOx~dkydjB zC+C8ejewgWp}P-s83yjT4>{t5)ubq1q1izjU#_ot-W1hNZA-v~`UHIQBMJC&NZm)^ z30f7G{`+e|<+FS8HIb`h_#eCv&Yi-HpIQpDc;P6%NV8)qfd0>+!@furn#0GV%Q$lR zSzX;#0cVQ{rkBTKT=)-BwDrTA+t~*0W#$|Bx=JHya9YwxPMzhk0*B5jVg)KkF?u2j z+q2{itV8cvLW8*kDF>}nQ z398AQGL0s4C}DN)p@dZiq~0R1^UU0$8;K!p`Jvnq{<%qNdw%ouJ zNY%gwLJO(g_}7M`5IUlAqhK*7c*c7tbTfby`7}tk4_QDn!maO_WUn*{c{8&6lL1dH{)BH-JT1}yQ$&=SLC1c3z922f>Cixr=y3gzHqFv7h@=8khDDVvYJ z1Ea1`g{-Z%>)yWoN)`@4LGuTA5aq*S70Sz)6Vk!MiWa<6~vWP-z)d znuwKp*hOjlHB69fD9@mW(VZc&5Ppkpi=&i!lwG)1bC?o?jsR>r0&{bfVtcld(~$0V z0IKQ>eTOn}Smpsn7N9I)2@^9>UJj?XMPOXD?EF7~o{N?0qg-JM80@V}#JfQNkG@~x zb(?sFSR1kIUAkfOsHJ=xvG+qC{!tYBa9Q%~^>JoFT@G&BEIte+J|ScT(}kaOwB5Jq z;mntCx8c$f*2P_xZ(FnKb;Bg#RTsBht(WhM6llG{7UWCrcl-t4PsukwD$h@q>t@wZ z$6&`tGAl%QXnZ#9EnVDS`BsqNgjK@@a*;%a1(f!U{GbhRAKBL(2-gE7o^Ty z;j!weLLWJ!J)}-ThGi(P(?ZUw52;kF^N!gct|Bst`t?1zN|Z7LyGWJ1uW!h zLpZ4*=q53j?rSumZnKZP?dX-KCnUw4l{HSx8}IJKyz%4+S1x745C^dZ{?tSWsHNg> z4o|KY8&c4Skw2JK>W)zWc@8Sw8qD5*;rBeEU16RldHqqb4(@v-RcLift66?U9=HJb zEK4LWAJ2cq(qyf9pe?{(rw?{u82M^&L90rS!37Zy9ZZIi3pdFyQl~o_Mh?M;`Oj+X zI>n%@CHcw=Z2s$eV__e7Z!F+{_TJd0p&xp0Y{w3*?e&*-gXK^KMukwcVegH(>{OJi zI#>!-uzPRpF^g8n>{c*Zp>%o0dt-sad9*?+6eBYy8vZ$(;oYBy@#!v#}~Y+`_uv*4^J~2q@f*8UR<2O@G1Dh!G{WASt>ewb+7BxL>X#W$g1!%)1D6|Gjf3Wz-3`R9&w zrtl%Fe(NAfhSJ43)0>`Q-XY>KqZsCEIRDlZa8gVQ)-6j3YaHgQTXrZU{!p}@ZiNRa zA))LEV`8wAF(K3&MS~2AoZ8x-@xNgTqT&j_S&s(?9TbQ>2``>R@f@4|GIsL&6cVI2*Eg)}4`_y|@DKN+7(d9FQ4@ava{3XB+tdsA;4~ z^K2YoUp!7z&BX3XMMo07lwwCc-6C*+kKxM%{R+JF?ARWBv%hQ)-qz2dJ^1B-e`^o+ z?l0SeYYnj3gMS!JLp$LX?t#~!VgF5%KqjPCLdTQw9~hiAozNbPdFI?t)%M_0?>}e{ zF1Y>^4eq!BaN$Rqap6bZrNw`LHZ28l2Q7up;qu~t15GA3#VL5LUi?XY+2Z%;-Drm*$jUbX(;Voyf!^&iF7 z{|#FIm)QEhM633E2VDOZrS%_$>pu^x_UG&W23!A^X#HPOum3)5{WC~2JJ9;Si0i*1 zTmJ;8pQH8P=YO#N`~2hj&pQ2Hb^jgmdL9}^k1mN`O|Bqi|BIWkdf(+{tRK&+;y~ig z@*t}XyD`YhAU0UJTXBT4Pai3Iz;anOV|m}D=mFzdb&!=)Kgq9tgPowv`-*fJaz;pD z-lnf>DDp-U%zMC$lI|lA z_N0`ssF#2-6zH!9Ixx`(hq)oS*+(E@8179{uIh?{#9lm31WlOcaXr{&l0kB?NQ0pi zy=^~XU3&>i?WuJya+TqU51|)BE(DQ#agpwTy1;s!AZ)q7M(|5oX@f96xQAj7XnLV1 z{G?Gl8=Tm|$$YI(p4BK8p)iA!#)Kl+{V-^O^!x7fCed-ny+l zX%PorphbMY9WLUU@L_IWp1gHMZAIgI;s_rxvDf+NUE*k1ryqRI>P*%|^?H=(a|?Hq zco^^b*?{8V36nUBP3B3Q%=0*zZF&n78QMs3WTz_Yl8(BRa30nMb!j4`X5$1GXI``2 zJp?AB`RC9q*OTs`s4fQr6;j6mZNeHjmFLV~4rT{zPMf{EaUE6d8J*UH>A-$yiUQEW z+!2J;_$!Fjt8@vghmcx)k(tCN)AWtQnH-^*$u9_$;D)1$7EoADZiHBhMMn#WjrUdj z86R3s(BXdR3RTLoHU(;Ps@&!%NG+8nmmp+xr^$^-r^&4nhLhVKKFp)b5)+~;+!-g5 z>n!U|v#iLo&1XRVN9S|Wo)69Egr00Z{rG$~hhB6=!$qRkZWFS`TTVo7>j6PYHbNhO z=Kg+;z3Lpq3-P?F^2cXjnbY;doll(%?RC3wV|( zfF~PPsAK4c4W}ydJ}kdT<5@H5L*rSaN5Szd^d*hw(6);4ynoR)o;}ZEPr~6}^O({F z$Mep98qcdeJ}{pBy2;}?qPskvMSD0NPqdFg`vWf8kLSfS#Nt$%ay)BxrSaU8hU2*< zjmC3%8^H7QCm$Toye|J@JiA~Je>EIX|7@}V;{#N5a{DC=Z~QtQNKeCyo<83&bdcJH z`3O#0LT^d6rIT38BB^JyGSI?96x%6{_Wl{I<^m|CSsR`B`$p%?!#mreL7?g&sJiE3 z2F;8?s-Kms4ne6v9TSo|lf@U%e7af7LK@x7H#)EjPCUEHW^0677~x)FaGzh0;CiTy zeyIpBATW>CVXky{T`PC?meTmO4w>pHc}SrO%b!g%><`(rT6BJjt|9vN4Cr@_79pJ9m<^Q&Fx*C&`$jJaXgb0=eZa7)fwTr|IFq;n@Xm=ULUC$hE(H{Dg|P8!^_SzPM2CW}kQQ}z~@*bagw zc~u5`G+sV*5{q%{4CoXnhpS#VsnulQ zF3`U_fn+X&dhhiG05TWVlk`+tbwYJUzm6ouOzM(CT4}9Bpz(dz+IBtk+BSD z^Eth}EcyQc_hTeK)P>Zv3os#P1%!4H#r5^=mGO?n<+1{#W?vxxHnRw%7E*Hl3Ygh+aQU{m^Qze+&AoVT6yy>c?Te z8neGgL23a4c;`hU=)pCwLtp${i>Jr~|2=5Wqecb^K#{PJZ5- zPYCE9;r=%lx#pYWTFuW`GulN(bvv}j3wLvL@oUNbih&htIw;+NDaR!c+aa|aLDW@X zpF!B~Xs7IOqFiMvq*h{;eDzH}H`?*xzh(AO;@e5C849W2u;x*9r0I%wDy3y!J3>Di z__QztvnWofH>9$r;cACjVGkLe50^14n<`k2X*G0#k9aFpxDFpDv8f);_Oo&$OgR+0 zc&$`nEu>Ckm8xp&T-wR=5ag=p*F?GISCC4>norc+?_?OC2Q-$V-NQFr*>n>bKut(p zL;xF{>}R1?m~s}}8@NfT@GX?6k%0|;!<&T82>pmSKRqcq*;Yyc5U1Nh z=jLme;~A!txtpVaUB-e~8+UQ z;cc<1SLF-}_AyuPCW}6%RN?kvt>!G%O^1|$F_In(dJDwW&Tde?EpsO^t-ljBpoQNo z21TK_ZD=Q$Jun=>hRFRk^ai@zVqZvwu@)cop%&9mAnOpq4wJ;=9E1{2Q}{6VD+1KH zDC%Wxq%~n`!`@)=MblI@?#txY9d#!QfW3cgKpWXe6Q}-lz`UI8u+przZG5>~{sQAq-e* ziaoIG)&R_S0Yx#BI0i&9mqx?CM~Q47WujOo0A&8wlSHwKOcaClK&wO&$4q$1^kwr8IqV_(?&vKZ zl$}ct+0SJjs)zy)*-Psg?epQ@bO&u0!?Y(9cZMst`*Xa6)+Aj*n+^0PogP7sIuVL5 zMz(Md#Velmuh!z?I7yEr(=!sBG|CSmcc*uf@m1uj{AYSB*`TDI<#8~12q?*RljyA# zq{jmfXf?kRA?N}r>p8sGhCLztLo4JK?=FX^)D$Ijgn`oI^QiW;oQ92!E!UtKA2nF9Q=3&0qpicBKNPH6t37|A- z#?(|66;v`*J{bfMg8;~831S`isKFtY^kz{)iU&a}r3yuPaghBWRTDeVAK&SPu`=Ov zpzkqah`#{Zg$AOXH@#8(i7DW%E^#wm8QBV70L`PfK2t5#C}RP80W{x-|5^+UytWrW ze|BXtLg9EVAl=QQjIDSQg0nN5UxlFGwDf~~_GK%HUF+hix^mIxg!xEI+l!5_)X!kf zCD>_XjHQoC=?o!La!cEQ3U6gII3YGIBGo zp}H9+u_aJQr%=X(MdAAcvTvdDPV_AV2A*cjQZTR>_tk7&V2JE{G{&Dc|I&r`!>WtZ zVLt)_-CJX{_$}RnBZ?)ux22%LYd9V;!J)DZ`%(Ki_EASw*!MrmvDZl0=l)9AoA)cQ zZy6$Ce}2D=effQaeTAcH>>q{NV}Gl&4f}geTuKIM?hRlon&~CA&1yOERSW1xHgwNG zu~7?-V5f>vRoDec+4R0E9LjB3A-08Z+)0XuLrc&d$AVr`h|Rw@UL6u5EeY$@i3UlHn+kYn&9(;SvxpPbT_3<{CN;; zTdcTJd0S`bXL|Sfl6h!D{%%>9zcC6vXpdI2!->D}TL(UNr}NhtZ)MH&q~8^1o2C<_ zCDKl7IbX~4k(P?hri*KWJjj}!)rbhi?If*c8?^w+P#SzpK&tV%C*~bi=52$ISj^K= z-WvGaP7oGBY6WKGXz??VXV7bfli*_>=3S?}QOdjs_?S!Gxs|n-vOB^rTc!4b;bRC^ zT}F9dz~>ezuL^whz`PlhS6a>kupaQyje{MeMd7?mOXhoxJ5RxR`c5=V6k`_qHkZGN zcR2`z@U8T)_UYY>iW0bF_-M_+=?R>vg_1)53i&&!a5nTEK2D{hd--8jw3b;g@jOKk zC-*-zM{*ByC6oKlnkzNa4l*$4WDtC$V<&(0C_wA0!5ApZmVl27Sa!4rsu6{ZVm?rN zKtr)Q1~q5$vY*9ES0O|ruM~v$1v)TI0aLwoiNP#R^b5c_1_W+=54vU^UAzZ`-?xo8 z!s;V^6*KUMpxHyUcb()=(Ghl`qUL7U&6fPax_Li4+{CYfY@4_rqkXfQ*>-IMY1h^? zNf*&VKW`gt_s~vnCa`OWE~6Q5L{oNTp6;fr)5hU#?cp4Ld^Wcw+IDM$W^7x+blt)Z zMW{Mdsu>^5U_8*>${S|d*Kj`16p#`u9@8y59M-s%uWngNe0uaJ?9xKustGkyjEO-` z#)MYhSyO2#USjWZG~;{zOZri`LCU`cuNO)oqtXMAQ2yA95{ln0t>zEfb)Q1&lk;dI zVfQAk2^W~do>gKGjZULV?|?z=qDtA2DvXuBXO%`ds$`-{$K^^%kjlrk)zb}^e_C_K z8SpW9k7n{ts+~hSsi{>zJ5W$^f$XO2V-vpspY5Z(O+ zdQ&rb4+AL{hB<0AL~3>K4hAk&*aWHCIDYL5Y1qj>;td1Z$Qm`q|I5XvK*|q`-&BXt zUk^}SetbFrk=OS=hUD6U=ccX_62LdZ+|3VjbFDC7xGAPN^Y>;&{lT9cZlSG#a=(C_ zI79n;DFF9Ds_QDmTy4Vl zE4$`@oaEZ(mq!*--yM0O31_dT&EL0@?v8BGh!3WEr><#2b_eomCx_8Xy3%yv{Xa># zW{b&axsdvcprv!4L%h16&Sw7S3@^ChUS zk_D>vLWkp6p{df4HwvH~Ah-h|H51|Db@HM9C-Fq;8T0z4vOOEUQWs2uM$yR~yRnnC zWEd47m4GlVxo8;OyTZ<|1W?!*LYS+DFp3~pwn`9gK}tjjQ`L6i#*Nt)*2UkW@PB;& z8-B{lps&DsTk(L68()g`7dY&Bl>oWtIA?`S_H*{$OYEpGg*291n2HC_Sm;PI7My*_TFuz(@JH|IDJ-^_1>=PQ^NWjkNd zR_vWApRd3Tb4g-!ew=9Hr z>(D#Yz>ut%W4^GJ7d1*F>hK>OPGs-Kk}w_}N~erW7=MBH*EPa*7F$ZOOEnE?|7V>d zL2CMDt>zF-K{TZ9;~3*hg{i_YIinY(?qbFs$_SS;T0rVHW-O-+fA~C)pEJqcYG`a@ zLU9dcCba$;F`?c-j~c2-Y~&Xzp40^-0LCr_$=&>BkY=C<4i3( zi%(IB4)*k{1~Pj`u)`SGjs*71?^?}r0($^bIS6)yz(X7Zg!1+IL-)t(;Y0U^)Z;`U z@$B7B{>Db9dUDV%@Vv<~xUV7gH-bx-pShn!bQmu*!PuEPsX}|XbTFjyvGhth?B-?? zpBcs1(o2NsOZHXlmYMa~WRc%E#3+Wk8v|m1DxV`eixBA#RM`jPc@3iLb2OS*k4p$! zDjCI)H$HYh7C~24I#J08GK-y+j^Y#VQ4r$7^_YE&-QuWEi~pc~t5|($)OB$$NtU~e z_N@ngHj2DL?NZ!Yms~eS{7>VyTzztxs@24}nMc%S4(lcLY*3AAPwS|<3^n#(<4ps9 zyHSOH7?o*l3#f9|#r?{7Sv{QMu4u3HgG3lkGMjFz{%b#5qf4D6{d6nSPjm3HDMkxm z{?`FpXY&uKFtqZLM-1hM*J1E~D312XV}wV0Z;~B9F$BEOB_5#>?FVyK_7#ea*5j6H zl<_-d^v?C+zcNKsKC{TERvHS^%AOANLrI~vcd&R7D84Ta2-nz-lE&6rt+BOMXl$*$ zvpQS3#s<@}&5vtr&8>LAPwMKtwOY+@)YUjh#bQ?9>9I=~9 zEr^N~#uz9P9t%5h;W4W=pq)<*jg)IfK&l3Uyh2nXrmi5L0^C+d9-hmOa_JP{uT;pd z4zhLI4Zd@0W2m}YnD_{tfOOa@T=xG(6!8Dm7KpVqvS(q&+Sneu#{#wbAbXNut+oU9 zQoJ_19%#nV$l%_6j==n{mWWpzq)M|<@d~C<$=RSScmeVGT0()ddHZWo&{vz)#H}Ay zLT=p{KFqyeluhb3XJ=<; zXS-I_t^&hX0asDi^aH5f5g7I@WpHYQ27>AZYo%rGIJes8jcVErRCOrakJ&!}>V{|n z$`~}JrQx&PV)+%ZB!x}kXfjqRXs!Yjg=j99)=AEKRj}H~DfnicEP3EpgAlSoeMb>p zs(^_1Bk4og2)FY7du3J>U8#1|0~syZdsM`iD8l-X01U8CW(PJ&}%7(zW`<3I+W=fQBLZJEh1P zKZWqfo7t}DbzC`{lqNFo04N?aZ^O)h4&O7x%Q0C%SRWDp0%}IaAYuUp`Z_+Z%)70$ zHE0AZ#`$Rf6$0`+_Zw>xly!PwTdYo-qZ-Tclq5#zTYu^;r$I?JgK($*!zGgPM9xF5 zND7;$6Y=9KNm`x?8RM24eyT$K(g#HhVyr8U7+S|z6VJdbmz#Q{2*`uP?t{{qWB^2)3q|C3nDN^ZWPgC^#pagincvFO+@g6E%BUFy zlchMb)K9B`x-I;y%&RGEUQNM?1KNG)dw*)C)1dsA4;keGmkj*aPL5m)KdjZwrkdq- zv+2c1xBb|tqSB9SHZ^ydO?j2s1i!Rj3uS!pfBWO|icEwuZw-1ex1*fICYUTm5@^X2 zYhtn_r+sJ{HltRS7vhcS2ihq)teluq3oDA57u$mx%H>Xy)t^-YIFdpFaGuHSX=$@> zEJ~BBuoh*Ra!kZ!#M10qwOHZEUjXty3L`kD7=FqkVGKZim@tYGhKPh-0Qq9V_muFR zNcajM6DEXHLa<1v36M7?R4;~YYEeO*U6aa**|qM5GP`o%kE(>}Qx@~Y4X5?&1Wd38 zPD|yAY-0(t>(U~VVGz}G1fXhIPktg`?;?dwHv{wr*>q!3@>_!*9gb!pMgEt?$m;18 zgbg(j@<&t2;Q%#6lqpowvM>>k06<>}%OdV_!&CNh+DX+A5X3P5M}V3msyIR=^$p~! z4$9g_R=F*(diy@ebzkr(w^pa8KFV#^Kt#=fpCk z1DNNe!p9qEw|P!Vu0y$w;B6LAO$$OP`BdT=bj_>@6%3}T0s-oQRs9H6nG>$lal~Qt zMnV^;uv#g#&Y%y>cjfTzpQ3}kSfCWY2T&g@UabgqW9nkzVo>)_9=Q4AYTd2NO!&kr z_`YFdK^Hw$8~UsWeAOF^VWp%~q^(-sZovDc6}7KWjun;00MrjF9aNZHJ4gfG4y~8p zgaoCL{v+~+0yF^gHZ5$>Df~-I>)3iGd?v#7hYnce;`8U5SX>-Bb{z`1W4i!Q1aif; zrS9BbN~@LLg8W0M!m|L4#|n!T&L*v+K?f2Ue*)?<1!YTfaA{uv*BTOWn3nYa(b&NTy z6p6{b*yg0Jdv$4XlxDfG8lCnILvMxR{RVo8c!fnHdYc+`%=#r2lQu3yj_BHlb4AKB z&K2E%(Q<{<8a^H9q-u+Xk>6R9bHzW=#1%DvA+DGNh3%ipY3lr&3_z!towF2j0Qrw3 zdg*2OmH;;I(3j$>7mB?KWk}RTBuAc%NDjM*eUjY%roBc1WVx{IsK!RfAu%XQERisZ zkwmK8elHY4(W1ci=u(^rD^Oxee3U{@Y4+PqCJQuu?ZXmq zCv;Pn@U$c);P&XEF5zNHYTC(+G}_Ed4{DM~IRz7O$9-Tg2fp)shW)q;f4qAXxv%;> zlVP|AUTrEj&!o5GB(kceWFu}MC0Jhlj3auIR<|~OEVRyhvH|#ZT1j-{sB-CMBy}uSYRU=0cJH!pl=6OI+#lDoU0J<2S9;X zI+bjYQT}-C99^|#-{kQa>U2y_Xm?2+F$HbX2q-p!5DWmQHXv}sX^sJo6ela+q}9|K z+&)Jn#TBxTV!K8KPi|;Gln%ktRq;`Al=A54uo5&WjWJ_%abm5FHtEwGnES`b{sYix zc2F^xE}tGz>M z?c$XR#m6%H7eH}1@E;ISQ1P!z;$rR$HqW(bNcAX2%Ta=#hi(J1GuEx*>{UXmj>v@Ct2g-m0xv@YT8AIA}!8s=R>}$1yp)f*N>s4Wtb# zMJhogdpRI|wo>UCfReD%qWO^a^VFWg&>j{E2=ZBVOU6+7TT9SP}_eSAeb{zLjR;^!ffIx@Lr9kj*CH za(h(gXP~BD6UN(*3?ZHox(LeC{YjmtOui9v8by zIXQ*uxdu?K<4{lOJajAsjBB2o0)RPjDV+fozu~X!S}<+SKKSWuL4~Koi|Dp1xX<)g zw=0uGHE{st!)kW^$H|>c|`Rk)i0f%DJ1HjbGbx)m7tTT_Y=58Z9f>;A-z18s4WJQL_L&15_K>X zwg(o|N>uc3W0j5vs3KN+IJYWMZ3Vfui+R5ndD{V08S{RVTQ})9S@aThnFSXZ))V-E zN!)N8?`NPx(ySd(NM%C_Q2xaHU#6K1O%ZwH++5@G@Yl}AtJ9R6#{p`FIrCFa-}Pg- ze&uh`ioo9>n@j~30ThV^7UUAzR26?xe`YA>zXE$SKpimikMy8g*o=szzG%{%fw5I- z4$HnbN8n|*^#!%n1wpwarvCxd2QdsI3^1wrgqT`@G^mh8%-tQQbyC+t_67l3et039 z4Aa>D7ob?gQ!N)U5@(>J_KqcV7uISNzzb`;M7a$B#bdb_7`EICN@!d%wlr~FP_qv~;Mt1%O&?2n+4tXg{7xMk* zqmmhfh*NVqA0rU$>&YePsHCnRZ=?RCWNkinQo=$kR}|G31?V@dzL$@lBZlSU;$3ZQ zPpU2M32fH!Q3V)^2HpJ3)BWgFV$3`%`E2EW8jfB7fQYu~GhlmkH7}NH?HwL;+MKW) zjRHZILizC$>Kp@~P*Hg`#{F1NJt>a7Y%3WK^&&-bh__YVfz}1*Mdd`{3bVoXLBBlw zSutzwY#JFJ{UIv2@m!QpY+DloMgZ9;hxCel3gAJeX#g;|SiWKE2lVoi#(>C)f&>DX## zPudzyal=~9d|K8rCrtVeM==-KQOrgAmb|nvVm(yfL*LtD{Aj!TZGRIBi$y!)8BR;t zeDq|^)F&>c=14zgTo0FDk>O_AOA2`>HfL4!ZTT}+zt(o}U~6rAb_N0)(%A$}1n4$0 z=J*_XqsDbJGiumJ=faVU!@y@D@S8PRx`IZRNuN9-l6~jR^Ct3>EyWQshaRFUhV{)T zkSd8YzYC+;0%2pPjeCQiAK+>t74cu?E7WnDTK^=(- zp6dV=Ks=Y&`{bvGpv(6`n$oY#pQV_OOCsbCkM4MH9!54VF&`HQGCMrlJOIQ@0GPq#} zIgkFps+*@?=I9QrmhuCurS?X?>H#o2$<~ZN(PruQ9Tz%BvE!YV&Av?L9P!Yt%U5#g zM9QSWZn^fZucBR;6PT?`3dyA$FxTrP4w!p+v*WNixi!aO<@7c7rGo93a*0TLmI9o( z+b#mJQ7*>I5kbR28h%UCP>uhjC%r-+y)@jxr6IecG7)y>^9YIsC=w^m5D&dHJZa+6 za8M2*4QrW5bR7FdNW-MriZnFO)<};^CX^n6=C{lZ*WCKn^KU-T5_hSZ!%swO0$=*+^^SL%azcBdx0x5Q4LUGkn{zt3>}eFytJXEy&|_WMTH->0(Q&91-4c;f=% zJ7O{!xX*m@K?C=bacJPahn6yLvZIW7;P4`M*~sDg^KXXri7VD3)Iz+cuX?|WT;-@|@)y8ga~{a(oR_v!5SlCHlGW53UH{k+27=&dPwK_@ck z;8?s^M_zX4sUos~my4+Q1@G>8IV1zcDGpYuv&wZwj>6-=9P~6+t*aQjAwEKm^TUU2 z$S2E5|YBA8onq&XrJ-e`Ga(i!~QIVxX(jHpw>HWQd}JrhiAXcyyo&mzH#!$NUm` zDlQvMlk4yIJ}|3hz=wUyp)6;u6m+DFr=aS1{f`DfH(Xu)Bk=4Y4L5(m7n#lteah?F zX4KWSmWbW&_)Y8Y7|R3F1z6?hk@C}8XCi{6YB|s(wXfD;fPc$LhAJQ>NGf5}n5x2& zgLg}4szPR|j`ut3(-oVuc?|7?$Zb;4_A%p z?{@VrmqXYF5MfS2*o7f{2$Ff{I7H}V>-usp5%#yP685($h5JPZ2G@wc3%$^fS&8_Y z=z+#g_6V%qYIYm+qMw&U*OmNsCLcC%I#@V6RYZqj9*uWv9sCxpY|_(hD}yCnD@zr` zR(55r#Pw(A3T$Oz*2-O;qLsCjR#y6KEC2RH)YQZwc@z%~e}mihC3&*;wb{9e+Sip; zIGgMi(x~wiCHu_?jKz{Uf&v(u6K3(|n-izdc;frFp2W~6N8tK!5dJ!%H60Y_sqdfy zp4tv7(art+KO-%v_z;h;mj!#L8}*LweOP{W{(BhX^K~9U^mQCT^Jv2xAA>#SU=|N8 z8ce|xa2iqcZ7W6-)dbkNdx@ClZN_-CyfdKaVs9>D89&uv6=5;@J0+I zn$+`Bg!~*zq=(2at+I{uw+H0%fNw-&*r9wZcoF0GP63!#ge)S5>WVZg^Y-!7Mc^*5*I)#6Xp}-^k9K&lYLuFGZ{k6 ziw{7RMScQp%N&sk0(Nh_k0IQ7fQeJc&F-Nj`)>aUHL=LUAb6veq2Tqc<3WmDt9T!# z(v5K%4Lds?CdPbARuAd+7!1tVj#R8~hno!TsD-{qU;6-8guxH?zWb36&=~-q<{08n zSMM&^J>EN=5y@RJ{C#I=^MDHB^3dwx@~HaCOSE0w#+#+J*Gd6?Sir_8{4X}JZ>_7? z>X=$i5#gs-U@-7X1Vy66i0qcMA83rUyxq)0q5w(t)evhlhnWn`nEngUUKHSWM02(*;}O0_Ab zRnQ9H=~9S8G|>Hh#7N9>)*zAX6wR^={pcQR&Hw93QT zU1r$0ezK~u2XbIm3dLvN@1xvh?)N^6y)dQMhOc}y8lcOWf+0O3>x6WE6uKIGEocb= z=ql2ZQ~$i=VkoR>_;mPG+q>>Nx9y$pG-}%Gh=qL-vwr~e6zk|uhH52-{ZF0UVrffQ zM8xyjjPBw@_dJ0!383eQ^J^a+-S<9VX=xk$#}|Q`$|3-rI#etIH#D8PnaW@^M*ARd zWeq6sj(4hl4M=2&d8f`Z6LI55B607AD#Sek$m0;6?Ro1KKPy#)kL}*q-wTHxHX0*_EOuO|;`TS=BFgy{^%>+!^w4C*2K(MtwrSh${QWUV*_d64io zLm)e|{{d7D2_FtU08AKUNx+$i0f;J5Zya%28bS+ji8Og@=hDlzZn>f{@}m#{GXQ-! zRWt#hV5}$)y{PHiHBR)$nK<4bK4W!0hVRDk{uta1`y)cG)3+NPKt5r?Z9G$S2$gOqkun$(qyaG^DBy%j;X<01IQczQjCPIW$O|>zKKIkw1VQ;niJ9R10%d{I3MA)Lv&Bj{yKz@aEErB<6E`U zaQyPOjCxu6VyGD5F2m^w+O9)1Ptd{$hrL%u_%-ABMketBEfAao$c!L@-$a`X!;s)a zNfT<}%lBFjic8T-?jr!jW9~utRwP+QEuG$L#pfR)?-GDUVqWs0OzH?NxTzb(2_oxI zfW~3gLd??Ky$!cCL$AwkjNH=PM&xe>&;-o?fMPrB=Th*EqltGx|Nz$Nb9JQ)52-D-(9H`nmO2K;dRvEU(?BU=~w6`bF}WVWJ{6FT*s;V#5e>I7XGHV<`Sv`LUY# zXTV(#-Y8@`*~>6Daw_4^Xkyj#p@|g`OYfiks8Bl%pruIdNKfs8S~%40Wc7Tbo2+-d z3Fon)h_kuCSs$R~i1U+&Zb6;%iWbx#UaEHnayJnw@r5ShN)%*{ln<~- zA@-IpvS{l_v9x_XxPa6ztJN5K5SwO@e*;a1O-M=$554?@Onk0X)3?dY+Jx(mO&T&# zX;UwN{z60)T9{_e>Nh(12N}L*@(-XC%zB+Pc}v+=>da~LN|`x@M1CKD_F?`FI!*9G z2e(5o?zNcO1#Qyl0VYFh!m=NrqleH+3uTLhV_6$jdE+Hj37J<7P^$a|pyQaiv8Ll* zy)d$gdjYqwO*};m!$f8g?g51^9zv+|0M;$gUFkWfyABU#vQ8T-V)YASHlyP#`c1D~ zj-lTkn-eH-J?>Y{iSyZoXc&J;%#f7?zLEXvg-)Yv^g_3oRmD&FiDNVw#|pjTYeH_D zv=nrZ7uf8wDF5Ty3E6u4RhA;9n%ks!$o7gFIs~9^SVOZUYG`^4xg2-xPg~#T8E8U^ zfDe20HrV)J1Qw?;FkF6ww|1+eL8(6OiDPgt*Oy=MbqVV*_PLSX%?!?V*|yhnYzRjG zwT5(c^F~$1)#onvX$PwICEPN-#&=IB4vTDQ0$dn^uK#Y|KLH+Lb|tZB4DV+$)MNI4 zfEu8F{DX&9MC@_TpEqBKS<#T)4VQKssq0opxrnGY}K^CZ>xbrrQDK9qqOLAA}G)>xo7|k79luFU1^gY?FKeWdnBp)5m1^ z-bU;;)r+bhJc!sWvk$S`$_L19*Wtr%*a{8ur_Cb|aV z>)mNCrkRXgAG5~;v3g@DUX%bzB;FW1#+Qpv$H!m#o}yRtfTtc}BoOj%ZR(A0Dae-M zA-GVnU?x@y$;-F}e_Q9mHS1xha1S39Ar$l1y-kL))Gc;^-W&u5^di5sRv5#nHI8l2 zk=SZZOW7wV;Nk-DEyDU3_9A%>4@A=QIi|!{QUby_iiXS0=`}(M;F2R;9!9Sb)|rT% zf*UcXW$81vjux{?v77=}k!(^=_;`mzOr)LX3HzR^=nr^Esm=anDSAFH=Qs3xUO+mb z!4*#0?ZNneAn`xoxl9jx<^`yCIvG%Yy5VE6|9cuZ6YaW=Vwz)%?wL4V?500au5p}i zmWiUHPCK%69H%IX7^l?oKG^Nl41Fr5W~ONv_N_2Qr~-IlgI*<H^^y$Et;E z9IFSKI94ZBuYtD|QE(b(&qeHi?P1!zM@EcHNw*JKdvn{@=_Jl9p zvfc5=3fq|ziqIBJq2`c%{=+O0Dfzm7YuB4t(@4?~?Ta}0Le~NVWW)C>qBKP2lhmgwPEqene5el1S^f31y$XHT?H`t9Iq^{n z^VI43AbtxW51RV$`HkdO9!|^iM=Cxqqd^cFn%vwI>U3K2K2*s`)jyunijwHj4p~$< zS|1Lt60Z>BVbUWh6Eq$5g_oNOmu09FJ=VwMxt<|fSVUB~P9OH?pA1&v1Ory+<+S)| zT1eNvT`T+|L#61dexEQfL$q-HQl-LQ^!_1M%EO`qCB9Yy(3lg_=_#PCJPz0id;Q-4 z0l6=mVZIWRgF^cUNp;|AyFaF1;^`}u^xt`U{ZM(oe9_*v1c~FI9dpCsrn+LD&zmgZ@+8 zr3rECHBB%mBt8~RXun?5g!G3z{gKiH`C@PLptCQ`_s`fJ#i<=1LZ}^MF7vF>D+ zSX(~*fNep$UIw+LKR`aWs4YD&LR$)I+cNl_N~=w323af93Qz~2jkp4|BW6=FlolBZ z0JH%!)Y4_}5E)){GZ}uz4CpKdIskmK2N|y0q>J#en--3b883*)!`kE>@bNECKIf@L zzoMIhehxsZ5dB}e3=>3#p#ZJG46}6^qC|#o09u9_2J133fuAcAzlMr4QvXfS4&uFKFxWM~CYG-miwmmvs#u0R>80`xs*h|pyyA~NI#s5@q; ztjqAWi;}?sP*==g(q*^=KbL3rFMwKOh73yBD-t#X)HIEIBEZBT)1CUnWqe+i4;lt`I|K!PS5)7iU5?b?3eE*8Vs=%546B$A~eUW^=OV2zQE@g z#cGzN%~>?Z7JQF$tN>7yNh6yBpkOw~Zk~lXw#5ch`Z~R_Ym+iM1Iw|Yv`OimnUaNe z6o#wS_oi$S4lCWwzRfNOzq!Vj@}zuDC6qLVz}jHod$Id>Ko%{f-_`hs@SF0G2efsU zKeaV5lG-B;pHQoS}OR z7i^C*JDCjCX+YBfdO{r`^<((I=|S70lbvXL^v4z49_@h-`>i#A7_>(_?!&G0mLSI4 z>WCZdC>%4|jK{lbLC7#36VYkPfbU|s`hW3~q+__GExOJ2@e>Zo6uw6~Ziq~VXh0R?FmbDe^3vgJ=J57ln5v!JhOVQELLus^%5>Y4R( zu$8ejdpbx<;q!DsA;#SwTK{t%xo>Z)+RI4_|9p(bj1LCdGW`V=nG;deMF4>za%(?% z-=y^9#>l2|gITQ6GZW2+B{?D2ti&v0` zNK(R>Bcp{Ug}(M@bg_>B`{c)JXT0&!ZN~E7G#VIpt76f41KGRrI_Q}Y8aj3rHVr*T zgBlmUZDcnG8_&35KeehKYqhgqRaHeQ-MYb6F?Q z8KT!!mBK(T-F<+N8t&tNrK{|A*^}??4%s^cS1Vn$O0Tq6zyMJ|uD@o<7LWR52oC4B zKF{2w**X=U4%GC^`|G+xmq*u`Ei49_U<(aIuR24<{r7lfPZ0X6dqQvBR44CKWdhRl z-JAZI>AOkadC}K#3OaEH$Ma`BS-+jNSGl70TMvD|`M4+No0}>xH89Y$p<$1GESeKA73USs(U5@LLW_tpLygOueh7 z`ioQ(K&hCTW+ofxH%h`Yfc9d-T1vPt5-tJsFD6WSu$%K_Se zsa@67St4~3Kr1k{2_cOa3HcRFl+XsC;h11l@rA%|CQ7XZP`(3@`XrA? zEhADb0GToMw3;f3)T}lpgDN&ARZ|bcZ$6Z|3m^lg4p&ou7paQ@ z`iL}tr=$W~*rcCChS31M#|-uJ;OAhG&=a7ym{5=sI>M(nCA0+SF(!QUrTvdcr~#0J zhMf}1!KW7`_yaTm6OK}XuSjsVHW~V1!WLg0dv?Cew62a34dVS^i6dX9;$2(ws9fkP zhf(NYZowp3(!}k=YH^jH)RX-ZK3a}?UlmqW3D7x8P^2iJ`tQr^SPG^mpOHUb!mM5Jy}8%) zUcw3oJ9pvrPx=P{a#pU*d{rnxbK3=acvds+%Git!yi>!ly*cy1>{2@E2vI3=-+ndN;+CWLq)qzJO2L>3 zP#eU!BbV;@w&g{1p1T`c7LcszY$A2eiqUwO`z2Gae4Uokkk278qA5DNZ1uBFddp74 z%d*<@w8u`L3N`srog)E?#yS&o;TCYpW!>@c(+nzfxg8d2D++}H6oZ9Y=R(_|(V)Ee z?6fq$p!LNF5JmCGy$uvLuVlr zyKMUfIxYy3y1_Ouwx{wC1sczL1;#inPtGX|6?Q{mfh!k4QxKQU^{gOrDxMQmwMma6 zl*~5(O2W(w=(r$9g!~#KDWfZ>HL2@V-0@x3bY&UZkzS4aQhoH|P7cz1eSq3H3w!j! zn2x%m^8gX*2>414#g{MCU-IB&I7=(+NWOLGi;UJ+w{_Tl&d8px&w_2xc-Jl9{Bz8P zniMzQe*TcEeZ12ft%sarOSY93F5-IW8E9v6CWyMdmgqG^M+! z$1f;jX-@DUPofldE#GO`a#qzc4(VSUe?mz|?O*()SYAiz4c;dxL)WRuUrQ;5Yy0u^ zh?f1>8MR?W#0!hrHd)DM*^xp#yY`r;@@K=(|9oC;!D3S1qzY$gvjC$`yDSidH6r9e zw9Bes#lt<2GqlTks@Y`~J~ie5%{rlOvo6_- z-B#O&t}UP4X8nGKZL>T)h}j}8sN1aOZns%|VVi})^4@5-Sq7JF)>F+ktJP<=S&X=G z9&WZ-1sPFzLjbo~^{{W*3!m&#X&KM#d#%1!`82YP)6g<0^p@CY;YR>2B}LNJ9-%9v zWExS~e#L2>qsGst8E>7PqVQHfy~;Y|G+Sa~6bAe91A9j{9{p$nKg%fnHT?Y0z_uNI zQPXd5im!E$u-c%jD+kp@j|by*h>Mj_n*bI0&ogvr+(kq8)l-b+#b#*jdsK|uSxp8D z(|-YabpYMaM+a8V_-Ldv0Fhb&ppPQ;CZ+nrZv~nD3s9MZN@^<28!71y3Em;CQ1Cu# zq2#>*P=Lt0o#pMy@;0ZuDI)I{fJ%tGGRs?om1RGBOUeEZWv>O9@=^A(0PQ}2t6JQ6R^%ORz51_dn9Pt}NaBisp$;`WEObOq5yy8h~ujmbK|v zy3(dCUy=PcOleaIfL4n(Wx;RsSP}dm+F*2GlsTc4hi;Sn-2JwG)JdUIp(5W!)YtSY zbhXQ}N&keJ3`MER-vOE+SUW+Fe`ig%_=}ztx(aIPA8so6Z@0wubP>o~0W?Vacn{5+V77><$0*g05i2}|%5_GdGm9bpPpwwIqS@q}z| zEA6F(>>A%%UZ8Kb`_D&=bpKe6^v1{0Tg0%((b0?3I^h87^`Ee)c|cry2VD$Rkf> zDff{(TqA}HhLvQ8-~Ru_edOjyNwT!Dt?oYZ%n)%O`Fe_SANgfF^*-_!A>uxAmqX;C za{VgRoCcD6N74NTejmABu*raC_9Urlu(*#r`;cxjPdY^W=@(4=**FFH)7b?0v-Gt8 z_C9jTJ=gol<@9wGB4Ty-kt5`5A>UdjJW63_lZglU`4W3Iik@6~9T6lYA4b#o3B0Nq zBBzBX4Yh~kMMv1BgvhT$Efs?SFwwpVQIk34k`H!r=CUjc8n$ z(~|e7QHj5U#hS8Wm8sZjQEVPS+pt(o+`l%cj?V_e%zT+8rHs*1t4orsBeU$Yg65Der>O6 zxE$>lPS^G#KpbGV$4D*m^H%tPnC2 zpmRvbF}yaVo(exYhzf-2p?vM2w(Wz;xNZ9bo38DLE;0Gv4BK8ADtbv(76&LDtK31B z3F$jTjSa5_?e#}z)k@F{ksChyqCcOWiqt`&&pOn!Un zw?+y9ivY?*0xsp$wfW5fqjLQA7>dSz2f!ToEw;6=WE`cdvrbFd1EQs7oAebRe1!<_ zNG|q^2#^>*E9s&adYyc{Ft`#2W@@J|J_TRhVY*Z`^lpN9ew`lagWc#%bD zk2uJT7g|q8qRml84;f|4_WgM7wT}f72c%h0r#WE)i2@)Yc)z;! zzNB|9J5EV-jT~BGm4C(NI)NKOE_|W_16UYOw%f)Ob^_9lNB6`tn2_XlfgbiNdq{De zS_8 zum&dey5vvCon)#wN$(1U-UzTSJ*jrVZ4aFZt4gYF7yi;L@_4(a0!}EQr-Jya9vpdvByF=<;_2BP?-tI6xh1ngdGq2X} zMKFG7gMI8=?oZ)|MQdWOa$OKR_CN!f$&bq7`DwGKy6ETfBech?6 zkZ>NLG1Pu4bVMZV251N-ykS0IB4H&!Z871R2M-E3W)E#^hSk*tvYGq(gTw@=e5ceIg--%?~jE@70{0h$a9aqYB3rW!>!`J}yK z)Bfjh3MU`rwB+8a^D_H!j}Sw!!z;9hc6e_BbvwLLxWg-LlTO!Rv=Ct_@R1*z_?GMd z_fo~~ui6~oQZT0lam8{41z5G%^D6Uew`Lmf^=apA+&$Hd!SAA>XCi1 zxDH!sJ87qey^bwSfn4&lKrW0U#|BWgaCwkFE=a+oly=|4_z>_zDQzT|gSoWvuXY=i zNG`Z5h#jkJHrbTahe$Z^_j>D*^vpA zhbBpK4GcCk0sh7nWc#vzh|`DGz}Q0lY7oDd2K@HKF%;sZG7b!mNd#!dI5*GRe}BfF zo`>$^i{0{nkYQ}(d#Qb%dn#w^@x=D{2CCpDtv_VDKtFmFlv_Ql_-;=v69ol={bhWZ z{D>IBDnGQcur74ldMmotpk5s&zoc8&`y1-+^lybvM>oKAG&j2)UVL9}&7J<^|8P$M zsdFuH>pH3_-RU3EP;;lhsM9i-bBq)&zhsyC`y62>4itz6Bm5`B@;6v+IDlt(MHN2SYB0JXKiC=#kDD_O3+x?Zk=Msch|S$ z#WEIbyU`nb2HI(JlxQiB{^ZX;^735`)Axpujrll+(ADlPe%Z#llkRL5eR z#Dq0W-`TF}S*5lKJ*)X3(z6CREvx?4okmK3(^8B(aT({SJeox;t54#Z{KH+1%xAVT z2hs}JOwv2H;wT+pceO*h?6*mEt1t$H7TTn;@bNN*I^a(mb-=uu*)8Kkw`R9tci&24 z_)%pNz!`s_!f~}SzE1}FV@6Y_#)CZL=)3IiE7PTLdS974mUm$H!+poXw1CxEei$l$ z43+QUm0gmasB@Fl98*yj>t+yqI(kCES9zG!tn(<3CRW9~t&DSJscbbNHCNQ7SU0sQ zYGU1h)C}6jrKVNB&Vp6cI7quW+!sZm=x)soH_s}W3}>0{4^V&LfQ&!MhH;i6B39aJ zRG<4fDDrLxXdvdb=&uy!|BJcBq`=SUx;5Z0qY@}-Dik?Kg+~GukA=giBFhrm`n?ev zdA2$Gc&paIrwJ54Pl##&lz@mnFvib3C}fLxxDWFGG`ykO_w+W_hj+#Tt_y# zy}TK;g~=|Iyk8$A_NreUCGVDs3NfnynvKMi)L%_BY!P;^S6k3=2Y^MJ0qBI%g}vGA zwA9?JZDJRJwG}|~5$hjbOb|z~M+njMU)Cno5*f<^v=B2+@-nao58p#qL_lw-qZ7B8 zPIXWMpj$+(1fl{^{0bq; z0gxvy(Wlv(R|I>5BKi0Ml)>yfY?j|FXENNNLZ<<$h=mrhWRJ1<1YuTw6D!*IF+jL9 zOOFaEKix)1_MKD+mHvxP%kw|Qeg@}G{(aPKAF5!t4FmM)R8e1m8em0t4C2k0H=DJp zNlQUgBY>J=-UXzO#FOocUW@sNak2f;*fV;QsI?(GvytYfQq2>o<_~2RY?%Okm4a79 z(+tdZYWW&S&Y<0(X8uz%d=G5q%Ak+^**}WkOI!<^^gE!rP6!tR^etP5%CRcVRZLnD z`E&!@2Y*L=*OvJ18vN$4YBC+gOdz$dZqL#_Jh62Ho(q2|Dyt4qXI9xiDOA~t%5-0= zWLa9wLf7D8mIprUH3nxnUH9ofY(RP75-p`QReg}g^}`>WOQh$2uywgLuG$@$UV^bL zy0gQw{hIq#xE}i9Zo!}8Z_@s@HHH{9cSwmut^fH8^SDrq#)4O+i5)3cXrOjqTAY4w z8o>Nb}C2lRnPE8#mQmU16`FlYeVarW3Cwx>*T(M3EbYKYSdnACg? zcs@FQj!*)O7G>MgUaPYQ7_HvUTM00F!rt~TzAbHtla<2kAfYUvuI$@r1D%B4s{=)B zp@DeW&H(#OOI>dR$0-$tDgbNEKp)ByAk1YQe}}DQT|nz-je8Ua=%G%}*m%Ht{|~}C zqYfhk4_EisQ8CV2MHth|xMIwK7+dTmwwbtx*k(XQoEG;=n+!V*7=QL^X$(V(FmO>h zKxBV5i1wsKXi#W8LeU|ZM(3>k#cOtvB#LXSc(D((y?Ee})*6dPa0exH4#v%qEnB^C z1l+~Td53LN;^olJlS`1({}RDFQP4}Zfy^CD{{<+04?0SD@O=;2eqVUG-2^Q9L&%5P zJcP~&hWC5Id##j$_XI$<_n>^(!c=HBxayKo>Nh%~e!l*{h++A7J(i*9ZNL4kgw1Ka z)@=;S)b(T{i|YZEoF`L@w5L4MSYOas37}_t4A~Uh$?Hk6&0mUS!KoD}3q0Y&UiL>8 zN;p=DA`COR`+iNy2qG}eHAnXNNR>ai=);OVp*>Cej(C{C0?JxLK^4JBNf^|oS73el zBOmn$`8EvH$Q+ClAV&q&+BGmRM#~iUeq&708ni{U%~V&IV)riUnAPPd{!4(#uz@-z zFF+p16u#tDEJd#4XQ4GCK{>>&M@4=X8jhaMTIH}MW@XA@&aKK(=!Vs#9J=mVN~}ZK z_=*QaTU63yFk_{aCH?v5TJ`)B3dDB6^H2CKwiQKyImq+sC;xq;j4Bi5+LQA71Ny)Lg2XP$Vr zsGNDClNc=QSb#msmF>*)t%vKG=l$jE%oD8(c;?C0&UmU|D>sPsLcb3RJ2T#pJ?spl zGXm`}#I!NG)M{(EhZw0GmM3q0T<);8L^1P~ddS+yQ*+2l#vVLmjgaf%AuC!I*cq!i zu^&4IhxLCo=pdbmBc85R4Hg%vt#mUnb(MPlwN`)BHhnca|B7KU@WFE*JpWqD&cC{Q z=)~9et93VqbLDa?F9)twk7PZW0(p29{)G7V!g9-_#ynci?#vZiqtd)hFE5|1Vu}P1 zcY&_YU=$LkWx*PWjiiOI30O#Ir^D|6yvWo~u^ zOc^ss_5Qe8-8MB?CALl7y3n?%nbWd+rS9aV_)4A2WZDYaoviiI?oQb0ISBHM<+144qZ zwpT!Ve03Bv^?9T?jMEP*X*RdVTg$UI=lF6`!C}$u7^3q~{Qs$6N3Hstex3GAqhEWh z_^f`t=B*~*<>miDzuvvTjeZ@j(XU^u<@)vMf8FWV*OrqeoLEV(U;kZ6)rR{mAZ_@J zzpFOe zjghIvOw8LdLVid_Nke{J0NrQ#_)(7Gg%3N*$$IXi9_4s0V=IF!%`7a8l0O!s0J_`q zX#(gLg??Esj&eS+qnt&X*dhk?N71VTN-SN+W;XweVYjs^Xfmv#c^3>&apZva%r9v4 z67mcBU&iAfwuJBAPuOeyrWpJ#FXVwq^}2J*B`gjmi#>eIqEN60pvp)=GySFdB1@Dg zbfCLfuF(u}XUZ(SOlJ@AV(olX6x-PwaIdCXIs#N5Yss&uRzcE^CHxep`(k#AbJVIR zjjtAIjfW)#n!EsgiD)*7Qyk$rhd0LJD%zxH1(e)(01C$36Fn3QVz``1wqn(N&X;

        6&y*MJ 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

        l{PithDa{q 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
        {stats_tab}
        ' self._send_msg(message, parse_mode=ParseMode.HTML) except RPCException as e: diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index a1e6d9f26..6c91db86a 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -203,16 +203,18 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee, # Try valid data update.message.text = '/daily 2' days = rpc._rpc_daily_profit(7, stake_currency, fiat_display_currency) - assert len(days) == 7 - for day in days: + assert len(days['data']) == 7 + assert days['stake_currency'] == default_conf['stake_currency'] + assert days['fiat_display_currency'] == default_conf['fiat_display_currency'] + for day in days['data']: # [datetime.date(2018, 1, 11), '0.00000000 BTC', '0.000 USD'] - assert (day[1] == '0.00000000 BTC' or - day[1] == '0.00006217 BTC') + assert (day['abs_profit'] == '0.00000000' or + day['abs_profit'] == '0.00006217') - assert (day[2] == '0.000 USD' or - day[2] == '0.767 USD') + assert (day['fiat_value'] == '0.000' or + day['fiat_value'] == '0.767') # ensure first day is current date - assert str(days[0][0]) == str(datetime.utcnow().date()) + assert str(days['data'][0]['date']) == str(datetime.utcnow().date()) # Try invalid data with pytest.raises(RPCException, match=r'.*must be an integer greater than 0*'): diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index b953097d5..688c8bdb6 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -333,8 +333,10 @@ def test_api_daily(botclient, mocker, ticker, fee, markets): ) rc = client_get(client, f"{BASE_URI}/daily") assert_response(rc) - assert len(rc.json) == 7 - assert rc.json[0][0] == str(datetime.utcnow().date()) + assert len(rc.json['data']) == 7 + assert rc.json['stake_currency'] == 'BTC' + assert rc.json['fiat_display_currency'] == 'USD' + assert rc.json['data'][0]['date'] == str(datetime.utcnow().date()) def test_api_trades(botclient, mocker, ticker, fee, markets): From 64b8d8c7bd2f56d4ce78cc702305062439873e44 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 20:18:35 +0200 Subject: [PATCH 1099/1106] Use correct Return hint --- freqtrade/rpc/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 7e2934579..3f6d0729d 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -186,7 +186,7 @@ class RPC: def _rpc_daily_profit( self, timescale: int, - stake_currency: str, fiat_display_currency: str) -> List[List[Any]]: + stake_currency: str, fiat_display_currency: str) -> Dict[str, Any]: today = datetime.utcnow().date() profit_days: Dict[date, Dict] = {} From 503a8a82431fc3b6d1c799eadabcb9f9c461f280 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 18 May 2020 07:02:57 +0200 Subject: [PATCH 1100/1106] Simplify sd_notify usage --- freqtrade/worker.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/freqtrade/worker.py b/freqtrade/worker.py index 55cf30d16..3f5ab734e 100755 --- a/freqtrade/worker.py +++ b/freqtrade/worker.py @@ -37,9 +37,7 @@ class Worker: self._heartbeat_msg: float = 0 # Tell systemd that we completed initialization phase - if self._sd_notify: - logger.debug("sd_notify: READY=1") - self._sd_notify.notify("READY=1") + self._notify("READY=1") def _init(self, reconfig: bool) -> None: """ @@ -60,6 +58,15 @@ class Worker: self._sd_notify = sdnotify.SystemdNotifier() if \ self._config.get('internals', {}).get('sd_notify', False) else None + def _notify(self, message: str) -> None: + """ + Removes the need to verify in all occurances if sd_notify is enabled + :param message: Message to send to systemd if it's enabled. + """ + if self._sd_notify: + logger.debug(f"sd_notify: {message}") + self._sd_notify.notify(message) + def run(self) -> None: state = None while True: @@ -89,17 +96,13 @@ class Worker: if state == State.STOPPED: # Ping systemd watchdog before sleeping in the stopped state - if self._sd_notify: - logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: STOPPED.") - self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: STOPPED.") + self._notify("WATCHDOG=1\nSTATUS=State: STOPPED.") self._throttle(func=self._process_stopped, throttle_secs=self._throttle_secs) elif state == State.RUNNING: # Ping systemd watchdog before throttling - if self._sd_notify: - logger.debug("sd_notify: WATCHDOG=1\\nSTATUS=State: RUNNING.") - self._sd_notify.notify("WATCHDOG=1\nSTATUS=State: RUNNING.") + self._notify("WATCHDOG=1\nSTATUS=State: RUNNING.") self._throttle(func=self._process_running, throttle_secs=self._throttle_secs) @@ -154,9 +157,7 @@ class Worker: replaces it with the new instance """ # Tell systemd that we initiated reconfiguration - if self._sd_notify: - logger.debug("sd_notify: RELOADING=1") - self._sd_notify.notify("RELOADING=1") + self._notify("RELOADING=1") # Clean up current freqtrade modules self.freqtrade.cleanup() @@ -167,15 +168,11 @@ class Worker: self.freqtrade.notify_status('config reloaded') # Tell systemd that we completed reconfiguration - if self._sd_notify: - logger.debug("sd_notify: READY=1") - self._sd_notify.notify("READY=1") + self._notify("READY=1") def exit(self) -> None: # Tell systemd that we are exiting now - if self._sd_notify: - logger.debug("sd_notify: STOPPING=1") - self._sd_notify.notify("STOPPING=1") + self._notify("STOPPING=1") if self.freqtrade: self.freqtrade.notify_status('process died') From 37fd675aace911736b5acf97757879fd1c936773 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:00:23 +0000 Subject: [PATCH 1101/1106] Bump flake8 from 3.7.9 to 3.8.1 Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.7.9 to 3.8.1. - [Release notes](https://gitlab.com/pycqa/flake8/tags) - [Commits](https://gitlab.com/pycqa/flake8/compare/3.7.9...3.8.1) Signed-off-by: dependabot-preview[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 616ca20f9..a37ac42ae 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -4,7 +4,7 @@ -r requirements-hyperopt.txt coveralls==2.0.0 -flake8==3.7.9 +flake8==3.8.1 flake8-type-annotations==0.1.0 flake8-tidy-imports==4.1.0 mypy==0.770 From a447efbe57d3a1b60c5d7c2ec3ca3d282ce85b1e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:00:45 +0000 Subject: [PATCH 1102/1106] Bump mkdocs-material from 5.1.6 to 5.1.7 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.6 to 5.1.7. - [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/5.1.6...5.1.7) Signed-off-by: dependabot-preview[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 c121dec64..485cd50cf 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1,2 +1,2 @@ -mkdocs-material==5.1.6 +mkdocs-material==5.1.7 mdx_truly_sane_lists==1.2 From 37a10d1d30073b8f6631d30e9af9e2d744c64a37 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:01:37 +0000 Subject: [PATCH 1103/1106] Bump joblib from 0.14.1 to 0.15.1 Bumps [joblib](https://github.com/joblib/joblib) from 0.14.1 to 0.15.1. - [Release notes](https://github.com/joblib/joblib/releases) - [Changelog](https://github.com/joblib/joblib/blob/master/CHANGES.rst) - [Commits](https://github.com/joblib/joblib/compare/0.14.1...0.15.1) Signed-off-by: dependabot-preview[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 9afd07357..c3dda6c4b 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -6,5 +6,5 @@ scipy==1.4.1 scikit-learn==0.22.2.post1 scikit-optimize==0.7.4 filelock==3.0.12 -joblib==0.14.1 +joblib==0.15.1 progressbar2==3.51.3 From ff8e85f2f5b451197fccf5ad7783d76dcd2c6871 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:02:29 +0000 Subject: [PATCH 1104/1106] Bump sqlalchemy from 1.3.16 to 1.3.17 Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.16 to 1.3.17. - [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases) - [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES) - [Commits](https://github.com/sqlalchemy/sqlalchemy/commits) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 017974c9e..654fa0853 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,7 +1,7 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs ccxt==1.27.49 -SQLAlchemy==1.3.16 +SQLAlchemy==1.3.17 python-telegram-bot==12.7 arrow==0.15.6 cachetools==4.1.0 From 601cbd1231dbd124541b732396cf10bd406a5e57 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 09:23:03 +0000 Subject: [PATCH 1105/1106] Bump ccxt from 1.27.49 to 1.27.91 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.49 to 1.27.91. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst) - [Commits](https://github.com/ccxt/ccxt/compare/1.27.49...1.27.91) Signed-off-by: dependabot-preview[bot] --- requirements-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-common.txt b/requirements-common.txt index 654fa0853..a2038d95e 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -1,6 +1,6 @@ # requirements without requirements installable via conda # mainly used for Raspberry pi installs -ccxt==1.27.49 +ccxt==1.27.91 SQLAlchemy==1.3.17 python-telegram-bot==12.7 arrow==0.15.6 From 5a9a31351abd7e0a2cc2226eaa7904e389ad70be Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 18 May 2020 11:40:25 +0200 Subject: [PATCH 1106/1106] Adjust empty f-strings to be non-fstrings --- freqtrade/commands/build_config_commands.py | 2 +- freqtrade/commands/cli_options.py | 4 ++-- freqtrade/commands/deploy_commands.py | 2 +- freqtrade/exchange/exchange.py | 3 +-- freqtrade/pairlist/VolumePairList.py | 2 +- freqtrade/rpc/rpc.py | 2 +- freqtrade/rpc/telegram.py | 4 ++-- freqtrade/rpc/webhook.py | 6 +++--- tests/conftest.py | 18 +++++++++-------- tests/exchange/test_exchange.py | 6 +++--- tests/optimize/test_backtesting.py | 2 +- tests/optimize/test_hyperopt.py | 2 +- tests/rpc/test_rpc.py | 6 +++--- tests/test_configuration.py | 2 +- tests/test_freqtradebot.py | 22 +++++++++------------ 15 files changed, 40 insertions(+), 43 deletions(-) diff --git a/freqtrade/commands/build_config_commands.py b/freqtrade/commands/build_config_commands.py index 58ac6ec27..87098f53c 100644 --- a/freqtrade/commands/build_config_commands.py +++ b/freqtrade/commands/build_config_commands.py @@ -163,7 +163,7 @@ def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None: ) except TemplateNotFound: selections['exchange'] = render_template( - templatefile=f"subtemplates/exchange_generic.j2", + templatefile="subtemplates/exchange_generic.j2", arguments=selections ) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index a8f2ffdba..ee9208c33 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -372,8 +372,8 @@ AVAILABLE_CLI_OPTIONS = { ), "timeframes": Arg( '-t', '--timeframes', - help=f'Specify which tickers to download. Space-separated list. ' - f'Default: `1m 5m`.', + help='Specify which tickers to download. Space-separated list. ' + 'Default: `1m 5m`.', choices=['1m', '3m', '5m', '15m', '30m', '1h', '2h', '4h', '6h', '8h', '12h', '1d', '3d', '1w'], default=['1m', '5m'], diff --git a/freqtrade/commands/deploy_commands.py b/freqtrade/commands/deploy_commands.py index a29ba346f..86562fa7c 100644 --- a/freqtrade/commands/deploy_commands.py +++ b/freqtrade/commands/deploy_commands.py @@ -51,7 +51,7 @@ def deploy_new_strategy(strategy_name: str, strategy_path: Path, subtemplate: st ) additional_methods = render_template_with_fallback( templatefile=f"subtemplates/strategy_methods_{subtemplate}.j2", - templatefallbackfile=f"subtemplates/strategy_methods_empty.j2", + templatefallbackfile="subtemplates/strategy_methods_empty.j2", ) strategy_text = render_template(templatefile='base_strategy.py.j2', diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 6ad7ad582..68022662a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -366,8 +366,7 @@ class Exchange: f"Invalid timeframe '{timeframe}'. This exchange supports: {self.timeframes}") if timeframe and timeframe_to_minutes(timeframe) < 1: - raise OperationalException( - f"Timeframes < 1m are currently not supported by Freqtrade.") + raise OperationalException("Timeframes < 1m are currently not supported by Freqtrade.") def validate_ordertypes(self, order_types: Dict) -> None: """ diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index e20fb3577..981e9915e 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -25,7 +25,7 @@ class VolumePairList(IPairList): if 'number_assets' not in self._pairlistconfig: raise OperationalException( - f'`number_assets` not specified. Please check your configuration ' + '`number_assets` not specified. Please check your configuration ' 'for "pairlist.config.number_assets"') self._stake_currency = config['stake_currency'] diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 3f6d0729d..21f54de50 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -545,5 +545,5 @@ class RPC: def _rpc_edge(self) -> List[Dict[str, Any]]: """ Returns information related to Edge """ if not self._freqtrade.edge: - raise RPCException(f'Edge is not enabled.') + raise RPCException('Edge is not enabled.') return self._freqtrade.edge.accepted_pairs() diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 1d7ebb21a..dfda15a26 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -234,7 +234,7 @@ class Telegram(RPC): lines.append("*Open Order:* `{open_order}`") # Filter empty lines using list-comprehension - messages.append("\n".join([l for l in lines if l]).format(**r)) + messages.append("\n".join([line for line in lines if line]).format(**r)) for msg in messages: self._send_msg(msg) @@ -289,7 +289,7 @@ class Telegram(RPC): 'Day', f'Profit {stake_cur}', f'Profit {fiat_disp_cur}', - f'Trades', + 'Trades', ], tablefmt='simple') message = f'Daily Profit over the last {timescale} days:\n
        {stats_tab}
        ' diff --git a/freqtrade/rpc/webhook.py b/freqtrade/rpc/webhook.py index 1309663d4..322d990ee 100644 --- a/freqtrade/rpc/webhook.py +++ b/freqtrade/rpc/webhook.py @@ -47,9 +47,9 @@ class Webhook(RPC): valuedict = self._config['webhook'].get('webhooksell', None) elif msg['type'] == RPCMessageType.SELL_CANCEL_NOTIFICATION: valuedict = self._config['webhook'].get('webhooksellcancel', None) - elif msg['type'] in(RPCMessageType.STATUS_NOTIFICATION, - RPCMessageType.CUSTOM_NOTIFICATION, - RPCMessageType.WARNING_NOTIFICATION): + elif msg['type'] in (RPCMessageType.STATUS_NOTIFICATION, + RPCMessageType.CUSTOM_NOTIFICATION, + RPCMessageType.WARNING_NOTIFICATION): valuedict = self._config['webhook'].get('webhookstatus', None) else: raise NotImplementedError('Unknown message type: {}'.format(msg['type'])) diff --git a/tests/conftest.py b/tests/conftest.py index 36c60e27e..d15cba1de 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1705,7 +1705,7 @@ def hyperopt_results(): { 'loss': 0.4366182531161519, 'params_dict': { - 'mfi-value': 15, 'fastd-value': 20, 'adx-value': 25, 'rsi-value': 28, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 88, 'sell-fastd-value': 97, 'sell-adx-value': 51, 'sell-rsi-value': 67, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1190, 'roi_t2': 541, 'roi_t3': 408, 'roi_p1': 0.026035863879169705, 'roi_p2': 0.12508730043628782, 'roi_p3': 0.27766427921605896, 'stoploss': -0.2562930402099556}, # noqa: E501 + 'mfi-value': 15, 'fastd-value': 20, 'adx-value': 25, 'rsi-value': 28, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 88, 'sell-fastd-value': 97, 'sell-adx-value': 51, 'sell-rsi-value': 67, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1190, 'roi_t2': 541, 'roi_t3': 408, 'roi_p1': 0.026035863879169705, 'roi_p2': 0.12508730043628782, 'roi_p3': 0.27766427921605896, 'stoploss': -0.2562930402099556}, # noqa: E501 'params_details': {'buy': {'mfi-value': 15, 'fastd-value': 20, 'adx-value': 25, 'rsi-value': 28, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 88, 'sell-fastd-value': 97, 'sell-adx-value': 51, 'sell-rsi-value': 67, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper'}, 'roi': {0: 0.4287874435315165, 408: 0.15112316431545753, 949: 0.026035863879169705, 2139: 0}, 'stoploss': {'stoploss': -0.2562930402099556}}, # noqa: E501 'results_metrics': {'trade_count': 2, 'avg_profit': -1.254995, 'total_profit': -0.00125625, 'profit': -2.50999, 'duration': 3930.0}, # noqa: E501 'results_explanation': ' 2 trades. Avg profit -1.25%. Total profit -0.00125625 BTC ( -2.51Σ%). Avg duration 3930.0 min.', # noqa: E501 @@ -1716,11 +1716,12 @@ def hyperopt_results(): }, { 'loss': 20.0, 'params_dict': { - 'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal', 'roi_t1': 334, 'roi_t2': 683, 'roi_t3': 140, 'roi_p1': 0.06403981740598495, 'roi_p2': 0.055519840060645045, 'roi_p3': 0.3253712811342459, 'stoploss': -0.338070047333259}, # noqa: E501 - 'params_details': {'buy': {'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, # noqa: E501 - 'sell': {'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal'}, # noqa: E501 - 'roi': {0: 0.4449309386008759, 140: 0.11955965746663, 823: 0.06403981740598495, 1157: 0}, # noqa: E501 - 'stoploss': {'stoploss': -0.338070047333259}}, + 'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal', 'roi_t1': 334, 'roi_t2': 683, 'roi_t3': 140, 'roi_p1': 0.06403981740598495, 'roi_p2': 0.055519840060645045, 'roi_p3': 0.3253712811342459, 'stoploss': -0.338070047333259}, # noqa: E501 + 'params_details': { + 'buy': {'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, # noqa: E501 + 'sell': {'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal'}, # noqa: E501 + 'roi': {0: 0.4449309386008759, 140: 0.11955965746663, 823: 0.06403981740598495, 1157: 0}, # noqa: E501 + 'stoploss': {'stoploss': -0.338070047333259}}, 'results_metrics': {'trade_count': 1, 'avg_profit': 0.12357, 'total_profit': 6.185e-05, 'profit': 0.12357, 'duration': 1200.0}, # noqa: E501 'results_explanation': ' 1 trades. Avg profit 0.12%. Total profit 0.00006185 BTC ( 0.12Σ%). Avg duration 1200.0 min.', # noqa: E501 'total_profit': 6.185e-05, @@ -1767,8 +1768,9 @@ def hyperopt_results(): }, { 'loss': 4.713497421432944, 'params_dict': {'mfi-value': 13, 'fastd-value': 41, 'adx-value': 21, 'rsi-value': 29, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower', 'sell-mfi-value': 99, 'sell-fastd-value': 60, 'sell-adx-value': 81, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 771, 'roi_t2': 620, 'roi_t3': 145, 'roi_p1': 0.0586919200378493, 'roi_p2': 0.04984118697312542, 'roi_p3': 0.37521058680247044, 'stoploss': -0.14613268022709905}, # noqa: E501 - 'params_details': {'buy': {'mfi-value': 13, 'fastd-value': 41, 'adx-value': 21, 'rsi-value': 29, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower'}, 'sell': {'sell-mfi-value': 99, 'sell-fastd-value': 60, 'sell-adx-value': 81, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.4837436938134452, 145: 0.10853310701097472, 765: 0.0586919200378493, 1536: 0}, # noqa: E501 - 'stoploss': {'stoploss': -0.14613268022709905}}, # noqa: E501 + 'params_details': { + 'buy': {'mfi-value': 13, 'fastd-value': 41, 'adx-value': 21, 'rsi-value': 29, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower'}, 'sell': {'sell-mfi-value': 99, 'sell-fastd-value': 60, 'sell-adx-value': 81, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.4837436938134452, 145: 0.10853310701097472, 765: 0.0586919200378493, 1536: 0}, # noqa: E501 + 'stoploss': {'stoploss': -0.14613268022709905}}, # noqa: E501 'results_metrics': {'trade_count': 318, 'avg_profit': -0.39833954716981146, 'total_profit': -0.06339929, 'profit': -126.67197600000004, 'duration': 3140.377358490566}, # noqa: E501 'results_explanation': ' 318 trades. Avg profit -0.40%. Total profit -0.06339929 BTC (-126.67Σ%). Avg duration 3140.4 min.', # noqa: E501 'total_profit': -0.06339929, diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index aa42950e2..7b1e9ddaa 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -517,9 +517,9 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog): mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency') Exchange(default_conf) - assert log_has(f"Pair XRP/BTC is restricted for some users on this exchange." - f"Please check if you are impacted by this restriction " - f"on the exchange and eventually remove XRP/BTC from your whitelist.", caplog) + assert log_has("Pair XRP/BTC is restricted for some users on this exchange." + "Please check if you are impacted by this restriction " + "on the exchange and eventually remove XRP/BTC from your whitelist.", caplog) def test_validate_pairs_stakecompatibility(default_conf, mocker, caplog): diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 093cbf966..019914720 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -555,7 +555,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir) """ Buy every xth candle - sell every other xth -2 (hold on to pairs a bit) """ - if metadata['pair'] in('ETH/BTC', 'LTC/BTC'): + if metadata['pair'] in ('ETH/BTC', 'LTC/BTC'): multi = 20 else: multi = 18 diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index cc8b9aa37..90e047954 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -820,7 +820,7 @@ def test_continue_hyperopt(mocker, default_conf, caplog): Hyperopt(default_conf) assert unlinkmock.call_count == 0 - assert log_has(f"Continuing on previous hyperopt results.", caplog) + assert log_has("Continuing on previous hyperopt results.", caplog) def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None: diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 1c3a43e4b..63691dfb4 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -83,7 +83,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: } == results[0] mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', - MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) + MagicMock(side_effect=DependencyException("Pair 'ETH/BTC' not available"))) results = rpc._rpc_trade_status() assert isnan(results[0]['current_profit']) assert isnan(results[0]['current_rate']) @@ -167,7 +167,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None: assert '-0.41% (-0.06)' == result[0][3] mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', - MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) + MagicMock(side_effect=DependencyException("Pair 'ETH/BTC' not available"))) result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD') assert 'instantly' == result[0][2] assert 'ETH/BTC' in result[0][1] @@ -319,7 +319,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, # Test non-available pair mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', - MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) + MagicMock(side_effect=DependencyException("Pair 'ETH/BTC' not available"))) stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) assert stats['trade_count'] == 2 assert stats['first_trade_date'] == 'just now' diff --git a/tests/test_configuration.py b/tests/test_configuration.py index c89f1381e..edcbe4516 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -73,7 +73,7 @@ def test_load_config_file_error(default_conf, mocker, caplog) -> None: mocker.patch('freqtrade.configuration.load_config.open', mocker.mock_open(read_data=filedata)) mocker.patch.object(Path, "read_text", MagicMock(return_value=filedata)) - with pytest.raises(OperationalException, match=f".*Please verify the following segment.*"): + with pytest.raises(OperationalException, match=r".*Please verify the following segment.*"): load_config_file('somefile') diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a1358abdc..9d9d133cc 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3153,10 +3153,8 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) caplog.set_level(logging.DEBUG) # Sell as trailing-stop is reached assert freqtrade.handle_trade(trade) is True - assert log_has( - f"ETH/BTC - HIT STOP: current price at 0.000012, " - f"stoploss is 0.000015, " - f"initial stoploss was at 0.000010, trade opened at 0.000011", caplog) + assert log_has("ETH/BTC - HIT STOP: current price at 0.000012, stoploss is 0.000015, " + "initial stoploss was at 0.000010, trade opened at 0.000011", caplog) assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value @@ -3199,8 +3197,8 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, })) # stop-loss not reached, adjusted stoploss assert freqtrade.handle_trade(trade) is False - assert log_has(f"ETH/BTC - Using positive stoploss: 0.01 offset: 0 profit: 0.2666%", caplog) - assert log_has(f"ETH/BTC - Adjusting stoploss...", caplog) + assert log_has("ETH/BTC - Using positive stoploss: 0.01 offset: 0 profit: 0.2666%", caplog) + assert log_has("ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000138501 mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', @@ -3256,9 +3254,8 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee, })) # stop-loss not reached, adjusted stoploss assert freqtrade.handle_trade(trade) is False - assert log_has(f"ETH/BTC - Using positive stoploss: 0.01 offset: 0.011 profit: 0.2666%", - caplog) - assert log_has(f"ETH/BTC - Adjusting stoploss...", caplog) + assert log_has("ETH/BTC - Using positive stoploss: 0.01 offset: 0.011 profit: 0.2666%", caplog) + assert log_has("ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000138501 mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', @@ -3322,7 +3319,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, # stop-loss should not be adjusted as offset is not reached yet assert freqtrade.handle_trade(trade) is False - assert not log_has(f"ETH/BTC - Adjusting stoploss...", caplog) + assert not log_has("ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000098910 # price rises above the offset (rises 12% when the offset is 5.5%) @@ -3334,9 +3331,8 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee, })) assert freqtrade.handle_trade(trade) is False - assert log_has(f"ETH/BTC - Using positive stoploss: 0.05 offset: 0.055 profit: 0.1218%", - caplog) - assert log_has(f"ETH/BTC - Adjusting stoploss...", caplog) + assert log_has("ETH/BTC - Using positive stoploss: 0.05 offset: 0.055 profit: 0.1218%", caplog) + assert log_has("ETH/BTC - Adjusting stoploss...", caplog) assert trade.stop_loss == 0.0000117705

        $A|6t6{{N!4b!`2pVt8GJ0vYO| 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%0DKK9 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 literal 0 HcmV?d00001 diff --git a/build_helpers/install_windows.ps1 b/build_helpers/install_windows.ps1 index 7dbdd77dd..0a55b6ddd 100644 --- a/build_helpers/install_windows.ps1 +++ b/build_helpers/install_windows.ps1 @@ -7,10 +7,10 @@ python -m pip install --upgrade pip $pyv = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" if ($pyv -eq '3.7') { - pip install build_helpers\TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl + pip install build_helpers\TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl } if ($pyv -eq '3.8') { - pip install build_helpers\TA_Lib-0.4.17-cp38-cp38-win_amd64.whl + pip install build_helpers\TA_Lib-0.4.18-cp38-cp38-win_amd64.whl } pip install -r requirements-dev.txt From a8f523adae66fb0eb4f28ffff4cd8394c7b6b0d4 Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Mon, 11 May 2020 19:32:28 +0400 Subject: [PATCH 1043/1106] attached pairlist manager onto dataprovider init for unified access to dynamic whitelist --- freqtrade/data/dataprovider.py | 12 +++++---- freqtrade/freqtradebot.py | 6 ++--- tests/data/test_dataprovider.py | 46 ++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index af0914939..01397d6b7 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -10,6 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple from pandas import DataFrame from freqtrade.data.history import load_pair_history +from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange from freqtrade.state import RunMode @@ -18,9 +19,10 @@ logger = logging.getLogger(__name__) class DataProvider: - def __init__(self, config: dict, exchange: Exchange) -> None: + def __init__(self, config: dict, exchange: Exchange, pairlists=None) -> None: self._config = config self._exchange = exchange + self._pairlists: Optional = pairlists def refresh(self, pairlist: List[Tuple[str, str]], @@ -125,8 +127,8 @@ class DataProvider: As available pairs does not show whitelist until after informative pairs have been cached. :return: list of pairs in whitelist """ - from freqtrade.pairlist.pairlistmanager import PairListManager - pairlists = PairListManager(self._exchange, self._config) - pairlists.refresh_pairlist() - return pairlists.whitelist + if self._pairlists: + return self._pairlists.whitelist + else: + raise OperationalException("Dataprovider was not initialized with a pairlist provider.") diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4f4b3e3bb..73f0873e4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -71,15 +71,15 @@ class FreqtradeBot: self.wallets = Wallets(self.config, self.exchange) - self.dataprovider = DataProvider(self.config, self.exchange) + self.pairlists = PairListManager(self.exchange, self.config) + + self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists) # Attach Dataprovider to Strategy baseclass IStrategy.dp = self.dataprovider # Attach Wallets to Strategy baseclass IStrategy.wallets = self.wallets - self.pairlists = PairListManager(self.exchange, self.config) - # Initializing Edge only if enabled self.edge = Edge(self.config, self.exchange, self.strategy) if \ self.config.get('edge', {}).get('enabled', False) else None diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index e5af80bc8..247703619 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -1,10 +1,12 @@ -from unittest.mock import MagicMock, PropertyMock +from unittest.mock import MagicMock, patch from pandas import DataFrame +import pytest from freqtrade.data.dataprovider import DataProvider +from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from tests.conftest import get_patched_exchange, get_patched_freqtradebot +from tests.conftest import get_patched_exchange def test_ohlcv(mocker, default_conf, ohlcv_history): @@ -151,21 +153,29 @@ def test_market(mocker, default_conf, markets): assert res is None -def test_current_whitelist(mocker, shitcoinmarkets, tickers, default_conf): - default_conf.update( - {"pairlists": [{"method": "VolumePairList", - "number_assets": 10, - "sort_key": "quoteVolume"}], }, ) - default_conf['exchange']['pair_blacklist'] = ['BLK/BTC'] +@patch('freqtrade.pairlist.pairlistmanager.PairListManager') +@patch('freqtrade.exchange.Exchange') +def test_current_whitelist(exchange, PairListManager, default_conf): + # patch default conf to volumepairlist + default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5} - mocker.patch.multiple('freqtrade.exchange.Exchange', get_tickers=tickers, - exchange_has=MagicMock(return_value=True), ) - bot = get_patched_freqtradebot(mocker, default_conf) - # Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture - mocker.patch.multiple('freqtrade.exchange.Exchange', - markets=PropertyMock(return_value=shitcoinmarkets), ) - # argument: use the whitelist dynamically by exchange-volume - whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'HOT/BTC', 'FUEL/BTC'] + pairlist = PairListManager(exchange, default_conf) + dp = DataProvider(default_conf, exchange, pairlist) - current_wl = bot.dataprovider.current_whitelist() - assert whitelist == current_wl + # Simulate volumepairs from exchange. + # pairlist.refresh_pairlist() + # Set the pairs manually... this would be done in refresh pairlist default whitelist + volumePL - blacklist + default_whitelist = default_conf['exchange']['pair_whitelist'] + default_blacklist = default_conf['exchange']['pair_blacklist'] + volume_pairlist = ['ETH/BTC', 'LINK/BTC', 'ZRX/BTC', 'BCH/BTC', 'XRP/BTC'] + current_whitelist = list(set(volume_pairlist + default_whitelist)) + for pair in default_blacklist: + if pair in current_whitelist: + current_whitelist.remove(pair) + pairlist._whitelist = current_whitelist + + assert dp.current_whitelist() == pairlist._whitelist + + with pytest.raises(OperationalException) as e: + dp = DataProvider(default_conf, exchange) + dp.current_whitelist() From bc9efc31ad6c6e0806111384e6fa8229285d298a Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Wed, 6 May 2020 19:48:57 +0400 Subject: [PATCH 1044/1106] Added Method for accessing current pair list on initialization for dynamic informative pairs moved import into function to avoid circular import with hyperopt --- freqtrade/data/dataprovider.py | 14 ++++++++++++++ tests/data/test_dataprovider.py | 33 +++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 1df710152..af0914939 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -116,3 +116,17 @@ class DataProvider: can be "live", "dry-run", "backtest", "edgecli", "hyperopt" or "other". """ return RunMode(self._config.get('runmode', RunMode.OTHER)) + + def current_whitelist(self) -> List[str]: + """ + fetch latest available whitelist. + + Useful when you have a large whitelist and need to call each pair as an informative pair. + As available pairs does not show whitelist until after informative pairs have been cached. + :return: list of pairs in whitelist + """ + from freqtrade.pairlist.pairlistmanager import PairListManager + + pairlists = PairListManager(self._exchange, self._config) + pairlists.refresh_pairlist() + return pairlists.whitelist diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 2b3dda188..e5af80bc8 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -1,10 +1,10 @@ -from unittest.mock import MagicMock +from unittest.mock import MagicMock, PropertyMock from pandas import DataFrame from freqtrade.data.dataprovider import DataProvider from freqtrade.state import RunMode -from tests.conftest import get_patched_exchange +from tests.conftest import get_patched_exchange, get_patched_freqtradebot def test_ohlcv(mocker, default_conf, ohlcv_history): @@ -64,8 +64,8 @@ def test_get_pair_dataframe(mocker, default_conf, ohlcv_history): assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty # Test with and without parameter - assert dp.get_pair_dataframe("UNITTEST/BTC", - ticker_interval).equals(dp.get_pair_dataframe("UNITTEST/BTC")) + assert dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval)\ + .equals(dp.get_pair_dataframe("UNITTEST/BTC")) default_conf["runmode"] = RunMode.LIVE dp = DataProvider(default_conf, exchange) @@ -90,10 +90,7 @@ def test_available_pairs(mocker, default_conf, ohlcv_history): dp = DataProvider(default_conf, exchange) assert len(dp.available_pairs) == 2 - assert dp.available_pairs == [ - ("XRP/BTC", ticker_interval), - ("UNITTEST/BTC", ticker_interval), - ] + assert dp.available_pairs == [("XRP/BTC", ticker_interval), ("UNITTEST/BTC", ticker_interval), ] def test_refresh(mocker, default_conf, ohlcv_history): @@ -152,3 +149,23 @@ def test_market(mocker, default_conf, markets): res = dp.market('UNITTEST/BTC') assert res is None + + +def test_current_whitelist(mocker, shitcoinmarkets, tickers, default_conf): + default_conf.update( + {"pairlists": [{"method": "VolumePairList", + "number_assets": 10, + "sort_key": "quoteVolume"}], }, ) + default_conf['exchange']['pair_blacklist'] = ['BLK/BTC'] + + mocker.patch.multiple('freqtrade.exchange.Exchange', get_tickers=tickers, + exchange_has=MagicMock(return_value=True), ) + bot = get_patched_freqtradebot(mocker, default_conf) + # Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture + mocker.patch.multiple('freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=shitcoinmarkets), ) + # argument: use the whitelist dynamically by exchange-volume + whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'HOT/BTC', 'FUEL/BTC'] + + current_wl = bot.dataprovider.current_whitelist() + assert whitelist == current_wl From a5bfa5515cbdbab500dbe9df614730107804bacd Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Mon, 11 May 2020 20:13:06 +0400 Subject: [PATCH 1045/1106] Fix flake8 mypy --- freqtrade/data/dataprovider.py | 2 +- tests/data/test_dataprovider.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 01397d6b7..984652e24 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -22,7 +22,7 @@ class DataProvider: def __init__(self, config: dict, exchange: Exchange, pairlists=None) -> None: self._config = config self._exchange = exchange - self._pairlists: Optional = pairlists + self._pairlists = pairlists def refresh(self, pairlist: List[Tuple[str, str]], diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 247703619..45ce1c009 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -164,7 +164,9 @@ def test_current_whitelist(exchange, PairListManager, default_conf): # Simulate volumepairs from exchange. # pairlist.refresh_pairlist() - # Set the pairs manually... this would be done in refresh pairlist default whitelist + volumePL - blacklist + + # Set the pairs manually... this would be done in refresh pairlist + # default whitelist + volumePL - blacklist default_whitelist = default_conf['exchange']['pair_whitelist'] default_blacklist = default_conf['exchange']['pair_blacklist'] volume_pairlist = ['ETH/BTC', 'LINK/BTC', 'ZRX/BTC', 'BCH/BTC', 'XRP/BTC'] @@ -176,6 +178,6 @@ def test_current_whitelist(exchange, PairListManager, default_conf): assert dp.current_whitelist() == pairlist._whitelist - with pytest.raises(OperationalException) as e: + with pytest.raises(OperationalException): dp = DataProvider(default_conf, exchange) dp.current_whitelist() From 9fbe1357902aa90243309781f164e7328fdc5b9a Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Mon, 11 May 2020 19:32:28 +0400 Subject: [PATCH 1046/1106] attached pairlist manager onto dataprovider init for unified access to dynamic whitelist --- freqtrade/data/dataprovider.py | 12 +++++---- freqtrade/freqtradebot.py | 6 ++--- tests/data/test_dataprovider.py | 48 ++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index af0914939..984652e24 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -10,6 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple from pandas import DataFrame from freqtrade.data.history import load_pair_history +from freqtrade.exceptions import OperationalException from freqtrade.exchange import Exchange from freqtrade.state import RunMode @@ -18,9 +19,10 @@ logger = logging.getLogger(__name__) class DataProvider: - def __init__(self, config: dict, exchange: Exchange) -> None: + def __init__(self, config: dict, exchange: Exchange, pairlists=None) -> None: self._config = config self._exchange = exchange + self._pairlists = pairlists def refresh(self, pairlist: List[Tuple[str, str]], @@ -125,8 +127,8 @@ class DataProvider: As available pairs does not show whitelist until after informative pairs have been cached. :return: list of pairs in whitelist """ - from freqtrade.pairlist.pairlistmanager import PairListManager - pairlists = PairListManager(self._exchange, self._config) - pairlists.refresh_pairlist() - return pairlists.whitelist + if self._pairlists: + return self._pairlists.whitelist + else: + raise OperationalException("Dataprovider was not initialized with a pairlist provider.") diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 4f4b3e3bb..73f0873e4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -71,15 +71,15 @@ class FreqtradeBot: self.wallets = Wallets(self.config, self.exchange) - self.dataprovider = DataProvider(self.config, self.exchange) + self.pairlists = PairListManager(self.exchange, self.config) + + self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists) # Attach Dataprovider to Strategy baseclass IStrategy.dp = self.dataprovider # Attach Wallets to Strategy baseclass IStrategy.wallets = self.wallets - self.pairlists = PairListManager(self.exchange, self.config) - # Initializing Edge only if enabled self.edge = Edge(self.config, self.exchange, self.strategy) if \ self.config.get('edge', {}).get('enabled', False) else None diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index e5af80bc8..45ce1c009 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -1,10 +1,12 @@ -from unittest.mock import MagicMock, PropertyMock +from unittest.mock import MagicMock, patch from pandas import DataFrame +import pytest from freqtrade.data.dataprovider import DataProvider +from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode -from tests.conftest import get_patched_exchange, get_patched_freqtradebot +from tests.conftest import get_patched_exchange def test_ohlcv(mocker, default_conf, ohlcv_history): @@ -151,21 +153,31 @@ def test_market(mocker, default_conf, markets): assert res is None -def test_current_whitelist(mocker, shitcoinmarkets, tickers, default_conf): - default_conf.update( - {"pairlists": [{"method": "VolumePairList", - "number_assets": 10, - "sort_key": "quoteVolume"}], }, ) - default_conf['exchange']['pair_blacklist'] = ['BLK/BTC'] +@patch('freqtrade.pairlist.pairlistmanager.PairListManager') +@patch('freqtrade.exchange.Exchange') +def test_current_whitelist(exchange, PairListManager, default_conf): + # patch default conf to volumepairlist + default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5} - mocker.patch.multiple('freqtrade.exchange.Exchange', get_tickers=tickers, - exchange_has=MagicMock(return_value=True), ) - bot = get_patched_freqtradebot(mocker, default_conf) - # Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture - mocker.patch.multiple('freqtrade.exchange.Exchange', - markets=PropertyMock(return_value=shitcoinmarkets), ) - # argument: use the whitelist dynamically by exchange-volume - whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'HOT/BTC', 'FUEL/BTC'] + pairlist = PairListManager(exchange, default_conf) + dp = DataProvider(default_conf, exchange, pairlist) - current_wl = bot.dataprovider.current_whitelist() - assert whitelist == current_wl + # Simulate volumepairs from exchange. + # pairlist.refresh_pairlist() + + # Set the pairs manually... this would be done in refresh pairlist + # default whitelist + volumePL - blacklist + default_whitelist = default_conf['exchange']['pair_whitelist'] + default_blacklist = default_conf['exchange']['pair_blacklist'] + volume_pairlist = ['ETH/BTC', 'LINK/BTC', 'ZRX/BTC', 'BCH/BTC', 'XRP/BTC'] + current_whitelist = list(set(volume_pairlist + default_whitelist)) + for pair in default_blacklist: + if pair in current_whitelist: + current_whitelist.remove(pair) + pairlist._whitelist = current_whitelist + + assert dp.current_whitelist() == pairlist._whitelist + + with pytest.raises(OperationalException): + dp = DataProvider(default_conf, exchange) + dp.current_whitelist() From c8f3ef884b13e359c572043b6e9e7892a448cb2d Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 11 May 2020 20:22:19 +0300 Subject: [PATCH 1047/1106] Minor: Add filterwarning for DeprecationWarning in test --- tests/optimize/test_backtesting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 6c2d6c9dd..093cbf966 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -649,6 +649,7 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): assert log_has(line, caplog) +@pytest.mark.filterwarnings("ignore:deprecated") def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): patch_exchange(mocker) From 258071928f8c673ab18cff5442c9abf5c0026f0e Mon Sep 17 00:00:00 2001 From: prashanthsandela Date: Mon, 11 May 2020 17:21:04 -0700 Subject: [PATCH 1048/1106] Correct log path in doc. --- docs/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker.md b/docs/docker.md index cd24994bc..ad98864a6 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -65,7 +65,7 @@ docker-compose up -d #### Docker-compose logs -Logs will be written to `user_data/freqtrade.log`. +Logs will be written to `user_data/logs/freqtrade.log`. Alternatively, you can check the latest logs using `docker-compose logs -f`. #### Database From e864db1843c378b0eb8c6936f1b8a4aa3230eddc Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 May 2020 06:38:14 +0200 Subject: [PATCH 1049/1106] Update test for dp.current_whitelist --- tests/data/test_dataprovider.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 45ce1c009..3e42abb95 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -1,9 +1,10 @@ -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock from pandas import DataFrame import pytest from freqtrade.data.dataprovider import DataProvider +from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.exceptions import OperationalException from freqtrade.state import RunMode from tests.conftest import get_patched_exchange @@ -153,30 +154,24 @@ def test_market(mocker, default_conf, markets): assert res is None -@patch('freqtrade.pairlist.pairlistmanager.PairListManager') -@patch('freqtrade.exchange.Exchange') -def test_current_whitelist(exchange, PairListManager, default_conf): +def test_current_whitelist(mocker, default_conf, tickers): # patch default conf to volumepairlist default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5} + mocker.patch.multiple('freqtrade.exchange.Exchange', + exchange_has=MagicMock(return_value=True), + get_tickers=tickers) + exchange = get_patched_exchange(mocker, default_conf) + pairlist = PairListManager(exchange, default_conf) dp = DataProvider(default_conf, exchange, pairlist) # Simulate volumepairs from exchange. - # pairlist.refresh_pairlist() - - # Set the pairs manually... this would be done in refresh pairlist - # default whitelist + volumePL - blacklist - default_whitelist = default_conf['exchange']['pair_whitelist'] - default_blacklist = default_conf['exchange']['pair_blacklist'] - volume_pairlist = ['ETH/BTC', 'LINK/BTC', 'ZRX/BTC', 'BCH/BTC', 'XRP/BTC'] - current_whitelist = list(set(volume_pairlist + default_whitelist)) - for pair in default_blacklist: - if pair in current_whitelist: - current_whitelist.remove(pair) - pairlist._whitelist = current_whitelist + pairlist.refresh_pairlist() assert dp.current_whitelist() == pairlist._whitelist + # The identity of the 2 lists should be identical + assert dp.current_whitelist() is pairlist._whitelist with pytest.raises(OperationalException): dp = DataProvider(default_conf, exchange) From aa25461e8854cd7e525b3b7eeddf1bfd8ae3a8d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 May 2020 07:20:59 +0200 Subject: [PATCH 1050/1106] Show forcebuy status so it's visible before calling forcebuy. --- freqtrade/rpc/rpc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 10eeb572f..851092f1a 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -104,6 +104,7 @@ class RPC: 'ticker_interval': config['ticker_interval'], 'exchange': config['exchange']['name'], 'strategy': config['strategy'], + 'forcebuy_enabled': self._freqtrade.config.get('forcebuy_enable', False), 'state': str(self._freqtrade.state) } return val From e2b9c248568a03b30016a3c13ac72b5f8f51ef91 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 12 May 2020 13:54:13 +0300 Subject: [PATCH 1051/1106] Docs: Fix sample in strategy-advanced --- docs/strategy-advanced.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 39e92d651..684e58f22 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -20,7 +20,7 @@ It applies a tight timeout for higher priced assets, while allowing more time to The function must return either `True` (cancel order) or `False` (keep order alive). ``` python -from datetime import datetime, timestamp +from datetime import datetime from freqtrade.persistence import Trade class Awesomestrategy(IStrategy): @@ -59,7 +59,7 @@ class Awesomestrategy(IStrategy): ### Custom order timeout example (using additional data) ``` python -from datetime import datetime, timestamp +from datetime import datetime from freqtrade.persistence import Trade class Awesomestrategy(IStrategy): From 77c9334c50cc43453b71e5ab4bd9e3353e8f80c0 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 12 May 2020 13:39:24 +0200 Subject: [PATCH 1052/1106] Use available config object Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- freqtrade/rpc/rpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 851092f1a..d3b6b9639 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -104,7 +104,7 @@ class RPC: 'ticker_interval': config['ticker_interval'], 'exchange': config['exchange']['name'], 'strategy': config['strategy'], - 'forcebuy_enabled': self._freqtrade.config.get('forcebuy_enable', False), + 'forcebuy_enabled': config.get('forcebuy_enable', False), 'state': str(self._freqtrade.state) } return val From f1367b38a4c52c605287d876721c9070873eb901 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 12 May 2020 14:42:33 +0300 Subject: [PATCH 1053/1106] Docs: Fix the fix --- docs/strategy-advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 684e58f22..69e2256a1 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -20,7 +20,7 @@ It applies a tight timeout for higher priced assets, while allowing more time to The function must return either `True` (cancel order) or `False` (keep order alive). ``` python -from datetime import datetime +from datetime import datetime, timedelta from freqtrade.persistence import Trade class Awesomestrategy(IStrategy): From 63dfe3669ff994b535adde5f1609bbba283de69f Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Wed, 13 May 2020 00:25:57 +0400 Subject: [PATCH 1054/1106] Updated docs for #3267 --- docs/strategy-customization.md | 160 +++++++++++++++++++++------------ 1 file changed, 105 insertions(+), 55 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index c4fc55811..20cde7556 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -324,62 +324,9 @@ class Awesomestrategy(IStrategy): !!! Note If the data is pair-specific, make sure to use pair as one of the keys in the dictionary. -### Additional data (DataProvider) +*** -The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy. - -All methods return `None` in case of failure (do not raise an exception). - -Please always check the mode of operation to select the correct method to get data (samples see below). - -#### Possible options for DataProvider - -- `available_pairs` - Property with tuples listing cached pairs with their intervals (pair, interval). -- `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame. -- `historic_ohlcv(pair, timeframe)` - Returns historical data stored on disk. -- `get_pair_dataframe(pair, timeframe)` - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes). -- `orderbook(pair, maximum)` - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries. -- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on Market data structure. -- `runmode` - Property containing the current runmode. - -#### Example: fetch live / historical candle (OHLCV) data for the first informative pair - -``` python -if self.dp: - inf_pair, inf_timeframe = self.informative_pairs()[0] - informative = self.dp.get_pair_dataframe(pair=inf_pair, - timeframe=inf_timeframe) -``` - -!!! Warning "Warning about backtesting" - Be carefull when using dataprovider in backtesting. `historic_ohlcv()` (and `get_pair_dataframe()` - for the backtesting runmode) provides the full time-range in one go, - so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode). - -!!! Warning "Warning in hyperopt" - This option cannot currently be used during hyperopt. - -#### Orderbook - -``` python -if self.dp: - if self.dp.runmode.value in ('live', 'dry_run'): - ob = self.dp.orderbook(metadata['pair'], 1) - dataframe['best_bid'] = ob['bids'][0][0] - dataframe['best_ask'] = ob['asks'][0][0] -``` - -!!! Warning - The order book is not part of the historic data which means backtesting and hyperopt will not work if this - method is used. - -#### Available Pairs - -``` python -if self.dp: - for pair, timeframe in self.dp.available_pairs: - print(f"available {pair}, {timeframe}") -``` +### Additional data (informative_pairs) #### Get data for non-tradeable pairs @@ -404,6 +351,108 @@ def informative_pairs(self): It is however better to use resampling to longer time-intervals when possible to avoid hammering the exchange with too many requests and risk being blocked. +*** + +### Additional data (DataProvider) + +The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy. + +All methods return `None` in case of failure (do not raise an exception). + +Please always check the mode of operation to select the correct method to get data (samples see below). + +#### Possible options for DataProvider + +- [`available_pairs`](#available_pairs) - Property with tuples listing cached pairs with their intervals (pair, interval). +- [`current_whitelist()`](#current_whitelist) - Returns a current list of whitelisted pairs. Useful for accessing dynamic whitelists (ie. VolumePairlist) +- [`get_pair_dataframe(pair, timeframe)`](#get_pair_dataframepair-timeframe) - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes). +- `historic_ohlcv(pair, timeframe)` - Returns historical data stored on disk. +- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on Market data structure. +- `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame. +- [`orderbook(pair, maximum)`](#orderbookpair-maximum) - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries. +- `runmode` - Property containing the current runmode. + +#### Example Usages: + +#### *available_pairs* + +``` python +if self.dp: + for pair, timeframe in self.dp.available_pairs: + print(f"available {pair}, {timeframe}") +``` + +#### *current_whitelist()* +Imagine you've developed a strategy that trades the `1m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume. + +The strategy might look something like this: + +*Scan through the top 10 pairs by volume using the `VolumePairList` every minute and use a 14 day ATR to buy and sell.* + +Due to the limited available data, it's impossible to resample our `1m` candles into daily candles for use in the 14 day ATR. Most exchanges limit us to just 500 candles which effectively gives us around 1/3 of a daily candle. We need 14 days at least! + +Since we can't resample our data we will have to use an informative pair; and since our whitelist will be dynamic we don't know which pair(s) to use. + +This is where calling `self.dp.current_whitelist()` comes in handy. + +```python +class SampleStrategy(IStrategy): + # strategy init stuff... + + ticker_interval = '1m' + + # more strategy init stuff.. + + def informative_pairs(self): + + # get access to all pairs available in whitelist. + pairs = self.dp.current_whitelist() + # Assign tf to each pair so they can be downloaded and cached for strategy. + informative_pairs = [(pair, '1d') for pair in pairs] + return informative_pairs + + def populate_indicators(self, dataframe, metadata): + # Get the informative pair + informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d') + # Get the 14 day ATR. + atr = ta.ATR(informative, timeperiod=14) + # Assign the Daily atr to the 1 minute dataframe. + dataframe['daily_atr'] = atr +``` + +#### *get_pair_dataframe(pair, timeframe)* + +``` python +# fetch live / historical candle (OHLCV) data for the first informative pair +if self.dp: + inf_pair, inf_timeframe = self.informative_pairs()[0] + informative = self.dp.get_pair_dataframe(pair=inf_pair, + timeframe=inf_timeframe) +``` + +!!! Warning "Warning about backtesting" + Be carefull when using dataprovider in backtesting. `historic_ohlcv()` (and `get_pair_dataframe()` + for the backtesting runmode) provides the full time-range in one go, + so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode). + +!!! Warning "Warning in hyperopt" + This option cannot currently be used during hyperopt. + +#### *orderbook(pair, maximum)* + +``` python +if self.dp: + if self.dp.runmode.value in ('live', 'dry_run'): + ob = self.dp.orderbook(metadata['pair'], 1) + dataframe['best_bid'] = ob['bids'][0][0] + dataframe['best_ask'] = ob['asks'][0][0] +``` + +!!! Warning + The order book is not part of the historic data which means backtesting and hyperopt will not work if this + method is used. + +*** ### Additional data (Wallets) The strategy provides access to the `Wallets` object. This contains the current balances on the exchange. @@ -426,6 +475,7 @@ if self.wallets: - `get_used(asset)` - currently tied up balance (open orders) - `get_total(asset)` - total available balance - sum of the 2 above +*** ### Additional data (Trades) A history of Trades can be retrieved in the strategy by querying the database. From 0c3bdd66aca0dab2ce912a547c57e24239babc95 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 13 May 2020 06:50:52 +0200 Subject: [PATCH 1055/1106] Update sql cheatsheet iwth current table structure --- docs/sql_cheatsheet.md | 79 +++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/docs/sql_cheatsheet.md b/docs/sql_cheatsheet.md index b7b38c3dc..895a0536a 100644 --- a/docs/sql_cheatsheet.md +++ b/docs/sql_cheatsheet.md @@ -1,13 +1,20 @@ # SQL Helper + This page contains some help if you want to edit your sqlite db. ## Install sqlite3 -**Ubuntu/Debian installation** + +Sqlite3 is a terminal based sqlite application. +Feel free to use a visual Database editor like SqliteBrowser if you feel more comfortable with that. + +### Ubuntu/Debian installation + ```bash sudo apt-get install sqlite3 ``` ## Open the DB + ```bash sqlite3 .open @@ -16,45 +23,61 @@ sqlite3 ## Table structure ### List tables + ```bash .tables ``` ### Display table structure + ```bash .schema ``` ### Trade table structure + ```sql -CREATE TABLE trades ( - id INTEGER NOT NULL, - exchange VARCHAR NOT NULL, - pair VARCHAR NOT NULL, - is_open BOOLEAN NOT NULL, - fee_open FLOAT NOT NULL, - fee_close FLOAT NOT NULL, - open_rate FLOAT, - open_rate_requested FLOAT, - close_rate FLOAT, - close_rate_requested FLOAT, - close_profit FLOAT, - stake_amount FLOAT NOT NULL, - amount FLOAT, - open_date DATETIME NOT NULL, - close_date DATETIME, - open_order_id VARCHAR, - stop_loss FLOAT, - initial_stop_loss FLOAT, - stoploss_order_id VARCHAR, - stoploss_last_update DATETIME, - max_rate FLOAT, - sell_reason VARCHAR, - strategy VARCHAR, - ticker_interval INTEGER, - PRIMARY KEY (id), - CHECK (is_open IN (0, 1)) +CREATE TABLE trades + id INTEGER NOT NULL, + exchange VARCHAR NOT NULL, + pair VARCHAR NOT NULL, + is_open BOOLEAN NOT NULL, + fee_open FLOAT NOT NULL, + fee_open_cost FLOAT, + fee_open_currency VARCHAR, + fee_close FLOAT NOT NULL, + fee_close_cost FLOAT, + fee_close_currency VARCHAR, + open_rate FLOAT, + open_rate_requested FLOAT, + open_trade_price FLOAT, + close_rate FLOAT, + close_rate_requested FLOAT, + close_profit FLOAT, + close_profit_abs FLOAT, + stake_amount FLOAT NOT NULL, + amount FLOAT, + open_date DATETIME NOT NULL, + close_date DATETIME, + open_order_id VARCHAR, + stop_loss FLOAT, + stop_loss_pct FLOAT, + initial_stop_loss FLOAT, + initial_stop_loss_pct FLOAT, + stoploss_order_id VARCHAR, + stoploss_last_update DATETIME, + max_rate FLOAT, + min_rate FLOAT, + sell_reason VARCHAR, + strategy VARCHAR, + ticker_interval INTEGER, + PRIMARY KEY (id), + CHECK (is_open IN (0, 1)) ); +CREATE INDEX ix_trades_stoploss_order_id ON trades (stoploss_order_id); +CREATE INDEX ix_trades_pair ON trades (pair); +CREATE INDEX ix_trades_is_open ON trades (is_open); + ``` ## Get all trades in the table From fe3ea8e7ec4f3c8af8dfec2a02b5299a926acf58 Mon Sep 17 00:00:00 2001 From: bmoulkaf Date: Wed, 13 May 2020 05:15:18 +0000 Subject: [PATCH 1056/1106] Fix stoploss on binance bug --- freqtrade/exchange/binance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 875628af9..37183dc2c 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -72,7 +72,7 @@ class Binance(Exchange): rate = self.price_to_precision(pair, rate) order = self._api.create_order(symbol=pair, type=ordertype, side='sell', - amount=amount, price=stop_price, params=params) + amount=amount, price=rate, params=params) logger.info('stoploss limit order added for %s. ' 'stop price: %s. limit: %s', pair, stop_price, rate) return order From 6e86a47764d1d246d4603292c864547200fa5bbf Mon Sep 17 00:00:00 2001 From: "Paul D. Mendes" Date: Wed, 13 May 2020 14:49:16 +0400 Subject: [PATCH 1057/1106] updated docs --- docs/strategy-customization.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 20cde7556..d5bc76c65 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -383,13 +383,13 @@ if self.dp: ``` #### *current_whitelist()* -Imagine you've developed a strategy that trades the `1m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume. +Imagine you've developed a strategy that trades the `5m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume. The strategy might look something like this: -*Scan through the top 10 pairs by volume using the `VolumePairList` every minute and use a 14 day ATR to buy and sell.* +*Scan through the top 10 pairs by volume using the `VolumePairList` every 5 minutes and use a 14 day ATR to buy and sell.* -Due to the limited available data, it's impossible to resample our `1m` candles into daily candles for use in the 14 day ATR. Most exchanges limit us to just 500 candles which effectively gives us around 1/3 of a daily candle. We need 14 days at least! +Due to the limited available data, it's very difficult to resample our `5m` candles into daily candles for use in a 14 day ATR. Most exchanges limit us to just 500 candles which effectively gives us around 1.74 daily candles. We need 14 days at least! Since we can't resample our data we will have to use an informative pair; and since our whitelist will be dynamic we don't know which pair(s) to use. @@ -399,7 +399,7 @@ This is where calling `self.dp.current_whitelist()` comes in handy. class SampleStrategy(IStrategy): # strategy init stuff... - ticker_interval = '1m' + ticker_interval = '5m' # more strategy init stuff.. @@ -416,8 +416,7 @@ class SampleStrategy(IStrategy): informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d') # Get the 14 day ATR. atr = ta.ATR(informative, timeperiod=14) - # Assign the Daily atr to the 1 minute dataframe. - dataframe['daily_atr'] = atr + # Do other stuff ``` #### *get_pair_dataframe(pair, timeframe)* From 6ff457e3911fecb1e471b1b4950c277eefc26300 Mon Sep 17 00:00:00 2001 From: Pedro Torres Date: Wed, 13 May 2020 20:50:11 +0800 Subject: [PATCH 1058/1106] Update doc Ta_lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the document with the latest Ta_lib-0.4.18. 👍 The requirements-common.txt has been updated previously on commit a379e68cf441407c9c04264714bfc7dbcc8e635d --- docs/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 88e2ef6eb..f017bef96 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -248,14 +248,14 @@ git clone https://github.com/freqtrade/freqtrade.git Install ta-lib according to the [ta-lib documentation](https://github.com/mrjbq7/ta-lib#windows). -As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial precompiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which needs to be downloaded and installed using `pip install TA_Lib‑0.4.17‑cp36‑cp36m‑win32.whl` (make sure to use the version matching your python version) +As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial precompiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which needs to be downloaded and installed using `pip install TA_Lib‑0.4.18‑cp38‑cp38‑win_amd64.whl` (make sure to use the version matching your python version) ```cmd >cd \path\freqtrade-develop >python -m venv .env >.env\Scripts\activate.bat REM optionally install ta-lib from wheel -REM >pip install TA_Lib‑0.4.17‑cp36‑cp36m‑win32.whl +REM >pip install TA_Lib‑0.4.18‑cp38‑cp38‑win_amd64.whl >pip install -r requirements.txt >pip install -e . >freqtrade From b3dd0a68d56f179eb11a6d3996420a1490922836 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Wed, 13 May 2020 18:51:38 +0300 Subject: [PATCH 1059/1106] minor: fix typo in configuration.md --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 67e8578dd..eb7f02d5c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -108,7 +108,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below.
        **Datatype:** Boolean | `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`.
        **Datatype:** ClassName | `strategy_path` | Adds an additional strategy lookup path (must be a directory).
        **Datatype:** String -| `internals.process_throttle_secs` | Set the process throttle. Value in second.
        *Defaults to `5` seconds.*
        **Datatype:** Positive Intege +| `internals.process_throttle_secs` | Set the process throttle. Value in second.
        *Defaults to `5` seconds.*
        **Datatype:** Positive Integer | `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages.
        *Defaults to `60` seconds.*
        **Datatype:** Positive Integer or 0 | `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
        **Datatype:** Boolean | `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file.
        **Datatype:** String From 60f26ba5014bccb42f6df91fd776b1f4ab5745f3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 13 May 2020 20:25:32 +0200 Subject: [PATCH 1060/1106] use update_trade_state also for closed stoploss orders --- freqtrade/freqtradebot.py | 59 ++++++++++++++++++++------------------ tests/test_freqtradebot.py | 3 +- tests/test_integration.py | 4 ++- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 1f9573122..8732533f7 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -752,7 +752,7 @@ class FreqtradeBot: # We check if stoploss order is fulfilled if stoploss_order and stoploss_order['status'] == 'closed': trade.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value - trade.update(stoploss_order) + self.update_trade_state(trade, stoploss_order, sl_order=True) # Lock pair for one candle to prevent immediate rebuys self.strategy.lock_pair(trade.pair, timeframe_to_next_date(self.config['ticker_interval'])) @@ -1123,7 +1123,7 @@ class FreqtradeBot: # def update_trade_state(self, trade: Trade, action_order: dict = None, - order_amount: float = None) -> bool: + order_amount: float = None, sl_order: bool = False) -> bool: """ Checks trades with open orders and updates the amount if necessary Handles closing both buy and sell orders. @@ -1131,34 +1131,37 @@ class FreqtradeBot: """ # Get order details for actual price per unit if trade.open_order_id: - # Update trade with order values - logger.info('Found open order for %s', trade) - try: - order = action_order or self.exchange.get_order(trade.open_order_id, trade.pair) - except InvalidOrderException as exception: - logger.warning('Unable to fetch order %s: %s', trade.open_order_id, exception) - return False - # Try update amount (binance-fix) - try: - new_amount = self.get_real_amount(trade, order, order_amount) - if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): - order['amount'] = new_amount - order.pop('filled', None) - trade.recalc_open_trade_price() - except DependencyException as exception: - logger.warning("Could not update trade amount: %s", exception) + order_id = trade.open_order_id + elif trade.stoploss_order_id and sl_order: + order_id = trade.stoploss_order_id + else: + return False + # Update trade with order values + logger.info('Found open order for %s', trade) + try: + order = action_order or self.exchange.get_order(order_id, trade.pair) + except InvalidOrderException as exception: + logger.warning('Unable to fetch order %s: %s', order_id, exception) + return False + # Try update amount (binance-fix) + try: + new_amount = self.get_real_amount(trade, order, order_amount) + if not isclose(order['amount'], new_amount, abs_tol=constants.MATH_CLOSE_PREC): + order['amount'] = new_amount + order.pop('filled', None) + trade.recalc_open_trade_price() + except DependencyException as exception: + logger.warning("Could not update trade amount: %s", exception) - if self.exchange.check_order_canceled_empty(order): - # Trade has been cancelled on exchange - # Handling of this will happen in check_handle_timeout. - return True - trade.update(order) + if self.exchange.check_order_canceled_empty(order): + # Trade has been cancelled on exchange + # Handling of this will happen in check_handle_timeout. + return True + trade.update(order) - # Updating wallets when order is closed - if not trade.is_open: - self.wallets.update() - - return False + # Updating wallets when order is closed + if not trade.is_open: + self.wallets.update() def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, amount: float, fee_abs: float) -> float: diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index b426368c9..2ff51dffd 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1140,7 +1140,8 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog, 'status': 'closed', 'type': 'stop_loss_limit', 'price': 3, - 'average': 2 + 'average': 2, + 'amount': limit_buy_order['amount'], }) mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hit) assert freqtrade.handle_stoploss_on_exchange(trade) is True diff --git a/tests/test_integration.py b/tests/test_integration.py index 90cdde61f..1396e86f5 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -44,6 +44,8 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, } stoploss_order_closed = stoploss_order_open.copy() stoploss_order_closed['status'] = 'closed' + stoploss_order_closed['filled'] = stoploss_order_closed['amount'] + # Sell first trade based on stoploss, keep 2nd and 3rd trade open stoploss_order_mock = MagicMock( side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open]) @@ -98,7 +100,7 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, assert cancel_order_mock.call_count == 1 # Wallets must be updated between stoploss cancellation and selling, and will be updated again # during update_trade_state - assert wallets_mock.call_count == 3 + assert wallets_mock.call_count == 4 trade = trades[0] assert trade.sell_reason == SellType.STOPLOSS_ON_EXCHANGE.value From 255ff6cd0641d2f5796038d34ae4ead799eecff3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 13 May 2020 20:52:40 +0200 Subject: [PATCH 1061/1106] Should return False if it's not been cancelled empty --- freqtrade/freqtradebot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8732533f7..7b012d7d3 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1162,6 +1162,7 @@ class FreqtradeBot: # Updating wallets when order is closed if not trade.is_open: self.wallets.update() + return False def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, amount: float, fee_abs: float) -> float: From ced812660bf6a0aeb41923ca82fada4c5df5c52c Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Wed, 13 May 2020 22:37:50 +0300 Subject: [PATCH 1062/1106] Minor fix in the strategy docs --- docs/strategy-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index d5bc76c65..dd451128c 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -331,7 +331,7 @@ class Awesomestrategy(IStrategy): #### Get data for non-tradeable pairs Data for additional, informative pairs (reference pairs) can be beneficial for some strategies. -Ohlcv data for these pairs will be downloaded as part of the regular whitelist refresh process and is available via `DataProvider` just as other pairs (see above). +Ohlcv data for these pairs will be downloaded as part of the regular whitelist refresh process and is available via `DataProvider` just as other pairs (see below). These parts will **not** be traded unless they are also specified in the pair whitelist, or have been selected by Dynamic Whitelisting. The pairs need to be specified as tuples in the format `("pair", "interval")`, with pair as the first and time interval as the second argument. From aae096c6ae30cbff0af2bf0db53f493b363e68cc Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 14 May 2020 13:36:48 +0300 Subject: [PATCH 1063/1106] Handle fetching ticker for non-existing pair safe way --- freqtrade/data/dataprovider.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/freqtrade/data/dataprovider.py b/freqtrade/data/dataprovider.py index 2efceae62..7ada4f642 100644 --- a/freqtrade/data/dataprovider.py +++ b/freqtrade/data/dataprovider.py @@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple from pandas import DataFrame from freqtrade.data.history import load_pair_history -from freqtrade.exceptions import OperationalException +from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.exchange import Exchange from freqtrade.state import RunMode @@ -97,9 +97,14 @@ class DataProvider: def ticker(self, pair: str): """ - Return last ticker data + Return last ticker data from exchange + :param pair: Pair to get the data for + :return: Ticker dict from exchange or empty dict if ticker is not available for the pair """ - return self._exchange.fetch_ticker(pair) + try: + return self._exchange.fetch_ticker(pair) + except DependencyException: + return {} def orderbook(self, pair: str, maximum: int) -> Dict[str, List]: """ From 38fd361c6865ec3986748b27f25bb90452472c1c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 14 May 2020 14:40:40 +0200 Subject: [PATCH 1064/1106] Add note about PI and docker --- docs/docker.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/docker.md b/docs/docker.md index ad98864a6..9e4e8eefc 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -22,6 +22,9 @@ Freqtrade provides an official Docker image on [Dockerhub](https://hub.docker.co !!! Note All below comands use relative directories and will have to be executed from the directory containing the `docker-compose.yml` file. +!!! Note "Docker on Raspberry" + If you're running freqtrade on a Raspberry PI, you must change the image from `freqtradeorg/freqtrade:master` to `freqtradeorg/freqtrade:master_pi` or ``freqtradeorg/freqtrade:develop_pi`, otherwise the image will not work. + ### Docker quick start Create a new directory and place the [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) in this directory. From 78b81bac48e2fbb5acee8f2f2ca897620b10a929 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Thu, 14 May 2020 16:43:16 +0300 Subject: [PATCH 1065/1106] Add test for dp.ticker() --- tests/data/test_dataprovider.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 3e42abb95..32ddfe99e 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -154,6 +154,23 @@ def test_market(mocker, default_conf, markets): assert res is None +def test_ticker(mocker, default_conf, tickers, markets): + api_mock = MagicMock() + api_mock.markets = markets + api_mock.fetch_ticker = MagicMock(side_effect=lambda x: tickers().get(x)) + exchange = get_patched_exchange(mocker, default_conf, api_mock=api_mock) + + dp = DataProvider(default_conf, exchange) + res = dp.ticker('ETH/BTC') + + assert type(res) is dict + assert 'symbol' in res + assert res['symbol'] == 'ETH/BTC' + + res = dp.ticker('UNITTEST/BTC') + assert res == {} + + def test_current_whitelist(mocker, default_conf, tickers): # patch default conf to volumepairlist default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5} From fb92300cfab9da7069b506a9943699d268b8066e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 14 May 2020 15:48:23 +0200 Subject: [PATCH 1066/1106] Update docs/docker.md Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker.md b/docs/docker.md index 9e4e8eefc..92478088a 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -23,7 +23,7 @@ Freqtrade provides an official Docker image on [Dockerhub](https://hub.docker.co All below comands use relative directories and will have to be executed from the directory containing the `docker-compose.yml` file. !!! Note "Docker on Raspberry" - If you're running freqtrade on a Raspberry PI, you must change the image from `freqtradeorg/freqtrade:master` to `freqtradeorg/freqtrade:master_pi` or ``freqtradeorg/freqtrade:develop_pi`, otherwise the image will not work. + If you're running freqtrade on a Raspberry PI, you must change the image from `freqtradeorg/freqtrade:master` to `freqtradeorg/freqtrade:master_pi` or `freqtradeorg/freqtrade:develop_pi`, otherwise the image will not work. ### Docker quick start From 481f9ba6d6f10befedcddaddd63d973ed3aa7cb0 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 03:00:55 +0300 Subject: [PATCH 1067/1106] Use list comprehension instead of filter() --- freqtrade/pairlist/VolumePairList.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index eb44fe725..7ac350de9 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -26,6 +26,7 @@ class VolumePairList(IPairList): raise OperationalException( f'`number_assets` not specified. Please check your configuration ' 'for "pairlist.config.number_assets"') + self._number_pairs = self._pairlistconfig['number_assets'] self._sort_key = self._pairlistconfig.get('sort_key', 'quoteVolume') self._min_value = self._pairlistconfig.get('min_value', 0) @@ -36,9 +37,11 @@ class VolumePairList(IPairList): 'Exchange does not support dynamic whitelist.' 'Please edit your config and restart the bot' ) + if not self._validate_keys(self._sort_key): raise OperationalException( f'key {self._sort_key} not in {SORT_VALUES}') + if self._sort_key != 'quoteVolume': logger.warning( "DEPRECATED: using any key other than quoteVolume for VolumePairList is deprecated." @@ -81,7 +84,9 @@ class VolumePairList(IPairList): self._sort_key, self._min_value) else: pairs = pairlist + self.log_on_refresh(logger.info, f"Searching {self._number_pairs} pairs: {pairs}") + return pairs def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict, @@ -100,11 +105,11 @@ class VolumePairList(IPairList): if (self._exchange.get_pair_quote_currency(k) == base_currency and v[key] is not None)] else: - # If other pairlist is in front, use the incomming pairlist. + # If other pairlist is in front, use the incoming pairlist. filtered_tickers = [v for k, v in tickers.items() if k in pairlist] if min_val > 0: - filtered_tickers = list(filter(lambda t: t[key] > min_val, filtered_tickers)) + filtered_tickers = [v for v in filtered_tickers if v[key] > min_val] sorted_tickers = sorted(filtered_tickers, reverse=True, key=lambda t: t[key]) From 2924b70fd70861555cfb664e0ce8c5ab3d6d359c Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 03:41:41 +0300 Subject: [PATCH 1068/1106] Cosmetics in tests/pairlist/ --- tests/pairlist/test_pairlist.py | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index f9e2893c3..10886d87c 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -69,44 +69,44 @@ def test_log_on_refresh(mocker, static_pl_conf, markets, tickers): def test_load_pairlist_noexist(mocker, markets, default_conf): - bot = get_patched_freqtradebot(mocker, default_conf) + freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)) - plm = PairListManager(bot.exchange, default_conf) + plm = PairListManager(freqtrade.exchange, default_conf) with pytest.raises(OperationalException, match=r"Impossible to load Pairlist 'NonexistingPairList'. " r"This class does not exist or contains Python code errors."): - PairListResolver.load_pairlist('NonexistingPairList', bot.exchange, plm, + PairListResolver.load_pairlist('NonexistingPairList', freqtrade.exchange, plm, default_conf, {}, 1) def test_refresh_market_pair_not_in_whitelist(mocker, markets, static_pl_conf): - freqtradebot = get_patched_freqtradebot(mocker, static_pl_conf) + freqtrade = get_patched_freqtradebot(mocker, static_pl_conf) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)) - freqtradebot.pairlists.refresh_pairlist() + freqtrade.pairlists.refresh_pairlist() # List ordered by BaseVolume whitelist = ['ETH/BTC', 'TKN/BTC'] # Ensure all except those in whitelist are removed - assert set(whitelist) == set(freqtradebot.pairlists.whitelist) + assert set(whitelist) == set(freqtrade.pairlists.whitelist) # Ensure config dict hasn't been changed assert (static_pl_conf['exchange']['pair_whitelist'] == - freqtradebot.config['exchange']['pair_whitelist']) + freqtrade.config['exchange']['pair_whitelist']) def test_refresh_static_pairlist(mocker, markets, static_pl_conf): - freqtradebot = get_patched_freqtradebot(mocker, static_pl_conf) + freqtrade = get_patched_freqtradebot(mocker, static_pl_conf) mocker.patch.multiple( 'freqtrade.exchange.Exchange', exchange_has=MagicMock(return_value=True), markets=PropertyMock(return_value=markets), ) - freqtradebot.pairlists.refresh_pairlist() + freqtrade.pairlists.refresh_pairlist() # List ordered by BaseVolume whitelist = ['ETH/BTC', 'TKN/BTC'] # Ensure all except those in whitelist are removed - assert set(whitelist) == set(freqtradebot.pairlists.whitelist) - assert static_pl_conf['exchange']['pair_blacklist'] == freqtradebot.pairlists.blacklist + assert set(whitelist) == set(freqtrade.pairlists.whitelist) + assert static_pl_conf['exchange']['pair_blacklist'] == freqtrade.pairlists.blacklist def test_refresh_pairlist_dynamic(mocker, shitcoinmarkets, tickers, whitelist_conf): @@ -116,7 +116,7 @@ def test_refresh_pairlist_dynamic(mocker, shitcoinmarkets, tickers, whitelist_co get_tickers=tickers, exchange_has=MagicMock(return_value=True), ) - bot = get_patched_freqtradebot(mocker, whitelist_conf) + freqtrade = get_patched_freqtradebot(mocker, whitelist_conf) # Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -124,9 +124,9 @@ def test_refresh_pairlist_dynamic(mocker, shitcoinmarkets, tickers, whitelist_co ) # argument: use the whitelist dynamically by exchange-volume whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'HOT/BTC'] - bot.pairlists.refresh_pairlist() + freqtrade.pairlists.refresh_pairlist() - assert whitelist == bot.pairlists.whitelist + assert whitelist == freqtrade.pairlists.whitelist whitelist_conf['pairlists'] = [{'method': 'VolumePairList', 'config': {} @@ -136,7 +136,7 @@ def test_refresh_pairlist_dynamic(mocker, shitcoinmarkets, tickers, whitelist_co with pytest.raises(OperationalException, match=r'`number_assets` not specified. Please check your configuration ' r'for "pairlist.config.number_assets"'): - PairListManager(bot.exchange, whitelist_conf) + PairListManager(freqtrade.exchange, whitelist_conf) def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): @@ -144,13 +144,13 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf): 'freqtrade.exchange.Exchange', exchange_has=MagicMock(return_value=True), ) - freqtradebot = get_patched_freqtradebot(mocker, whitelist_conf) + freqtrade = get_patched_freqtradebot(mocker, whitelist_conf) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets_empty)) # argument: use the whitelist dynamically by exchange-volume whitelist = [] whitelist_conf['exchange']['pair_whitelist'] = [] - freqtradebot.pairlists.refresh_pairlist() + freqtrade.pairlists.refresh_pairlist() pairslist = whitelist_conf['exchange']['pair_whitelist'] assert set(whitelist) == set(pairslist) @@ -312,18 +312,18 @@ def test_volumepairlist_caching(mocker, markets, whitelist_conf, tickers): exchange_has=MagicMock(return_value=True), get_tickers=tickers ) - bot = get_patched_freqtradebot(mocker, whitelist_conf) - assert bot.pairlists._pairlists[0]._last_refresh == 0 + freqtrade = get_patched_freqtradebot(mocker, whitelist_conf) + assert freqtrade.pairlists._pairlists[0]._last_refresh == 0 assert tickers.call_count == 0 - bot.pairlists.refresh_pairlist() + freqtrade.pairlists.refresh_pairlist() assert tickers.call_count == 1 - assert bot.pairlists._pairlists[0]._last_refresh != 0 - lrf = bot.pairlists._pairlists[0]._last_refresh - bot.pairlists.refresh_pairlist() + assert freqtrade.pairlists._pairlists[0]._last_refresh != 0 + lrf = freqtrade.pairlists._pairlists[0]._last_refresh + freqtrade.pairlists.refresh_pairlist() assert tickers.call_count == 1 # Time should not be updated. - assert bot.pairlists._pairlists[0]._last_refresh == lrf + assert freqtrade.pairlists._pairlists[0]._last_refresh == lrf def test_pairlistmanager_no_pairlist(mocker, markets, whitelist_conf, caplog): From f0c3a0d2f88ce57443c3313100cdb796f8c46f4a Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 03:59:13 +0300 Subject: [PATCH 1069/1106] Simplify VolumePairList --- freqtrade/pairlist/VolumePairList.py | 25 ++++++++++++------------- tests/pairlist/test_pairlist.py | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 7ac350de9..602a2e7cb 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -27,6 +27,7 @@ class VolumePairList(IPairList): f'`number_assets` not specified. Please check your configuration ' 'for "pairlist.config.number_assets"') + self._stake_currency = config['stake_currency'] self._number_pairs = self._pairlistconfig['number_assets'] self._sort_key = self._pairlistconfig.get('sort_key', 'quoteVolume') self._min_value = self._pairlistconfig.get('min_value', 0) @@ -79,9 +80,7 @@ class VolumePairList(IPairList): (self._last_refresh + self.refresh_period < datetime.now().timestamp())): self._last_refresh = int(datetime.now().timestamp()) - pairs = self._gen_pair_whitelist(pairlist, tickers, - self._config['stake_currency'], - self._sort_key, self._min_value) + pairs = self._gen_pair_whitelist(pairlist, tickers) else: pairs = pairlist @@ -89,29 +88,29 @@ class VolumePairList(IPairList): return pairs - def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict, - base_currency: str, key: str, min_val: int) -> List[str]: + def _gen_pair_whitelist(self, pairlist: List[str], tickers: Dict) -> List[str]: """ Updates the whitelist with with a dynamically generated list - :param base_currency: base currency as str - :param key: sort key (defaults to 'quoteVolume') + :param pairlist: pairlist to filter or sort :param tickers: Tickers (from exchange.get_tickers()). :return: List of pairs """ if self._pairlist_pos == 0: # If VolumePairList is the first in the list, use fresh pairlist # Check if pair quote currency equals to the stake currency. - filtered_tickers = [v for k, v in tickers.items() - if (self._exchange.get_pair_quote_currency(k) == base_currency - and v[key] is not None)] + filtered_tickers = [ + v for k, v in tickers.items() + if (self._exchange.get_pair_quote_currency(k) == self._stake_currency + and v[self._sort_key] is not None)] else: # If other pairlist is in front, use the incoming pairlist. filtered_tickers = [v for k, v in tickers.items() if k in pairlist] - if min_val > 0: - filtered_tickers = [v for v in filtered_tickers if v[key] > min_val] + if self._min_value > 0: + filtered_tickers = [ + v for v in filtered_tickers if v[self._sort_key] > self._min_value] - sorted_tickers = sorted(filtered_tickers, reverse=True, key=lambda t: t[key]) + sorted_tickers = sorted(filtered_tickers, reverse=True, key=lambda t: t[self._sort_key]) # Validate whitelist to only have active market pairs pairs = self._whitelist_for_active_markets([s['symbol'] for s in sorted_tickers]) diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index 10886d87c..61f6b4bd5 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -206,6 +206,7 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t pairlists, base_currency, whitelist_result, caplog) -> None: whitelist_conf['pairlists'] = pairlists + whitelist_conf['stake_currency'] = base_currency mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True)) freqtrade = get_patched_freqtradebot(mocker, whitelist_conf) @@ -215,7 +216,6 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t markets=PropertyMock(return_value=shitcoinmarkets), ) - freqtrade.config['stake_currency'] = base_currency freqtrade.pairlists.refresh_pairlist() whitelist = freqtrade.pairlists.whitelist From afa7a5846b29eaf0794a06e5ad9ec8514aca0fac Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 04:05:31 +0300 Subject: [PATCH 1070/1106] Simplify PriceFilter --- freqtrade/pairlist/PriceFilter.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index 2f7e98e24..a7c2bd2d9 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -38,14 +38,12 @@ class PriceFilter(IPairList): :return: True if the pair can stay, false if it should be removed """ if ticker['last'] is None: - self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, because " "ticker['last'] is empty (Usually no trade in the last 24h).") return False - compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'], - ticker['last']) - changeperc = (compare - ticker['last']) / ticker['last'] + compare = self._exchange.price_get_one_pip(ticker['symbol'], ticker['last']) + changeperc = compare / ticker['last'] if changeperc > self._low_price_ratio: self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " f"because 1 unit is {changeperc * 100:.3f}%") From 794ed304b1a3356d010feafe7d57816dc07b657e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 04:17:23 +0300 Subject: [PATCH 1071/1106] Make stoploss an attribute --- freqtrade/pairlist/PrecisionFilter.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 2a2ba46b7..35eed5392 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -1,6 +1,6 @@ import logging from copy import deepcopy -from typing import Dict, List +from typing import Any, Dict, List from freqtrade.pairlist.IPairList import IPairList @@ -9,6 +9,16 @@ logger = logging.getLogger(__name__) class PrecisionFilter(IPairList): + def __init__(self, exchange, pairlistmanager, + config: Dict[str, Any], pairlistconfig: Dict[str, Any], + pairlist_pos: int) -> None: + super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) + + self._stoploss = self._config.get('stoploss') + if self._stoploss is not None: + # Precalculate sanitized stoploss value to avoid recalculation for every pair + self._stoploss = 1 - abs(self._stoploss) + @property def needstickers(self) -> bool: """ @@ -49,15 +59,12 @@ class PrecisionFilter(IPairList): """ Filters and sorts pairlists and assigns and returns them again. """ - stoploss = self._config.get('stoploss') - if stoploss is not None: - # Precalculate sanitized stoploss value to avoid recalculation for every pair - stoploss = 1 - abs(stoploss) # Copy list since we're modifying this list for p in deepcopy(pairlist): ticker = tickers.get(p) # Filter out assets which would not allow setting a stoploss - if not ticker or (stoploss and not self._validate_precision_filter(ticker, stoploss)): + if not ticker or (self._stoploss + and not self._validate_precision_filter(ticker, self._stoploss)): pairlist.remove(p) continue From 2aa80f915d5a494fc30637c5f785d9a92f05c72f Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 04:24:18 +0300 Subject: [PATCH 1072/1106] Cosmetics: improve readability --- freqtrade/pairlist/PrecisionFilter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 35eed5392..7491cf1b0 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -44,15 +44,19 @@ class PrecisionFilter(IPairList): :return: True if the pair can stay, false if it should be removed """ stop_price = ticker['ask'] * stoploss + # Adjust stop-prices to precision sp = self._exchange.price_to_precision(ticker["symbol"], stop_price) + stop_gap_price = self._exchange.price_to_precision(ticker["symbol"], stop_price * 0.99) logger.debug(f"{ticker['symbol']} - {sp} : {stop_gap_price}") + if sp <= stop_gap_price: self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " f"because stop price {sp} would be <= stop limit {stop_gap_price}") return False + return True def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: From cbb2ce3708b7f1a88e6b255ef2006ac98b360788 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 04:55:28 +0300 Subject: [PATCH 1073/1106] Simplify PriceFilter --- freqtrade/pairlist/PriceFilter.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index a7c2bd2d9..166515148 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -58,14 +58,12 @@ class PriceFilter(IPairList): :param tickers: Tickers (from exchange.get_tickers()). May be cached. :return: new whitelist """ - # Copy list since we're modifying this list - for p in deepcopy(pairlist): - ticker = tickers.get(p) - if not ticker: - pairlist.remove(p) - - # Filter out assets which would not allow setting a stoploss - if self._low_price_ratio and not self._validate_ticker_lowprice(ticker): - pairlist.remove(p) + if self._low_price_ratio: + # Copy list since we're modifying this list + for p in deepcopy(pairlist): + ticker = tickers[p] + # Filter out assets which would not allow setting a stoploss + if not self._validate_ticker_lowprice(ticker): + pairlist.remove(p) return pairlist From 143e6f52af7d9f177975226e4a699d23338d51d4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 05:14:06 +0300 Subject: [PATCH 1074/1106] Simplify SpreadFilter --- freqtrade/pairlist/PrecisionFilter.py | 17 +++++++------- freqtrade/pairlist/SpreadFilter.py | 33 ++++++++++++++++----------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 7491cf1b0..422cd865c 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -41,7 +41,7 @@ class PrecisionFilter(IPairList): :param ticker: ticker dict as returned from ccxt.load_markets() :param stoploss: stoploss value as set in the configuration (already cleaned to be 1 - stoploss) - :return: True if the pair can stay, false if it should be removed + :return: True if the pair can stay, False if it should be removed """ stop_price = ticker['ask'] * stoploss @@ -63,13 +63,12 @@ class PrecisionFilter(IPairList): """ Filters and sorts pairlists and assigns and returns them again. """ - # Copy list since we're modifying this list - for p in deepcopy(pairlist): - ticker = tickers.get(p) - # Filter out assets which would not allow setting a stoploss - if not ticker or (self._stoploss - and not self._validate_precision_filter(ticker, self._stoploss)): - pairlist.remove(p) - continue + if self._stoploss: + # Copy list since we're modifying this list + for p in deepcopy(pairlist): + ticker = tickers[p] + # Filter out assets which would not allow setting a stoploss + if not self._validate_precision_filter(ticker, self._stoploss): + pairlist.remove(p) return pairlist diff --git a/freqtrade/pairlist/SpreadFilter.py b/freqtrade/pairlist/SpreadFilter.py index 49731ef11..5b886135f 100644 --- a/freqtrade/pairlist/SpreadFilter.py +++ b/freqtrade/pairlist/SpreadFilter.py @@ -31,8 +31,24 @@ class SpreadFilter(IPairList): return (f"{self.name} - Filtering pairs with ask/bid diff above " f"{self._max_spread_ratio * 100}%.") - def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: + def _validate_spread(self, ticker: dict) -> bool: + """ + Validate spread for the ticker + :param ticker: ticker dict as returned from ccxt.load_markets() + :return: True if the pair can stay, False if it should be removed + """ + if 'bid' in ticker and 'ask' in ticker: + spread = 1 - ticker['bid'] / ticker['ask'] + if spread > self._max_spread_ratio: + self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " + f"because spread {spread * 100:.3f}% >" + f"{self._max_spread_ratio * 100}%") + return False + else: + return True + return False + def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: """ Filters and sorts pairlist and returns the whitelist again. Called on each bot iteration - please use internal caching if necessary @@ -41,19 +57,10 @@ class SpreadFilter(IPairList): :return: new whitelist """ # Copy list since we're modifying this list - - spread = None for p in deepcopy(pairlist): - ticker = tickers.get(p) - assert ticker is not None - if 'bid' in ticker and 'ask' in ticker: - spread = 1 - ticker['bid'] / ticker['ask'] - if not ticker or spread > self._max_spread_ratio: - self.log_on_refresh(logger.info, f"Removed {ticker['symbol']} from whitelist, " - f"because spread {spread * 100:.3f}% >" - f"{self._max_spread_ratio * 100}%") - pairlist.remove(p) - else: + ticker = tickers[p] + # Filter out assets + if not self._validate_spread(ticker): pairlist.remove(p) return pairlist From 92b6d3e2fadb0d233839870e4a1e40f94eb496f8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 15 May 2020 08:04:14 +0200 Subject: [PATCH 1075/1106] Adjust test to reflect correct behaviour --- tests/exchange/test_binance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index e4599dcd7..1753af363 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -42,7 +42,8 @@ def test_stoploss_order_binance(default_conf, mocker): assert api_mock.create_order.call_args_list[0][1]['type'] == order_type assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 - assert api_mock.create_order.call_args_list[0][1]['price'] == 220 + # Price should be 1% below stopprice + assert api_mock.create_order.call_args_list[0][1]['price'] == 220 * 0.99 assert api_mock.create_order.call_args_list[0][1]['params'] == {'stopPrice': 220} # test exception handling From a7b469e83d67e0f0201e7ef0489ca5aab83b6dc6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 15 May 2020 08:09:53 +0200 Subject: [PATCH 1076/1106] Add test verifying correct price reduction on limit stoploss orders --- tests/exchange/test_binance.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 1753af363..52faa284b 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -9,7 +9,12 @@ from freqtrade.exceptions import (DependencyException, InvalidOrderException, from tests.conftest import get_patched_exchange -def test_stoploss_order_binance(default_conf, mocker): +@pytest.mark.parametrize('limitratio,expected', [ + (None, 220 * 0.99), + (0.99, 220 * 0.99), + (0.98, 220 * 0.98), +]) +def test_stoploss_order_binance(default_conf, mocker, limitratio, expected): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'stop_loss_limit' @@ -20,7 +25,6 @@ def test_stoploss_order_binance(default_conf, mocker): 'foo': 'bar' } }) - default_conf['dry_run'] = False mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) @@ -32,8 +36,8 @@ def test_stoploss_order_binance(default_conf, mocker): order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() - - order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) + order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio} + order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types=order_types) assert 'id' in order assert 'info' in order @@ -43,7 +47,7 @@ def test_stoploss_order_binance(default_conf, mocker): assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 # Price should be 1% below stopprice - assert api_mock.create_order.call_args_list[0][1]['price'] == 220 * 0.99 + assert api_mock.create_order.call_args_list[0][1]['price'] == expected assert api_mock.create_order.call_args_list[0][1]['params'] == {'stopPrice': 220} # test exception handling From 33091f95c29734c013d17acb88264dd2275f1ecb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 15 May 2020 06:24:54 +0000 Subject: [PATCH 1077/1106] Bump python from 3.8.2-slim-buster to 3.8.3-slim-buster Bumps python from 3.8.2-slim-buster to 3.8.3-slim-buster. Signed-off-by: dependabot-preview[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d986f20ae..b6333fb13 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8.2-slim-buster +FROM python:3.8.3-slim-buster RUN apt-get update \ && apt-get -y install curl build-essential libssl-dev \ From 323b491962e468a75a99d48a21ee79b4ae6dac3e Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 15 May 2020 16:35:48 +0300 Subject: [PATCH 1078/1106] Add description and example for dp.ticker() to the docs --- docs/strategy-customization.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index dd451128c..42474c2dc 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -367,9 +367,10 @@ Please always check the mode of operation to select the correct method to get da - [`current_whitelist()`](#current_whitelist) - Returns a current list of whitelisted pairs. Useful for accessing dynamic whitelists (ie. VolumePairlist) - [`get_pair_dataframe(pair, timeframe)`](#get_pair_dataframepair-timeframe) - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes). - `historic_ohlcv(pair, timeframe)` - Returns historical data stored on disk. -- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on Market data structure. +- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on the Market data structure. - `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame. - [`orderbook(pair, maximum)`](#orderbookpair-maximum) - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries. +- `ticker(pair)` - Returns current ticker data for the pair. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#price-tickers) for more details on the Ticker data structure. - `runmode` - Property containing the current runmode. #### Example Usages: @@ -451,6 +452,17 @@ if self.dp: The order book is not part of the historic data which means backtesting and hyperopt will not work if this method is used. +#### *ticker(pair)* + +``` python +if self.dp: + if self.dp.runmode.value in ('live', 'dry_run'): + ticker = self.dp.ticker(metadata['pair']) + dataframe['last_price'] = ticker['last'] + dataframe['volume24h'] = ticker['quoteVolume'] + dataframe['vwap'] = ticker['vwap'] +``` + *** ### Additional data (Wallets) From 06b12c0a7095e0b4ee611694cbff26bdb88fed1e Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 15 May 2020 18:46:28 +0300 Subject: [PATCH 1079/1106] Add warning to docs for ticker data --- docs/strategy-customization.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 42474c2dc..c50266183 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -370,7 +370,7 @@ Please always check the mode of operation to select the correct method to get da - `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on the Market data structure. - `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame. - [`orderbook(pair, maximum)`](#orderbookpair-maximum) - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries. -- `ticker(pair)` - Returns current ticker data for the pair. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#price-tickers) for more details on the Ticker data structure. +- [`ticker(pair)`](#tickerpair) - Returns current ticker data for the pair. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#price-tickers) for more details on the Ticker data structure. - `runmode` - Property containing the current runmode. #### Example Usages: @@ -463,6 +463,12 @@ if self.dp: dataframe['vwap'] = ticker['vwap'] ``` +!!! Warning + Although the ticker data structure is a part of the ccxt Unified Interface, the values returned by this method can + vary for different exchanges. For instance, many exchanges do not return `vwap` values, the FTX exchange + does not always fills in the `last` field (so it can be None), etc. So you need to carefully verify the ticker + data returned from the exchange you are working with. + *** ### Additional data (Wallets) From d84cb3be77b9aeda62331594ef1ce2500e5f7ee3 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 15 May 2020 19:19:52 +0300 Subject: [PATCH 1080/1106] Improve test --- tests/data/test_dataprovider.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/data/test_dataprovider.py b/tests/data/test_dataprovider.py index 32ddfe99e..c2d6e82f1 100644 --- a/tests/data/test_dataprovider.py +++ b/tests/data/test_dataprovider.py @@ -5,7 +5,7 @@ import pytest from freqtrade.data.dataprovider import DataProvider from freqtrade.pairlist.pairlistmanager import PairListManager -from freqtrade.exceptions import OperationalException +from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.state import RunMode from tests.conftest import get_patched_exchange @@ -154,19 +154,20 @@ def test_market(mocker, default_conf, markets): assert res is None -def test_ticker(mocker, default_conf, tickers, markets): - api_mock = MagicMock() - api_mock.markets = markets - api_mock.fetch_ticker = MagicMock(side_effect=lambda x: tickers().get(x)) - exchange = get_patched_exchange(mocker, default_conf, api_mock=api_mock) - +def test_ticker(mocker, default_conf, tickers): + ticker_mock = MagicMock(return_value=tickers()['ETH/BTC']) + mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock) + exchange = get_patched_exchange(mocker, default_conf) dp = DataProvider(default_conf, exchange) res = dp.ticker('ETH/BTC') - assert type(res) is dict assert 'symbol' in res assert res['symbol'] == 'ETH/BTC' + ticker_mock = MagicMock(side_effect=DependencyException('Pair not found')) + mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock) + exchange = get_patched_exchange(mocker, default_conf) + dp = DataProvider(default_conf, exchange) res = dp.ticker('UNITTEST/BTC') assert res == {} From ac076ee0af6b0ee95b902534af2a4ac51c855da8 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 15 May 2020 21:51:33 +0300 Subject: [PATCH 1081/1106] Update docs/strategy-customization.md Co-authored-by: Matthias --- docs/strategy-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index c50266183..7197b0fba 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -467,7 +467,7 @@ if self.dp: Although the ticker data structure is a part of the ccxt Unified Interface, the values returned by this method can vary for different exchanges. For instance, many exchanges do not return `vwap` values, the FTX exchange does not always fills in the `last` field (so it can be None), etc. So you need to carefully verify the ticker - data returned from the exchange you are working with. + data returned from the exchange and add appropriate error handling / defaults. *** ### Additional data (Wallets) From 61f6acb5c99734542971e49b170663eda05a93f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 May 2020 07:07:24 +0200 Subject: [PATCH 1082/1106] Add cors support - needed for UI --- freqtrade/rpc/api_server.py | 2 ++ requirements-common.txt | 1 + setup.py | 2 +- tests/rpc/test_rpc_apiserver.py | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 68f4b1ca9..61eacf639 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -7,6 +7,7 @@ from typing import Any, Callable, Dict from arrow import Arrow from flask import Flask, jsonify, request from flask.json import JSONEncoder +from flask_cors import CORS from flask_jwt_extended import (JWTManager, create_access_token, create_refresh_token, get_jwt_identity, jwt_refresh_token_required, @@ -88,6 +89,7 @@ class ApiServer(RPC): self._config = freqtrade.config self.app = Flask(__name__) + self._cors = CORS(self.app, resources={r"/api/*": {"origins": "*"}}) # Setup the Flask-JWT-Extended extension self.app.config['JWT_SECRET_KEY'] = self._config['api_server'].get( diff --git a/requirements-common.txt b/requirements-common.txt index 02c4ebc20..017974c9e 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -26,6 +26,7 @@ sdnotify==0.3.2 # Api server flask==1.1.2 flask-jwt-extended==3.24.1 +flask-cors==3.0.8 # Support for colorized terminal output colorama==0.4.3 diff --git a/setup.py b/setup.py index 8c0de095e..20963a15f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ if readme_file.is_file(): readme_long = (Path(__file__).parent / "README.md").read_text() # Requirements used for submodules -api = ['flask', 'flask-jwt-extended'] +api = ['flask', 'flask-jwt-extended', 'flask-cors'] plot = ['plotly>=4.0'] hyperopt = [ 'scipy', diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index ffdd5be15..b953097d5 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -49,6 +49,7 @@ def client_get(client, url): def assert_response(response, expected_code=200): assert response.status_code == expected_code assert response.content_type == "application/json" + assert ('Access-Control-Allow-Origin', '*') in response.headers._list def test_api_not_found(botclient): From 1b3864ebf8eb29f8e089e721d17377f22ed44384 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 16 May 2020 09:21:36 +0300 Subject: [PATCH 1083/1106] Make flake happy --- freqtrade/pairlist/VolumePairList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 602a2e7cb..46ff4b9c8 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -101,7 +101,7 @@ class VolumePairList(IPairList): filtered_tickers = [ v for k, v in tickers.items() if (self._exchange.get_pair_quote_currency(k) == self._stake_currency - and v[self._sort_key] is not None)] + and v[self._sort_key] is not None)] else: # If other pairlist is in front, use the incoming pairlist. filtered_tickers = [v for k, v in tickers.items() if k in pairlist] From c3f3242f28f01b282c6970b45a3f3bbfeea7955c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 May 2020 11:05:34 +0200 Subject: [PATCH 1084/1106] Add tests for cancel_open_orders_on_exit --- tests/test_freqtradebot.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 8adc834cf..8e3bc8928 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -48,13 +48,31 @@ def test_freqtradebot_state(mocker, default_conf, markets) -> None: assert freqtrade.state is State.STOPPED -def test_cleanup(mocker, default_conf, caplog) -> None: - mock_cleanup = MagicMock() - mocker.patch('freqtrade.persistence.cleanup', mock_cleanup) +def test_process_stopped(mocker, default_conf) -> None: + + freqtrade = get_patched_freqtradebot(mocker, default_conf) + coo_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cancel_all_open_orders') + freqtrade.process_stopped() + assert coo_mock.call_count == 0 + + default_conf['cancel_open_orders_on_exit'] = True + freqtrade = get_patched_freqtradebot(mocker, default_conf) + freqtrade.process_stopped() + assert coo_mock.call_count == 1 + + +def test_bot_cleanup(mocker, default_conf, caplog) -> None: + mock_cleanup = mocker.patch('freqtrade.persistence.cleanup') + coo_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cancel_all_open_orders') freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade.cleanup() assert log_has('Cleaning up modules ...', caplog) assert mock_cleanup.call_count == 1 + assert coo_mock.call_count == 0 + + freqtrade.config['cancel_open_orders_on_exit'] = True + freqtrade.cleanup() + assert coo_mock.call_count == 1 def test_order_dict_dry_run(default_conf, mocker, caplog) -> None: From 22a08768f73112f8f1e1cddbb63774cb988c0eba Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 May 2020 12:40:25 +0200 Subject: [PATCH 1085/1106] Add test for cancel_open_order --- tests/test_freqtradebot.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 8e3bc8928..940ae8e77 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -22,7 +22,7 @@ from freqtrade.strategy.interface import SellCheckTuple, SellType from freqtrade.worker import Worker from tests.conftest import (get_patched_freqtradebot, get_patched_worker, log_has, log_has_re, patch_edge, patch_exchange, - patch_get_signal, patch_wallet, patch_whitelist) + patch_get_signal, patch_wallet, patch_whitelist, create_mock_trades) def patch_RPCManager(mocker) -> MagicMock: @@ -3882,3 +3882,21 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, assert log_has_re(r"Unable to create trade for XRP/BTC: " r"Available balance \(0.0 BTC\) is lower than stake amount \(0.001 BTC\)", caplog) + + +@pytest.mark.usefixtures("init_persistence") +def test_cancel_all_open_orders(mocker, default_conf, fee, limit_buy_order, limit_sell_order): + default_conf['cancel_open_orders_on_exit'] = True + mocker.patch('freqtrade.exchange.Exchange.get_order', + side_effect=[DependencyException(), limit_sell_order, limit_buy_order]) + buy_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_cancel_buy') + sell_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_cancel_sell') + + freqtrade = get_patched_freqtradebot(mocker, default_conf) + create_mock_trades(fee) + trades = Trade.query.all() + assert len(trades) == 3 + freqtrade.cancel_all_open_orders() + assert buy_mock.call_count == 1 + assert sell_mock.call_count == 1 + From 7a11219b613b2ce782afa113456e2571a54817cc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 May 2020 13:17:48 +0200 Subject: [PATCH 1086/1106] Reword some documentation strings Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> --- docs/configuration.md | 2 +- freqtrade/commands/cli_options.py | 2 +- freqtrade/freqtradebot.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index b0b840fcc..7405fc92e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -51,7 +51,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
        **Datatype:** String | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode.
        *Defaults to `true`.*
        **Datatype:** Boolean | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.
        *Defaults to `1000`.*
        **Datatype:** Float -| `cancel_open_orders_on_exit` | Cancel orders when `/stop` is issued or `ctrl+c` is pressed. This will allow you to use `/stop` to cancel unfilled orders in the event of a market crash. This will not impact open positions.
        *Defaults to `False`.*
        **Datatype:** Boolean +| `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions.
        *Defaults to `false`.*
        **Datatype:** Boolean | `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
        *Defaults to `false`.*
        **Datatype:** Boolean | `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy).
        **Datatype:** Dict | `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
        **Datatype:** Float (as ratio) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index cca9d7048..7a2110a91 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -111,7 +111,7 @@ AVAILABLE_CLI_OPTIONS = { ), "cancel_open_orders_on_exit": Arg( '--cancel-open-orders-on-exit', - help='Close unfilled open orders when the bot stops / exits', + help='Close unfilled and partially filled open orders when the bot stops / exits.', action='store_true', ), # Optimize common diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index cad8b4aea..3b3758f36 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -170,7 +170,7 @@ class FreqtradeBot: def process_stopped(self) -> None: """ - Close all trades that were left open + Close all orders that were left open """ if self.config['cancel_open_orders_on_exit']: self.cancel_all_open_orders() From fed75d8718303b837f5192711f9a68189a9c7efa Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 May 2020 13:23:40 +0200 Subject: [PATCH 1087/1106] remove --cancel_open_orders cli switch --- freqtrade/commands/arguments.py | 2 +- freqtrade/commands/cli_options.py | 5 ----- freqtrade/configuration/configuration.py | 5 ----- tests/test_arguments.py | 8 -------- tests/test_configuration.py | 2 -- 5 files changed, 1 insertion(+), 21 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 234b719f7..a03da00ab 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -13,7 +13,7 @@ ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_dat ARGS_STRATEGY = ["strategy", "strategy_path"] -ARGS_TRADE = ["db_url", "sd_notify", "dry_run", "cancel_open_orders_on_exit"] +ARGS_TRADE = ["db_url", "sd_notify", "dry_run"] ARGS_COMMON_OPTIMIZE = ["ticker_interval", "timerange", "max_open_trades", "stake_amount", "fee"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 7a2110a91..a8f2ffdba 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -109,11 +109,6 @@ AVAILABLE_CLI_OPTIONS = { help='Enforce dry-run for trading (removes Exchange secrets and simulates trades).', action='store_true', ), - "cancel_open_orders_on_exit": Arg( - '--cancel-open-orders-on-exit', - help='Close unfilled and partially filled open orders when the bot stops / exits.', - action='store_true', - ), # Optimize common "ticker_interval": Arg( '-i', '--ticker-interval', diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 188d79f90..7edd9bca1 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -134,11 +134,6 @@ class Configuration: if config['runmode'] not in TRADING_MODES: return - if self.args.get('cancel_open_orders_on_exit', False): - config.update({ - 'cancel_open_orders_on_exit': self.args.get('cancel_open_orders_on_exit') - }) - if config.get('dry_run', False): logger.info('Dry run is enabled') if config.get('db_url') in [None, constants.DEFAULT_DB_PROD_URL]: diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 91501384b..0052a61d0 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -64,14 +64,6 @@ def test_parse_args_db_url() -> None: assert args["db_url"] == 'sqlite:///test.sqlite' -def test_parse_args_cancel_open_orders_on_exit() -> None: - args = Arguments(['trade']).get_parsed_arg() - assert args["cancel_open_orders_on_exit"] is False - - args = Arguments(['trade', '--cancel-open-orders-on-exit']).get_parsed_arg() - assert args["cancel_open_orders_on_exit"] is True - - def test_parse_args_verbose() -> None: args = Arguments(['trade', '-v']).get_parsed_arg() assert args["verbosity"] == 1 diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 0315ffe1b..c89f1381e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -250,7 +250,6 @@ def test_load_config_with_params(default_conf, mocker) -> None: '--strategy', 'TestStrategy', '--strategy-path', '/some/path', '--db-url', 'sqlite:///someurl', - '--cancel-open-orders-on-exit', ] args = Arguments(arglist).get_parsed_arg() configuration = Configuration(args) @@ -259,7 +258,6 @@ def test_load_config_with_params(default_conf, mocker) -> None: assert validated_conf.get('strategy') == 'TestStrategy' assert validated_conf.get('strategy_path') == '/some/path' assert validated_conf.get('db_url') == 'sqlite:///someurl' - assert validated_conf.get('cancel_open_orders_on_exit') is True # Test conf provided db_url prod conf = default_conf.copy() From baf5f4f29cd0caa5d0c76471e989a193daec0bcd Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Sat, 16 May 2020 21:28:54 +0300 Subject: [PATCH 1088/1106] Update freqtrade/constants.py --- freqtrade/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 0c8dde8c4..e56586bbc 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -326,6 +326,6 @@ SCHEMA_MINIMAL_REQUIRED = [ CANCEL_REASON = { "TIMEOUT": "cancelled due to timeout", "PARTIALLY_FILLED": "partially filled - keeping order open", - "ALL_CANCELLED": "cancelled (all unfilled orders cancelled)", + "ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)", "CANCELLED_ON_EXCHANGE": "cancelled on exchange", } From d457542d962796011a4dd23259d1a453182720d2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 17 May 2020 11:11:49 +0300 Subject: [PATCH 1089/1106] Fix PrecisionFilter --- freqtrade/pairlist/PrecisionFilter.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 422cd865c..85fa592f8 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -14,10 +14,8 @@ class PrecisionFilter(IPairList): pairlist_pos: int) -> None: super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) - self._stoploss = self._config.get('stoploss') - if self._stoploss is not None: - # Precalculate sanitized stoploss value to avoid recalculation for every pair - self._stoploss = 1 - abs(self._stoploss) + # Precalculate sanitized stoploss value to avoid recalculation for every pair + self._stoploss = 1 - abs(self._config['stoploss']) @property def needstickers(self) -> bool: @@ -63,12 +61,11 @@ class PrecisionFilter(IPairList): """ Filters and sorts pairlists and assigns and returns them again. """ - if self._stoploss: - # Copy list since we're modifying this list - for p in deepcopy(pairlist): - ticker = tickers[p] - # Filter out assets which would not allow setting a stoploss - if not self._validate_precision_filter(ticker, self._stoploss): - pairlist.remove(p) + # Copy list since we're modifying this list + for p in deepcopy(pairlist): + ticker = tickers[p] + # Filter out assets which would not allow setting a stoploss + if not self._validate_precision_filter(ticker, self._stoploss): + pairlist.remove(p) return pairlist From ce185a3b193429a0ca00cb8119ad8a99e786f422 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 17 May 2020 11:39:18 +0300 Subject: [PATCH 1090/1106] Remove pairs with no ticker available when it's needed --- freqtrade/pairlist/pairlistmanager.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/freqtrade/pairlist/pairlistmanager.py b/freqtrade/pairlist/pairlistmanager.py index 5b4c5b602..07dec912e 100644 --- a/freqtrade/pairlist/pairlistmanager.py +++ b/freqtrade/pairlist/pairlistmanager.py @@ -5,6 +5,7 @@ Provides lists as configured in config.json """ import logging +from copy import deepcopy from typing import Dict, List from cachetools import TTLCache, cached @@ -79,13 +80,14 @@ class PairListManager(): Run pairlist through all configured pairlists. """ - pairlist = self._whitelist.copy() - # tickers should be cached to avoid calling the exchange on each call. tickers: Dict = {} if self._tickers_needed: tickers = self._get_cached_tickers() + # Adjust whitelist if filters are using tickers + pairlist = self._prepare_whitelist(self._whitelist.copy(), tickers) + # Process all pairlists in chain for pl in self._pairlists: pairlist = pl.filter_pairlist(pairlist, tickers) @@ -94,3 +96,17 @@ class PairListManager(): pairlist = IPairList.verify_blacklist(pairlist, self.blacklist, True) self._whitelist = pairlist + + def _prepare_whitelist(self, pairlist: List[str], tickers) -> List[str]: + """ + Prepare pairlist for Pairlist Filters that use tickers data - remove + pairs that do not have ticker available + """ + if self._tickers_needed: + # Copy list since we're modifying this list + for p in deepcopy(pairlist): + ticker = tickers.get(p) + if not ticker: + pairlist.remove(p) + + return pairlist From 1e76bff1bd5cef49fa7f61de13ece4e5fc354b96 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 10:52:20 +0200 Subject: [PATCH 1091/1106] Add sell_order_status to keep track of cancellations --- freqtrade/persistence.py | 9 +++++++-- freqtrade/rpc/telegram.py | 8 ++++++-- tests/rpc/test_rpc.py | 2 ++ tests/rpc/test_rpc_apiserver.py | 2 ++ tests/rpc/test_rpc_telegram.py | 1 + tests/test_persistence.py | 3 +++ 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index ea34fd5bf..3f7f4e0e9 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -86,7 +86,7 @@ def check_migrate(engine) -> None: logger.debug(f'trying {table_back_name}') # Check for latest column - if not has_column(cols, 'fee_close_cost'): + if not has_column(cols, 'sell_order_status'): logger.info(f'Running database migration - backup available as {table_back_name}') fee_open = get_column_def(cols, 'fee_open', 'fee') @@ -113,6 +113,7 @@ def check_migrate(engine) -> None: close_profit_abs = get_column_def( cols, 'close_profit_abs', f"(amount * close_rate * (1 - {fee_close})) - {open_trade_price}") + sell_order_status = get_column_def(cols, 'sell_order_status', 'null') # Schema migration necessary engine.execute(f"alter table trades rename to {table_back_name}") @@ -131,7 +132,7 @@ def check_migrate(engine) -> None: stake_amount, amount, open_date, close_date, open_order_id, stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct, stoploss_order_id, stoploss_last_update, - max_rate, min_rate, sell_reason, strategy, + max_rate, min_rate, sell_reason, sell_order_status, strategy, ticker_interval, open_trade_price, close_profit_abs ) select id, lower(exchange), @@ -153,6 +154,7 @@ def check_migrate(engine) -> None: {initial_stop_loss_pct} initial_stop_loss_pct, {stoploss_order_id} stoploss_order_id, {stoploss_last_update} stoploss_last_update, {max_rate} max_rate, {min_rate} min_rate, {sell_reason} sell_reason, + {sell_order_status} sell_order_status, {strategy} strategy, {ticker_interval} ticker_interval, {open_trade_price} open_trade_price, {close_profit_abs} close_profit_abs from {table_back_name} @@ -228,6 +230,7 @@ class Trade(_DECL_BASE): # Lowest price reached min_rate = Column(Float, nullable=True) sell_reason = Column(String, nullable=True) + sell_order_status = Column(String, nullable=True) strategy = Column(String, nullable=True) ticker_interval = Column(Integer, nullable=True) @@ -267,6 +270,7 @@ class Trade(_DECL_BASE): 'stake_amount': round(self.stake_amount, 8), 'close_profit': self.close_profit, 'sell_reason': self.sell_reason, + 'sell_order_status': self.sell_order_status, 'stop_loss': self.stop_loss, 'stop_loss_pct': (self.stop_loss_pct * 100) if self.stop_loss_pct else None, 'initial_stop_loss': self.initial_stop_loss, @@ -370,6 +374,7 @@ class Trade(_DECL_BASE): self.close_profit_abs = self.calc_profit() self.close_date = datetime.utcnow() self.is_open = False + self.sell_order_status = 'closed' self.open_order_id = None logger.info( 'Marking %s as closed as the trade is fulfilled and found no open orders for it.', diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 856b8f138..19307253c 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -226,9 +226,13 @@ class Telegram(RPC): # Adding stoploss and stoploss percentage only if it is not None "*Stoploss:* `{stop_loss:.8f}` " + ("`({stop_loss_pct:.2f}%)`" if r['stop_loss_pct'] else ""), - - "*Open Order:* `{open_order}`" if r['open_order'] else "" ] + if r['open_order']: + if r['sell_order_status']: + lines.append("*Open Order:* `{open_order}` - `{sell_order_status}`") + else: + lines.append("*Open Order:* `{open_order}`") + # Filter empty lines using list-comprehension messages.append("\n".join([l for l in lines if l]).format(**r)) diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index a1e6d9f26..8a4c812a7 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -60,6 +60,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_trade_price': ANY, 'close_rate_requested': ANY, 'sell_reason': ANY, + 'sell_order_status': ANY, 'min_rate': ANY, 'max_rate': ANY, 'strategy': ANY, @@ -103,6 +104,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'open_trade_price': ANY, 'close_rate_requested': ANY, 'sell_reason': ANY, + 'sell_order_status': ANY, 'min_rate': ANY, 'max_rate': ANY, 'strategy': ANY, diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index b953097d5..a0e8e0c9e 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -520,6 +520,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets): 'open_rate_requested': 1.098e-05, 'open_trade_price': 0.0010025, 'sell_reason': None, + 'sell_order_status': None, 'strategy': 'DefaultStrategy', 'ticker_interval': 5}] @@ -626,6 +627,7 @@ def test_api_forcebuy(botclient, mocker, fee): 'open_rate_requested': None, 'open_trade_price': 0.2460546025, 'sell_reason': None, + 'sell_order_status': None, 'strategy': None, 'ticker_interval': None } diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index bbc961763..b84073dcc 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -170,6 +170,7 @@ def test_status(default_conf, update, mocker, fee, ticker,) -> None: 'current_profit': -0.59, 'initial_stop_loss': 1.098e-05, 'stop_loss': 1.099e-05, + 'sell_order_status': None, 'initial_stop_loss_pct': -0.05, 'stop_loss_pct': -0.01, 'open_order': '(limit buy rem=0.00000000)' diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 5c7686e28..25afed397 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -477,6 +477,7 @@ def test_migrate_old(mocker, default_conf, fee): assert trade.close_rate_requested is None assert trade.close_rate is not None assert pytest.approx(trade.close_profit_abs) == trade.calc_profit() + assert trade.sell_order_status is None def test_migrate_new(mocker, default_conf, fee, caplog): @@ -756,6 +757,7 @@ def test_to_json(default_conf, fee): 'stake_amount': 0.001, 'close_profit': None, 'sell_reason': None, + 'sell_order_status': None, 'stop_loss': None, 'stop_loss_pct': None, 'initial_stop_loss': None, @@ -810,6 +812,7 @@ def test_to_json(default_conf, fee): 'open_rate_requested': None, 'open_trade_price': 12.33075, 'sell_reason': None, + 'sell_order_status': None, 'strategy': None, 'ticker_interval': None} From dd55d2eea378fa385bbfa7a6ad7b9d6f81e1818a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 10:53:07 +0200 Subject: [PATCH 1092/1106] Reduce spammyness of parcial cancel orders --- freqtrade/freqtradebot.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 3b3758f36..c0d7026b2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -879,10 +879,10 @@ class FreqtradeBot: logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc()) continue - trade_state_update = self.update_trade_state(trade, order) + fully_cancelled = self.update_trade_state(trade, order) if (order['side'] == 'buy' and ( - trade_state_update + fully_cancelled or self._check_timed_out('buy', order) or strategy_safe_wrapper(self.strategy.check_buy_timeout, default_retval=False)(pair=trade.pair, @@ -891,7 +891,7 @@ class FreqtradeBot: self.handle_cancel_buy(trade, order, constants.CANCEL_REASON['TIMEOUT']) elif (order['side'] == 'sell' and ( - trade_state_update + fully_cancelled or self._check_timed_out('sell', order) or strategy_safe_wrapper(self.strategy.check_sell_timeout, default_retval=False)(pair=trade.pair, @@ -1126,6 +1126,11 @@ class FreqtradeBot: """ Sends rpc notification when a sell cancel occured. """ + if trade.sell_order_status == reason: + return + else: + trade.sell_order_status = reason + profit_rate = trade.close_rate if trade.close_rate else trade.close_rate_requested profit_trade = trade.calc_profit(rate=profit_rate) current_rate = self.get_sell_rate(trade.pair, False) From 2074d986a6c91d4bc8d80e713a8d846a3307eb83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 11:12:30 +0200 Subject: [PATCH 1093/1106] Update test to verify we're not spamming messages --- freqtrade/freqtradebot.py | 4 ++-- tests/test_freqtradebot.py | 31 ++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c0d7026b2..a6d32d8fe 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -881,7 +881,7 @@ class FreqtradeBot: fully_cancelled = self.update_trade_state(trade, order) - if (order['side'] == 'buy' and ( + if (order['side'] == 'buy' and (order['status'] == 'open' or fully_cancelled) and ( fully_cancelled or self._check_timed_out('buy', order) or strategy_safe_wrapper(self.strategy.check_buy_timeout, @@ -890,7 +890,7 @@ class FreqtradeBot: order=order))): self.handle_cancel_buy(trade, order, constants.CANCEL_REASON['TIMEOUT']) - elif (order['side'] == 'sell' and ( + elif (order['side'] == 'sell' and (order['status'] == 'open' or fully_cancelled) and ( fully_cancelled or self._check_timed_out('sell', order) or strategy_safe_wrapper(self.strategy.check_sell_timeout, diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 5c5785ca3..fb4765b48 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2407,30 +2407,47 @@ def test_handle_cancel_buy_corder_empty(mocker, default_conf, limit_buy_order, assert cancel_order_mock.call_count == 1 -def test_handle_cancel_sell_limit(mocker, default_conf) -> None: - patch_RPCManager(mocker) +def test_handle_cancel_sell_limit(mocker, default_conf, fee) -> None: + send_msg_mock = patch_RPCManager(mocker) patch_exchange(mocker) cancel_order_mock = MagicMock() mocker.patch.multiple( 'freqtrade.exchange.Exchange', - cancel_order=cancel_order_mock + cancel_order=cancel_order_mock, ) + mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate', return_value=0.245441) freqtrade = FreqtradeBot(default_conf) - freqtrade._notify_sell_cancel = MagicMock() - trade = MagicMock() + trade = Trade( + pair='LTC/ETH', + amount=2, + exchange='binance', + open_rate=0.245441, + open_order_id="123456", + open_date=arrow.utcnow().datetime, + fee_open=fee.return_value, + fee_close=fee.return_value, + ) order = {'remaining': 1, 'amount': 1, 'status': "open"} reason = CANCEL_REASON['TIMEOUT'] assert freqtrade.handle_cancel_sell(trade, order, reason) assert cancel_order_mock.call_count == 1 + assert send_msg_mock.call_count == 1 + + send_msg_mock.reset_mock() + order['amount'] = 2 - assert (freqtrade.handle_cancel_sell(trade, order, reason) - == CANCEL_REASON['PARTIALLY_FILLED']) + assert freqtrade.handle_cancel_sell(trade, order, reason) == CANCEL_REASON['PARTIALLY_FILLED'] # Assert cancel_order was not called (callcount remains unchanged) assert cancel_order_mock.call_count == 1 + assert send_msg_mock.call_count == 1 + assert freqtrade.handle_cancel_sell(trade, order, reason) == CANCEL_REASON['PARTIALLY_FILLED'] + # Message should not be iterated again + assert trade.sell_order_status == CANCEL_REASON['PARTIALLY_FILLED'] + assert send_msg_mock.call_count == 1 def test_handle_cancel_sell_cancel_exception(mocker, default_conf) -> None: From 285bc2511e61eb37a852b651f1e76ffc1eafa01a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 11:23:55 +0200 Subject: [PATCH 1094/1106] Improve testcov for default check_*_timeout methods --- tests/test_freqtradebot.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index fb4765b48..a1358abdc 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -1976,6 +1976,10 @@ def test_check_handle_timedout_buy_usercustom(default_conf, ticker, limit_buy_or Trade.session.add(open_trade) + # Ensure default is to return empty (so not mocked yet) + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 + # Return false - trade remains open freqtrade.strategy.check_buy_timeout = MagicMock(return_value=False) freqtrade.check_handle_timedout() @@ -2106,6 +2110,9 @@ def test_check_handle_timedout_sell_usercustom(default_conf, ticker, limit_sell_ open_trade.is_open = False Trade.session.add(open_trade) + # Ensure default is false + freqtrade.check_handle_timedout() + assert cancel_order_mock.call_count == 0 freqtrade.strategy.check_sell_timeout = MagicMock(return_value=False) # Return false - No impact From 97c50f86e984c7b48ab6ec192c1835ba9b9ef178 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 17 May 2020 14:10:11 +0300 Subject: [PATCH 1095/1106] Cleanup pairlistmanager --- freqtrade/pairlist/pairlistmanager.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/freqtrade/pairlist/pairlistmanager.py b/freqtrade/pairlist/pairlistmanager.py index 07dec912e..b01f1342b 100644 --- a/freqtrade/pairlist/pairlistmanager.py +++ b/freqtrade/pairlist/pairlistmanager.py @@ -1,9 +1,6 @@ """ -Static List provider - -Provides lists as configured in config.json - - """ +PairList manager class +""" import logging from copy import deepcopy from typing import Dict, List @@ -14,6 +11,7 @@ from freqtrade.exceptions import OperationalException from freqtrade.pairlist.IPairList import IPairList from freqtrade.resolvers import PairListResolver + logger = logging.getLogger(__name__) @@ -79,8 +77,7 @@ class PairListManager(): """ Run pairlist through all configured pairlists. """ - - # tickers should be cached to avoid calling the exchange on each call. + # Tickers should be cached to avoid calling the exchange on each call. tickers: Dict = {} if self._tickers_needed: tickers = self._get_cached_tickers() @@ -92,21 +89,21 @@ class PairListManager(): for pl in self._pairlists: pairlist = pl.filter_pairlist(pairlist, tickers) - # Validation against blacklist happens after the pairlists to ensure blacklist is respected. + # Validation against blacklist happens after the pairlists to ensure + # blacklist is respected. pairlist = IPairList.verify_blacklist(pairlist, self.blacklist, True) self._whitelist = pairlist def _prepare_whitelist(self, pairlist: List[str], tickers) -> List[str]: """ - Prepare pairlist for Pairlist Filters that use tickers data - remove + Prepare sanitized pairlist for Pairlist Filters that use tickers data - remove pairs that do not have ticker available """ if self._tickers_needed: # Copy list since we're modifying this list for p in deepcopy(pairlist): - ticker = tickers.get(p) - if not ticker: + if p not in tickers: pairlist.remove(p) return pairlist From ae69d31095bb5241690036c39acb2ca768b96f26 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 17 May 2020 14:13:26 +0300 Subject: [PATCH 1096/1106] Cosmetics in IPairList --- freqtrade/pairlist/IPairList.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index e089e546c..e2eb364bc 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -1,9 +1,6 @@ """ -Static List provider - -Provides lists as configured in config.json - - """ +PairList base class +""" import logging from abc import ABC, abstractmethod, abstractproperty from copy import deepcopy @@ -13,6 +10,7 @@ from cachetools import TTLCache, cached from freqtrade.exchange import market_is_active + logger = logging.getLogger(__name__) From 16622bbfadc26561fe134a08f7bfeaba89134390 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 17 May 2020 14:26:21 +0300 Subject: [PATCH 1097/1106] Cosmetics in pair lists --- freqtrade/pairlist/PrecisionFilter.py | 7 +++++-- freqtrade/pairlist/PriceFilter.py | 7 +++++-- freqtrade/pairlist/SpreadFilter.py | 4 ++++ freqtrade/pairlist/StaticPairList.py | 8 ++++---- freqtrade/pairlist/VolumePairList.py | 9 +++++---- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/freqtrade/pairlist/PrecisionFilter.py b/freqtrade/pairlist/PrecisionFilter.py index 85fa592f8..6bd9c594e 100644 --- a/freqtrade/pairlist/PrecisionFilter.py +++ b/freqtrade/pairlist/PrecisionFilter.py @@ -1,9 +1,13 @@ +""" +Precision pair list filter +""" import logging from copy import deepcopy from typing import Any, Dict, List from freqtrade.pairlist.IPairList import IPairList + logger = logging.getLogger(__name__) @@ -63,9 +67,8 @@ class PrecisionFilter(IPairList): """ # Copy list since we're modifying this list for p in deepcopy(pairlist): - ticker = tickers[p] # Filter out assets which would not allow setting a stoploss - if not self._validate_precision_filter(ticker, self._stoploss): + if not self._validate_precision_filter(tickers[p], self._stoploss): pairlist.remove(p) return pairlist diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py index 166515148..167717656 100644 --- a/freqtrade/pairlist/PriceFilter.py +++ b/freqtrade/pairlist/PriceFilter.py @@ -1,9 +1,13 @@ +""" +Price pair list filter +""" import logging from copy import deepcopy from typing import Any, Dict, List from freqtrade.pairlist.IPairList import IPairList + logger = logging.getLogger(__name__) @@ -61,9 +65,8 @@ class PriceFilter(IPairList): if self._low_price_ratio: # Copy list since we're modifying this list for p in deepcopy(pairlist): - ticker = tickers[p] # Filter out assets which would not allow setting a stoploss - if not self._validate_ticker_lowprice(ticker): + if not self._validate_ticker_lowprice(tickers[p]): pairlist.remove(p) return pairlist diff --git a/freqtrade/pairlist/SpreadFilter.py b/freqtrade/pairlist/SpreadFilter.py index 5b886135f..88e143a50 100644 --- a/freqtrade/pairlist/SpreadFilter.py +++ b/freqtrade/pairlist/SpreadFilter.py @@ -1,9 +1,13 @@ +""" +Spread pair list filter +""" import logging from copy import deepcopy from typing import Dict, List from freqtrade.pairlist.IPairList import IPairList + logger = logging.getLogger(__name__) diff --git a/freqtrade/pairlist/StaticPairList.py b/freqtrade/pairlist/StaticPairList.py index 0050fbd5c..07e559168 100644 --- a/freqtrade/pairlist/StaticPairList.py +++ b/freqtrade/pairlist/StaticPairList.py @@ -1,14 +1,14 @@ """ -Static List provider +Static Pair List provider -Provides lists as configured in config.json - - """ +Provides pair white list as it configured in config +""" import logging from typing import Dict, List from freqtrade.pairlist.IPairList import IPairList + logger = logging.getLogger(__name__) diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 46ff4b9c8..e20fb3577 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -1,9 +1,8 @@ """ Volume PairList provider -Provides lists as configured in config.json - - """ +Provides dynamic pair list based on trade volumes +""" import logging from datetime import datetime from typing import Any, Dict, List @@ -11,8 +10,10 @@ from typing import Any, Dict, List from freqtrade.exceptions import OperationalException from freqtrade.pairlist.IPairList import IPairList + logger = logging.getLogger(__name__) + SORT_VALUES = ['askVolume', 'bidVolume', 'quoteVolume'] @@ -115,7 +116,7 @@ class VolumePairList(IPairList): # Validate whitelist to only have active market pairs pairs = self._whitelist_for_active_markets([s['symbol'] for s in sorted_tickers]) pairs = self._verify_blacklist(pairs, aswarning=False) - # Limit to X number of pairs + # Limit pairlist to the requested number of pairs pairs = pairs[:self._number_pairs] return pairs From 943a2a08f858d472a84be39080dcc7c6cf93eb2f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 May 2020 20:12:01 +0200 Subject: [PATCH 1098/1106] Improve daily API format --- freqtrade/rpc/rpc.py | 26 ++++++++++++-------------- freqtrade/rpc/telegram.py | 20 ++++++++++++-------- tests/rpc/test_rpc.py | 16 +++++++++------- tests/rpc/test_rpc_apiserver.py | 6 ++++-- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index d3b6b9639..7e2934579 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -206,28 +206,26 @@ class RPC: 'trades': len(trades) } - return [ - [ - key, - '{value:.8f} {symbol}'.format( - value=float(value['amount']), - symbol=stake_currency - ), - '{value:.3f} {symbol}'.format( + data = [ + { + 'date': key, + 'abs_profit': f'{float(value["amount"]):.8f}', + 'fiat_value': '{value:.3f}'.format( value=self._fiat_converter.convert_amount( value['amount'], stake_currency, fiat_display_currency ) if self._fiat_converter else 0, - symbol=fiat_display_currency ), - '{value} trade{s}'.format( - value=value['trades'], - s='' if value['trades'] < 2 else 's' - ), - ] + 'trade_count': f'{value["trades"]}', + } for key, value in profit_days.items() ] + return { + 'stake_currency': stake_currency, + 'fiat_display_currency': fiat_display_currency, + 'data': data + } def _rpc_trade_history(self, limit: int) -> Dict: """ Returns the X last trades """ diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 856b8f138..c77567429 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -276,14 +276,18 @@ class Telegram(RPC): stake_cur, fiat_disp_cur ) - stats_tab = tabulate(stats, - headers=[ - 'Day', - f'Profit {stake_cur}', - f'Profit {fiat_disp_cur}', - f'Trades' - ], - tablefmt='simple') + stats_tab = tabulate( + [[day['date'], + f"{day['abs_profit']} {stats['stake_currency']}", + f"{day['fiat_value']} {stats['fiat_display_currency']}", + f"{day['trade_count']} trades"] for day in stats['data']], + headers=[ + 'Day', + f'Profit {stake_cur}', + f'Profit {fiat_disp_cur}', + f'Trades', + ], + tablefmt='simple') message = f'Daily Profit over the last {timescale} days:\n

        d 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

  2. x_M!XPLE%oRD~2wx0)=+L_}4j? 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�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�Qk$3gocQAho6wcwBsW*0bL|R5~rW)SVwv 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