Added price as param to fetch_ohlcv
This commit is contained in:
parent
aad37bb8f3
commit
c8162479d6
@ -200,24 +200,36 @@ class Binance(Exchange):
|
|||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
async def _async_get_historic_ohlcv(self, pair: str, timeframe: str,
|
async def _async_get_historic_ohlcv(
|
||||||
since_ms: int, is_new_pair: bool = False,
|
self,
|
||||||
raise_: bool = False
|
pair: str,
|
||||||
|
timeframe: str,
|
||||||
|
since_ms: int,
|
||||||
|
is_new_pair: bool,
|
||||||
|
raise_: bool = False,
|
||||||
|
price: Optional[str] = None
|
||||||
) -> Tuple[str, str, List]:
|
) -> Tuple[str, str, List]:
|
||||||
"""
|
"""
|
||||||
Overwrite to introduce "fast new pair" functionality by detecting the pair's listing date
|
Overwrite to introduce "fast new pair" functionality by detecting the pair's listing date
|
||||||
Does not work for other exchanges, which don't return the earliest data when called with "0"
|
Does not work for other exchanges, which don't return the earliest data when called with "0"
|
||||||
|
:param price: "mark" if retrieving the mark price cnadles
|
||||||
"""
|
"""
|
||||||
if is_new_pair:
|
if is_new_pair:
|
||||||
x = await self._async_get_candle_history(pair, timeframe, 0)
|
x = await self._async_get_candle_history(pair, timeframe, 0, price)
|
||||||
if x and x[2] and x[2][0] and x[2][0][0] > since_ms:
|
if x and x[2] and x[2][0] and x[2][0][0] > since_ms:
|
||||||
# Set starting date to first available candle.
|
# Set starting date to first available candle.
|
||||||
since_ms = x[2][0][0]
|
since_ms = x[2][0][0]
|
||||||
logger.info(f"Candle-data for {pair} available starting with "
|
logger.info(f"Candle-data for {pair} available starting with "
|
||||||
f"{arrow.get(since_ms // 1000).isoformat()}.")
|
f"{arrow.get(since_ms // 1000).isoformat()}.")
|
||||||
|
|
||||||
return await super()._async_get_historic_ohlcv(
|
return await super()._async_get_historic_ohlcv(
|
||||||
pair=pair, timeframe=timeframe, since_ms=since_ms, is_new_pair=is_new_pair,
|
pair=pair,
|
||||||
raise_=raise_)
|
timeframe=timeframe,
|
||||||
|
since_ms=since_ms,
|
||||||
|
is_new_pair=is_new_pair,
|
||||||
|
raise_=raise_,
|
||||||
|
price=price
|
||||||
|
)
|
||||||
|
|
||||||
def funding_fee_cutoff(self, open_date: datetime):
|
def funding_fee_cutoff(self, open_date: datetime):
|
||||||
"""
|
"""
|
||||||
|
@ -1309,8 +1309,14 @@ class Exchange:
|
|||||||
|
|
||||||
# Historic data
|
# Historic data
|
||||||
|
|
||||||
def get_historic_ohlcv(self, pair: str, timeframe: str,
|
def get_historic_ohlcv(
|
||||||
since_ms: int, is_new_pair: bool = False) -> List:
|
self,
|
||||||
|
pair: str,
|
||||||
|
timeframe: str,
|
||||||
|
since_ms: int,
|
||||||
|
is_new_pair: bool = False,
|
||||||
|
price: Optional[str] = None
|
||||||
|
) -> List:
|
||||||
"""
|
"""
|
||||||
Get candle history using asyncio and returns the list of candles.
|
Get candle history using asyncio and returns the list of candles.
|
||||||
Handles all async work for this.
|
Handles all async work for this.
|
||||||
@ -1318,34 +1324,52 @@ class Exchange:
|
|||||||
:param pair: Pair to download
|
:param pair: Pair to download
|
||||||
:param timeframe: Timeframe to get data for
|
:param timeframe: Timeframe to get data for
|
||||||
:param since_ms: Timestamp in milliseconds to get history from
|
:param since_ms: Timestamp in milliseconds to get history from
|
||||||
|
:param price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||||
:return: List with candle (OHLCV) data
|
:return: List with candle (OHLCV) data
|
||||||
"""
|
"""
|
||||||
pair, timeframe, data = asyncio.get_event_loop().run_until_complete(
|
pair, timeframe, data = asyncio.get_event_loop().run_until_complete(
|
||||||
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
|
self._async_get_historic_ohlcv(
|
||||||
since_ms=since_ms, is_new_pair=is_new_pair))
|
pair=pair,
|
||||||
|
timeframe=timeframe,
|
||||||
|
since_ms=since_ms,
|
||||||
|
is_new_pair=is_new_pair,
|
||||||
|
price=price
|
||||||
|
))
|
||||||
logger.info(f"Downloaded data for {pair} with length {len(data)}.")
|
logger.info(f"Downloaded data for {pair} with length {len(data)}.")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
|
def get_historic_ohlcv_as_df(
|
||||||
since_ms: int) -> DataFrame:
|
self,
|
||||||
|
pair: str,
|
||||||
|
timeframe: str,
|
||||||
|
since_ms: int,
|
||||||
|
price: Optional[str] = None
|
||||||
|
) -> DataFrame:
|
||||||
"""
|
"""
|
||||||
Minimal wrapper around get_historic_ohlcv - converting the result into a dataframe
|
Minimal wrapper around get_historic_ohlcv - converting the result into a dataframe
|
||||||
:param pair: Pair to download
|
:param pair: Pair to download
|
||||||
:param timeframe: Timeframe to get data for
|
:param timeframe: Timeframe to get data for
|
||||||
:param since_ms: Timestamp in milliseconds to get history from
|
:param since_ms: Timestamp in milliseconds to get history from
|
||||||
|
:param price: "mark" if retrieving the mark price candles, "index" for index price candles
|
||||||
:return: OHLCV DataFrame
|
:return: OHLCV DataFrame
|
||||||
"""
|
"""
|
||||||
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms)
|
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms, price=price)
|
||||||
return ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
|
return ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
|
||||||
drop_incomplete=self._ohlcv_partial_candle)
|
drop_incomplete=self._ohlcv_partial_candle)
|
||||||
|
|
||||||
async def _async_get_historic_ohlcv(self, pair: str, timeframe: str,
|
async def _async_get_historic_ohlcv(
|
||||||
since_ms: int, is_new_pair: bool = False,
|
self,
|
||||||
raise_: bool = False
|
pair: str,
|
||||||
|
timeframe: str,
|
||||||
|
since_ms: int,
|
||||||
|
is_new_pair: bool,
|
||||||
|
raise_: bool = False,
|
||||||
|
price: Optional[str] = None
|
||||||
) -> Tuple[str, str, List]:
|
) -> Tuple[str, str, List]:
|
||||||
"""
|
"""
|
||||||
Download historic ohlcv
|
Download historic ohlcv
|
||||||
:param is_new_pair: used by binance subclass to allow "fast" new pair downloading
|
:param is_new_pair: used by binance subclass to allow "fast" new pair downloading
|
||||||
|
:param price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||||
"""
|
"""
|
||||||
|
|
||||||
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
||||||
@ -1354,8 +1378,13 @@ class Exchange:
|
|||||||
one_call,
|
one_call,
|
||||||
arrow.utcnow().shift(seconds=one_call // 1000).humanize(only_distance=True)
|
arrow.utcnow().shift(seconds=one_call // 1000).humanize(only_distance=True)
|
||||||
)
|
)
|
||||||
input_coroutines = [self._async_get_candle_history(
|
input_coroutines = [
|
||||||
pair, timeframe, since) for since in
|
self._async_get_candle_history(
|
||||||
|
pair,
|
||||||
|
timeframe,
|
||||||
|
since,
|
||||||
|
price
|
||||||
|
) for since in
|
||||||
range(since_ms, arrow.utcnow().int_timestamp * 1000, one_call)]
|
range(since_ms, arrow.utcnow().int_timestamp * 1000, one_call)]
|
||||||
|
|
||||||
data: List = []
|
data: List = []
|
||||||
@ -1378,8 +1407,12 @@ class Exchange:
|
|||||||
data = sorted(data, key=lambda x: x[0])
|
data = sorted(data, key=lambda x: x[0])
|
||||||
return pair, timeframe, data
|
return pair, timeframe, data
|
||||||
|
|
||||||
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
|
def refresh_latest_ohlcv(
|
||||||
since_ms: Optional[int] = None, cache: bool = True
|
self,
|
||||||
|
pair_list: ListPairsWithTimeframes, *,
|
||||||
|
since_ms: Optional[int] = None,
|
||||||
|
cache: bool = True,
|
||||||
|
price: Optional[str] = None
|
||||||
) -> Dict[Tuple[str, str], DataFrame]:
|
) -> Dict[Tuple[str, str], DataFrame]:
|
||||||
"""
|
"""
|
||||||
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
|
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
|
||||||
@ -1388,6 +1421,7 @@ class Exchange:
|
|||||||
:param pair_list: List of 2 element tuples containing pair, interval to refresh
|
:param pair_list: List of 2 element tuples containing pair, interval to refresh
|
||||||
:param since_ms: time since when to download, in milliseconds
|
:param since_ms: time since when to download, in milliseconds
|
||||||
:param cache: Assign result to _klines. Usefull for one-off downloads like for pairlists
|
:param cache: Assign result to _klines. Usefull for one-off downloads like for pairlists
|
||||||
|
:param price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||||
:return: Dict of [{(pair, timeframe): Dataframe}]
|
:return: Dict of [{(pair, timeframe): Dataframe}]
|
||||||
"""
|
"""
|
||||||
logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list))
|
logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list))
|
||||||
@ -1411,7 +1445,7 @@ class Exchange:
|
|||||||
else:
|
else:
|
||||||
# One call ... "regular" refresh
|
# One call ... "regular" refresh
|
||||||
input_coroutines.append(self._async_get_candle_history(
|
input_coroutines.append(self._async_get_candle_history(
|
||||||
pair, timeframe, since_ms=since_ms))
|
pair, timeframe, since_ms=since_ms, price=price))
|
||||||
else:
|
else:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Using cached candle (OHLCV) data for pair %s, timeframe %s ...",
|
"Using cached candle (OHLCV) data for pair %s, timeframe %s ...",
|
||||||
@ -1454,10 +1488,16 @@ class Exchange:
|
|||||||
+ interval_in_sec) >= arrow.utcnow().int_timestamp)
|
+ interval_in_sec) >= arrow.utcnow().int_timestamp)
|
||||||
|
|
||||||
@retrier_async
|
@retrier_async
|
||||||
async def _async_get_candle_history(self, pair: str, timeframe: str,
|
async def _async_get_candle_history(
|
||||||
since_ms: Optional[int] = None) -> Tuple[str, str, List]:
|
self,
|
||||||
|
pair: str,
|
||||||
|
timeframe: str,
|
||||||
|
since_ms: Optional[int] = None,
|
||||||
|
price: Optional[str] = None
|
||||||
|
) -> Tuple[str, str, List]:
|
||||||
"""
|
"""
|
||||||
Asynchronously get candle history data using fetch_ohlcv
|
Asynchronously get candle history data using fetch_ohlcv
|
||||||
|
:param price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||||
returns tuple: (pair, timeframe, ohlcv_list)
|
returns tuple: (pair, timeframe, ohlcv_list)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@ -1467,7 +1507,8 @@ class Exchange:
|
|||||||
"Fetching pair %s, interval %s, since %s %s...",
|
"Fetching pair %s, interval %s, since %s %s...",
|
||||||
pair, timeframe, since_ms, s
|
pair, timeframe, since_ms, s
|
||||||
)
|
)
|
||||||
params = self._ft_has.get('ohlcv_params', {})
|
# TODO-lev: Does this put price into params correctly?
|
||||||
|
params = self._ft_has.get('ohlcv_params', {price: price})
|
||||||
data = await self._api_async.fetch_ohlcv(pair, timeframe=timeframe,
|
data = await self._api_async.fetch_ohlcv(pair, timeframe=timeframe,
|
||||||
since=since_ms,
|
since=since_ms,
|
||||||
limit=self.ohlcv_candle_limit(timeframe),
|
limit=self.ohlcv_candle_limit(timeframe),
|
||||||
|
@ -1568,7 +1568,7 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name):
|
|||||||
]
|
]
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
|
|
||||||
async def mock_candle_hist(pair, timeframe, since_ms):
|
async def mock_candle_hist(pair, timeframe, since_ms, price=None):
|
||||||
return pair, timeframe, ohlcv
|
return pair, timeframe, ohlcv
|
||||||
|
|
||||||
exchange._async_get_candle_history = Mock(wraps=mock_candle_hist)
|
exchange._async_get_candle_history = Mock(wraps=mock_candle_hist)
|
||||||
@ -1625,7 +1625,7 @@ def test_get_historic_ohlcv_as_df(default_conf, mocker, exchange_name):
|
|||||||
]
|
]
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
|
|
||||||
async def mock_candle_hist(pair, timeframe, since_ms):
|
async def mock_candle_hist(pair, timeframe, since_ms, price=None):
|
||||||
return pair, timeframe, ohlcv
|
return pair, timeframe, ohlcv
|
||||||
|
|
||||||
exchange._async_get_candle_history = Mock(wraps=mock_candle_hist)
|
exchange._async_get_candle_history = Mock(wraps=mock_candle_hist)
|
||||||
|
Loading…
Reference in New Issue
Block a user