implement get_ticker as wrapper around get_orderbook

This commit is contained in:
gcarq 2017-10-15 18:59:52 +02:00
parent e482372f4a
commit 42e67da9e7
7 changed files with 51 additions and 96 deletions

View File

@ -85,6 +85,10 @@ def get_balance(currency: str) -> float:
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]]:
return EXCHANGE.get_orderbook(pair, top_most)

View File

@ -69,6 +69,13 @@ class Bittrex(Exchange):
raise RuntimeError('{}: {}'.format(self.name.upper(), data['message']))
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]]:
data = _API.get_orderbook(pair.replace('_', '-'))
if not data['success']:

View File

@ -49,6 +49,17 @@ class Exchange(ABC):
: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
def get_orderbook(self, pair: str, top_most: Optional[int] = None) -> Dict[str, List[Dict]]:
"""

View File

@ -134,7 +134,7 @@ def handle_trade(trade: Trade) -> None:
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()):
execute_sell(trade, current_rate)
return
@ -143,15 +143,14 @@ def handle_trade(trade: Trade) -> None:
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
bid and ask prices from the given orderbook
:param orderbook:
:param ticker: ticker data
:return: target bit as float
"""
ask = orderbook['ask'][0]['Rate'] # Get lowest ask
bid = orderbook['bid'][0]['Rate'] # Get highest bid
ask, bid = ticker['ask'], ticker['bid']
balance = _CONF['bid_strategy']['bid_ask_balance']
return bid + balance * (ask - bid)
@ -186,7 +185,7 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
else:
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
order_id = exchange.buy(pair, open_rate, amount)

View File

@ -99,7 +99,7 @@ def _status(bot: Bot, update: Update) -> None:
else:
for trade in trades:
# 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)
orders = exchange.get_open_orders(trade.pair)
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
else:
# 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_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))
return
# 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
currency = trade.pair.split('_')[1]
balance = exchange.get_balance(currency)

View File

@ -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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.07256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.072661
}]
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
}),
buy=MagicMock(return_value='mocked_order_id'))
# 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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.17256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.172661
}]
get_ticker=MagicMock(return_value={
'bid': 0.17256061,
'ask': 0.172661,
}),
buy=MagicMock(return_value='mocked_order_id'))
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):
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.0}})
orderbook = {
'bid': [{
'Quantity': 10,
'Rate': 10
}],
'ask': [{
'Quantity': 20,
'Rate': 20
}]
}
assert get_target_bid(orderbook) == 10
assert get_target_bid({'bid': 10, 'ask': 20}) == 10
def test_balance_fully_ask_side(mocker):
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 1.0}})
orderbook = {
'bid': [{
'Quantity': 10,
'Rate': 10
}],
'ask': [{
'Quantity': 20,
'Rate': 20
}]
}
assert get_target_bid(orderbook) == 20
assert get_target_bid({'bid': 10, 'ask': 20}) == 20
def test_balance_half(mocker):
mocker.patch.dict('freqtrade.main._CONF', {'bid_strategy': {'bid_ask_balance': 0.5}})
orderbook = {
'bid': [{
'Quantity': 10,
'Rate': 10
}],
'ask': [{
'Quantity': 20,
'Rate': 20
}]
}
assert get_target_bid(orderbook) == 15
assert get_target_bid({'bid': 10, 'ask': 20}) == 15

View File

@ -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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.07256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.072661
}]
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
}),
buy=MagicMock(return_value='mocked_order_id'))
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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.07256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.072661
}]
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
}),
buy=MagicMock(return_value='mocked_order_id'))
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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.07256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.072661
}]
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
}),
buy=MagicMock(return_value='mocked_order_id'))
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.exchange',
validate_pairs=MagicMock(),
get_orderbook=MagicMock(return_value={
'bid': [{
'Quantity': 1,
'Rate': 0.07256061
}],
'ask': [{
'Quantity': 1,
'Rate': 0.072661
}]
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
}),
buy=MagicMock(return_value='mocked_order_id'))
init(conf, 'sqlite://')