Разработка системы бэктестинга с учетом funding rate

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка системы бэктестинга с учетом funding rate
Средний
~3-5 дней
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1286
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    902
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1122
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    859

Разработка системы бэктестинга с учётом funding rate

Funding rate — периодический платёж между лонгами и шортами на perpetual futures рынках. Его игнорирование в бэктесте может существенно исказить результаты: при постоянно положительном funding (бычий рынок) лонговые стратегии переплачивают, при отрицательном — получают доход.

Механика funding rate

На большинстве perpetual futures бирж (Binance, Bybit, OKX) funding выплачивается каждые 8 часов в 00:00, 08:00, 16:00 UTC.

Формула:

Funding Payment = Position Value × Funding Rate

Если Funding Rate > 0: лонги платят шортам
Если Funding Rate < 0: шорты платят лонгам

Funding rate обычно находится в диапазоне -0.3% до +0.3% за 8 часов, но в периоды высокой волатильности может достигать 3–5%.

Загрузка исторических данных funding rate

import ccxt
import pandas as pd

class FundingRateLoader:
    async def load_history(
        self,
        exchange_name: str,
        symbol: str,
        start_date: str,
        end_date: str,
    ) -> pd.DataFrame:
        exchange = getattr(ccxt, exchange_name)({'enableRateLimit': True})

        all_rates = []
        since = pd.Timestamp(start_date).timestamp() * 1000

        while True:
            rates = await exchange.fetch_funding_rate_history(
                symbol=symbol,
                since=int(since),
                limit=500,
            )
            if not rates:
                break

            all_rates.extend(rates)
            since = rates[-1]['timestamp'] + 1

            if rates[-1]['timestamp'] > pd.Timestamp(end_date).timestamp() * 1000:
                break

        df = pd.DataFrame(all_rates)
        df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True)
        df = df.set_index('datetime')
        return df[['fundingRate']]

Интеграция в бэктест движок

class FundingAwareBacktester:
    FUNDING_INTERVAL_HOURS = 8
    FUNDING_TIMES_UTC = [0, 8, 16]  # часы UTC

    def __init__(self, funding_data: pd.DataFrame, commission: float = 0.0005):
        self.funding_data = funding_data
        self.commission = commission

    def calculate_funding_payments(
        self,
        position: Position,
        from_timestamp: int,
        to_timestamp: int,
    ) -> float:
        """Рассчитываем суммарный funding за период удержания позиции"""
        from_dt = pd.Timestamp(from_timestamp, unit='ms', tz='UTC')
        to_dt = pd.Timestamp(to_timestamp, unit='ms', tz='UTC')

        # Находим все funding моменты внутри периода
        funding_events = self.funding_data[
            (self.funding_data.index > from_dt) &
            (self.funding_data.index <= to_dt)
        ]

        total_funding = 0.0
        for ts, row in funding_events.iterrows():
            rate = row['fundingRate']
            position_value = abs(position.quantity) * position.current_price

            if position.side == 'LONG':
                # Лонги платят при положительном rate
                payment = -position_value * rate
            else:
                # Шорты платят при отрицательном rate
                payment = position_value * rate

            total_funding += payment

        return total_funding

    def run_with_funding(self, strategy, ohlcv_data: pd.DataFrame) -> BacktestResult:
        portfolio = Portfolio(initial_cash=100_000)
        current_position = None

        for i, (timestamp, row) in enumerate(ohlcv_data.iterrows()):
            bar = Bar(timestamp=timestamp.value // 10**6, **row.to_dict())

            # Применяем funding если есть открытая позиция
            if current_position:
                prev_ts = ohlcv_data.index[i-1].value // 10**6 if i > 0 else bar.timestamp
                funding = self.calculate_funding_payments(
                    current_position, prev_ts, bar.timestamp
                )
                portfolio.cash += funding
                current_position.funding_paid += -funding

            # Стратегия
            signal = strategy.on_bar(bar)
            if signal:
                current_position = self.execute_signal(portfolio, signal, bar)

        return BacktestResult(portfolio)

Стратегии с funding rate как сигналом

Funding rate сам по себе является торговым сигналом:

class FundingRateStrategy:
    """
    Funding Rate Arbitrage: при экстремальном funding
    открываем противоположную направлению позицию.
    При funding > 0.1% лонги переплачивают — значит рынок перегрет,
    идём в шорт или держим нейтральную позицию.
    """
    EXTREME_FUNDING_THRESHOLD = 0.001  # 0.1% за 8 часов

    def on_bar(self, bar: Bar, current_funding_rate: float) -> Optional[Signal]:
        if current_funding_rate > self.EXTREME_FUNDING_THRESHOLD:
            # Экстремально позитивный funding: рынок бычий, много лонгов
            # Открываем шорт или выходим из лонга
            return Signal.SHORT

        elif current_funding_rate < -self.EXTREME_FUNDING_THRESHOLD:
            # Экстремально отрицательный: рынок медвежий
            return Signal.LONG

        return None

Влияние funding на P&L

Для стратегий удержания позиций несколько дней/недель funding существенен:

Период Среднее funding (8h) Дневной cost За 30 дней
Бычий рынок (2021) +0.05–0.15% +0.15–0.45% +4.5–13.5%
Медвежий рынок (2022) -0.01–0.05% -0.03–0.15% -0.9–4.5%
Боковик ±0.01% ±0.03% ±0.9%

В bull market лонговые стратегии теряли до 13% за месяц только на funding. Это существенно — его нельзя игнорировать в бэктесте фьючерсных стратегий.