From 989682457ea34c3ad90a2e1a33cf44b270405df0 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 17 Sep 2017 22:37:46 +0300 Subject: [PATCH 1/5] add a field to config for setting balance between trying to buy with ask price and last price --- config.json.example | 3 +++ misc.py | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/config.json.example b/config.json.example index 411d2af87..a0b93c455 100644 --- a/config.json.example +++ b/config.json.example @@ -9,6 +9,9 @@ "0": 0.02 }, "stoploss": -0.10, + "bid_strategy": { + "ask_last_balance": 0.0 + }, "bittrex": { "enabled": true, "key": "key", diff --git a/misc.py b/misc.py index dcf0bfe86..be8cf71b9 100644 --- a/misc.py +++ b/misc.py @@ -48,6 +48,18 @@ CONF_SCHEMA = { 'minProperties': 1 }, 'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True}, + 'bid_strategy': { + 'type': 'object', + 'properties': { + 'ask_last_balance': { + 'type': 'number', + 'minimum': 0, + 'maximum': 1, + 'exclusiveMaximum': False + }, + }, + 'required': ['ask_last_balance'] + }, 'bittrex': {'$ref': '#/definitions/exchange'}, 'telegram': { 'type': 'object', @@ -85,6 +97,7 @@ CONF_SCHEMA = { 'stake_amount', 'dry_run', 'minimal_roi', + 'bid_strategy', 'telegram' ] } From 465dc47b23bea453d4a310db53e9804caf57bb97 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Sun, 17 Sep 2017 23:21:46 +0300 Subject: [PATCH 2/5] balance bid price between ask and last --- main.py | 9 ++++++++- test/test_main.py | 17 ++++++++++++++++- test/test_telegram.py | 3 +++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 493be3494..be1cee447 100755 --- a/main.py +++ b/main.py @@ -138,6 +138,13 @@ def handle_trade(trade: Trade) -> None: except ValueError: logger.exception('Unable to handle open order') +def get_target_bid(ticker) -> float: + """ Calculates bid target between current ask price and last price """ + if ticker['ask'] < ticker['last']: + return ticker['ask'] + balance = _CONF['bid_strategy']['ask_last_balance'] + return ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + def create_trade(stake_amount: float, _exchange: exchange.Exchange) -> Optional[Trade]: """ @@ -174,7 +181,7 @@ def create_trade(stake_amount: float, _exchange: exchange.Exchange) -> Optional[ else: return None - open_rate = exchange.get_ticker(pair)['ask'] + open_rate = get_target_bid(exchange.get_ticker(pair)) amount = stake_amount / open_rate order_id = exchange.buy(pair, open_rate, amount) diff --git a/test/test_main.py b/test/test_main.py index e4ee83de3..9ff4f97f2 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -4,7 +4,7 @@ from unittest.mock import patch, MagicMock from jsonschema import validate import exchange -from main import create_trade, handle_trade, close_trade_if_fulfilled, init +from main import create_trade, handle_trade, close_trade_if_fulfilled, init, get_target_bid from misc import CONF_SCHEMA from persistence import Trade @@ -20,6 +20,9 @@ class TestMain(unittest.TestCase): "720": 0.01, "0": 0.02 }, + "bid_strategy": { + "ask_last_balance": 0.0 + }, "bittrex": { "enabled": True, "key": "key", @@ -90,6 +93,18 @@ class TestMain(unittest.TestCase): self.assertTrue(closed) self.assertEqual(trade.is_open, False) + def test_balance_fully_ask_side(self): + with patch.dict('main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): + self.assertEqual(get_target_bid({'ask': 20, 'last': 10}), 20) + + def test_balance_fully_last_side(self): + with patch.dict('main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): + self.assertEqual(get_target_bid({'ask': 20, 'last': 10}), 10) + + def test_balance_when_last_bigger_than_ask(self): + with patch.dict('main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): + self.assertEqual(get_target_bid({'ask': 5, 'last': 10}), 5) + @classmethod def setUpClass(cls): validate(cls.conf, CONF_SCHEMA) diff --git a/test/test_telegram.py b/test/test_telegram.py index 906df8e87..e7af1a876 100644 --- a/test/test_telegram.py +++ b/test/test_telegram.py @@ -28,6 +28,9 @@ class TestTelegram(unittest.TestCase): "720": 0.01, "0": 0.02 }, + "bid_strategy": { + "ask_last_balance": 0.0 + }, "bittrex": { "enabled": True, "key": "key", From 4d651e0082ede9d41ac4158cd621ac7accabf8e6 Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Mon, 18 Sep 2017 05:08:05 -0700 Subject: [PATCH 3/5] add ask_last_balance to README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3753a015b..4e307300e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ profit dips below -10% for a given trade. This parameter is optional. Possible values are `running` or `stopped`. (default=`running`) If the value is `stopped` the bot has to be started with `/start` first. +`ask_last_balance` sets the bidding price. Value `0.0` will use `ask` price, `1.0` will +use the `last` price and values between those interpolate between ask and last price. + The other values should be self-explanatory, if not feel free to raise a github issue. From e5a742cf2e9301df42f0142d05ac4eaf015619ae Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Mon, 18 Sep 2017 05:09:45 -0700 Subject: [PATCH 4/5] add a little more explanation for ask_last_balance to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e307300e..211b0fdb6 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Possible values are `running` or `stopped`. (default=`running`) If the value is `stopped` the bot has to be started with `/start` first. `ask_last_balance` sets the bidding price. Value `0.0` will use `ask` price, `1.0` will -use the `last` price and values between those interpolate between ask and last price. +use the `last` price and values between those interpolate between ask and last price. Using `ask` price will guarantee quick success in bid, but bot will also end up paying more then would probably have been necessary. The other values should be self-explanatory, if not feel free to raise a github issue. From 358a1eb73fc904133919a248ceaa51d205f6f50c Mon Sep 17 00:00:00 2001 From: Janne Sinivirta Date: Wed, 20 Sep 2017 07:34:47 -0700 Subject: [PATCH 5/5] add type hint for ticker --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index be1cee447..44e060eb3 100755 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ import logging import time import traceback from datetime import datetime -from typing import Optional +from typing import Dict, Optional from jsonschema import validate @@ -138,7 +138,7 @@ def handle_trade(trade: Trade) -> None: except ValueError: logger.exception('Unable to handle open order') -def get_target_bid(ticker) -> float: +def get_target_bid(ticker: Dict[str, float]) -> float: """ Calculates bid target between current ask price and last price """ if ticker['ask'] < ticker['last']: return ticker['ask']