added: disable_buy feature, this will only tell bot to sell whatever is needed to sell

added: order book buy and sell will check ticker first; for buying, if ticker is lower than buy order price, use ticker; for selling, if ticker is higher than sell order price, use ticker
This commit is contained in:
Nullart 2018-06-14 09:57:14 +08:00
parent 5ed7008933
commit dc03b41c68
6 changed files with 42 additions and 20 deletions

View File

@ -5,6 +5,7 @@
"fiat_display_currency": "USD", "fiat_display_currency": "USD",
"ticker_interval" : "5m", "ticker_interval" : "5m",
"dry_run": false, "dry_run": false,
"disable_buy" : true,
"unfilledtimeout": { "unfilledtimeout": {
"buy":10, "buy":10,
"sell":30 "sell":30

View File

@ -4,6 +4,7 @@
"stake_amount": 0.05, "stake_amount": 0.05,
"fiat_display_currency": "USD", "fiat_display_currency": "USD",
"dry_run": false, "dry_run": false,
"disable_buy" : true,
"ticker_interval": "5m", "ticker_interval": "5m",
"minimal_roi": { "minimal_roi": {
"40": 0.0, "40": 0.0,

View File

@ -240,9 +240,9 @@ def get_balances() -> dict:
raise OperationalException(e) raise OperationalException(e)
@retrier @retrier
def get_order_book(pair: str, refresh: Optional[bool] = True) -> dict: def get_order_book(pair: str, limit: Optional[int] = 1000) -> dict:
try: try:
return _API.fetch_order_book(pair) return _API.fetch_order_book(pair, limit)
except ccxt.NotSupported as e: except ccxt.NotSupported as e:
raise OperationalException( raise OperationalException(
f'Exchange {_API.name} does not support fetching order book.' f'Exchange {_API.name} does not support fetching order book.'

View File

@ -159,6 +159,9 @@ class FreqtradeBot(object):
state_changed |= self.process_maybe_execute_sell(trade) state_changed |= self.process_maybe_execute_sell(trade)
# Then looking for buy opportunities # Then looking for buy opportunities
if (self.config['disable_buy']):
logger.info('Buy disabled...')
else:
if len(trades) < self.config['max_open_trades']: if len(trades) < self.config['max_open_trades']:
state_changed = self.process_maybe_execute_buy() state_changed = self.process_maybe_execute_buy()
@ -244,17 +247,23 @@ class FreqtradeBot(object):
:return: float: Price :return: float: Price
""" """
if self.config['bid_strategy']['use_book_order']:
logger.info('Getting price from Order Book')
orderBook = exchange.get_order_book(pair)
return orderBook['bids'][self.config['bid_strategy']['book_order_top']][0]
else:
logger.info('Using Ask / Last Price')
ticker = exchange.get_ticker(pair); ticker = exchange.get_ticker(pair);
if ticker['ask'] < ticker['last']: if ticker['ask'] < ticker['last']:
return ticker['ask'] return ticker['ask']
balance = self.config['bid_strategy']['ask_last_balance'] balance = self.config['bid_strategy']['ask_last_balance']
return ticker['ask'] + balance * (ticker['last'] - ticker['ask']) 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)
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:
return ticker_rate
return orderBook_rate
else:
logger.info('Using Ask / Last Price')
return ticker_rate
def create_trade(self) -> bool: def create_trade(self) -> bool:
@ -444,7 +453,10 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
orderBook = exchange.get_order_book(trade.pair) orderBook = exchange.get_order_book(trade.pair)
# logger.debug('Order book %s',orderBook) # logger.debug('Order book %s',orderBook)
for i in range(self.config['ask_strategy']['book_order_min'],self.config['ask_strategy']['book_order_max']+1): for i in range(self.config['ask_strategy']['book_order_min'],self.config['ask_strategy']['book_order_max']+1):
sell_rate = orderBook['asks'][i-1][0] orderBook_rate = orderBook['asks'][i-1][0]
# if orderbook has higher rate (high profit), use orderbook, otherwise just use sell rate
if (sell_rate < orderBook_rate):
sell_rate = orderBook_rate
if self.check_sell(trade, sell_rate, buy, sell): if self.check_sell(trade, sell_rate, buy, sell):
return True return True
break break

View File

@ -85,7 +85,11 @@ def default_conf():
"0": 0.04 "0": 0.04
}, },
"stoploss": -0.10, "stoploss": -0.10,
"unfilledtimeout": 600, "disable_buy": False,
"unfilledtimeout": {
"buy":10,
"sell":30
},
"bid_strategy": { "bid_strategy": {
"use_book_order": False, "use_book_order": False,
"book_order_top": 6, "book_order_top": 6,
@ -248,7 +252,8 @@ def limit_buy_order():
'price': 0.00001099, 'price': 0.00001099,
'amount': 90.99181073, 'amount': 90.99181073,
'remaining': 0.0, 'remaining': 0.0,
'status': 'closed' 'status': 'closed',
'filled':0.0
} }
@ -263,7 +268,8 @@ def limit_buy_order_old():
'price': 0.00001099, 'price': 0.00001099,
'amount': 90.99181073, 'amount': 90.99181073,
'remaining': 90.99181073, 'remaining': 90.99181073,
'status': 'open' 'status': 'open',
'filled':0.0
} }
@ -278,7 +284,8 @@ def limit_sell_order_old():
'price': 0.00001099, 'price': 0.00001099,
'amount': 90.99181073, 'amount': 90.99181073,
'remaining': 90.99181073, 'remaining': 90.99181073,
'status': 'open' 'status': 'open',
'filled':0.0
} }
@ -293,7 +300,8 @@ def limit_buy_order_old_partial():
'price': 0.00001099, 'price': 0.00001099,
'amount': 90.99181073, 'amount': 90.99181073,
'remaining': 67.99181073, 'remaining': 67.99181073,
'status': 'open' 'status': 'open',
'filled':0.0
} }

View File

@ -852,7 +852,7 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, fe
Trade.session.add(trade_buy) Trade.session.add(trade_buy)
# check it does cancel buy orders over the time limit # check it does cancel buy orders over the time limit
freqtrade.check_handle_timedout(600) freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1 assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1 assert rpc_mock.call_count == 1
trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all() trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all()
@ -893,7 +893,7 @@ def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old,
Trade.session.add(trade_sell) Trade.session.add(trade_sell)
# check it does cancel sell orders over the time limit # check it does cancel sell orders over the time limit
freqtrade.check_handle_timedout(600) freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1 assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1 assert rpc_mock.call_count == 1
assert trade_sell.is_open is True assert trade_sell.is_open is True
@ -933,7 +933,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old
# check it does cancel buy orders over the time limit # check it does cancel buy orders over the time limit
# note this is for a partially-complete buy order # note this is for a partially-complete buy order
freqtrade.check_handle_timedout(600) freqtrade.check_handle_timedout()
assert cancel_order_mock.call_count == 1 assert cancel_order_mock.call_count == 1
assert rpc_mock.call_count == 1 assert rpc_mock.call_count == 1
trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all() trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all()
@ -984,7 +984,7 @@ def test_check_handle_timedout_exception(default_conf, ticker, mocker, caplog) -
'recent call last):\n.*' 'recent call last):\n.*'
) )
freqtrade.check_handle_timedout(600) freqtrade.check_handle_timedout()
assert filter(regexp.match, caplog.record_tuples) assert filter(regexp.match, caplog.record_tuples)