diff --git a/README.md b/README.md index 3753a015b..211b0fdb6 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. 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. 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/main.py b/main.py index 493be3494..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,6 +138,13 @@ def handle_trade(trade: Trade) -> None: except ValueError: logger.exception('Unable to handle open order') +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'] + 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/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' ] } 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",