Update more to use candleType

This commit is contained in:
Matthias 2021-12-03 14:11:24 +01:00
parent 5493212672
commit 2f17fa2765
18 changed files with 56 additions and 55 deletions

View File

@ -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__)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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']

View File

@ -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

View File

@ -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]

View File

@ -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))

View File

@ -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 = '',

View File

@ -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 = (