Pure funding-rate math: APR annualisation, cross-venue comparison, arbitrage detection, and trend analysis.
All functions take caller-supplied Decimal rates — no exchange clients or I/O.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
funding_trend | 1 | Analyse a funding-rate time series for direction, slope, and volatility. | series: value |
find_arbitrage_opportunities | 2 | Find cross-venue funding spreads that exceed a minimum delta threshold. | comparison: value, min_delta: value |
compare_funding_rates | 2 | Compare venue funding rates for one or more symbols and rank venues by rate. | rates: value, periods_per_day: value |
funding_apr | 2 | Annualise a per-period funding rate into hourly, daily, and annual percentages. | rate: value, period_hours: value |
Summary
Types
Annualised funding-rate breakdown as percentage Decimals.
Per-symbol cross-venue funding comparison.
Funding trend summary from a rate series.
Functions
Compare funding rates across venues.
Return arbitrage opportunities from a comparison map, filtered by min_delta.
Convert a per-period funding rate into hourly, daily, and annual percentage APR.
Summarise a funding-rate series with trend direction and half-series slope.
Types
Annualised funding-rate breakdown as percentage Decimals.
@type comparison_result() :: %{ optional(:insufficient_data) => true, optional(:arbitrage_opportunity) => boolean(), optional(:delta) => Decimal.t(), optional(:delta_unit) => delta_unit(), optional(:max_exchange) => atom(), optional(:min_exchange) => atom(), optional(:annual_apr_delta) => Decimal.t(), optional(:ranked) => [{atom(), Decimal.t()}] }
Per-symbol cross-venue funding comparison.
@type decimal_input() :: DeltaCalc.Decimal.input()
@type delta_unit() :: :raw_per_period | :daily_normalized
@type periods_per_day_input() :: decimal_input() | %{required(atom()) => decimal_input()}
@type trend_result() :: %{ avg_rate: Decimal.t(), max_rate: Decimal.t(), min_rate: Decimal.t(), trend: :increasing | :decreasing | :flat, slope: Decimal.t(), volatility: Decimal.t(), data_points: non_neg_integer() }
Funding trend summary from a rate series.
Functions
@spec compare_funding_rates(map(), periods_per_day_input()) :: map() | comparison_result()
Compare funding rates across venues.
Pass %{binance: rate, bybit: rate} for one symbol, or
%{"BTCUSDT" => %{binance: rate, bybit: rate}} for many.
periods_per_day defaults to 3 for 8-hour funding; pass 24 for Deribit
hourly funding or %{venue => periods} when venues use different cadences.
Each result tags delta_unit. With a scalar cadence, delta is a raw
per-period spread (:raw_per_period) for unchanged 8-hour/24-hour behavior.
With a venue cadence map, venues are ranked by per-day-normalized rate
(rate * periods_per_day), delta is that daily-normalized spread
(:daily_normalized), annual_apr_delta is the daily spread annualized to
APR percentage points, and the arbitrage threshold is the default 8-hour raw
threshold normalized to daily terms (0.0005 * 3 = 0.0015).
@spec find_arbitrage_opportunities(map(), decimal_input()) :: [map()]
Return arbitrage opportunities from a comparison map, filtered by min_delta.
min_delta keeps the legacy scalar raw-period threshold scale. Entries tagged
:daily_normalized compare against min_delta multiplied by the default
periods per day so scalar- and map-cadence comparison results can be filtered
together without scale skew.
@spec funding_apr(decimal_input(), pos_integer()) :: {:ok, apr_result()} | {:error, :invalid_rate}
Convert a per-period funding rate into hourly, daily, and annual percentage APR.
@spec funding_trend(list()) :: {:ok, trend_result()} | {:error, :insufficient_data}
Summarise a funding-rate series with trend direction and half-series slope.