Strategy Calculation Formulas
Mathematical reference for funding rate arbitrage calculations, position sizing, and profitability analysis
Table of Contents
- Funding Rate Arbitrage
- Expected Value (EV) Calculation
- Position Sizing
- Fee Calculations
- Profit & Loss
- Risk Metrics
- Configuration Reference
Funding Rate Arbitrage
Core Concept
Funding rate arbitrage exploits differences in funding rates across exchanges while maintaining delta-neutral positions.
Funding Rate Spread
Where:
rate_short= funding rate on high-rate exchange (short position)rate_long= funding rate on low-rate exchange (long position)
Example:
Binance BTCUSDT: +0.0001 (1 basis point)
HyperLiquid BTCUSDT: +0.0006 (6 basis points)
spread = |0.0006 - 0.0001| = 0.0005 = 5 basis points = 0.05%
Annual Percentage Yield (APY)
Where:
funding_intervals_per_yeardepends on exchange funding frequency- Spread is expressed as a decimal (e.g., 0.0005)
APY by Exchange Interval:
| Exchange | Intervals/Day | Intervals/Year | APY Multiplier |
|---|---|---|---|
| Binance/Bybit | 3 | 1,095 | spread × 1,095 |
| HyperLiquid | 24 | 8,760 | spread × 8,760 |
| Aster | 3-6 | 1,095-2,190 | varies by symbol |
Example (8-hour interval):
spread = 0.0005 (5 basis points)
APY = 0.0005 × 1,095 = 0.5475 = 54.75%
Example (1-hour interval - HyperLiquid):
spread = 0.0001 (1 basis point per hour)
APY = 0.0001 × 8,760 = 0.876 = 87.6%
Expected Value (EV) Calculation
The bot uses risk-adjusted expected value to filter opportunities and ensure trades are profitable after all costs.
Funding Intervals by Exchange
| Exchange | Interval | Minutes | Payments/Day |
|---|---|---|---|
| Binance | 8 hours | 480 | 3 |
| Bybit | 4-8 hours | 240-480 | 3-6 (per-symbol)* |
| HyperLiquid | 1 hour | 60 | 24 |
| Aster | 4-8 hours | 240-480 | 3-6 (per-symbol)* |
*Bybit and Aster funding intervals vary by symbol. The bot automatically fetches per-symbol intervals via REST API at startup (refreshed every 4h) and from WebSocket streams in real-time.
Cross-Exchange Yield Normalization
When trading across exchanges with different funding intervals (e.g., HyperLiquid + Binance), the bot normalizes yields to a common 8-hour reference period. This is important because HyperLiquid pays funding 8x more frequently than Binance/Bybit.
How It Works:
| Position | Rate | Payments in 8h | Yield |
|---|---|---|---|
| Long Binance | +0.01%/8h | 1 | -0.01% (pay) |
| Short HyperLiquid | +0.10%/1h | 8 | +0.80% (receive) |
| Total | +0.79% |
Key Benefit: A 9 bps simple spread becomes 79 bps normalized yield when HyperLiquid's 8x payment frequency is properly accounted for.
Time Weighting
Where:
min_interval= minimum of both exchange intervals (determines next funding)- Weight approaches 1 as funding time approaches
- Weight approaches 0 immediately after funding
Gross Expected Value
Transaction Costs
For limit orders (maker fees):
For market orders (taker fees + slippage):
Staleness Haircut
Default: haircut = 0.03 (3 basis points = 0.03%)
Adjusted Expected Value
Qualification Criteria
An opportunity qualifies if:
Default thresholds (percentage form):
min_ev_bps= 0.05 (5 basis points = 0.05%)min_spread_threshold= 0.04 (4 basis points = 0.04%)
Complete EV Example
Scenario:
- Binance BTCUSDT: +0.01% (long position, 8h interval)
- HyperLiquid BTCUSDT: +0.10% (short position, 1h interval)
- Time to funding: 60 minutes (HyperLiquid's next funding)
- Order type: Limit (maker fees)
Step 1: Calculate normalized spread
Long Binance: -0.01% × (480/480) = -0.01% (pay 1 payment)
Short HyperLiquid: +0.10% × (480/60) = +0.80% (receive 8 payments)
Normalized spread = -0.01% + 0.80% = +0.79% (79 bps)
Step 2: Time weighting (using minimum interval = 60 min)
Step 3: Gross EV
Step 4: Calculate costs
Binance fees: 0.02% maker (entry) + 0.02% maker (exit) = 0.04%
HyperLiquid fees: 0.0144% maker (entry) + 0.0144% maker (exit) = 0.0288%
Total costs: ~7 bps
Step 5: Staleness haircut
Data age: < 4 minutes
Staleness: 0
Step 6: Adjusted EV
Step 7: Qualification check
adjusted_ev (72 bps) >= min_ev (5 bps) ✅
raw_spread (9 bps) >= min_spread (4 bps) ✅
Result: QUALIFIES
Expected profit per $10,000 position (over 8h reference):
Note: The normalized EV (72 bps after costs) is much higher than what you'd calculate from the simple 9 bps spread because HyperLiquid pays funding 8 times per Binance cycle.
Position Sizing
Conservative Sizing Formula
The bot reserves margin for both opening AND closing positions:
Where:
balance= available balance on exchange (USDT)percentage= position size percentage (default: 0.30 = 30%)leverage= configured leverage (default: 10x)- Division by 2 reserves margin for closing
Example:
balance = $1,000 USDT
percentage = 0.30 (30%)
leverage = 10x
position_size = (1,000 × 0.30 / 2) × 10
= (300 / 2) × 10
= 150 × 10
= $1,500 USD notional
Quantity Calculation
Must be rounded to exchange precision:
Example:
position_size = $1,500
BTC price = $50,000
precision = 3 decimals (0.001 BTC minimum)
quantity = 1,500 / 50,000 = 0.030 BTC
quantity_rounded = floor(0.030 / 0.001) × 0.001 = 0.030 BTC ✅
Kelly Criterion Sizing
The bot supports two position sizing modes:
Mode 1: Kelly Criterion (Dynamic)
Enabled when use_kelly_criterion = true (default). Sizes positions based on expected value and variance:
With safety caps:
Where:
kelly_cap= 0.25 (quarter-Kelly, default)max_notional=$10,000(per-symbol cap, default)max_utilization= 0.50 (50% of balance, default)
Use when: You want dynamic sizing that increases with edge quality and decreases with variance.
Mode 2: Fixed Percentage (Simple)
Enabled when use_kelly_criterion = false. Uses fixed percentage of available capital:
With safety cap:
Use when: You want predictable, consistent position sizing regardless of opportunity quality.
Configuration:
[trading]
use_kelly_criterion = true # Toggle between Kelly and fixed modes
kelly_fraction = 0.25 # Only used in Kelly mode
max_exchange_utilization = 0.5 # Used in both modes
max_notional_per_symbol = 10000 # Hard cap for both modes
Fee Calculations
Exchange Fee Structure
| Exchange | Maker Fee | Taker Fee | Funding Interval |
|---|---|---|---|
| Binance | 0.02% | 0.04% | 8 hours |
| Bybit | 0.01% | 0.06% | 4-8 hours* |
| HyperLiquid | 0.00% | 0.035% | 1 hour** |
| Aster | 0.02% | 0.04% | 4-8 hours* |
*Bybit and Aster funding intervals vary per symbol (4h or 8h), fetched dynamically via API and WebSocket **HyperLiquid has 24 funding payments per day (hourly)
Order Fee Calculation
Example:
quantity = 0.1 BTC
price = $50,000
fee_rate = 0.0004 (0.04% taker)
notional = 0.1 × 50,000 = $5,000
fee = 5,000 × 0.0004 = $2.00
Round-Trip Cost
For entering and exiting a position:
Example (limit orders):
Binance maker: 0.02%
HyperLiquid maker: 0.00%
Entry cost: (0.0002 + 0.0000) = 0.0002 = 0.02%
Exit cost: (0.0002 + 0.0000) = 0.0002 = 0.02%
Total: 0.0004 = 0.04% = 4 basis points
On $10,000 position: $10,000 × 0.0004 = $4.00
Breakeven Spread
Minimum spread needed to be profitable:
Example (3 funding periods = 24 hours):
round_trip_cost = 0.0004 (4 bps)
holding_periods = 3
breakeven = 0.0004 / 3 = 0.000133 = 1.33 bps per period
Profit & Loss
Funding Payment Calculation
For long position:
- Positive rate: pay funding
- Negative rate: receive funding
For short position:
- Positive rate: receive funding
- Negative rate: pay funding
Arbitrage Profit Per Period
Example:
position_size = $10,000
Binance rate (long): +0.0001
HyperLiquid rate (short): +0.0006
profit = 10,000 × (0.0006 - 0.0001)
= 10,000 × 0.0005
= $5.00 per funding period
Net Profit After Fees
Example:
gross_profit = $5.00 per period × 3 periods = $15.00
entry_fees = $4.00
exit_fees = $4.00
net_profit = 15.00 - 4.00 - 4.00 = $7.00 per day
monthly = $7.00 × 30 = $210.00
Return on Capital
Example:
position_size = $10,000
leverage = 10x
margin_used = 10,000 / 10 = $1,000
daily_profit = $7.00
daily_ROC = 7.00 / 1,000 = 0.007 = 0.7%
annual_ROC = 0.007 × 365 = 2.555 = 255.5%
ROI (Return on Investment)
The ROI displayed in the TUI is calculated as:
Where:
funding_collected= total funding payments received since position openedtrading_fees= trading fees for both legs (entry + exit). Note: as of now, the fee tracker only captures entry fees; exit fees are included in the formula but are effectively $0 until exit-fee tracking is implemented.position_size= notional value of the position
ROI Display States:
| Display | Meaning |
|---|---|
1.23% | Actual ROI with confirmed fees from exchange API |
1.23%* | ROI with estimated fees (asterisk = estimation) |
... | Fees being fetched from exchange |
N/A | Legacy position without fee tracking data |
Fee Estimation Fallback:
When exchange API calls fail or timeout (2 minutes), fees are estimated:
This uses a default taker fee rate of 0.05% (5 basis points) per leg.
Example:
position_size = $1,000
funding_collected = $5.00
entry_fee_long = $0.50
entry_fee_short = $0.35
ROI = (5.00 - 0.50 - 0.35) / 1,000 × 100%
= 4.15 / 1,000 × 100%
= 0.415%
Unrealized P&L (Price Spread)
Added in v0.58: The TUI and metrics now display unrealized P&L from price spread movements, not just funding collected.
While funding rate arbitrage is theoretically delta-neutral, price divergence between exchanges creates real P&L that must be tracked. This is especially important when exchanges have different liquidity or when prices move during entry/exit.
Formula:
Where:
Example (Spread Reversal - Loss):
# Position entered with 0.1 BTC
long_entry_price = $40,000 (Binance)
short_entry_price = $40,000 (Aster)
current_price = $40,100 (price moved up)
long_leg_pnl = (40,100 - 40,000) × 0.1 = +$10.00 (profit)
short_leg_pnl = (40,000 - 40,100) × 0.1 = -$10.00 (loss)
# In theory, should net to $0 if hedged properly
# But with slippage or different prices on each exchange:
long_entry_price = $40,000 (Binance)
short_entry_price = $39,950 (Aster - worse fill)
current_price = $40,100
long_leg_pnl = (40,100 - 40,000) × 0.1 = +$10.00
short_leg_pnl = (39,950 - 40,100) × 0.1 = -$15.00
total_price_pnl = 10.00 - 15.00 = -$5.00 (loss from spread)
Total Unrealized P&L:
Important: A position can show positive funding collected but still be losing money overall if the price spread moved against you.
Risk Metrics
Maximum Position Size
Where:
config_max=$10,000(default per-symbol cap)utilization= 0.50 (50% of balance usage)margin_rate= 1 / leverage
Example:
balance = $5,000
utilization = 0.50
leverage = 10x
margin_rate = 0.1
balance_limit = (5,000 × 0.50) / 0.1 = 25,000
max_size = min(10,000, 25,000) = $10,000
Margin Requirement
The 1.2 factor provides a 20% safety buffer.
Example:
position_size = $10,000
leverage = 10x
margin = (10,000 / 10) × 1.2 = 1,000 × 1.2 = $1,200
Liquidation Distance
Example:
margin = $1,000
maintenance = $100 (10% of margin)
position_size = $10,000
liq_distance = (1,000 - 100) / 10,000 = 0.09 = 9%
Position liquidates at 9% adverse price move
Sharpe Ratio
Calculated over historical trades for strategy performance evaluation.
Maximum Drawdown
Tracks the largest peak-to-trough decline in account equity.
Configuration Reference
Default Values
| Parameter | Default | Description |
|---|---|---|
min_spread_threshold | 0.04 (4 bps) | Minimum spread to qualify |
min_ev_bps | 0.05 (5 bps) | Minimum expected value |
max_position_usd | $10,000 | Maximum position size |
position_size_percentage | 0.30 (30%) | Percentage of balance |
leverage | 10x | Default leverage |
kelly_cap | 0.25 | Quarter-Kelly |
max_exchange_utilization | 0.50 (50%) | Max balance usage |
staleness_haircut_bps | 0.03 (3 bps) | Penalty for stale data |
Exchange Fee Rates
| Exchange | Maker | Taker |
|---|---|---|
| Binance Futures (VIP 0) | 0.02% | 0.04% |
| Bybit (Standard) | 0.01% | 0.06% |
| HyperLiquid | 0.00% | 0.035% |
| Aster | 0.02% | 0.04% |
Example Configuration
[trading]
# Spread thresholds
min_funding_spread = 0.04 # 4 basis points
min_ev_bps = 0.05 # 5 basis points
# Position sizing
position_size_percent = 0.30 # 30% of balance
max_position_usd = 10000 # $10,000 cap
leverage = 10 # 10x leverage
# Kelly criterion settings
use_kelly_criterion = true
kelly_fraction = 0.25 # Quarter-Kelly
max_exchange_utilization = 0.50 # 50% max usage
[risk]
# Slippage
max_slippage_bps = 50 # 0.5% maximum
estimated_slippage = 0.001 # 0.1% estimate
Quick Reference Card
Profit Estimation
| Spread (bps) | Position Size | Per Period | Daily | Monthly |
|---|---|---|---|---|
| 4 | $10,000 | $4.00 | $12.00 | $360 |
| 5 | $10,000 | $5.00 | $15.00 | $450 |
| 10 | $10,000 | $10.00 | $30.00 | $900 |
| 20 | $10,000 | $20.00 | $60.00 | $1,800 |
APY by Spread
| Spread (bps) | APY (Pre-Fee) | APY (Post-Fee, ~4bps cost) |
|---|---|---|
| 4 | 43.8% | 0% |
| 5 | 54.75% | 10.95% |
| 10 | 109.5% | 65.7% |
| 20 | 219% | 175.2% |
Minimum Capital Requirements
| Position Target | Leverage | Margin Needed | Recommended Buffer |
|---|---|---|---|
| $5,000 | 10x | $500 | $750 |
| $10,000 | 10x | $1,000 | $1,500 |
| $20,000 | 10x | $2,000 | $3,000 |
| $50,000 | 10x | $5,000 | $7,500 |
See Also
- Trading Strategy - Strategy overview and concepts
- Configuration Guide - Detailed parameter reference
- Getting Started - Initial setup
- Monitoring Guide - Track your positions
Note: All formulas use decimal representation (e.g., 0.0005 = 5 basis points = 0.05%). The bot maintains high precision using Rust's Decimal type (96-bit precision) for all calculations.