From 1ed13f5784eea3d026ac78e63311bf14ca0d0055 Mon Sep 17 00:00:00 2001 From: Nullart Date: Thu, 14 Jun 2018 18:49:43 +0800 Subject: [PATCH 01/15] documentation updates & bug fixes in unfulfilled timeout --- README.md | 41 +++++++++++++------------ docs/configuration.md | 63 +++++++++++++++++++-------------------- freqtrade/constants.py | 9 +++--- freqtrade/freqtradebot.py | 5 ++-- freqtrade/rpc/telegram.py | 3 +- 5 files changed, 62 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 7fe20e2cb..66b77f905 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ hesitate to read the source code and understand the mechanism of this bot. ## Table of Contents - [Features](#features) - [Quick start](#quick-start) -- [Documentations](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md) - - [Installation](https://github.com/freqtrade/freqtrade/blob/develop/docs/installation.md) - - [Configuration](https://github.com/freqtrade/freqtrade/blob/develop/docs/configuration.md) - - [Strategy Optimization](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md) - - [Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/backtesting.md) - - [Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md) +- [Documentations](docs/index.md) + - [Installation](docs/installation.md) + - [Configuration](docs/configuration.md) + - [Strategy Optimization](docs/bot-optimization.md) + - [Backtesting](docs/backtesting.md) + - [Hyperopt](docs/hyperopt.md) - [Support](#support) - [Help](#help--slack) - [Bugs](#bugs--issues) @@ -84,6 +84,9 @@ strategy parameters with real exchange data. - [x] more indicators - [x] more telegram features - [x] advanced plotting +- [x] [using book orders for buy and/or sell] (docs/configuration.md) +- [x] [separated unfilled orders timeout] (docs/configuration.md) +- [x] [option to disable buying] (docs/configuration.md) ### Drawbacks @@ -99,7 +102,7 @@ strategy parameters with real exchange data. ## Quick start This quick start section is a very short explanation on how to test the bot in dry-run. We invite you to read the -[bot documentation](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md) +[bot documentation](docs/index.md) to ensure you understand how the bot is working. ### Easy installation @@ -135,26 +138,26 @@ For any questions not covered by the documentation or for further information about the bot, we encourage you to join our slack channel. - [Click here to join Slack channel](https://join.slack.com/t/highfrequencybot/shared_invite/enQtMjQ5NTM0OTYzMzY3LWMxYzE3M2MxNDdjMGM3ZTYwNzFjMGIwZGRjNTc3ZGU3MGE3NzdmZGMwNmU3NDM5ZTNmM2Y3NjRiNzk4NmM4OGE). -### [Bugs / Issues](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue) +### [Bugs / Issues](issues?q=is%3Aissue) If you discover a bug in the bot, please -[search our issue tracker](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue) +[search our issue tracker](issues?q=is%3Aissue) first. If it hasn't been reported, please -[create a new issue](https://github.com/freqtrade/freqtrade/issues/new) and +[create a new issue](issues/new) and ensure you follow the template guide so that our team can assist you as quickly as possible. -### [Feature Requests](https://github.com/freqtrade/freqtrade/labels/enhancement) +### [Feature Requests](labels/enhancement) Have you a great idea to improve the bot you want to share? Please, -first search if this feature was not [already discussed](https://github.com/freqtrade/freqtrade/labels/enhancement). +first search if this feature was not [already discussed](labels/enhancement). If it hasn't been requested, please -[create a new request](https://github.com/freqtrade/freqtrade/issues/new) +[create a new request](issues/new) and ensure you follow the template guide so that it does not get lost in the bug reports. -### [Pull Requests](https://github.com/freqtrade/freqtrade/pulls) +### [Pull Requests](pulls) Feel like our bot is missing a feature? We welcome your pull requests! Please read our -[Contributing document](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md) +[Contributing document](develop/CONTRIBUTING.md) to understand the requirements before sending your pull-requests. **Important:** Always create your PR against the `develop` branch, not @@ -197,14 +200,14 @@ optional arguments: only if dry_run is enabled. ``` More details on: -- [How to run the bot](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-usage.md#bot-commands) -- [How to use Backtesting](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-usage.md#backtesting-commands) -- [How to use Hyperopt](https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-usage.md#hyperopt-commands) +- [How to run the bot](docs/bot-usage.md#bot-commands) +- [How to use Backtesting](docs/bot-usage.md#backtesting-commands) +- [How to use Hyperopt](docs/bot-usage.md#hyperopt-commands) ### Telegram RPC commands Telegram is not mandatory. However, this is a great way to control your bot. More details on our -[documentation](https://github.com/freqtrade/freqtrade/blob/develop/docs/index.md) +[documentation](develop/docs/index.md) - `/start`: Starts the trader - `/stop`: Stops the trader diff --git a/docs/configuration.md b/docs/configuration.md index d5d53860b..028fd4e2c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -22,8 +22,15 @@ The table below will list all configuration parameters. | `dry_run` | true | Yes | Define if the bot must be in Dry-run or production mode. | `minimal_roi` | See below | No | Set the threshold in percent the bot will use to sell a trade. More information below. If set, this parameter will override `minimal_roi` from your strategy file. | `stoploss` | -0.10 | No | Value of the stoploss in percent used by the bot. More information below. If set, this parameter will override `stoploss` from your strategy file. -| `unfilledtimeout` | 0 | No | How long (in minutes) the bot will wait for an unfilled order to complete, after which the order will be cancelled. +| `disable_buy` | false | No | Disables buying of crypto-currency +| `unfilledtimeout.buy` | 10 | Yes | How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. +| `unfilledtimeout.sell` | 10 | Yes | How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. | `bid_strategy.ask_last_balance` | 0.0 | Yes | Set the bidding price. More information below. +| `bid_strategy.use_book_order` | false | No | Use book order to set the bidding price. More information below. +| `bid_strategy.book_order_top` | 1 | No | Selects the top n bidding price in book order. More information below. +| `ask_strategy.use_book_order` | false | No | Use book order to set the asking price. More information below. +| `ask_strategy.book_order_min` | 1 | No | The minimum index from the top to search for profitable asking price from book order. More information below. +| `ask_strategy.book_order_max` | 1 | No | The maximum index from the top to search for profitable asking price from book order. More information below. | `exchange.name` | bittrex | Yes | Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). | `exchange.key` | key | No | API key to use for the exchange. Only required when you are in production mode. | `exchange.secret` | secret | No | API secret to use for the exchange. Only required when you are in production mode. @@ -43,7 +50,7 @@ The table below will list all configuration parameters. The definition of each config parameters is in [misc.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/misc.py#L205). -### Understand minimal_roi +### Understanding minimal_roi `minimal_roi` is a JSON object where the key is a duration in minutes and the value is the minimum ROI in percent. See the example below: @@ -56,41 +63,31 @@ See the example below: }, ``` -Most of the strategy files already include the optimal `minimal_roi` -value. This parameter is optional. If you use it, it will take over the -`minimal_roi` value from the strategy file. +Most of the strategy files already include the optimal `minimal_roi` value. This parameter is optional. If you use it, it will take over the `minimal_roi` value from the strategy file. -### Understand stoploss -`stoploss` is loss in percentage that should trigger a sale. -For example value `-0.10` will cause immediate sell if the +### Understanding stoploss +`stoploss` is loss in percentage that should trigger a sale. For example value `-0.10` will cause immediate sell if the profit dips below -10% for a given trade. This parameter is optional. -Most of the strategy files already include the optimal `stoploss` -value. This parameter is optional. If you use it, it will take over the -`stoploss` value from the strategy file. +Most of the strategy files already include the optimal `stoploss` value. This parameter is optional. If you use it, it will take over the `stoploss` value from the strategy file. -### Understand initial_state -`initial_state` is an optional field that defines the initial application state. -Possible values are `running` or `stopped`. (default=`running`) -If the value is `stopped` the bot has to be started with `/start` first. +### Understanding initial_state +`initial_state` is an optional field that defines the initial application state. Possible values are `running` or `stopped`. (default=`running`) If the value is `stopped` the bot has to be started with `/start` first. -### Understand process_throttle_secs -`process_throttle_secs` is an optional field that defines in seconds how long the bot should wait -before asking the strategy if we should buy or a sell an asset. After each wait period, the strategy is asked again for -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. +### Understanding process_throttle_secs +`process_throttle_secs` is an optional field that defines in seconds how long the bot should wait before asking the strategy if we should buy or a sell an asset. After each wait period, the strategy is asked again for 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 -`ask_last_balance` 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. +### Understanding bid_strategy.ask_last_balance +`ask_last_balance` sets the bidding price. Value `0.0` will use `ask` price, `1.0` will use the `last` price and the 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. -### What values for exchange.name? -Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports 115 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. +### Understanding bid_strategy.use_book_order +`bid_strategy.use_book_order` loads the exchange book order and sets the bidding price between `book_order_min` and `book_order_max` value. If the `book_order_top` is set to 3, then the 3rd bidding price from the top of the book order will be selected as the bidding price for the trade. + +### Understanding ask_strategy.use_book_order +`ask_strategy.use_book_order` loads the exchange book order and sets the askng price based on the `book_order_top` value. If the `book_order_min` is set to 3 and `book_order_max` is set to 10, then the bot will search between top 3rd and 10th asking prices from the top of the book order will be selected as the bidding price for the trade. + +### What are the valid values for exchange.name? +Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports 115+ 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 thoroughly tested with only Bittrex and Binance. The bot was tested with the following exchanges: - [Bittrex](https://bittrex.com/): "bittrex" @@ -98,13 +95,13 @@ The bot was tested with the following exchanges: Feel free to test other exchanges and submit your PR to improve the bot. -### What values for fiat_display_currency? +### What are the valid values for fiat_display_currency? `fiat_display_currency` set the base currency to use for the conversion from coin to fiat in Telegram. The valid values are: "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD". In addition to central bank currencies, a range of cryto currencies are supported. The valid values are: "BTC", "ETH", "XRP", "LTC", "BCH", "USDT". -## Switch to dry-run mode +## Switch to dry-run / paper trading mode We recommend starting the bot in dry-run mode to see how your bot will behave and how is the performance of your strategy. In Dry-run mode the bot does not engage your money. It only runs a live simulation without @@ -131,7 +128,7 @@ creating trades. Once you will be happy with your bot performance, you can switch it to production mode. -## Switch to production mode +## Switch to production / live mode In production mode, the bot will engage your money. Be careful a wrong strategy can lose all your money. Be aware of what you are doing when you run it in production mode. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index bc8a7223c..85ea0727e 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -58,10 +58,10 @@ CONF_SCHEMA = { 'unfilledtimeout': { 'type': 'object', 'properties': { - 'use_book_order': {'type': 'boolean'}, 'buy': {'type': 'number', 'minimum': 3}, 'sell': {'type': 'number', 'minimum': 10} - } + }, + 'required': ['buy','sell'] }, 'bid_strategy': { 'type': 'object', @@ -75,7 +75,7 @@ CONF_SCHEMA = { 'use_book_order': {'type': 'boolean'}, 'book_order_top': {'type': 'number', 'maximum': 20, 'minimum': 1} }, - 'required': ['ask_last_balance'] + 'required': ['ask_last_balance','use_book_order'] }, 'ask_strategy': { 'type': 'object', @@ -83,7 +83,8 @@ CONF_SCHEMA = { 'use_book_order': {'type': 'boolean'}, 'book_order_min': {'type': 'number', 'minimum': 1}, 'book_order_max': {'type': 'number', 'minimum': 1} - } + }, + 'required': ['use_book_order'] }, 'exchange': {'$ref': '#/definitions/exchange'}, 'experimental': { diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ee8735d57..c97aa1697 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -164,8 +164,9 @@ class FreqtradeBot(object): if 'unfilledtimeout' in self.config: # Check and handle any timed out open orders - self.check_handle_timedout() - Trade.session.flush() + if not self.config['dry_run']: + self.check_handle_timedout() + Trade.session.flush() except TemporaryError as error: logger.warning('%s, retrying in 30 seconds...', error) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 4dd23971b..1a7e39595 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -180,7 +180,8 @@ class Telegram(RPC): headers=[ 'Day', 'Profit {}'.format(self._config['stake_currency']), - 'Profit {}'.format(self._config['fiat_display_currency']) + 'Profit {}'.format(self._config['fiat_display_currency']), + 'Trades' ], tablefmt='simple') message = 'Daily Profit over the last {} days:\n
{}
'\ From f52a7eef6a04f666ce6f74a4c19bc25b7a8e6eba Mon Sep 17 00:00:00 2001 From: Nullart Date: Thu, 14 Jun 2018 18:51:11 +0800 Subject: [PATCH 02/15] readme patch --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 66b77f905..1a987f80c 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,9 @@ strategy parameters with real exchange data. - [x] more indicators - [x] more telegram features - [x] advanced plotting -- [x] [using book orders for buy and/or sell] (docs/configuration.md) -- [x] [separated unfilled orders timeout] (docs/configuration.md) -- [x] [option to disable buying] (docs/configuration.md) +- [x] [using book orders for buy and/or sell](docs/configuration.md) +- [x] [separated unfilled orders timeout](docs/configuration.md) +- [x] [option to disable buying](docs/configuration.md) ### Drawbacks From bd1ef7a8132cc06adf04849ade7e882538e38b48 Mon Sep 17 00:00:00 2001 From: Nullart Date: Fri, 15 Jun 2018 11:03:44 +0800 Subject: [PATCH 03/15] buy & sell order book update: move up book order position to 1 --- freqtrade/freqtradebot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c97aa1697..be319cff5 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -258,7 +258,7 @@ class FreqtradeBot(object): # if ticker has lower rate, then use ticker ( usefull if down trending ) if ticker_rate < orderBook_rate: return ticker_rate - return orderBook_rate + return orderBook_rate+0.00000001 else: logger.info('Using Ask / Last Price') return ticker_rate @@ -456,7 +456,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ # if orderbook has higher rate (high profit), # use orderbook, otherwise just use sell rate if (sell_rate < orderBook_rate): - sell_rate = orderBook_rate + sell_rate = orderBook_rate-0.00000001 if self.check_sell(trade, sell_rate, buy, sell): return True From 654c69c0153082ab0352eccf756aedd18581fd89 Mon Sep 17 00:00:00 2001 From: Nullart Date: Fri, 15 Jun 2018 11:07:25 +0800 Subject: [PATCH 04/15] book order download limit to increase performance even for a little bit --- freqtrade/exchange/__init__.py | 2 +- freqtrade/freqtradebot.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index c0fc32633..e25f4c8b9 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -241,7 +241,7 @@ def get_balances() -> dict: @retrier -def get_order_book(pair: str, limit: Optional[int] = 1000) -> dict: +def get_order_book(pair: str, limit: Optional[int] = 100) -> dict: try: return _API.fetch_order_book(pair, limit) except ccxt.NotSupported as e: diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index be319cff5..a8fb11934 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -253,7 +253,7 @@ class FreqtradeBot(object): if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') - orderBook = exchange.get_order_book(pair) + orderBook = exchange.get_order_book(pair,self.config['bid_strategy']['book_order_top']) orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] # if ticker has lower rate, then use ticker ( usefull if down trending ) if ticker_rate < orderBook_rate: @@ -447,10 +447,13 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ if self.config['ask_strategy']['use_book_order']: logger.info('Using order book for selling...') - orderBook = exchange.get_order_book(trade.pair) + # logger.debug('Order book %s',orderBook) orderBook_min = self.config['ask_strategy']['book_order_min'] orderBook_max = self.config['ask_strategy']['book_order_max'] + + orderBook = exchange.get_order_book(trade.pair,orderBook_max) + for i in range(orderBook_min, orderBook_max+1): orderBook_rate = orderBook['asks'][i-1][0] # if orderbook has higher rate (high profit), From a9739d4557d5af1aead3cf917cbe992eb0a2864a Mon Sep 17 00:00:00 2001 From: Nullart Date: Fri, 15 Jun 2018 12:21:59 +0800 Subject: [PATCH 05/15] bug fix for book order not triggered, now using ticker bid --- freqtrade/freqtradebot.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index a8fb11934..2c5b9664b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -245,18 +245,22 @@ class FreqtradeBot(object): :return: float: Price """ + # Why is this ASK not BID? ticker = exchange.get_ticker(pair) - if ticker['ask'] < ticker['last']: - return ticker['ask'] - balance = self.config['bid_strategy']['ask_last_balance'] - ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + if ticker['bid'] < ticker['last']: + ticker_rate = ticker['bid'] + else: + balance = self.config['bid_strategy']['ask_last_balance'] + ticker_rate = ticker['bid'] + balance * (ticker['last'] - ticker['bid']) if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') orderBook = exchange.get_order_book(pair,self.config['bid_strategy']['book_order_top']) orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] # if ticker has lower rate, then use ticker ( usefull if down trending ) + logger.info('...book order bid rate %0.8f',orderBook_rate+0.00000001) if ticker_rate < orderBook_rate: + logger.info('...using ticker rate instead %0.8f',ticker_rate ) return ticker_rate return orderBook_rate+0.00000001 else: @@ -437,9 +441,9 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ if not trade.is_open: raise ValueError(f'attempt to handle closed trade: {trade}') - logger.debug('Handling %s ...', trade) + logger.info('Handling %s ...', trade) sell_rate = exchange.get_ticker(trade.pair)['bid'] - + logger.info(' ticker rate %0.8f',sell_rate) (buy, sell) = (False, False) if self.config.get('experimental', {}).get('use_sell_signal'): @@ -453,11 +457,12 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ orderBook_max = self.config['ask_strategy']['book_order_max'] orderBook = exchange.get_order_book(trade.pair,orderBook_max) - + for i in range(orderBook_min, orderBook_max+1): orderBook_rate = orderBook['asks'][i-1][0] # if orderbook has higher rate (high profit), # use orderbook, otherwise just use sell rate + logger.info(' order book sell rate top %s: %0.8f',i,orderBook_rate) if (sell_rate < orderBook_rate): sell_rate = orderBook_rate-0.00000001 From d682424c0468791cc810779af06b04edfd868bbe Mon Sep 17 00:00:00 2001 From: Nullart Date: Fri, 15 Jun 2018 13:39:58 +0800 Subject: [PATCH 06/15] got confused with bid and ask all of a sudden @_@.. reverting back --- freqtrade/freqtradebot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 2c5b9664b..1f3bf688b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -245,13 +245,13 @@ class FreqtradeBot(object): :return: float: Price """ - # Why is this ASK not BID? + # Why is this Ask not BID? ticker = exchange.get_ticker(pair) - if ticker['bid'] < ticker['last']: - ticker_rate = ticker['bid'] + if ticker['ask'] < ticker['last']: + ticker_rate = ticker['ask'] else: balance = self.config['bid_strategy']['ask_last_balance'] - ticker_rate = ticker['bid'] + balance * (ticker['last'] - ticker['bid']) + ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') From e5ad5a6aaacd28d8b48233436ece7dc9121c054a Mon Sep 17 00:00:00 2001 From: Nullart Date: Sun, 17 Jun 2018 06:42:02 +0800 Subject: [PATCH 07/15] added experimental "sell_fullfilled_at_roi" --- freqtrade/analyze.py | 16 ++++++++++++++-- freqtrade/constants.py | 4 ++-- freqtrade/freqtradebot.py | 29 ++++++++++++++++++----------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index c7958552b..cb04abd40 100644 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -10,7 +10,7 @@ import arrow from pandas import DataFrame, to_datetime from freqtrade import constants -from freqtrade.exchange import get_ticker_history +from freqtrade.exchange import get_fee, get_ticker_history from freqtrade.persistence import Trade from freqtrade.strategy.resolver import StrategyResolver, IStrategy @@ -196,7 +196,6 @@ class Analyze(object): :return True if bot should sell at current rate """ current_profit = trade.calc_profit_percent(current_rate) - if trade.stop_loss is None: # initially adjust the stop loss to the base value trade.adjust_stop_loss(trade.open_rate, self.strategy.stoploss) @@ -247,3 +246,16 @@ class Analyze(object): """ return {pair: self.populate_indicators(self.parse_ticker_dataframe(pair_data)) for pair, pair_data in tickerdata.items()} + + def trunc_num(self,f, n): + import math + return math.floor(f * 10 ** n) / 10 ** n + + def get_roi_rate(self, trade: Trade) -> float: + current_time = datetime.utcnow() + time_diff = (current_time.timestamp() - trade.open_date.timestamp()) / 60 + for duration, threshold in self.strategy.minimal_roi.items(): + if time_diff > duration: + roi_rate = (trade.open_rate * (1 + threshold)) * (1+(2.1*get_fee(trade.pair))) + return self.trunc_num(roi_rate,8) + diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 85ea0727e..dae7dd65c 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -58,8 +58,8 @@ CONF_SCHEMA = { 'unfilledtimeout': { 'type': 'object', 'properties': { - 'buy': {'type': 'number', 'minimum': 3}, - 'sell': {'type': 'number', 'minimum': 10} + 'buy': {'type': 'number', 'minimum': 1}, + 'sell': {'type': 'number', 'minimum': 1} }, 'required': ['buy','sell'] }, diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 1f3bf688b..13a72450b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -244,27 +244,29 @@ class FreqtradeBot(object): :param ticker: Ticker to use for getting Ask and Last Price :return: float: Price """ - - # Why is this Ask not BID? + ticker = exchange.get_ticker(pair) + logger.info('ticker data %s',ticker) + if ticker['ask'] < ticker['last']: ticker_rate = ticker['ask'] else: balance = self.config['bid_strategy']['ask_last_balance'] ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) - + if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') orderBook = exchange.get_order_book(pair,self.config['bid_strategy']['book_order_top']) orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] + orderBook_rate = orderBook_rate+0.00000001 # if ticker has lower rate, then use ticker ( usefull if down trending ) - logger.info('...book order bid rate %0.8f',orderBook_rate+0.00000001) + logger.info('...book order bid rate %0.8f',orderBook_rate) if ticker_rate < orderBook_rate: logger.info('...using ticker rate instead %0.8f',ticker_rate ) return ticker_rate - return orderBook_rate+0.00000001 + return orderBook_rate else: - logger.info('Using Ask / Last Price') + logger.info('Using Last Ask / Last Price') return ticker_rate def create_trade(self) -> bool: @@ -449,7 +451,12 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ if self.config.get('experimental', {}).get('use_sell_signal'): (buy, sell) = self.analyze.get_signal(trade.pair, self.analyze.get_ticker_interval()) - if self.config['ask_strategy']['use_book_order']: + is_set_fullfilled_at_roi = self.config.get('experimental', {}).get('sell_fullfilled_at_roi') + if is_set_fullfilled_at_roi: + sell_rate = self.analyze.get_roi_rate(trade) + logger.info('trying to selling at roi rate %0.8f',sell_rate) + + if self.config['ask_strategy']['use_book_order'] and not is_set_fullfilled_at_roi: logger.info('Using order book for selling...') # logger.debug('Order book %s',orderBook) @@ -461,15 +468,16 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ for i in range(orderBook_min, orderBook_max+1): orderBook_rate = orderBook['asks'][i-1][0] # if orderbook has higher rate (high profit), - # use orderbook, otherwise just use sell rate - logger.info(' order book sell rate top %s: %0.8f',i,orderBook_rate) + # use orderbook, otherwise just use bids rate + logger.info(' order book asks top %s: %0.8f',i,orderBook_rate) if (sell_rate < orderBook_rate): - sell_rate = orderBook_rate-0.00000001 + sell_rate = orderBook_rate if self.check_sell(trade, sell_rate, buy, sell): return True break else: + logger.info('checking sell') if self.check_sell(trade, sell_rate, buy, sell): return True @@ -510,7 +518,6 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ continue ordertime = arrow.get(order['datetime']).datetime - print(order) # Check if trade is still actually open if (int(order['filled']) == 0) and (order['status'] == 'open'): if order['side'] == 'buy' and ordertime < buy_timeoutthreashold: From 735356197d573b1c4690ffb2386f0c7a5d18fe26 Mon Sep 17 00:00:00 2001 From: Nullart Date: Sun, 17 Jun 2018 15:40:38 +0800 Subject: [PATCH 08/15] for testing feature: percent from top of book or from ask/bid --- config.json.example | 3 ++- config_full.json.example | 3 ++- freqtrade/constants.py | 3 ++- freqtrade/freqtradebot.py | 15 ++++++++++++--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/config.json.example b/config.json.example index 671e29a4d..8ff849649 100644 --- a/config.json.example +++ b/config.json.example @@ -17,7 +17,8 @@ "bid_strategy": { "ask_last_balance": 0.0, "use_book_order": true, - "book_order_top": 6 + "book_order_top": 6, + "percent_from_top": 0.005 }, "ask_strategy":{ "use_book_order": true, diff --git a/config_full.json.example b/config_full.json.example index 8a031dd65..1dbed091f 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -21,7 +21,8 @@ "bid_strategy": { "ask_last_balance": 0.0, "use_book_order": true, - "book_order_top": 6 + "book_order_top": 6, + "percent_from_top": 0.005 }, "ask_strategy":{ "use_book_order": true, diff --git a/freqtrade/constants.py b/freqtrade/constants.py index dae7dd65c..495586077 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -73,7 +73,8 @@ CONF_SCHEMA = { 'exclusiveMaximum': False }, 'use_book_order': {'type': 'boolean'}, - 'book_order_top': {'type': 'number', 'maximum': 20, 'minimum': 1} + 'book_order_top': {'type': 'number', 'maximum': 20, 'minimum': 1}, + 'percent_from_top' : {'type': 'number', 'minimum': 0} }, 'required': ['ask_last_balance','use_book_order'] }, diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 13a72450b..26a360d50 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -253,6 +253,8 @@ class FreqtradeBot(object): else: balance = self.config['bid_strategy']['ask_last_balance'] ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + + used_rate = ticker_rate if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') @@ -263,11 +265,18 @@ class FreqtradeBot(object): logger.info('...book order bid rate %0.8f',orderBook_rate) if ticker_rate < orderBook_rate: logger.info('...using ticker rate instead %0.8f',ticker_rate ) - return ticker_rate - return orderBook_rate + used_rate = ticker_rate + used_rate = orderBook_rate else: logger.info('Using Last Ask / Last Price') - return ticker_rate + used_rate = ticker_rate + + logger.info('used rate %0.8f',used_rate) + + if self.config['bid_strategy']['percent_from_top'] > 0: + used_rate = self.analyze.trunc_num(used_rate - (used_rate * self.config['bid_strategy']['percent_from_top']),8) + logger.info('used rate xx %0.8f',used_rate) + return used_rate def create_trade(self) -> bool: """ From 2f6673fbe73629cf877fe0f7b0aa2394289fde8c Mon Sep 17 00:00:00 2001 From: Nullart Date: Mon, 18 Jun 2018 18:05:43 +0800 Subject: [PATCH 09/15] tests and flake8 compliance --- freqtrade/analyze.py | 5 ++-- freqtrade/constants.py | 6 ++-- freqtrade/freqtradebot.py | 42 ++++++++++++++++------------ freqtrade/tests/conftest.py | 1 + freqtrade/tests/test_freqtradebot.py | 21 ++++++++++++-- 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index cb04abd40..80854520e 100644 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -247,7 +247,7 @@ class Analyze(object): return {pair: self.populate_indicators(self.parse_ticker_dataframe(pair_data)) for pair, pair_data in tickerdata.items()} - def trunc_num(self,f, n): + def trunc_num(self, f, n): import math return math.floor(f * 10 ** n) / 10 ** n @@ -257,5 +257,4 @@ class Analyze(object): for duration, threshold in self.strategy.minimal_roi.items(): if time_diff > duration: roi_rate = (trade.open_rate * (1 + threshold)) * (1+(2.1*get_fee(trade.pair))) - return self.trunc_num(roi_rate,8) - + return self.trunc_num(roi_rate, 8) \ No newline at end of file diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 495586077..7e69e45ff 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -61,7 +61,7 @@ CONF_SCHEMA = { 'buy': {'type': 'number', 'minimum': 1}, 'sell': {'type': 'number', 'minimum': 1} }, - 'required': ['buy','sell'] + 'required': ['buy', 'sell'] }, 'bid_strategy': { 'type': 'object', @@ -74,9 +74,9 @@ CONF_SCHEMA = { }, 'use_book_order': {'type': 'boolean'}, 'book_order_top': {'type': 'number', 'maximum': 20, 'minimum': 1}, - 'percent_from_top' : {'type': 'number', 'minimum': 0} + 'percent_from_top': {'type': 'number', 'minimum': 0} }, - 'required': ['ask_last_balance','use_book_order'] + 'required': ['ask_last_balance', 'use_book_order'] }, 'ask_strategy': { 'type': 'object', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 26a360d50..823911991 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -244,9 +244,8 @@ class FreqtradeBot(object): :param ticker: Ticker to use for getting Ask and Last Price :return: float: Price """ - ticker = exchange.get_ticker(pair) - logger.info('ticker data %s',ticker) + logger.info('ticker data %s', ticker) if ticker['ask'] < ticker['last']: ticker_rate = ticker['ask'] @@ -255,28 +254,32 @@ class FreqtradeBot(object): ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask']) used_rate = ticker_rate - + if self.config['bid_strategy']['use_book_order']: logger.info('Getting price from Order Book') - orderBook = exchange.get_order_book(pair,self.config['bid_strategy']['book_order_top']) + orderBook = exchange.get_order_book(pair, self.config['bid_strategy']['book_order_top']) orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] orderBook_rate = orderBook_rate+0.00000001 # if ticker has lower rate, then use ticker ( usefull if down trending ) - logger.info('...book order bid rate %0.8f',orderBook_rate) + logger.info('...book order bid rate %0.8f', orderBook_rate) if ticker_rate < orderBook_rate: - logger.info('...using ticker rate instead %0.8f',ticker_rate ) + logger.info('...using ticker rate instead %0.8f', ticker_rate) used_rate = ticker_rate used_rate = orderBook_rate else: logger.info('Using Last Ask / Last Price') used_rate = ticker_rate - logger.info('used rate %0.8f',used_rate) + logger.info('used rate %0.8f', used_rate) + logger.info('percent_from_top %0.8f', self.config['bid_strategy']['percent_from_top']) + logger.info('percent_from_top %s', self.config['bid_strategy']['percent_from_top'] > 0) if self.config['bid_strategy']['percent_from_top'] > 0: - used_rate = self.analyze.trunc_num(used_rate - (used_rate * self.config['bid_strategy']['percent_from_top']),8) - logger.info('used rate xx %0.8f',used_rate) - return used_rate + used_rate = used_rate - (used_rate * self.config['bid_strategy']['percent_from_top']) + used_rate = self.analyze.trunc_num(used_rate, 8) + logger.info('used rate xx %0.8f', used_rate) + + return used_rate def create_trade(self) -> bool: """ @@ -285,6 +288,7 @@ class FreqtradeBot(object): :return: True if a trade object has been created and persisted, False otherwise """ stake_amount = self.config['stake_amount'] + interval = self.analyze.get_ticker_interval() stake_currency = self.config['stake_currency'] fiat_currency = self.config['fiat_display_currency'] @@ -295,8 +299,10 @@ class FreqtradeBot(object): stake_amount ) whitelist = copy.deepcopy(self.config['exchange']['pair_whitelist']) + # Check if stake_amount is fulfilled - if exchange.get_balance(stake_currency) < stake_amount: + current_balance = exchange.get_balance(self.config['stake_currency']) + if current_balance < stake_amount: raise DependencyException( f'stake amount is not fulfilled (currency={stake_currency})') @@ -454,7 +460,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ logger.info('Handling %s ...', trade) sell_rate = exchange.get_ticker(trade.pair)['bid'] - logger.info(' ticker rate %0.8f',sell_rate) + logger.info(' ticker rate %0.8f', sell_rate) (buy, sell) = (False, False) if self.config.get('experimental', {}).get('use_sell_signal'): @@ -463,22 +469,22 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ is_set_fullfilled_at_roi = self.config.get('experimental', {}).get('sell_fullfilled_at_roi') if is_set_fullfilled_at_roi: sell_rate = self.analyze.get_roi_rate(trade) - logger.info('trying to selling at roi rate %0.8f',sell_rate) + logger.info('trying to selling at roi rate %0.8f', sell_rate) if self.config['ask_strategy']['use_book_order'] and not is_set_fullfilled_at_roi: logger.info('Using order book for selling...') - + # logger.debug('Order book %s',orderBook) orderBook_min = self.config['ask_strategy']['book_order_min'] orderBook_max = self.config['ask_strategy']['book_order_max'] - orderBook = exchange.get_order_book(trade.pair,orderBook_max) - + orderBook = exchange.get_order_book(trade.pair, orderBook_max) + for i in range(orderBook_min, orderBook_max+1): orderBook_rate = orderBook['asks'][i-1][0] # if orderbook has higher rate (high profit), # use orderbook, otherwise just use bids rate - logger.info(' order book asks top %s: %0.8f',i,orderBook_rate) + logger.info(' order book asks top %s: %0.8f', i, orderBook_rate) if (sell_rate < orderBook_rate): sell_rate = orderBook_rate @@ -528,7 +534,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ ordertime = arrow.get(order['datetime']).datetime # Check if trade is still actually open - if (int(order['filled']) == 0) and (order['status'] == 'open'): + if (order['status'] == 'open'): if order['side'] == 'buy' and ordertime < buy_timeoutthreashold: self.handle_timedout_limit_buy(trade, order) elif order['side'] == 'sell' and ordertime < sell_timeoutthreashold: diff --git a/freqtrade/tests/conftest.py b/freqtrade/tests/conftest.py index ab5a6ce17..2a18cb9a7 100644 --- a/freqtrade/tests/conftest.py +++ b/freqtrade/tests/conftest.py @@ -98,6 +98,7 @@ def default_conf(): "use_book_order": False, "book_order_top": 6, "ask_last_balance": 0.0, + "percent_from_top": 0.0 }, "ask_strategy": { "use_book_order": False, diff --git a/freqtrade/tests/test_freqtradebot.py b/freqtrade/tests/test_freqtradebot.py index dc3fd388b..0b8260026 100644 --- a/freqtrade/tests/test_freqtradebot.py +++ b/freqtrade/tests/test_freqtradebot.py @@ -499,7 +499,12 @@ def test_balance_fully_ask_side(mocker) -> None: """ Test get_target_bid() method """ - param = {'use_book_order': False, 'book_order_top': 6, 'ask_last_balance': 0.0} + param = { + 'use_book_order': False, + 'book_order_top': 6, + 'ask_last_balance': 0.0, + 'percent_from_top': 0 + } freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': param}) assert freqtrade.get_target_bid('ETH/BTC') >= 0.07 @@ -509,7 +514,12 @@ def test_balance_fully_last_side(mocker) -> None: """ Test get_target_bid() method """ - param = {'use_book_order': False, 'book_order_top': 6, 'ask_last_balance': 0.0} + param = { + 'use_book_order': False, + 'book_order_top': 6, + 'ask_last_balance': 0.0, + 'percent_from_top': 0 + } freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': param}) assert freqtrade.get_target_bid('ETH/BTC') >= 0.07 @@ -519,7 +529,12 @@ def test_balance_bigger_last_ask(mocker) -> None: """ Test get_target_bid() method """ - param = {'use_book_order': False, 'book_order_top': 6, 'ask_last_balance': 0.0} + param = { + 'use_book_order': False, + 'book_order_top': 6, + 'ask_last_balance': 0.0, + 'percent_from_top': 0.00 + } freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': param}) assert freqtrade.get_target_bid('ETH/BTC') >= 0.07 From 921f18b5188e3929edabb843d35430d52a0ab224 Mon Sep 17 00:00:00 2001 From: Nullart Date: Mon, 18 Jun 2018 18:25:40 +0800 Subject: [PATCH 10/15] docs update --- README.md | 1 + docs/configuration.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 1a987f80c..9bca7032e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ strategy parameters with real exchange data. - [x] [using book orders for buy and/or sell](docs/configuration.md) - [x] [separated unfilled orders timeout](docs/configuration.md) - [x] [option to disable buying](docs/configuration.md) +- [x] [option to get a buy price based on %](docs/configuration.md) ### Drawbacks diff --git a/docs/configuration.md b/docs/configuration.md index 028fd4e2c..5ec5462ea 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -28,6 +28,7 @@ The table below will list all configuration parameters. | `bid_strategy.ask_last_balance` | 0.0 | Yes | Set the bidding price. More information below. | `bid_strategy.use_book_order` | false | No | Use book order to set the bidding price. More information below. | `bid_strategy.book_order_top` | 1 | No | Selects the top n bidding price in book order. More information below. +| `bid_strategy.percent_from_top` | 1 | No | Set the percent to deduct from the buy rate from book order (if enabled) or from ask/last price. More information below. | `ask_strategy.use_book_order` | false | No | Use book order to set the asking price. More information below. | `ask_strategy.book_order_min` | 1 | No | The minimum index from the top to search for profitable asking price from book order. More information below. | `ask_strategy.book_order_max` | 1 | No | The maximum index from the top to search for profitable asking price from book order. More information below. @@ -83,6 +84,9 @@ Most of the strategy files already include the optimal `stoploss` value. This pa ### Understanding bid_strategy.use_book_order `bid_strategy.use_book_order` loads the exchange book order and sets the bidding price between `book_order_min` and `book_order_max` value. If the `book_order_top` is set to 3, then the 3rd bidding price from the top of the book order will be selected as the bidding price for the trade. +### Understanding bid_strategy.percent_from_top +`bid_strategy.percent_from_top` sets the percent to deduct from buy price of the pair. If `bid_strategy.use_book_order` is enabled, the percent value is deducted from the rate of `book_order_top`, otherwise, the percent value is deducted from the value provided by `bid_strategy.ask_last_balance`. Example: If `ask_last_balance` rate is 100 and the `bid_strategy.percent_from_top` is `0.005` or `0.5%`, the bot would buy at the price of `99.5`. + ### Understanding ask_strategy.use_book_order `ask_strategy.use_book_order` loads the exchange book order and sets the askng price based on the `book_order_top` value. If the `book_order_min` is set to 3 and `book_order_max` is set to 10, then the bot will search between top 3rd and 10th asking prices from the top of the book order will be selected as the bidding price for the trade. From 6c300e0a05e714b615ec90789f7050ff9f682fe4 Mon Sep 17 00:00:00 2001 From: Nullart Date: Mon, 18 Jun 2018 18:42:48 +0800 Subject: [PATCH 11/15] docs update --- config.json.example | 3 ++- config_full.json.example | 3 ++- docs/configuration.md | 23 ++++++++++++----------- freqtrade/constants.py | 3 ++- freqtrade/freqtradebot.py | 8 ++------ 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/config.json.example b/config.json.example index 8ff849649..9dab7b998 100644 --- a/config.json.example +++ b/config.json.example @@ -47,7 +47,8 @@ }, "experimental": { "use_sell_signal": false, - "sell_profit_only": false + "sell_profit_only": false, + "sell_fullfilled_at_roi": false }, "telegram": { "enabled": true, diff --git a/config_full.json.example b/config_full.json.example index 1dbed091f..1601f672e 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -51,7 +51,8 @@ }, "experimental": { "use_sell_signal": false, - "sell_profit_only": false + "sell_profit_only": false, + "sell_fullfilled_at_roi": false }, "telegram": { "enabled": true, diff --git a/docs/configuration.md b/docs/configuration.md index 5ec5462ea..925af823b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -18,20 +18,20 @@ The table below will list all configuration parameters. | `stake_currency` | BTC | Yes | Crypto-currency used for trading. | `stake_amount` | 0.05 | Yes | Amount of crypto-currency your bot will use for each trade. Per default, the bot will use (0.05 BTC x 3) = 0.15 BTC in total will be always engaged. | `ticker_interval` | [1m, 5m, 30m, 1h, 1d] | No | The ticker interval to use (1min, 5 min, 30 min, 1 hour or 1 day). Default is 5 minutes -| `fiat_display_currency` | USD | Yes | Fiat currency used to show your profits. More information below. -| `dry_run` | true | Yes | Define if the bot must be in Dry-run or production mode. -| `minimal_roi` | See below | No | Set the threshold in percent the bot will use to sell a trade. More information below. If set, this parameter will override `minimal_roi` from your strategy file. +| `fiat_display_currency` | USD | Yes | Fiat currency used to show your profits. [More information below](docs/configuration.md#what-are-the-valid-values-for-fiat_display_currency). +| `dry_run` | true | Yes | Define if the bot must be in Dry-run or production mode. [More information below](docs/configuration.md#switch-to-dry-run--paper-trading-mode) +| `minimal_roi` | See below | No | Set the threshold in percent the bot will use to sell a trade. More information below. If set, this parameter will override `minimal_roi` from your strategy file. [More information below](docs/configuration.md#understanding-minimal_roi). | `stoploss` | -0.10 | No | Value of the stoploss in percent used by the bot. More information below. If set, this parameter will override `stoploss` from your strategy file. -| `disable_buy` | false | No | Disables buying of crypto-currency +| `disable_buy` | false | No | Disables buying of crypto-currency. Bot will continue to sell. | `unfilledtimeout.buy` | 10 | Yes | How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. | `unfilledtimeout.sell` | 10 | Yes | How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. -| `bid_strategy.ask_last_balance` | 0.0 | Yes | Set the bidding price. More information below. -| `bid_strategy.use_book_order` | false | No | Use book order to set the bidding price. More information below. -| `bid_strategy.book_order_top` | 1 | No | Selects the top n bidding price in book order. More information below. -| `bid_strategy.percent_from_top` | 1 | No | Set the percent to deduct from the buy rate from book order (if enabled) or from ask/last price. More information below. +| `bid_strategy.ask_last_balance` | 0.0 | Yes | Set the bidding price. [More information below](docs/configuration.md#understanding-bid_strategyask_last_balance). +| `bid_strategy.use_book_order` | false | No | Use book order to set the bidding price. [More information below](docs/configuration.md#understanding-bid_strategyuse_book_order). +| `bid_strategy.book_order_top` | 1 | No | Selects the top n bidding price in book order. [More information below](docs/configuration.md#understanding-bid_strategyuse_book_order). +| `bid_strategy.percent_from_top` | 0 | No | Set the percent to deduct from the buy rate from book order (if enabled) or from ask/last price. [More information below](docs/configuration.md#understanding-bid_strategypercent_from_top). | `ask_strategy.use_book_order` | false | No | Use book order to set the asking price. More information below. -| `ask_strategy.book_order_min` | 1 | No | The minimum index from the top to search for profitable asking price from book order. More information below. -| `ask_strategy.book_order_max` | 1 | No | The maximum index from the top to search for profitable asking price from book order. More information below. +| `ask_strategy.book_order_min` | 1 | No | The minimum index from the top to search for profitable asking price from book order. [More information below](docs/configuration.md#understanding-ask_strategyuse_book_order). +| `ask_strategy.book_order_max` | 1 | No | The maximum index from the top to search for profitable asking price from book order. [More information below](docs/configuration.md#understanding-ask_strategyuse_book_order). | `exchange.name` | bittrex | Yes | Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). | `exchange.key` | key | No | API key to use for the exchange. Only required when you are in production mode. | `exchange.secret` | secret | No | API secret to use for the exchange. Only required when you are in production mode. @@ -39,11 +39,12 @@ The table below will list all configuration parameters. | `exchange.pair_blacklist` | [] | No | List of currency the bot must avoid. Useful when using `--dynamic-whitelist` param. | `experimental.use_sell_signal` | false | No | Use your sell strategy in addition of the `minimal_roi`. | `experimental.sell_profit_only` | false | No | waits until you have made a positive profit before taking a sell decision. +| `experimental.sell_fullfilled_at_roi` | false | No | automatically creates a sell order based on `minimal_roi` once a buy order has been fullfilled. | `telegram.enabled` | true | Yes | Enable or not the usage of Telegram. | `telegram.token` | token | No | Your Telegram bot token. Only required if `telegram.enabled` is `true`. | `telegram.chat_id` | chat_id | No | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. | `db_url` | `sqlite:///tradesv3.sqlite` | No | Declares database URL to use. NOTE: This defaults to `sqlite://` if `dry_run` is `True`. -| `initial_state` | running | No | Defines the initial application state. More information below. +| `initial_state` | running | No | Defines the initial application state. [More information below](docs/configuration.md#understanding-initial_state). | `strategy` | DefaultStrategy | No | Defines Strategy class to use. | `strategy_path` | null | No | Adds an additional strategy lookup path (must be a folder). | `internals.process_throttle_secs` | 5 | Yes | Set the process throttle. Value in second. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 7e69e45ff..4031f9eed 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -92,7 +92,8 @@ CONF_SCHEMA = { 'type': 'object', 'properties': { 'use_sell_signal': {'type': 'boolean'}, - 'sell_profit_only': {'type': 'boolean'} + 'sell_profit_only': {'type': 'boolean'}, + 'sell_fullfilled_at_roi' : {'type': 'boolean'} } }, 'telegram': { diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 823911991..1fb93e007 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -261,7 +261,7 @@ class FreqtradeBot(object): orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] orderBook_rate = orderBook_rate+0.00000001 # if ticker has lower rate, then use ticker ( usefull if down trending ) - logger.info('...book order bid rate %0.8f', orderBook_rate) + logger.info('...book order buy rate %0.8f', orderBook_rate) if ticker_rate < orderBook_rate: logger.info('...using ticker rate instead %0.8f', ticker_rate) used_rate = ticker_rate @@ -270,14 +270,10 @@ class FreqtradeBot(object): logger.info('Using Last Ask / Last Price') used_rate = ticker_rate - logger.info('used rate %0.8f', used_rate) - - logger.info('percent_from_top %0.8f', self.config['bid_strategy']['percent_from_top']) - logger.info('percent_from_top %s', self.config['bid_strategy']['percent_from_top'] > 0) if self.config['bid_strategy']['percent_from_top'] > 0: used_rate = used_rate - (used_rate * self.config['bid_strategy']['percent_from_top']) used_rate = self.analyze.trunc_num(used_rate, 8) - logger.info('used rate xx %0.8f', used_rate) + logger.info('...percent_from_top enabled, new buy rate %0.8f', used_rate) return used_rate From d4e500fb53ab27171b015589bdce4c23f579ed2b Mon Sep 17 00:00:00 2001 From: nullart Date: Tue, 19 Jun 2018 07:39:17 +0800 Subject: [PATCH 12/15] Update freqtradebot.py added default config settings --- freqtrade/freqtradebot.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index e051e9268..9a801e319 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -257,8 +257,9 @@ class FreqtradeBot(object): if self.config['bid_strategy'].get('use_book_order', False): logger.info('Getting price from Order Book') - orderBook = exchange.get_order_book(pair, self.config['bid_strategy']['book_order_top']) - orderBook_rate = orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] + orderBook_top = self.config.get('bid_strategy',{}).get('book_order_top',1) + orderBook = exchange.get_order_book(pair, orderBook_top) + orderBook_rate = orderBook['bids'][orderBook_top][0] orderBook_rate = orderBook_rate+0.00000001 # if ticker has lower rate, then use ticker ( usefull if down trending ) logger.info('...book order buy rate %0.8f', orderBook_rate) @@ -269,9 +270,9 @@ class FreqtradeBot(object): else: logger.info('Using Last Ask / Last Price') used_rate = ticker_rate - + percent_from_top = self.config.get('bid_strategy',{}).get('percent_from_top',0) if self.config['bid_strategy']['percent_from_top'] > 0: - used_rate = used_rate - (used_rate * self.config['bid_strategy']['percent_from_top']) + used_rate = used_rate - (used_rate * percent_from_top) used_rate = self.analyze.trunc_num(used_rate, 8) logger.info('...percent_from_top enabled, new buy rate %0.8f', used_rate) @@ -462,7 +463,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ if self.config.get('experimental', {}).get('use_sell_signal'): (buy, sell) = self.analyze.get_signal(trade.pair, self.analyze.get_ticker_interval()) - is_set_fullfilled_at_roi = self.config.get('experimental', {}).get('sell_fullfilled_at_roi') + is_set_fullfilled_at_roi = self.config.get('experimental', {}).get('sell_fullfilled_at_roi', False) if is_set_fullfilled_at_roi: sell_rate = self.analyze.get_roi_rate(trade) logger.info('trying to selling at roi rate %0.8f', sell_rate) From 8193ce557c93e7055695cfcd544be3cb65deb89d Mon Sep 17 00:00:00 2001 From: nullart Date: Tue, 19 Jun 2018 07:43:33 +0800 Subject: [PATCH 13/15] Update freqtradebot.py --- freqtrade/freqtradebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 9a801e319..39278e73a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -271,7 +271,7 @@ class FreqtradeBot(object): logger.info('Using Last Ask / Last Price') used_rate = ticker_rate percent_from_top = self.config.get('bid_strategy',{}).get('percent_from_top',0) - if self.config['bid_strategy']['percent_from_top'] > 0: + if percent_from_top > 0: used_rate = used_rate - (used_rate * percent_from_top) used_rate = self.analyze.trunc_num(used_rate, 8) logger.info('...percent_from_top enabled, new buy rate %0.8f', used_rate) From 65ce10a12441b27fc490a8d44785ec6e47692ca5 Mon Sep 17 00:00:00 2001 From: nullart Date: Tue, 19 Jun 2018 07:52:22 +0800 Subject: [PATCH 14/15] Update freqtradebot.py --- freqtrade/freqtradebot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 39278e73a..f0180768e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -259,7 +259,8 @@ class FreqtradeBot(object): logger.info('Getting price from Order Book') orderBook_top = self.config.get('bid_strategy',{}).get('book_order_top',1) orderBook = exchange.get_order_book(pair, orderBook_top) - orderBook_rate = orderBook['bids'][orderBook_top][0] + # top 1 = index 0 + orderBook_rate = orderBook['bids'][orderBook_top-1][0] orderBook_rate = orderBook_rate+0.00000001 # if ticker has lower rate, then use ticker ( usefull if down trending ) logger.info('...book order buy rate %0.8f', orderBook_rate) From 97a621325b647dd53c6566453ca3a66435636cd8 Mon Sep 17 00:00:00 2001 From: Nullart Date: Tue, 19 Jun 2018 21:33:42 +0800 Subject: [PATCH 15/15] bug fix: book order limit for binance --- freqtrade/constants.py | 2 +- freqtrade/exchange/__init__.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 4031f9eed..4e15d471c 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -83,7 +83,7 @@ CONF_SCHEMA = { 'properties': { 'use_book_order': {'type': 'boolean'}, 'book_order_min': {'type': 'number', 'minimum': 1}, - 'book_order_max': {'type': 'number', 'minimum': 1} + 'book_order_max': {'type': 'number', 'minimum': 1, 'maximum': 50} }, 'required': ['use_book_order'] }, diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index e25f4c8b9..be5c3940d 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -243,6 +243,16 @@ def get_balances() -> dict: @retrier def get_order_book(pair: str, limit: Optional[int] = 100) -> dict: try: + params = {} + # 20180619: bittrex doesnt support limits -.- + # 20180619: binance limit fix.. binance currently has valid range + if _API.name == 'Binance': + limit_range = [5, 10, 20, 50, 100, 500, 1000] + for limitx in limit_range: + if limit < limitx: + limit = limitx + break + return _API.fetch_order_book(pair, limit) except ccxt.NotSupported as e: raise OperationalException(