Merge pull request #817 from gcarq/feature/gdax
Enable Backtesting with GDAX and allow trading with EUR/USD
This commit is contained in:
commit
20815771ab
@ -37,7 +37,7 @@ CONF_SCHEMA = {
|
||||
'properties': {
|
||||
'max_open_trades': {'type': 'integer', 'minimum': 0},
|
||||
'ticker_interval': {'type': 'string', 'enum': list(TICKER_INTERVAL_MINUTES.keys())},
|
||||
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']},
|
||||
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT', 'EUR', 'USD']},
|
||||
'stake_amount': {'type': 'number', 'minimum': 0.0005},
|
||||
'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT},
|
||||
'dry_run': {'type': 'boolean'},
|
||||
|
@ -294,6 +294,11 @@ def get_ticker_history(pair: str, tick_interval: str, since_ms: Optional[int] =
|
||||
while not since_ms or since_ms < till_time_ms:
|
||||
data_part = _API.fetch_ohlcv(pair, timeframe=tick_interval, since=since_ms)
|
||||
|
||||
# Because some exchange sort Tickers ASC and other DESC.
|
||||
# Ex: Bittrex returns a list of tickers ASC (oldest first, newest last)
|
||||
# when GDAX returns a list of tickers DESC (newest first, oldest last)
|
||||
data_part = sorted(data_part, key=lambda x: x[0])
|
||||
|
||||
if not data_part:
|
||||
break
|
||||
|
||||
|
@ -88,8 +88,11 @@ class CryptoToFiatConverter(object):
|
||||
coinlistings = self._coinmarketcap.listings()
|
||||
self._cryptomap = dict(map(lambda coin: (coin["symbol"], str(coin["id"])),
|
||||
coinlistings["data"]))
|
||||
except (ValueError, RequestException) as e:
|
||||
logger.error("Could not load FIAT Cryptocurrency map for the following problem: %s", e)
|
||||
except (ValueError, RequestException) as exception:
|
||||
logger.error(
|
||||
"Could not load FIAT Cryptocurrency map for the following problem: %s",
|
||||
exception
|
||||
)
|
||||
|
||||
def convert_amount(self, crypto_amount: float, crypto_symbol: str, fiat_symbol: str) -> float:
|
||||
"""
|
||||
@ -181,6 +184,10 @@ class CryptoToFiatConverter(object):
|
||||
if not self._is_supported_fiat(fiat=fiat_symbol):
|
||||
raise ValueError('The fiat {} is not supported.'.format(fiat_symbol))
|
||||
|
||||
# No need to convert if both crypto and fiat are the same
|
||||
if crypto_symbol == fiat_symbol:
|
||||
return 1.0
|
||||
|
||||
if crypto_symbol not in self._cryptomap:
|
||||
# return 0 for unsupported stake currencies (fiat-convert should not break the bot)
|
||||
logger.warning("unsupported crypto-symbol %s - returning 0.0", crypto_symbol)
|
||||
@ -192,6 +199,6 @@ class CryptoToFiatConverter(object):
|
||||
convert=fiat_symbol
|
||||
)['data']['quotes'][fiat_symbol.upper()]['price']
|
||||
)
|
||||
except BaseException as ex:
|
||||
logger.error("Error in _find_price: %s", ex)
|
||||
except BaseException as exception:
|
||||
logger.error("Error in _find_price: %s", exception)
|
||||
return 0.0
|
||||
|
@ -393,6 +393,78 @@ def test_get_ticker_history(default_conf, mocker):
|
||||
get_ticker_history('EFGH/BTC', default_conf['ticker_interval'])
|
||||
|
||||
|
||||
def test_get_ticker_history_sort(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
|
||||
# GDAX use-case (real data from GDAX)
|
||||
# This ticker history is ordered DESC (newest first, oldest last)
|
||||
tick = [
|
||||
[1527833100000, 0.07666, 0.07671, 0.07666, 0.07668, 16.65244264],
|
||||
[1527832800000, 0.07662, 0.07666, 0.07662, 0.07666, 1.30051526],
|
||||
[1527832500000, 0.07656, 0.07661, 0.07656, 0.07661, 12.034778840000001],
|
||||
[1527832200000, 0.07658, 0.07658, 0.07655, 0.07656, 0.59780186],
|
||||
[1527831900000, 0.07658, 0.07658, 0.07658, 0.07658, 1.76278136],
|
||||
[1527831600000, 0.07658, 0.07658, 0.07658, 0.07658, 2.22646521],
|
||||
[1527831300000, 0.07655, 0.07657, 0.07655, 0.07657, 1.1753],
|
||||
[1527831000000, 0.07654, 0.07654, 0.07651, 0.07651, 0.8073060299999999],
|
||||
[1527830700000, 0.07652, 0.07652, 0.07651, 0.07652, 10.04822687],
|
||||
[1527830400000, 0.07649, 0.07651, 0.07649, 0.07651, 2.5734867]
|
||||
]
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
|
||||
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
|
||||
mocker.patch('freqtrade.exchange._API', api_mock)
|
||||
|
||||
# Test the ticker history sort
|
||||
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
|
||||
assert ticks[0][0] == 1527830400000
|
||||
assert ticks[0][1] == 0.07649
|
||||
assert ticks[0][2] == 0.07651
|
||||
assert ticks[0][3] == 0.07649
|
||||
assert ticks[0][4] == 0.07651
|
||||
assert ticks[0][5] == 2.5734867
|
||||
|
||||
assert ticks[9][0] == 1527833100000
|
||||
assert ticks[9][1] == 0.07666
|
||||
assert ticks[9][2] == 0.07671
|
||||
assert ticks[9][3] == 0.07666
|
||||
assert ticks[9][4] == 0.07668
|
||||
assert ticks[9][5] == 16.65244264
|
||||
|
||||
# Bittrex use-case (real data from Bittrex)
|
||||
# This ticker history is ordered ASC (oldest first, newest last)
|
||||
tick = [
|
||||
[1527827700000, 0.07659999, 0.0766, 0.07627, 0.07657998, 1.85216924],
|
||||
[1527828000000, 0.07657995, 0.07657995, 0.0763, 0.0763, 26.04051037],
|
||||
[1527828300000, 0.0763, 0.07659998, 0.0763, 0.0764, 10.36434124],
|
||||
[1527828600000, 0.0764, 0.0766, 0.0764, 0.0766, 5.71044773],
|
||||
[1527828900000, 0.0764, 0.07666998, 0.0764, 0.07666998, 47.48888565],
|
||||
[1527829200000, 0.0765, 0.07672999, 0.0765, 0.07672999, 3.37640326],
|
||||
[1527829500000, 0.0766, 0.07675, 0.0765, 0.07675, 8.36203831],
|
||||
[1527829800000, 0.07675, 0.07677999, 0.07620002, 0.076695, 119.22963884],
|
||||
[1527830100000, 0.076695, 0.07671, 0.07624171, 0.07671, 1.80689244],
|
||||
[1527830400000, 0.07671, 0.07674399, 0.07629216, 0.07655213, 2.31452783]
|
||||
]
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
|
||||
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
|
||||
mocker.patch('freqtrade.exchange._API', api_mock)
|
||||
|
||||
# Test the ticker history sort
|
||||
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
|
||||
assert ticks[0][0] == 1527827700000
|
||||
assert ticks[0][1] == 0.07659999
|
||||
assert ticks[0][2] == 0.0766
|
||||
assert ticks[0][3] == 0.07627
|
||||
assert ticks[0][4] == 0.07657998
|
||||
assert ticks[0][5] == 1.85216924
|
||||
|
||||
assert ticks[9][0] == 1527830400000
|
||||
assert ticks[9][1] == 0.07671
|
||||
assert ticks[9][2] == 0.07674399
|
||||
assert ticks[9][3] == 0.07629216
|
||||
assert ticks[9][4] == 0.07655213
|
||||
assert ticks[9][5] == 2.31452783
|
||||
|
||||
|
||||
def test_cancel_order_dry_run(default_conf, mocker):
|
||||
default_conf['dry_run'] = True
|
||||
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
|
||||
|
@ -126,6 +126,20 @@ def test_fiat_convert_get_price(mocker):
|
||||
assert fiat_convert._pairs[0]._expiration is not expiration
|
||||
|
||||
|
||||
def test_fiat_convert_same_currencies(mocker):
|
||||
patch_coinmarketcap(mocker)
|
||||
fiat_convert = CryptoToFiatConverter()
|
||||
|
||||
assert fiat_convert.get_price(crypto_symbol='USD', fiat_symbol='USD') == 1.0
|
||||
|
||||
|
||||
def test_fiat_convert_two_FIAT(mocker):
|
||||
patch_coinmarketcap(mocker)
|
||||
fiat_convert = CryptoToFiatConverter()
|
||||
|
||||
assert fiat_convert.get_price(crypto_symbol='USD', fiat_symbol='EUR') == 0.0
|
||||
|
||||
|
||||
def test_loadcryptomap(mocker):
|
||||
patch_coinmarketcap(mocker)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user