Merge pull request #2982 from freqtrade/rate_side_optional

Rate side configurable
This commit is contained in:
hroff-1902
2020-03-04 16:07:08 +03:00
committed by GitHub
9 changed files with 222 additions and 122 deletions

View File

@@ -15,6 +15,7 @@ UNLIMITED_STAKE_AMOUNT = 'unlimited'
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
REQUIRED_ORDERTIF = ['buy', 'sell']
REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
ORDERBOOK_SIDES = ['ask', 'bid']
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList',
@@ -113,15 +114,16 @@ CONF_SCHEMA = {
'minimum': 0,
'maximum': 1,
'exclusiveMaximum': False,
'use_order_book': {'type': 'boolean'},
'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1},
'check_depth_of_market': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'bids_to_ask_delta': {'type': 'number', 'minimum': 0},
}
},
},
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'bid'},
'use_order_book': {'type': 'boolean'},
'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1},
'check_depth_of_market': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'bids_to_ask_delta': {'type': 'number', 'minimum': 0},
}
},
},
'required': ['ask_last_balance']
@@ -129,6 +131,7 @@ CONF_SCHEMA = {
'ask_strategy': {
'type': 'object',
'properties': {
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'ask'},
'use_order_book': {'type': 'boolean'},
'order_book_min': {'type': 'integer', 'minimum': 1},
'order_book_max': {'type': 'integer', 'minimum': 1, 'maximum': 50},
@@ -299,6 +302,7 @@ SCHEMA_TRADE_REQUIRED = [
'last_stake_amount_min_ratio',
'dry_run',
'dry_run_wallet',
'ask_strategy',
'bid_strategy',
'unfilledtimeout',
'stoploss',

View File

@@ -242,25 +242,25 @@ class FreqtradeBot:
logger.info(f"Using cached buy rate for {pair}.")
return rate
config_bid_strategy = self.config.get('bid_strategy', {})
if 'use_order_book' in config_bid_strategy and\
config_bid_strategy.get('use_order_book', False):
logger.info('Getting price from order book')
order_book_top = config_bid_strategy.get('order_book_top', 1)
bid_strategy = self.config.get('bid_strategy', {})
if 'use_order_book' in bid_strategy and bid_strategy.get('use_order_book', False):
logger.info(
f"Getting price from order book {bid_strategy['price_side'].capitalize()} side."
)
order_book_top = bid_strategy.get('order_book_top', 1)
order_book = self.exchange.get_order_book(pair, order_book_top)
logger.debug('order_book %s', order_book)
# top 1 = index 0
order_book_rate = order_book['bids'][order_book_top - 1][0]
logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate)
order_book_rate = order_book[f"{bid_strategy['price_side']}s"][order_book_top - 1][0]
logger.info(f'...top {order_book_top} order book buy rate {order_book_rate:.8f}')
used_rate = order_book_rate
else:
logger.info('Using Last Ask / Last Price')
logger.info(f"Using Last {bid_strategy['price_side'].capitalize()} / Last Price")
ticker = self.exchange.fetch_ticker(pair)
if ticker['ask'] < ticker['last']:
ticker_rate = ticker['ask']
else:
ticker_rate = ticker[bid_strategy['price_side']]
if ticker['last'] and ticker_rate > ticker['last']:
balance = self.config['bid_strategy']['ask_last_balance']
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
ticker_rate = ticker_rate + balance * (ticker['last'] - ticker_rate)
used_rate = ticker_rate
self._buy_rate_cache[pair] = used_rate
@@ -617,6 +617,15 @@ class FreqtradeBot:
return trades_closed
def _order_book_gen(self, pair: str, side: str, order_book_max: int = 1,
order_book_min: int = 1):
"""
Helper generator to query orderbook in loop (used for early sell-order placing)
"""
order_book = self.exchange.get_order_book(pair, order_book_max)
for i in range(order_book_min, order_book_max + 1):
yield order_book[side][i - 1][0]
def get_sell_rate(self, pair: str, refresh: bool) -> float:
"""
Get sell rate - either using get-ticker bid or first bid based on orderbook
@@ -636,13 +645,12 @@ class FreqtradeBot:
config_ask_strategy = self.config.get('ask_strategy', {})
if config_ask_strategy.get('use_order_book', False):
# This code is only used for notifications, selling uses the generator directly
logger.debug('Using order book to get sell rate')
order_book = self.exchange.get_order_book(pair, 1)
rate = order_book['bids'][0][0]
rate = next(self._order_book_gen(pair, f"{config_ask_strategy['price_side']}s"))
else:
rate = self.exchange.fetch_ticker(pair)['bid']
rate = self.exchange.fetch_ticker(pair)[config_ask_strategy['price_side']]
self._sell_rate_cache[pair] = rate
return rate
@@ -672,12 +680,13 @@ class FreqtradeBot:
order_book_min = config_ask_strategy.get('order_book_min', 1)
order_book_max = config_ask_strategy.get('order_book_max', 1)
order_book = self.exchange.get_order_book(trade.pair, order_book_max)
order_book = self._order_book_gen(trade.pair, f"{config_ask_strategy['price_side']}s",
order_book_min=order_book_min,
order_book_max=order_book_max)
for i in range(order_book_min, order_book_max + 1):
order_book_rate = order_book['asks'][i - 1][0]
logger.debug(' order book asks top %s: %0.8f', i, order_book_rate)
sell_rate = order_book_rate
sell_rate = next(order_book)
logger.debug(f" order book {config_ask_strategy['price_side']} top {i}: "
f"{sell_rate:0.8f}")
if self._check_and_execute_sell(trade, sell_rate, buy, sell):
return True

View File

@@ -11,6 +11,7 @@
"sell": 30
},
"bid_strategy": {
"price_side": "bid",
"ask_last_balance": 0.0,
"use_order_book": false,
"order_book_top": 1,
@@ -20,6 +21,7 @@
}
},
"ask_strategy": {
"price_side": "ask",
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9,