I’m attempting to reproduce the historical funding rate on a minute-by-minute basis using the premium index Kline data, following the steps provided in the Binance Futures Funding Rates Introduction. However, despite following the outlined procedure, the values I calculate do not match the real-time funding rate data retrieved from the Binance API.
Has anyone else encountered a similar issue, or is there a known discrepancy between the documented process and the real-time API data?
import requests
import numpy as np
import pandas as pd
def clamp(value, upper_limit=0.0005, lower_limit=-0.0005):
if value > upper_limit:
return upper_limit
elif value < lower_limit:
return lower_limit
else:
return value
def calculate_funding_rate(average_premium_index, funding_interval_hours=8):
interest_rate_per_hours = 0.0003/24
interest_rate = interest_rate_per_hours * funding_interval_hours
clamp_value = clamp(interest_rate - average_premium_index, 0.0005, -0.0005)
return average_premium_index + clamp_value
candle_columns = ['open_time', 'open', 'high', 'low', 'close',
'volume', 'close_time','quote_volume', 'count',
'taker_buy_volume', 'taker_buy_quote_volume','ignore']
symbol = 'BTCUSDT'
funding_interval_hours = 8
funding_interval_minutes = funding_interval_hours * 60
index_kline_url = "https://fapi.binance.com/fapi/v1/premiumIndexKlines"
kline_param = {"symbol":symbol, "interval":'1m', 'limit':1000}
kline_res = requests.get(index_kline_url, params=kline_param)
kline_list = kline_res.json()
kline_df = pd.DataFrame(kline_list, columns = candle_columns)
premium_indexs = kline_df['close'].iloc[-funding_interval_minutes:].astype(float).to_numpy()
weights = pd.Series(np.arange(1,funding_interval_minutes+1))
weighted_premium_index = weights * premium_indexs
average_premium_index = weighted_premium_index.sum() / weights.sum()
index_url = "https://fapi.binance.com/fapi/v1/premiumIndex"
index_res = requests.get(index_url, params={"symbol":symbol})
index_data = index_res.json()
pct_real_finding_rate = float(index_data['lastFundingRate']) * 100
estimate_funding_rate = calculate_funding_rate(average_premium_index, funding_interval_hours=funding_interval_hours)
print(f"{symbol} reproduced_rate:{estimate_funding_rate*100:.4f}% exchange_rate{pct_real_finding_rate:.4f}%")