implement get_ticker as wrapper around get_orderbook
This commit is contained in:
parent
e482372f4a
commit
42e67da9e7
@ -85,6 +85,10 @@ def get_balance(currency: str) -> float:
|
|||||||
return EXCHANGE.get_balance(currency)
|
return EXCHANGE.get_balance(currency)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ticker(pair: str) -> Dict[str, float]:
|
||||||
|
return EXCHANGE.get_ticker(pair)
|
||||||
|
|
||||||
|
|
||||||
def get_orderbook(pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
def get_orderbook(pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
||||||
return EXCHANGE.get_orderbook(pair, top_most)
|
return EXCHANGE.get_orderbook(pair, top_most)
|
||||||
|
|
||||||
|
@ -69,6 +69,13 @@ class Bittrex(Exchange):
|
|||||||
raise RuntimeError('{}: {}'.format(self.name.upper(), data['message']))
|
raise RuntimeError('{}: {}'.format(self.name.upper(), data['message']))
|
||||||
return float(data['result']['Balance'] or 0.0)
|
return float(data['result']['Balance'] or 0.0)
|
||||||
|
|
||||||
|
def get_ticker(self, pair: str) -> Dict[str, float]:
|
||||||
|
data = self.get_orderbook(pair, top_most=1)
|
||||||
|
return {
|
||||||
|
'bid': data['bid'][0]['Rate'],
|
||||||
|
'ask': data['ask'][0]['Rate'],
|
||||||
|
}
|
||||||
|
|
||||||
def get_orderbook(self, pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
def get_orderbook(self, pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
||||||
data = _API.get_orderbook(pair.replace('_', '-'))
|
data = _API.get_orderbook(pair.replace('_', '-'))
|
||||||
if not data['success']:
|
if not data['success']:
|
||||||
|
@ -49,6 +49,17 @@ class Exchange(ABC):
|
|||||||
:return: float
|
:return: float
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_ticker(self, pair: str) -> Dict[str, float]:
|
||||||
|
"""
|
||||||
|
Gets ticker for given pair.
|
||||||
|
:param pair: Pair as str, format: BTC_ETC
|
||||||
|
:return: dict, format: {
|
||||||
|
'bid': float,
|
||||||
|
'ask': float
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_orderbook(self, pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
def get_orderbook(self, pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
|
||||||
"""
|
"""
|
||||||
|
@ -134,7 +134,7 @@ def handle_trade(trade: Trade) -> None:
|
|||||||
|
|
||||||
logger.debug('Handling open trade %s ...', trade)
|
logger.debug('Handling open trade %s ...', trade)
|
||||||
|
|
||||||
current_rate = exchange.get_orderbook(trade.pair, top_most=1)['bid'][0]['Rate']
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
if should_sell(trade, current_rate, datetime.utcnow()):
|
if should_sell(trade, current_rate, datetime.utcnow()):
|
||||||
execute_sell(trade, current_rate)
|
execute_sell(trade, current_rate)
|
||||||
return
|
return
|
||||||
@ -143,15 +143,14 @@ def handle_trade(trade: Trade) -> None:
|
|||||||
logger.exception('Unable to handle open order')
|
logger.exception('Unable to handle open order')
|
||||||
|
|
||||||
|
|
||||||
def get_target_bid(orderbook: Dict[str, List[Dict]]) -> float:
|
def get_target_bid(ticker: Dict[str, float]) -> float:
|
||||||
"""
|
"""
|
||||||
Calculates bid target between
|
Calculates bid target between
|
||||||
bid and ask prices from the given orderbook
|
bid and ask prices from the given orderbook
|
||||||
:param orderbook:
|
:param ticker: ticker data
|
||||||
:return: target bit as float
|
:return: target bit as float
|
||||||
"""
|
"""
|
||||||
ask = orderbook['ask'][0]['Rate'] # Get lowest ask
|
ask, bid = ticker['ask'], ticker['bid']
|
||||||
bid = orderbook['bid'][0]['Rate'] # Get highest bid
|
|
||||||
balance = _CONF['bid_strategy']['bid_ask_balance']
|
balance = _CONF['bid_strategy']['bid_ask_balance']
|
||||||
return bid + balance * (ask - bid)
|
return bid + balance * (ask - bid)
|
||||||
|
|
||||||
@ -186,7 +185,7 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
open_rate = get_target_bid(exchange.get_orderbook(pair, top_most=1))
|
open_rate = get_target_bid(exchange.get_ticker(pair))
|
||||||
amount = stake_amount / open_rate
|
amount = stake_amount / open_rate
|
||||||
order_id = exchange.buy(pair, open_rate, amount)
|
order_id = exchange.buy(pair, open_rate, amount)
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ def _status(bot: Bot, update: Update) -> None:
|
|||||||
else:
|
else:
|
||||||
for trade in trades:
|
for trade in trades:
|
||||||
# calculate profit and send message to user
|
# calculate profit and send message to user
|
||||||
current_rate = exchange.get_orderbook(trade.pair, top_most=1)['bid'][0]['Rate']
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
current_profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
|
current_profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
|
||||||
orders = exchange.get_open_orders(trade.pair)
|
orders = exchange.get_open_orders(trade.pair)
|
||||||
orders = [o for o in orders if o['id'] == trade.open_order_id]
|
orders = [o for o in orders if o['id'] == trade.open_order_id]
|
||||||
@ -156,7 +156,7 @@ def _profit(bot: Bot, update: Update) -> None:
|
|||||||
profit = trade.close_profit
|
profit = trade.close_profit
|
||||||
else:
|
else:
|
||||||
# Get current rate
|
# Get current rate
|
||||||
current_rate = exchange.get_orderbook(trade.pair, top_most=1)['bid'][0]['Rate']
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
|
profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
|
||||||
|
|
||||||
profit_amounts.append((profit / 100) * trade.stake_amount)
|
profit_amounts.append((profit / 100) * trade.stake_amount)
|
||||||
@ -250,7 +250,7 @@ def _forcesell(bot: Bot, update: Update) -> None:
|
|||||||
send_msg('There is no open trade with ID: `{}`'.format(trade_id))
|
send_msg('There is no open trade with ID: `{}`'.format(trade_id))
|
||||||
return
|
return
|
||||||
# Get current rate
|
# Get current rate
|
||||||
current_rate = exchange.get_orderbook(trade.pair, top_most=1)['bid'][0]['Rate']
|
current_rate = exchange.get_ticker(trade.pair)['bid']
|
||||||
# Get available balance
|
# Get available balance
|
||||||
currency = trade.pair.split('_')[1]
|
currency = trade.pair.split('_')[1]
|
||||||
balance = exchange.get_balance(currency)
|
balance = exchange.get_balance(currency)
|
||||||
|
@ -55,15 +55,9 @@ def test_create_trade(conf, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock())
|
mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock())
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.07256061,
|
||||||
'Quantity': 1,
|
'ask': 0.072661,
|
||||||
'Rate': 0.07256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.072661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
# Save state of current whitelist
|
# Save state of current whitelist
|
||||||
@ -94,15 +88,9 @@ def test_handle_trade(conf, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock())
|
mocker.patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock())
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.17256061,
|
||||||
'Quantity': 1,
|
'ask': 0.172661,
|
||||||
'Rate': 0.17256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.172661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
|
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
|
||||||
@ -129,44 +117,14 @@ def test_close_trade(conf, mocker):
|
|||||||
|
|
||||||
def test_balance_fully_bid_side(mocker):
|
def test_balance_fully_bid_side(mocker):
|
||||||
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.0}})
|
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.0}})
|
||||||
orderbook = {
|
assert get_target_bid({'bid': 10, 'ask': 20}) == 10
|
||||||
'bid': [{
|
|
||||||
'Quantity': 10,
|
|
||||||
'Rate': 10
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 20,
|
|
||||||
'Rate': 20
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
assert get_target_bid(orderbook) == 10
|
|
||||||
|
|
||||||
|
|
||||||
def test_balance_fully_ask_side(mocker):
|
def test_balance_fully_ask_side(mocker):
|
||||||
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 1.0}})
|
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 1.0}})
|
||||||
orderbook = {
|
assert get_target_bid({'bid': 10, 'ask': 20}) == 20
|
||||||
'bid': [{
|
|
||||||
'Quantity': 10,
|
|
||||||
'Rate': 10
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 20,
|
|
||||||
'Rate': 20
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
assert get_target_bid(orderbook) == 20
|
|
||||||
|
|
||||||
|
|
||||||
def test_balance_half(mocker):
|
def test_balance_half(mocker):
|
||||||
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.5}})
|
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.5}})
|
||||||
orderbook = {
|
assert get_target_bid({'bid': 10, 'ask': 20}) == 15
|
||||||
'bid': [{
|
|
||||||
'Quantity': 10,
|
|
||||||
'Rate': 10
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 20,
|
|
||||||
'Rate': 20
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
assert get_target_bid(orderbook) == 15
|
|
||||||
|
@ -65,15 +65,9 @@ def test_status_handle(conf, update, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.07256061,
|
||||||
'Quantity': 1,
|
'ask': 0.072661,
|
||||||
'Rate': 0.07256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.072661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
init(conf, 'sqlite://')
|
init(conf, 'sqlite://')
|
||||||
@ -96,15 +90,9 @@ def test_profit_handle(conf, update, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.07256061,
|
||||||
'Quantity': 1,
|
'ask': 0.072661,
|
||||||
'Rate': 0.07256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.072661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
init(conf, 'sqlite://')
|
init(conf, 'sqlite://')
|
||||||
@ -132,15 +120,9 @@ def test_forcesell_handle(conf, update, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.07256061,
|
||||||
'Quantity': 1,
|
'ask': 0.072661,
|
||||||
'Rate': 0.07256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.072661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
init(conf, 'sqlite://')
|
init(conf, 'sqlite://')
|
||||||
@ -166,15 +148,9 @@ def test_performance_handle(conf, update, mocker):
|
|||||||
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
mocker.patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock)
|
||||||
mocker.patch.multiple('freqtrade.main.exchange',
|
mocker.patch.multiple('freqtrade.main.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_orderbook=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
'bid': [{
|
'bid': 0.07256061,
|
||||||
'Quantity': 1,
|
'ask': 0.072661,
|
||||||
'Rate': 0.07256061
|
|
||||||
}],
|
|
||||||
'ask': [{
|
|
||||||
'Quantity': 1,
|
|
||||||
'Rate': 0.072661
|
|
||||||
}]
|
|
||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value='mocked_order_id'))
|
buy=MagicMock(return_value='mocked_order_id'))
|
||||||
init(conf, 'sqlite://')
|
init(conf, 'sqlite://')
|
||||||
|
Loading…
Reference in New Issue
Block a user