Merge pull request #2 from xmatthias/ccxt-async-xmatt

Ccxt async xmatt
This commit is contained in:
misagh 2018-08-02 16:33:02 +02:00 committed by GitHub
commit 7dc440b874
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 6 deletions

View File

@ -13,7 +13,7 @@ addons:
install:
- ./install_ta-lib.sh
- export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
- pip install --upgrade flake8 coveralls pytest-random-order mypy
- pip install --upgrade flake8 coveralls pytest-random-order pytest-asyncio mypy
- pip install -r requirements.txt
- pip install -e .
jobs:

View File

@ -334,7 +334,7 @@ class Exchange(object):
logger.info("returning cached ticker-data for %s", pair)
return self._cached_ticker[pair]
async def async_get_tickers_history(self, pairs, tick_interval):
async def async_get_tickers_history(self, pairs, tick_interval) -> List[Tuple[str, List]]:
# COMMENTED CODE IS FOR DISCUSSION: where should we close the loop on async ?
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)

View File

@ -55,7 +55,7 @@ class FreqtradeBot(object):
self.persistence = None
self.exchange = Exchange(self.config)
self._init_modules()
self._klines = {}
self._klines: Dict[str, List[Dict]] = {}
def _init_modules(self) -> None:
"""

View File

@ -6,7 +6,7 @@ import logging
from abc import ABC, abstractmethod
from datetime import datetime
from enum import Enum
from typing import Dict, List, NamedTuple, Tuple
from typing import Dict, List, NamedTuple, Optional, Tuple
import warnings
import arrow
@ -118,7 +118,7 @@ class IStrategy(ABC):
dataframe = self.advise_sell(dataframe, metadata)
return dataframe
def get_signal(self, pair: str, interval: str, ticker_hist: List[Dict]) -> Tuple[bool, bool]:
def get_signal(self, pair: str, interval: str, ticker_hist: Optional[List[Dict]]) -> Tuple[bool, bool]:
"""
Calculates current signal based several technical analysis indicators
:param pair: pair in format ANT/BTC

View File

@ -27,6 +27,20 @@ def ccxt_exceptionhandlers(mocker, default_conf, api_mock, fun, mock_ccxt_fun, *
assert api_mock.__dict__[mock_ccxt_fun].call_count == 1
async def async_ccxt_exception(mocker, default_conf, api_mock, fun, mock_ccxt_fun, **kwargs):
with pytest.raises(TemporaryError):
api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.NetworkError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
await getattr(exchange, fun)(**kwargs)
assert api_mock.__dict__[mock_ccxt_fun].call_count == 1
with pytest.raises(OperationalException):
api_mock.__dict__[mock_ccxt_fun] = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
await getattr(exchange, fun)(**kwargs)
assert api_mock.__dict__[mock_ccxt_fun].call_count == 1
def test_init(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
get_patched_exchange(mocker, default_conf)
@ -515,6 +529,92 @@ def test_get_ticker(default_conf, mocker):
exchange.get_ticker(pair='ETH/BTC', refresh=True)
@pytest.mark.asyncio
async def test_async_get_ticker_history(default_conf, mocker):
tick = [
[
1511686200000, # unix timestamp ms
1, # open
2, # high
3, # low
4, # close
5, # volume (in quote currency)
]
]
async def async_fetch_ohlcv(pair, timeframe, since):
return tick
exchange = get_patched_exchange(mocker, default_conf)
# Monkey-patch async function
exchange._api_async.fetch_ohlcv = async_fetch_ohlcv
exchange = Exchange(default_conf)
pair = 'ETH/BTC'
res = await exchange.async_get_ticker_history(pair, "5m")
assert type(res) is tuple
assert len(res) == 2
assert res[0] == pair
assert res[1] == tick
await async_ccxt_exception(mocker, default_conf, MagicMock(),
"async_get_ticker_history", "fetch_ohlcv",
pair='ABCD/BTC', tick_interval=default_conf['ticker_interval'])
api_mock = MagicMock()
with pytest.raises(OperationalException, match=r'Could not fetch ticker data*'):
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
await exchange.async_get_ticker_history(pair, "5m")
@pytest.mark.asyncio
async def test_async_get_tickers_history(default_conf, mocker):
tick = [
[
1511686200000, # unix timestamp ms
1, # open
2, # high
3, # low
4, # close
5, # volume (in quote currency)
]
]
async def async_fetch_ohlcv(pair, timeframe, since):
return tick
exchange = get_patched_exchange(mocker, default_conf)
# Monkey-patch async function
exchange._api_async.fetch_ohlcv = async_fetch_ohlcv
exchange = Exchange(default_conf)
pairs = ['ETH/BTC', 'XRP/BTC']
res = await exchange.async_get_tickers_history(pairs, "5m")
assert type(res) is list
assert len(res) == 2
assert type(res[0]) is tuple
assert res[0][0] == pairs[0]
assert res[0][1] == tick
assert res[1][0] == pairs[1]
assert res[1][1] == tick
# await async_ccxt_exception(mocker, default_conf, MagicMock(),
# "async_get_tickers_history", "fetch_ohlcv",
# pairs=pairs, tick_interval=default_conf['ticker_interval'])
# api_mock = MagicMock()
# with pytest.raises(OperationalException, match=r'Could not fetch ticker data*'):
# api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError)
# exchange = get_patched_exchange(mocker, default_conf, api_mock)
# await exchange.async_get_tickers_history('ETH/BTC', "5m")
def test_refresh_tickers():
# TODO: Implement test for this
pass
def make_fetch_ohlcv_mock(data):
def fetch_ohlcv_mock(pair, timeframe, since):
if since:

View File

@ -15,6 +15,7 @@ TA-Lib==0.4.17
pytest==3.6.4
pytest-mock==1.10.0
pytest-cov==2.5.1
pytest-asyncio==0.9.0
tabulate==0.8.2
coinmarketcap==5.0.3