HoldingCost

Defined in fynance.backtest

class HoldingCost(borrow=0.0, financing=0.0, cash_rate=0.0, period=252)[source]

Bases: object

Per-bar carry cost on the held book (not turnover).

Unlike ProportionalCost and MarketImpactCost, which charge on trades (the change between consecutive weights), HoldingCost charges on the held weights at each bar: shorting, leverage and idle cash all carry a cost — or, for idle cash, a credit — for every bar the position is held, regardless of turnover. Three additive terms, each de-annualized to a per-bar rate (rate / period):

  • borrow: cost of the short gross exposure \(\sum_i \max(-w_{t,i}, 0)\), at the annualized borrow rate.

  • financing: cost of leverage in excess of fully invested (total gross exposure above 1), \(\max\big(0, \sum_i |w_{t,i}| - 1\big)\), at the annualized financing rate.

  • cash: a credit (non-positive) on unused cash, \(\max\big(0, 1 - \sum_i |w_{t,i}|\big)\), at the annualized cash_rate.

\[c_t = \frac{borrow}{period} \sum_i \max(-w_{t,i}, 0) + \frac{financing}{period} \max\Big(0, \sum_i |w_{t,i}| - 1\Big) - \frac{cash\_rate}{period} \max\Big(0, 1 - \sum_i |w_{t,i}|\Big)\]

The total cost at each bar is the sum of the three terms; see components for the per-term breakdown. Conforms to CostModel.

Parameters:
borrowfloat

Annualized borrow rate charged on short gross exposure (e.g. 0.02 = 2%/yr). Default 0.0.

financingfloat

Annualized financing rate charged on leverage above 1x (gross exposure in excess of fully invested). Default 0.0.

cash_ratefloat

Annualized rate credited on unused cash (idle capital not deployed into any position). Default 0.0.

periodint

Number of bars per year used to de-annualize the rates (e.g. 252 for daily bars, 12 for monthly). Default 252.

Examples

>>> import numpy as np
>>> cost = HoldingCost(borrow=0.02, financing=0.01, cash_rate=0.005, period=250)
>>> w = np.array([[0.5, 0.0], [-0.5, 1.5], [0.0, 0.0]])
>>> cost(w)
array([-1.e-05,  8.e-05, -2.e-05])
__call__(weights)[source]

Return the per-step (borrow + financing - cash credit) cost.

components(weights)[source]

Per-step cost split into its borrow/financing/cash terms.

Returns {"borrow", "financing", "cash"}; the values sum to __call__. cash entries are non-positive (a credit on idle capital). The optional components convention lets the engine carry a cost breakdown for the tearsheet’s cumulative-fees panel.