Update more to use candleType
This commit is contained in:
parent
5493212672
commit
2f17fa2765
@ -11,7 +11,7 @@ import pandas as pd
|
|||||||
from pandas import DataFrame, to_datetime
|
from pandas import DataFrame, to_datetime
|
||||||
|
|
||||||
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
|
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
|
||||||
from freqtrade.enums.candletype import CandleType
|
from freqtrade.enums import CandleType
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -13,8 +13,7 @@ from pandas import DataFrame
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe
|
from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe
|
||||||
from freqtrade.data.history import load_pair_history
|
from freqtrade.data.history import load_pair_history
|
||||||
from freqtrade.enums import RunMode
|
from freqtrade.enums import CandleType, RunMode
|
||||||
from freqtrade.enums.candletype import CandleType
|
|
||||||
from freqtrade.exceptions import ExchangeError, OperationalException
|
from freqtrade.exceptions import ExchangeError, OperationalException
|
||||||
from freqtrade.exchange import Exchange, timeframe_to_seconds
|
from freqtrade.exchange import Exchange, timeframe_to_seconds
|
||||||
|
|
||||||
@ -223,7 +222,7 @@ class DataProvider:
|
|||||||
raise OperationalException(NO_EXCHANGE_EXCEPTION)
|
raise OperationalException(NO_EXCHANGE_EXCEPTION)
|
||||||
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
|
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
|
||||||
return self._exchange.klines(
|
return self._exchange.klines(
|
||||||
(pair, timeframe or self._config['timeframe'], candle_type),
|
(pair, timeframe or self._config['timeframe'], CandleType.from_string(candle_type)),
|
||||||
copy=copy
|
copy=copy
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -9,7 +9,7 @@ import pandas as pd
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS,
|
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS,
|
||||||
ListPairsWithTimeframes, TradeList)
|
ListPairsWithTimeframes, TradeList)
|
||||||
from freqtrade.enums.candletype import CandleType
|
from freqtrade.enums import CandleType
|
||||||
|
|
||||||
from .idatahandler import IDataHandler
|
from .idatahandler import IDataHandler
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
|
|||||||
from freqtrade.data.converter import (clean_ohlcv_dataframe, ohlcv_to_dataframe,
|
from freqtrade.data.converter import (clean_ohlcv_dataframe, ohlcv_to_dataframe,
|
||||||
trades_remove_duplicates, trades_to_ohlcv)
|
trades_remove_duplicates, trades_to_ohlcv)
|
||||||
from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler
|
from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler
|
||||||
from freqtrade.enums.candletype import CandleType
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.misc import format_ms_time
|
from freqtrade.misc import format_ms_time
|
||||||
|
@ -17,7 +17,7 @@ from freqtrade import misc
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.constants import ListPairsWithTimeframes, TradeList
|
from freqtrade.constants import ListPairsWithTimeframes, TradeList
|
||||||
from freqtrade.data.converter import clean_ohlcv_dataframe, trades_remove_duplicates, trim_dataframe
|
from freqtrade.data.converter import clean_ohlcv_dataframe, trades_remove_duplicates, trim_dataframe
|
||||||
from freqtrade.enums.candletype import CandleType
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exchange import timeframe_to_seconds
|
from freqtrade.exchange import timeframe_to_seconds
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from freqtrade import misc
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, ListPairsWithTimeframes, TradeList
|
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, ListPairsWithTimeframes, TradeList
|
||||||
from freqtrade.data.converter import trades_dict_to_list
|
from freqtrade.data.converter import trades_dict_to_list
|
||||||
from freqtrade.enums.candletype import CandleType
|
from freqtrade.enums import CandleType
|
||||||
|
|
||||||
from .idatahandler import IDataHandler
|
from .idatahandler import IDataHandler
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from typing import Dict, List, Optional, Tuple
|
|||||||
import arrow
|
import arrow
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
from freqtrade.enums import Collateral, TradingMode
|
from freqtrade.enums import CandleType, Collateral, TradingMode
|
||||||
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
||||||
OperationalException, TemporaryError)
|
OperationalException, TemporaryError)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
@ -197,14 +197,13 @@ class Binance(Exchange):
|
|||||||
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(self, pair: str, timeframe: str,
|
||||||
since_ms: int, is_new_pair: bool = False,
|
since_ms: int, candle_type: CandleType,
|
||||||
raise_: bool = False,
|
is_new_pair: bool = False, raise_: bool = False,
|
||||||
candle_type: str = ''
|
|
||||||
) -> Tuple[str, str, str, List]:
|
) -> Tuple[str, 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 candle_type: '', mark, index, premiumIndex, or funding_rate
|
:param candle_type: Any of the enum CandleType (must match trading mode!)
|
||||||
"""
|
"""
|
||||||
if is_new_pair:
|
if is_new_pair:
|
||||||
x = await self._async_get_candle_history(pair, timeframe, 0, candle_type)
|
x = await self._async_get_candle_history(pair, timeframe, 0, candle_type)
|
||||||
|
@ -20,9 +20,9 @@ from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, TRU
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHANGE_STATES,
|
from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHANGE_STATES,
|
||||||
ListPairsWithTimeframes)
|
ListPairsWithTimeframes, PairWithTimeframe)
|
||||||
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
||||||
from freqtrade.enums import Collateral, TradingMode
|
from freqtrade.enums import CandleType, Collateral, TradingMode
|
||||||
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
|
||||||
InvalidOrderException, OperationalException, PricingError,
|
InvalidOrderException, OperationalException, PricingError,
|
||||||
RetryableOrderError, TemporaryError)
|
RetryableOrderError, TemporaryError)
|
||||||
@ -92,7 +92,7 @@ class Exchange:
|
|||||||
self._config.update(config)
|
self._config.update(config)
|
||||||
|
|
||||||
# Holds last candle refreshed time of each pair
|
# Holds last candle refreshed time of each pair
|
||||||
self._pairs_last_refresh_time: Dict[Tuple[str, str, str], int] = {}
|
self._pairs_last_refresh_time: Dict[PairWithTimeframe, int] = {}
|
||||||
# Timestamp of last markets refresh
|
# Timestamp of last markets refresh
|
||||||
self._last_markets_refresh: int = 0
|
self._last_markets_refresh: int = 0
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ class Exchange:
|
|||||||
self._buy_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=1800)
|
self._buy_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=1800)
|
||||||
|
|
||||||
# Holds candles
|
# Holds candles
|
||||||
self._klines: Dict[Tuple[str, str, str], DataFrame] = {}
|
self._klines: Dict[PairWithTimeframe, DataFrame] = {}
|
||||||
|
|
||||||
# Holds all open sell orders for dry_run
|
# Holds all open sell orders for dry_run
|
||||||
self._dry_run_open_orders: Dict[str, Any] = {}
|
self._dry_run_open_orders: Dict[str, Any] = {}
|
||||||
@ -359,7 +359,7 @@ class Exchange:
|
|||||||
or (self.trading_mode == TradingMode.FUTURES and self.market_is_future(market))
|
or (self.trading_mode == TradingMode.FUTURES and self.market_is_future(market))
|
||||||
)
|
)
|
||||||
|
|
||||||
def klines(self, pair_interval: Tuple[str, str, str], copy: bool = True) -> DataFrame:
|
def klines(self, pair_interval: PairWithTimeframe, copy: bool = True) -> DataFrame:
|
||||||
if pair_interval in self._klines:
|
if pair_interval in self._klines:
|
||||||
return self._klines[pair_interval].copy() if copy else self._klines[pair_interval]
|
return self._klines[pair_interval].copy() if copy else self._klines[pair_interval]
|
||||||
else:
|
else:
|
||||||
@ -1314,8 +1314,8 @@ class Exchange:
|
|||||||
# Historic data
|
# Historic data
|
||||||
|
|
||||||
def get_historic_ohlcv(self, pair: str, timeframe: str,
|
def get_historic_ohlcv(self, pair: str, timeframe: str,
|
||||||
since_ms: int, is_new_pair: bool = False,
|
since_ms: int, candle_type: CandleType,
|
||||||
candle_type: str = '') -> List:
|
is_new_pair: bool = False) -> 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.
|
||||||
@ -1327,7 +1327,7 @@ class Exchange:
|
|||||||
:return: List with candle (OHLCV) data
|
:return: List with candle (OHLCV) data
|
||||||
"""
|
"""
|
||||||
data: List
|
data: List
|
||||||
pair, timeframe, candle_type, data = asyncio.get_event_loop().run_until_complete(
|
pair, _, _, data = asyncio.get_event_loop().run_until_complete(
|
||||||
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
|
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
|
||||||
since_ms=since_ms, is_new_pair=is_new_pair,
|
since_ms=since_ms, is_new_pair=is_new_pair,
|
||||||
candle_type=candle_type))
|
candle_type=candle_type))
|
||||||
@ -1335,13 +1335,13 @@ class Exchange:
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
|
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
|
||||||
since_ms: int, candle_type: str = '') -> DataFrame:
|
since_ms: int, candle_type: CandleType) -> 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 candle_type: '', mark, index, premiumIndex, or funding_rate
|
:param candle_type: Any of the enum CandleType (must match trading mode!)
|
||||||
:return: OHLCV DataFrame
|
:return: OHLCV DataFrame
|
||||||
"""
|
"""
|
||||||
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms, candle_type=candle_type)
|
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms, candle_type=candle_type)
|
||||||
@ -1349,14 +1349,13 @@ class Exchange:
|
|||||||
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(self, pair: str, timeframe: str,
|
||||||
since_ms: int, is_new_pair: bool = False,
|
since_ms: int, candle_type: CandleType,
|
||||||
raise_: bool = False,
|
is_new_pair: bool = False, raise_: bool = False,
|
||||||
candle_type: str = ''
|
|
||||||
) -> Tuple[str, str, str, List]:
|
) -> Tuple[str, 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 candle_type: '', mark, index, premiumIndex, or funding_rate
|
:param candle_type: Any of the enum CandleType (must match trading mode!)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
||||||
@ -1391,8 +1390,8 @@ class Exchange:
|
|||||||
|
|
||||||
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
|
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
|
||||||
since_ms: Optional[int] = None, cache: bool = True,
|
since_ms: Optional[int] = None, cache: bool = True,
|
||||||
candle_type: str = ''
|
candle_type: CandleType = CandleType.SPOT_
|
||||||
) -> Dict[Tuple[str, str, str], DataFrame]:
|
) -> Dict[PairWithTimeframe, DataFrame]:
|
||||||
"""
|
"""
|
||||||
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
|
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
|
||||||
Loops asynchronously over pair_list and downloads all pairs async (semi-parallel).
|
Loops asynchronously over pair_list and downloads all pairs async (semi-parallel).
|
||||||
@ -1410,7 +1409,7 @@ class Exchange:
|
|||||||
# Gather coroutines to run
|
# Gather coroutines to run
|
||||||
for pair, timeframe, candle_type in set(pair_list):
|
for pair, timeframe, candle_type in set(pair_list):
|
||||||
if ((pair, timeframe, candle_type) not in self._klines or not cache
|
if ((pair, timeframe, candle_type) not in self._klines or not cache
|
||||||
or self._now_is_time_to_refresh(pair, timeframe)):
|
or self._now_is_time_to_refresh(pair, timeframe, candle_type)):
|
||||||
if not since_ms and self.required_candle_call_count > 1:
|
if not since_ms and self.required_candle_call_count > 1:
|
||||||
# Multiple calls for one pair - to get more history
|
# Multiple calls for one pair - to get more history
|
||||||
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
|
||||||
@ -1463,12 +1462,7 @@ class Exchange:
|
|||||||
|
|
||||||
return results_df
|
return results_df
|
||||||
|
|
||||||
def _now_is_time_to_refresh(
|
def _now_is_time_to_refresh(self, pair: str, timeframe: str, candle_type: CandleType) -> bool:
|
||||||
self,
|
|
||||||
pair: str,
|
|
||||||
timeframe: str,
|
|
||||||
candle_type: str = ''
|
|
||||||
) -> bool:
|
|
||||||
# Timeframe in seconds
|
# Timeframe in seconds
|
||||||
interval_in_sec = timeframe_to_seconds(timeframe)
|
interval_in_sec = timeframe_to_seconds(timeframe)
|
||||||
|
|
||||||
|
@ -17,9 +17,7 @@ from freqtrade.data import history
|
|||||||
from freqtrade.data.btanalysis import trade_list_to_dataframe
|
from freqtrade.data.btanalysis import trade_list_to_dataframe
|
||||||
from freqtrade.data.converter import trim_dataframe, trim_dataframes
|
from freqtrade.data.converter import trim_dataframe, trim_dataframes
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.enums import BacktestState, SellType
|
from freqtrade.enums import BacktestState, CandleType, SellType, TradingMode
|
||||||
from freqtrade.enums.candletype import CandleType
|
|
||||||
from freqtrade.enums.tradingmode import TradingMode
|
|
||||||
from freqtrade.exceptions import DependencyException, OperationalException
|
from freqtrade.exceptions import DependencyException, OperationalException
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
||||||
from freqtrade.mixins import LoggingMixin
|
from freqtrade.mixins import LoggingMixin
|
||||||
|
@ -9,6 +9,7 @@ import arrow
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.configuration import PeriodicCache
|
from freqtrade.configuration import PeriodicCache
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
@ -72,7 +73,7 @@ class AgeFilter(IPairList):
|
|||||||
:return: new allowlist
|
:return: new allowlist
|
||||||
"""
|
"""
|
||||||
needed_pairs = [
|
needed_pairs = [
|
||||||
(p, '1d', '') for p in pairlist
|
(p, '1d', CandleType.SPOT_) for p in pairlist
|
||||||
if p not in self._symbolsChecked and p not in self._symbolsCheckFailed]
|
if p not in self._symbolsChecked and p not in self._symbolsCheckFailed]
|
||||||
if not needed_pairs:
|
if not needed_pairs:
|
||||||
# Remove pairs that have been removed before
|
# Remove pairs that have been removed before
|
||||||
@ -88,7 +89,8 @@ class AgeFilter(IPairList):
|
|||||||
candles = self._exchange.refresh_latest_ohlcv(needed_pairs, since_ms=since_ms, cache=False)
|
candles = self._exchange.refresh_latest_ohlcv(needed_pairs, since_ms=since_ms, cache=False)
|
||||||
if self._enabled:
|
if self._enabled:
|
||||||
for p in deepcopy(pairlist):
|
for p in deepcopy(pairlist):
|
||||||
daily_candles = candles[(p, '1d', '')] if (p, '1d', '') in candles else None
|
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if (
|
||||||
|
p, '1d', CandleType.SPOT_) in candles else None
|
||||||
if not self._validate_pair_loc(p, daily_candles):
|
if not self._validate_pair_loc(p, daily_candles):
|
||||||
pairlist.remove(p)
|
pairlist.remove(p)
|
||||||
self.log_once(f"Validated {len(pairlist)} pairs.", logger.info)
|
self.log_once(f"Validated {len(pairlist)} pairs.", logger.info)
|
||||||
|
@ -5,7 +5,7 @@ import logging
|
|||||||
import random
|
import random
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from freqtrade.enums.runmode import RunMode
|
from freqtrade.enums import RunMode
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import numpy as np
|
|||||||
from cachetools.ttl import TTLCache
|
from cachetools.ttl import TTLCache
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
@ -67,7 +68,7 @@ class VolatilityFilter(IPairList):
|
|||||||
:param tickers: Tickers (from exchange.get_tickers()). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers()). May be cached.
|
||||||
:return: new allowlist
|
:return: new allowlist
|
||||||
"""
|
"""
|
||||||
needed_pairs = [(p, '1d', '') for p in pairlist if p not in self._pair_cache]
|
needed_pairs = [(p, '1d', CandleType.SPOT_) for p in pairlist if p not in self._pair_cache]
|
||||||
|
|
||||||
since_ms = (arrow.utcnow()
|
since_ms = (arrow.utcnow()
|
||||||
.floor('day')
|
.floor('day')
|
||||||
@ -81,7 +82,8 @@ class VolatilityFilter(IPairList):
|
|||||||
|
|
||||||
if self._enabled:
|
if self._enabled:
|
||||||
for p in deepcopy(pairlist):
|
for p in deepcopy(pairlist):
|
||||||
daily_candles = candles[(p, '1d', '')] if (p, '1d', '') in candles else None
|
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if (
|
||||||
|
p, '1d', CandleType.SPOT_) in candles else None
|
||||||
if not self._validate_pair_loc(p, daily_candles):
|
if not self._validate_pair_loc(p, daily_candles):
|
||||||
pairlist.remove(p)
|
pairlist.remove(p)
|
||||||
return pairlist
|
return pairlist
|
||||||
|
@ -10,6 +10,7 @@ from typing import Any, Dict, List
|
|||||||
import arrow
|
import arrow
|
||||||
from cachetools.ttl import TTLCache
|
from cachetools.ttl import TTLCache
|
||||||
|
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.exchange import timeframe_to_minutes
|
from freqtrade.exchange import timeframe_to_minutes
|
||||||
from freqtrade.misc import format_ms_time
|
from freqtrade.misc import format_ms_time
|
||||||
@ -160,7 +161,7 @@ class VolumePairList(IPairList):
|
|||||||
f"{self._lookback_timeframe}, starting from {format_ms_time(since_ms)} "
|
f"{self._lookback_timeframe}, starting from {format_ms_time(since_ms)} "
|
||||||
f"till {format_ms_time(to_ms)}", logger.info)
|
f"till {format_ms_time(to_ms)}", logger.info)
|
||||||
needed_pairs = [
|
needed_pairs = [
|
||||||
(p, self._lookback_timeframe, '') for p in
|
(p, self._lookback_timeframe, CandleType.SPOT_) for p in
|
||||||
[s['symbol'] for s in filtered_tickers]
|
[s['symbol'] for s in filtered_tickers]
|
||||||
if p not in self._pair_cache
|
if p not in self._pair_cache
|
||||||
]
|
]
|
||||||
@ -173,8 +174,8 @@ class VolumePairList(IPairList):
|
|||||||
)
|
)
|
||||||
for i, p in enumerate(filtered_tickers):
|
for i, p in enumerate(filtered_tickers):
|
||||||
pair_candles = candles[
|
pair_candles = candles[
|
||||||
(p['symbol'], self._lookback_timeframe, '')
|
(p['symbol'], self._lookback_timeframe, CandleType.SPOT_)
|
||||||
] if (p['symbol'], self._lookback_timeframe, '') in candles else None
|
] if (p['symbol'], self._lookback_timeframe, CandleType.SPOT_) in candles else None
|
||||||
# in case of candle data calculate typical price and quoteVolume for candle
|
# in case of candle data calculate typical price and quoteVolume for candle
|
||||||
if pair_candles is not None and not pair_candles.empty:
|
if pair_candles is not None and not pair_candles.empty:
|
||||||
pair_candles['typical_price'] = (pair_candles['high'] + pair_candles['low']
|
pair_candles['typical_price'] = (pair_candles['high'] + pair_candles['low']
|
||||||
|
@ -9,6 +9,7 @@ import arrow
|
|||||||
from cachetools.ttl import TTLCache
|
from cachetools.ttl import TTLCache
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
@ -65,7 +66,7 @@ class RangeStabilityFilter(IPairList):
|
|||||||
:param tickers: Tickers (from exchange.get_tickers()). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers()). May be cached.
|
||||||
:return: new allowlist
|
:return: new allowlist
|
||||||
"""
|
"""
|
||||||
needed_pairs = [(p, '1d', '') for p in pairlist if p not in self._pair_cache]
|
needed_pairs = [(p, '1d', CandleType.SPOT_) for p in pairlist if p not in self._pair_cache]
|
||||||
|
|
||||||
since_ms = (arrow.utcnow()
|
since_ms = (arrow.utcnow()
|
||||||
.floor('day')
|
.floor('day')
|
||||||
@ -79,7 +80,8 @@ class RangeStabilityFilter(IPairList):
|
|||||||
|
|
||||||
if self._enabled:
|
if self._enabled:
|
||||||
for p in deepcopy(pairlist):
|
for p in deepcopy(pairlist):
|
||||||
daily_candles = candles[(p, '1d', '')] if (p, '1d', '') in candles else None
|
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if (
|
||||||
|
p, '1d', CandleType.SPOT_) in candles else None
|
||||||
if not self._validate_pair_loc(p, daily_candles):
|
if not self._validate_pair_loc(p, daily_candles):
|
||||||
pairlist.remove(p)
|
pairlist.remove(p)
|
||||||
return pairlist
|
return pairlist
|
||||||
|
@ -8,6 +8,7 @@ from typing import Dict, List
|
|||||||
from cachetools import TTLCache, cached
|
from cachetools import TTLCache, cached
|
||||||
|
|
||||||
from freqtrade.constants import ListPairsWithTimeframes
|
from freqtrade.constants import ListPairsWithTimeframes
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
||||||
@ -138,4 +139,4 @@ class PairListManager():
|
|||||||
"""
|
"""
|
||||||
Create list of pair tuples with (pair, timeframe)
|
Create list of pair tuples with (pair, timeframe)
|
||||||
"""
|
"""
|
||||||
return [(pair, timeframe or self._config['timeframe'], '') for pair in pairs]
|
return [(pair, timeframe or self._config['timeframe'], CandleType.SPOT) for pair in pairs]
|
||||||
|
@ -9,6 +9,7 @@ from fastapi.exceptions import HTTPException
|
|||||||
from freqtrade import __version__
|
from freqtrade import __version__
|
||||||
from freqtrade.constants import USERPATH_STRATEGIES
|
from freqtrade.constants import USERPATH_STRATEGIES
|
||||||
from freqtrade.data.history import get_datahandler
|
from freqtrade.data.history import get_datahandler
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.rpc import RPC
|
from freqtrade.rpc import RPC
|
||||||
from freqtrade.rpc.api_server.api_schemas import (AvailablePairs, Balances, BlacklistPayload,
|
from freqtrade.rpc.api_server.api_schemas import (AvailablePairs, Balances, BlacklistPayload,
|
||||||
@ -250,7 +251,7 @@ def get_strategy(strategy: str, config=Depends(get_config)):
|
|||||||
|
|
||||||
@router.get('/available_pairs', response_model=AvailablePairs, tags=['candle data'])
|
@router.get('/available_pairs', response_model=AvailablePairs, tags=['candle data'])
|
||||||
def list_available_pairs(timeframe: Optional[str] = None, stake_currency: Optional[str] = None,
|
def list_available_pairs(timeframe: Optional[str] = None, stake_currency: Optional[str] = None,
|
||||||
candletype: Optional[str] = None, config=Depends(get_config)):
|
candletype: Optional[CandleType] = None, config=Depends(get_config)):
|
||||||
|
|
||||||
dh = get_datahandler(config['datadir'], config.get('dataformat_ohlcv', None))
|
dh = get_datahandler(config['datadir'], config.get('dataformat_ohlcv', None))
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from typing import Any, Callable, NamedTuple, Optional, Union
|
|||||||
|
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.strategy.strategy_helper import merge_informative_pair
|
from freqtrade.strategy.strategy_helper import merge_informative_pair
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ class InformativeData(NamedTuple):
|
|||||||
timeframe: str
|
timeframe: str
|
||||||
fmt: Union[str, Callable[[Any], str], None]
|
fmt: Union[str, Callable[[Any], str], None]
|
||||||
ffill: bool
|
ffill: bool
|
||||||
candle_type: str = ''
|
candle_type: CandleType = CandleType.SPOT_
|
||||||
|
|
||||||
|
|
||||||
def informative(timeframe: str, asset: str = '',
|
def informative(timeframe: str, asset: str = '',
|
||||||
|
@ -13,8 +13,7 @@ from pandas import DataFrame
|
|||||||
|
|
||||||
from freqtrade.constants import ListPairsWithTimeframes
|
from freqtrade.constants import ListPairsWithTimeframes
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.enums import SellType, SignalDirection, SignalTagType, SignalType
|
from freqtrade.enums import CandleType, SellType, SignalDirection, SignalTagType, SignalType
|
||||||
from freqtrade.enums.candletype import CandleType
|
|
||||||
from freqtrade.exceptions import OperationalException, StrategyError
|
from freqtrade.exceptions import OperationalException, StrategyError
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
||||||
from freqtrade.exchange.exchange import timeframe_to_next_date
|
from freqtrade.exchange.exchange import timeframe_to_next_date
|
||||||
@ -424,7 +423,9 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
"""
|
"""
|
||||||
informative_pairs = self.informative_pairs()
|
informative_pairs = self.informative_pairs()
|
||||||
# Compatibility code for 2 tuple informative pairs
|
# Compatibility code for 2 tuple informative pairs
|
||||||
informative_pairs = [(p[0], p[1], p[2] if len(p) > 2 else '') for p in informative_pairs]
|
informative_pairs = [
|
||||||
|
(p[0], p[1], CandleType.from_string(p[2]) if len(p) > 2 else CandleType.SPOT_)
|
||||||
|
for p in informative_pairs]
|
||||||
for inf_data, _ in self._ft_informative:
|
for inf_data, _ in self._ft_informative:
|
||||||
if inf_data.asset:
|
if inf_data.asset:
|
||||||
pair_tf = (
|
pair_tf = (
|
||||||
|
Loading…
Reference in New Issue
Block a user