Sample Codes
Input:
Weight Generator
Weight Part
import pandas as pd
import numpy as np
import itertools
def generate_weights_with_constraints_25(num_weights, num_simulation=70):
possible_values = [0, 0.25, 0.5, 0.75, 1]
simulations = []
# Generate all possible combinations
all_combinations = list(itertools.product(possible_values, repeat=num_weights))
valid_combinations = [combo for combo in all_combinations if np.isclose(sum(combo), 1)]
simulations = np.random.choice(len(valid_combinations), num_simulation, replace=False)
simulations = [valid_combinations[i] for i in simulations]
return simulations
# For 0.25 interval, total number of simulation are 70
num_weights = 5
num_simulation = 70
simulations = generate_weights_with_constraints_25(num_weights, num_simulation)
simulations = pd.DataFrame(simulations
Allocation Part
def generate_allcations_with_constraints_10(num_allocations, num_simulation=70):
possible_values = [0, 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
simulations = []
# Generate all possible combinations
all_combinations = list(itertools.product(possible_values, repeat=num_allocations))
valid_combinations = [combo for combo in all_combinations if np.isclose(sum(combo), 1)]
simulations = np.random.choice(len(valid_combinations), num_simulation, replace=False)
simulations = [valid_combinations[i] for i in simulations]
return simulations
# For 0.1 interval, total number of allocations are 66
num_allocations = 3
num_simulation = 66
allocations_simulation = generate_allcations_with_constraints_10(num_allocations, num_simulation)
allocations_simulation = pd.DataFrame(allocations_simulation)
Data Combination
simulations['Re-Balance Frequence Day'] = 3
allocations_simulation['Re-Balance Frequence Day'] = 3
simulations_df = pd.merge(simulations, allocations_simulation, on='Re-Balance Frequence Day')
simulations_df = simulations_df.reset_index()
simulations_df = simulations_df.rename(columns={'index': 'Simulation ID',
'0_y':'% Allocation for Priority 1',
'1_y':'% Allocation for Priority 2',
'2_y': '% Allocation for Priority 3',
'0_x': 'Previous Funding Rate APR Weight',
'1_x': 'Next Funding Rate APR Weight',
'2_x': '3 Day Cum Funding APR Weight',
3: '7 Day Cum Funding APR Weight',
4: '30 Day Cum Funding APR Weight'
})
simulations_df.to_csv('new_funding_rate_weight_df_2.csv', index=False)
Simulation Configurations Input:
funding rate weights input
allocation weights input
Historical Funding Rates Data:
simulations_df = pd.read_csv('/~path/funding_rate_weight_df.csv')
# Define the weights by properly calling tolist() with parentheses
W3 = simulations_df['3 Day Cum Funding APR Weight'].tolist()
W7 = simulations_df['7 Day Cum Funding APR Weight'].tolist()
W30 = simulations_df['30 Day Cum Funding APR Weight'].tolist()
W_next = simulations_df['Next Funding Rate APR Weight'].tolist()
W_prev = simulations_df['Previous Funding Rate APR Weight'].tolist()
A1 = simulations_df['% Allocation for Priority 1'].tolist()
A2 = simulations_df['% Allocation for Priority 2'].tolist()
A3 = simulations_df['% Allocation for Priority 3'].tolist()
F = simulations_df['Re-Balance Frequence Day'].tolist()
# Global weights for APR calculation
WEIGHTS = [W3, W7, W30, W_prev, W_next]
ALLOCATIONS = [A1, A2, A3]
Creating feasible DataFrame
# Load the data
with open('historical_funding_rates_0707.json', 'r') as file:
data = json.load(file)
frames = []
for symbol, records in data.items():
df = pd.json_normalize(records)
df['symbol'] = symbol
# Check if 'fundingRate' exists in the dataframe and convert to numeric
if 'fundingRate' in df.columns:
df['fundingRate'] = pd.to_numeric(df['fundingRate'], errors='coerce')
else:
df['fundingRate'] = pd.NA # Assign a missing value indicator if 'fundingRate' is not present
frames.append(df)
# Concatenate all frames into a single DataFrame
df = pd.concat(frames, ignore_index=True)
# Convert 'fundingTime' from milliseconds to a datetime object
df['fundingTime'] = pd.to_datetime(df['fundingTime'], unit='ms')
# Split 'fundingTime' into separate date and time components
df['date'] = df['fundingTime'].dt.date
df['time'] = df['fundingTime'].dt.time
# Drop rows where any column has NaN values
df = df.dropna()
# Sort by 'date' in descending order
df = df.sort_values(by='date', ascending=False)
# Display the first few rows to verify
df = df[['symbol', 'date', 'time', 'fundingRate', 'markPrice']]
Math functions & formulas:
Token Scores Function:
'token_score_func(symbol, simulations_id, model_num)'
Simulation Realized APR Function:
'simulation_apr_func(Tokens_names, simulations_id, model_num)'
def token_score_func(symbol, simulations_id, model_num):
group = df.loc[df['symbol'] == symbol, 'fundingRate']
i = len(group) % 90 + (model_num - 1) * 9
aprs = [
group.iloc[i : i + 9].mean() * 3 * 360 * 100,
group.iloc[i : 21 + i].mean() * 3 * 360 * 100,
group.iloc[i : 90 + i].mean() * 3 * 360 * 100,
group.iloc[1 + i] * 3 * 360 * 100,
group.iloc[i] * 3 * 360 * 100
]
#simulations_id = simulations_id - 1
weights = [W[simulations_id] for W in WEIGHTS] # Gather weights for each APR based on simulation ID
# Calculate the weighted APR score
apr_score = sum(apr * weight for apr, weight in zip(aprs, weights))
return apr_score
def simulation_apr_func(Tokens_names, simulations_id, model_num):
top3_rates = []
for symbol in Tokens_names:
group = df.loc[df['symbol'] == symbol, 'fundingRate']
i = len(group) % 90 + (model_num - 1) * 9
rates = group.iloc[i - 9 : i ].mean()
top3_rates.append(rates)
allocations = [A[simulations_id] for A in ALLOCATIONS]
sim_apr = sum(rate * allocation for rate, allocation in zip(top3_rates, allocations)) * 360 * 3
return sim_apr
token_score = {}
simulaiton_id = simulations_df.index.tolist()
model_nums = range(1,11)
token_score_rank = []
simulation_avg_apr = {}
for id in simulaiton_id:
simulation_total_apr = 0
for i in model_nums:
token_score = {}
simulation_apr = {}
for symbol in symbols:
score = token_score_func(symbol, id, i)
token_score[(symbol, id, i)] = score
top3_score = dict(sorted(token_score.items(), key=lambda item: item[1],reverse=True)[:3])
Token_names = [key[0] for key in top3_score.keys()]
cal_apr = simulation_apr_func(Token_names, id, i)
simulation_apr[(f'Model Num {i}', f'Simulation {id}')] = cal_apr
simulation_total_apr += cal_apr
simulation_avg_apr[id] = simulation_total_apr / len(model_nums)
sorted_simulation_avg_apr = dict(sorted(simulation_avg_apr.items(), key=lambda item: item[1], reverse=True))
sorted_simulation_avg_apr
Output
Funding rate weight and Portfolio allocation configurations for monitor
max_realized_apr = [
{'Simulation ID': key, 'Realized APR': value}
for key, value in sorted_simulation_avg_apr.items()
]
max_realized_apr_token = [
{'Simulation ID': key, 'Tokens': value}
for key, value in simulation_top3_token.items()
]
max_realized_apr = pd.DataFrame(max_realized_apr)
max_realized_apr.reset_index(drop=True, inplace=True)
max_realized_apr_token = pd.DataFrame(max_realized_apr_token)
max_realized_apr = pd.merge(max_realized_apr, max_realized_apr_token, on='Simulation ID')
max_realized_apr.to_csv('max_realized_apr_may.csv', index=False)
max_realized_apr