Added price as param to fetch_ohlcv
This commit is contained in:
parent
0459c934fe
commit
92a5d7583d
@ -242,27 +242,38 @@ class Binance(Exchange):
|
||||
- interest rate: 0.03% daily, BNBUSDT, LINKUSDT, and LTCUSDT are 0%
|
||||
- premium: varies by price difference between the perpetual contract and mark price
|
||||
"""
|
||||
if premium_index is None:
|
||||
raise OperationalException("Premium index cannot be None for Binance._get_funding_fee")
|
||||
if mark_price is None:
|
||||
raise OperationalException("Mark price cannot be None for Binance._get_funding_fee")
|
||||
nominal_value = mark_price * contract_size
|
||||
funding_rate = self._calculate_funding_rate(pair, premium_index)
|
||||
if funding_rate is None:
|
||||
raise OperationalException("Funding rate should never be none on Binance")
|
||||
raise OperationalException(
|
||||
"Funding rate should never be none on Binance._get_funding_fee")
|
||||
return nominal_value * funding_rate
|
||||
|
||||
async def _async_get_historic_ohlcv(self, pair: str, timeframe: str,
|
||||
since_ms: int, is_new_pair: bool
|
||||
async def _async_get_historic_ohlcv(
|
||||
self,
|
||||
pair: str,
|
||||
timeframe: str,
|
||||
since_ms: int,
|
||||
is_new_pair: bool,
|
||||
price: Optional[str]
|
||||
) -> List:
|
||||
"""
|
||||
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"
|
||||
:param price: "mark" if retrieving the mark price cnadles
|
||||
"""
|
||||
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:
|
||||
# Set starting date to first available candle.
|
||||
since_ms = x[2][0][0]
|
||||
logger.info(f"Candle-data for {pair} available starting with "
|
||||
f"{arrow.get(since_ms // 1000).isoformat()}.")
|
||||
return await super()._async_get_historic_ohlcv(
|
||||
pair=pair, timeframe=timeframe, 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
|
||||
)
|
||||
|
@ -1264,8 +1264,14 @@ class Exchange:
|
||||
|
||||
# Historic data
|
||||
|
||||
def get_historic_ohlcv(self, pair: str, timeframe: str,
|
||||
since_ms: int, is_new_pair: bool = False) -> List:
|
||||
def get_historic_ohlcv(
|
||||
self,
|
||||
pair: str,
|
||||
timeframe: str,
|
||||
since_ms: int,
|
||||
is_new_pair: bool = False,
|
||||
price: Optional[str]
|
||||
) -> List:
|
||||
"""
|
||||
Get candle history using asyncio and returns the list of candles.
|
||||
Handles all async work for this.
|
||||
@ -1273,31 +1279,55 @@ class Exchange:
|
||||
:param pair: Pair to download
|
||||
:param timeframe: Timeframe to get data for
|
||||
: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 asyncio.get_event_loop().run_until_complete(
|
||||
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
|
||||
since_ms=since_ms, is_new_pair=is_new_pair))
|
||||
self._async_get_historic_ohlcv(
|
||||
pair=pair,
|
||||
timeframe=timeframe,
|
||||
since_ms=since_ms,
|
||||
is_new_pair=is_new_pair,
|
||||
price=price
|
||||
))
|
||||
|
||||
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
|
||||
since_ms: int) -> DataFrame:
|
||||
def get_historic_ohlcv_as_df(
|
||||
self,
|
||||
pair: str,
|
||||
timeframe: str,
|
||||
since_ms: int,
|
||||
price: Optional[str]
|
||||
) -> DataFrame:
|
||||
"""
|
||||
Minimal wrapper around get_historic_ohlcv - converting the result into a dataframe
|
||||
:param pair: Pair to download
|
||||
:param timeframe: Timeframe to get data for
|
||||
: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: OHLCV DataFrame
|
||||
"""
|
||||
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms)
|
||||
return ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
|
||||
drop_incomplete=self._ohlcv_partial_candle)
|
||||
return ohlcv_to_dataframe(
|
||||
ticks,
|
||||
timeframe,
|
||||
pair=pair,
|
||||
fill_missing=True,
|
||||
drop_incomplete=self._ohlcv_partial_candle,
|
||||
price=price
|
||||
)
|
||||
|
||||
async def _async_get_historic_ohlcv(self, pair: str, timeframe: str,
|
||||
since_ms: int, is_new_pair: bool
|
||||
async def _async_get_historic_ohlcv(
|
||||
self,
|
||||
pair: str,
|
||||
timeframe: str,
|
||||
since_ms: int,
|
||||
is_new_pair: bool,
|
||||
price: Optional[str]
|
||||
) -> List:
|
||||
"""
|
||||
Download historic ohlcv
|
||||
: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)
|
||||
@ -1306,8 +1336,13 @@ class Exchange:
|
||||
one_call,
|
||||
arrow.utcnow().shift(seconds=one_call // 1000).humanize(only_distance=True)
|
||||
)
|
||||
input_coroutines = [self._async_get_candle_history(
|
||||
pair, timeframe, since) for since in
|
||||
input_coroutines = [
|
||||
self._async_get_candle_history(
|
||||
pair,
|
||||
timeframe,
|
||||
since,
|
||||
price
|
||||
) for since in
|
||||
range(since_ms, arrow.utcnow().int_timestamp * 1000, one_call)]
|
||||
|
||||
data: List = []
|
||||
@ -1328,8 +1363,12 @@ class Exchange:
|
||||
logger.info(f"Downloaded data for {pair} with length {len(data)}.")
|
||||
return data
|
||||
|
||||
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
|
||||
since_ms: Optional[int] = None, cache: bool = True
|
||||
def refresh_latest_ohlcv(
|
||||
self,
|
||||
pair_list: ListPairsWithTimeframes, *,
|
||||
since_ms: Optional[int] = None,
|
||||
cache: bool = True,
|
||||
price: Optional[str]
|
||||
) -> Dict[Tuple[str, str], DataFrame]:
|
||||
"""
|
||||
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
|
||||
@ -1338,6 +1377,7 @@ class Exchange:
|
||||
:param pair_list: List of 2 element tuples containing pair, interval to refresh
|
||||
: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 price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||
:return: Dict of [{(pair, timeframe): Dataframe}]
|
||||
"""
|
||||
logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list))
|
||||
@ -1348,8 +1388,9 @@ class Exchange:
|
||||
for pair, timeframe in set(pair_list):
|
||||
if (((pair, timeframe) not in self._klines)
|
||||
or self._now_is_time_to_refresh(pair, timeframe)):
|
||||
input_coroutines.append(self._async_get_candle_history(pair, timeframe,
|
||||
since_ms=since_ms))
|
||||
input_coroutines.append(
|
||||
self._async_get_candle_history(pair, timeframe, since_ms=since_ms, price=price)
|
||||
)
|
||||
else:
|
||||
logger.debug(
|
||||
"Using cached candle (OHLCV) data for pair %s, timeframe %s ...",
|
||||
@ -1392,10 +1433,16 @@ class Exchange:
|
||||
+ interval_in_sec) >= arrow.utcnow().int_timestamp)
|
||||
|
||||
@retrier_async
|
||||
async def _async_get_candle_history(self, pair: str, timeframe: str,
|
||||
since_ms: Optional[int] = None) -> Tuple[str, str, List]:
|
||||
async def _async_get_candle_history(
|
||||
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
|
||||
:param price: "mark" if retrieving the mark price cnadles, "index" for index price candles
|
||||
returns tuple: (pair, timeframe, ohlcv_list)
|
||||
"""
|
||||
try:
|
||||
@ -1405,11 +1452,15 @@ class Exchange:
|
||||
"Fetching pair %s, interval %s, since %s %s...",
|
||||
pair, timeframe, since_ms, s
|
||||
)
|
||||
params = self._ft_has.get('ohlcv_params', {})
|
||||
data = await self._api_async.fetch_ohlcv(pair, timeframe=timeframe,
|
||||
# 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,
|
||||
since=since_ms,
|
||||
limit=self.ohlcv_candle_limit(timeframe),
|
||||
params=params)
|
||||
params=params
|
||||
)
|
||||
|
||||
# Some exchanges sort OHLCV in ASC order and others in DESC.
|
||||
# Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last)
|
||||
|
Loading…
Reference in New Issue
Block a user