A Feature for the bot to use sell orders instead of tickers. New config settings (min & max) are also introduced to allow the bot to search from the sell orders a profitable rate based on minimum roi.

Expected issue: cannot be used in backtesting
This commit is contained in:
Nullart 2018-06-12 10:27:08 +08:00
parent d36d536724
commit f530a7db0e
6 changed files with 54 additions and 13 deletions

View File

@ -11,6 +11,11 @@
"use_book_order": true, "use_book_order": true,
"book_order_top": 6 "book_order_top": 6
}, },
"ask_strategy":{
"use_book_order": true,
"book_order_min": 1,
"book_order_max": 30
},
"exchange": { "exchange": {
"name": "bittrex", "name": "bittrex",
"key": "your_exchange_key", "key": "your_exchange_key",

View File

@ -18,6 +18,11 @@
"use_book_order": true, "use_book_order": true,
"book_order_top": 6 "book_order_top": 6
}, },
"ask_strategy":{
"use_book_order": true,
"book_order_min": 1,
"book_order_max": 30
},
"exchange": { "exchange": {
"name": "bittrex", "name": "bittrex",
"key": "your_exchange_key", "key": "your_exchange_key",

View File

@ -70,6 +70,14 @@ CONF_SCHEMA = {
}, },
'required': ['ask_last_balance'] 'required': ['ask_last_balance']
}, },
'ask_strategy': {
'type': 'object',
'properties': {
'use_book_order': {'type': 'boolean'},
'book_order_min': {'type': 'number', 'minimum':1},
'book_order_max': {'type': 'number', 'minimum':1}
},
},
'exchange': {'$ref': '#/definitions/exchange'}, 'exchange': {'$ref': '#/definitions/exchange'},
'experimental': { 'experimental': {
'type': 'object', 'type': 'object',

View File

@ -245,9 +245,8 @@ class FreqtradeBot(object):
""" """
if self.config['bid_strategy']['use_book_order']: if self.config['bid_strategy']['use_book_order']:
logger.info('Using order book ') logger.info('Getting price from Order Book')
orderBook = exchange.get_order_book(pair) orderBook = exchange.get_order_book(pair)
return orderBook['bids'][self.config['bid_strategy']['use_book_order']][0]
return orderBook['bids'][self.config['bid_strategy']['book_order_top']][0] return orderBook['bids'][self.config['bid_strategy']['book_order_top']][0]
else: else:
logger.info('Using Ask / Last Price') logger.info('Using Ask / Last Price')
@ -433,19 +432,36 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
raise ValueError(f'attempt to handle closed trade: {trade}') raise ValueError(f'attempt to handle closed trade: {trade}')
logger.debug('Handling %s ...', trade) logger.debug('Handling %s ...', trade)
current_rate = exchange.get_ticker(trade.pair)['bid'] sell_rate = exchange.get_ticker(trade.pair)['bid']
(buy, sell) = (False, False) (buy, sell) = (False, False)
if self.config.get('experimental', {}).get('use_sell_signal'): if self.config.get('experimental', {}).get('use_sell_signal'):
(buy, sell) = self.analyze.get_signal(trade.pair, self.analyze.get_ticker_interval()) (buy, sell) = self.analyze.get_signal(trade.pair, self.analyze.get_ticker_interval())
if self.analyze.should_sell(trade, current_rate, datetime.utcnow(), buy, sell): if self.config['ask_strategy']['use_book_order']:
self.execute_sell(trade, current_rate) logger.info('Using order book for selling...')
return True orderBook = exchange.get_order_book(trade.pair)
# logger.debug('Order book %s',orderBook)
for i in range(self.config['ask_strategy']['book_order_min'],self.config['ask_strategy']['book_order_max']):
sell_rate = orderBook['asks'][i-1][0]
logger.debug('checking sell rate %s) %.8f > %.8f (%f %%)',i,trade.open_rate,sell_rate,((sell_rate/trade.open_rate)*100)-100)
if self.check_sell(trade, sell_rate, buy, sell):
return True
break
else:
if self.check_sell(trade, sell_rate, buy, sell):
return True
logger.info('Found no sell signals for whitelisted currencies. Trying again..') logger.info('Found no sell signals for whitelisted currencies. Trying again..')
return False return False
def check_sell(self, trade: Trade, sell_rate: float, buy: bool, sell: bool ) -> bool:
if self.analyze.should_sell(trade, sell_rate, datetime.utcnow(), buy, sell):
self.execute_sell(trade, sell_rate)
return True
return False
def check_handle_timedout(self, timeoutvalue: int) -> None: def check_handle_timedout(self, timeoutvalue: int) -> None:
""" """
Check if any orders are timed out and cancel if neccessary Check if any orders are timed out and cancel if neccessary

View File

@ -87,7 +87,14 @@ def default_conf():
"stoploss": -0.10, "stoploss": -0.10,
"unfilledtimeout": 600, "unfilledtimeout": 600,
"bid_strategy": { "bid_strategy": {
"ask_last_balance": 0.0 "use_book_order": False,
"book_order_top": 6,
"ask_last_balance": 0.0,
},
"ask_strategy": {
"use_book_order": False,
"book_order_min": 1,
"book_order_max": 10
}, },
"exchange": { "exchange": {
"name": "bittrex", "name": "bittrex",

View File

@ -502,27 +502,27 @@ def test_balance_fully_ask_side(mocker) -> None:
""" """
Test get_target_bid() method Test get_target_bid() method
""" """
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 0.0}}) freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'use_book_order':False,'book_order_top':6,'ask_last_balance': 0.0}})
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 20 assert freqtrade.get_target_bid('ETH/BTC') >= 0.07
def test_balance_fully_last_side(mocker) -> None: def test_balance_fully_last_side(mocker) -> None:
""" """
Test get_target_bid() method Test get_target_bid() method
""" """
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 1.0}}) freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'use_book_order':False,'book_order_top':6,'ask_last_balance': 1.0}})
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 10 assert freqtrade.get_target_bid('ETH/BTC') >= 0.07
def test_balance_bigger_last_ask(mocker) -> None: def test_balance_bigger_last_ask(mocker) -> None:
""" """
Test get_target_bid() method Test get_target_bid() method
""" """
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 1.0}}) freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'use_book_order':False,'book_order_top':6,'ask_last_balance': 1.0}})
assert freqtrade.get_target_bid({'ask': 5, 'last': 10}) == 5 assert freqtrade.get_target_bid('ETH/BTC') >= 0.07
def test_process_maybe_execute_buy(mocker, default_conf) -> None: def test_process_maybe_execute_buy(mocker, default_conf) -> None: