diff --git a/README.md b/README.md index 2074f2a07..8fe97f630 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,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) @@ -85,6 +85,10 @@ 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] [option to get a buy price based on %](docs/configuration.md) ### Drawbacks @@ -100,7 +104,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 @@ -136,26 +140,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 @@ -198,14 +202,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/config.json.example b/config.json.example index 671e29a4d..9dab7b998 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, @@ -46,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 8a031dd65..1601f672e 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, @@ -50,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 d5d53860b..925af823b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -18,12 +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. -| `unfilledtimeout` | 0 | No | How long (in minutes) the bot will wait for an unfilled 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. +| `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](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](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. @@ -31,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. @@ -43,7 +52,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 +65,34 @@ 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 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. + +### 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 +100,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 +133,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/analyze.py b/freqtrade/analyze.py index 9fcb70a76..18586982c 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 @@ -197,7 +197,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) @@ -248,3 +247,15 @@ 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) \ No newline at end of file diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 7558ae032..e2d8e6a28 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} - } + 'buy': {'type': 'number', 'minimum': 1}, + 'sell': {'type': 'number', 'minimum': 1} + }, + 'required': ['buy', 'sell'] }, 'bid_strategy': { 'type': 'object', @@ -73,24 +73,27 @@ 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'] + 'required': ['ask_last_balance', 'use_book_order'] }, 'ask_strategy': { 'type': 'object', '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'] }, 'exchange': {'$ref': '#/definitions/exchange'}, 'experimental': { '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/exchange/__init__.py b/freqtrade/exchange/__init__.py index 39767cd32..16402d54b 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -242,8 +242,18 @@ 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: + 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( diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ecd5cf952..f0180768e 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) @@ -243,24 +244,40 @@ 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) + 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']) + ticker_rate = ticker['ask'] + 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'].get('use_book_order', False): logger.info('Getting price from Order Book') - orderBook = exchange.get_order_book(pair) - 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) + # 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) if ticker_rate < orderBook_rate: - return ticker_rate - return orderBook_rate + logger.info('...using ticker rate instead %0.8f', ticker_rate) + used_rate = ticker_rate + used_rate = orderBook_rate else: - logger.info('Using Ask / Last Price') - return ticker_rate + 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 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) + + return used_rate def create_trade(self) -> bool: """ @@ -269,6 +286,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'] @@ -279,8 +297,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})') @@ -436,24 +456,34 @@ 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'): (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', 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) + if 'ask_strategy' in self.config and self.config['ask_strategy'].get('use_book_order', False): 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'] - for i in range(orderBook_min, orderBook_max + 1): - orderBook_rate = orderBook['asks'][i - 1][0] + + 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 + # 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 @@ -461,6 +491,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ return True break else: + logger.info('checking sell') if self.check_sell(trade, sell_rate, buy, sell): return True @@ -502,7 +533,7 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \ ordertime = arrow.get(order['datetime']).datetime # Check if trade is still actually open - if 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/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
{}
'\ 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