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:
parent
d36d536724
commit
f530a7db0e
@ -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",
|
||||||
|
@ -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",
|
||||||
|
@ -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',
|
||||||
|
@ -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...')
|
||||||
|
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
|
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
|
||||||
|
@ -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",
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user