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:
parent
5ed7008933
commit
dc03b41c68
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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.'
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user