DeltaCalc.Funding (DeltaCalc v0.3.0)

Copy Markdown View Source

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

FunctionArityDescriptionParam Kinds
funding_trend1Analyse a funding-rate time series for direction, slope, and volatility.series: value
find_arbitrage_opportunities2Find cross-venue funding spreads that exceed a minimum delta threshold.comparison: value, min_delta: value
compare_funding_rates2Compare venue funding rates for one or more symbols and rank venues by rate.rates: value, periods_per_day: value
funding_apr2Annualise 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

apr_result()

@type apr_result() :: %{hourly: Decimal.t(), daily: Decimal.t(), annual: Decimal.t()}

Annualised funding-rate breakdown as percentage Decimals.

comparison_result()

@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.

decimal_input()

@type decimal_input() :: DeltaCalc.Decimal.input()

delta_unit()

@type delta_unit() :: :raw_per_period | :daily_normalized

periods_per_day_input()

@type periods_per_day_input() ::
  decimal_input() | %{required(atom()) => decimal_input()}

trend_result()

@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

compare_funding_rates(rates, periods_per_day \\ 3)

@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).

find_arbitrage_opportunities(comparison, min_delta \\ Decimal.new("0.001"))

@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.

funding_apr(rate, period_hours \\ 8)

@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.

funding_trend(series)

@spec funding_trend(list()) :: {:ok, trend_result()} | {:error, :insufficient_data}

Summarise a funding-rate series with trend direction and half-series slope.