Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Estimating Leveraging Cost

Estimating Leveraging Cost

The following equation is given as a way to estimate leveraging costs:
$$\mathsf{LevCost}(t) = (1+L)∙k∙A(0)∙(1 + r + α\, – fc\%)^t - (1+L)∙k∙A(0)∙(1 + r + α\, – fc\% \, – lc\%)^t$$ where \(L\) is the leveraging factor used, \(k\) is a strategy amplifier, \(A_0\) is the initial capital at work, \(r\) is the average market return, \(\alpha\) is the excess return above market average, \(fc\%\) the frictional costs (commissions, fees, and slippage) while \(lc\%\) is the equivalent leveraging charge as a percent of equity.

It took me some time to find a solution to the leveraging costs that could be applied from within a trading strategy. The method used is not intended to be accurate to the penny but only to give an estimate of how much leveraging will cost over the whole trading interval.

You pay leveraging fees on the amount of context.account.leverage > 1.0 or pay margin fees if context.account.leverage < 0.0 (going short). The record_vars(context, data) function holds all the calculations for these estimates. For instance, IB's leveraging is about 3.8\(\%\). I used 4.0\(\%\) in these estimates. Feel free to increase or decrease those fees to see how your trading strategy would perform under more or less adverse trading conditions.

What you get from this is an estimate of the leveraging costs as applied to the total equity. The more you increase the leverage, the more it will cost, evidently. The objective being that whatever margin level you use (within your broker's constraints), your trading strategy has to pay for it. That is where you get the net liquidation value of the portfolio which is simply: context.portfolio.portfolio_value - context.cum_lev . Copy and paste the code snippets below in initialize(context) and record_vars(context, data) .

It should be understood that this is just an estimate since the leverage rate has been fixed for the duration of the simulation. IB's rate changes over time. All I wanted was a rough estimate. You think it should cost more, then raise the IB_margin.

The big surprise here is the impact all of this has. For instance, lev_as_pct_eq gives the cumulative leveraging costs as a percent of total equity. If your trading strategy did 20\(\%\) with no leverage and then you applied some leverage to it and your net CAGR after costs drops below 20\(\%\), you know that the effort was not worth it. However, if your net CAGR goes higher than 20\(\%\) then you know you had some advantage and was able to produce more with some leveraging than without.

In a trading strategy, you can quit at any time you want, and get the portfolio's net liquidating value. If leveraging costs represent less than 10\(\%\) of your equity at any one time, and your net liquidating value increased due to the use of leverage, what was the real nature of your risk when applying it?

Leveraging has a cost!

But it is also a tool you have to increase performance. It can be applied wisely.

def initialize(context):  
    context.lev = 1.0  
    context.i = 0  
    # set slippage off to see bt analysis in needed  
    # set_slippage(slippage.FixedSlippage(spread = 0.0))  
    context.if_trade = True  
    context.est_lev = True  
    context.cum_lev = 0  
    context.lev_fee = 0  
    context.liquidation_value = 0  
    context.IB_margin = 0.04/365  
    context.bet_size = 0  
    context.do_more = False  


def record_vars(context, data):  
    longs = shorts = 0  
    for stock in context.portfolio.positions:  
        if context.portfolio.positions[stock].amount > 0:  
            longs += 1  
        elif  context.portfolio.positions[stock].amount < 0:  
            shorts += 1  
    record(longs = longs)  
    #record(shorts = shorts)  
    #record(booster = context.Alpha_booster)  
    context.lev_fee = 0  
    if context.est_lev:  
        if context.account.leverage > 1.0:  
            context.lev_fee = int(context.portfolio.portfolio_value*(context.account.leverage-1)*(context.IB_margin))  
        if context.account.leverage < 0.0:  
            context.lev_fee = int(context.portfolio.portfolio_value*(abs(context.account.leverage))*(context.IB_margin))  
        context.cum_lev += int(context.lev_fee)  
    if context.cum_lev > 0:  
        #cummulative leveraging cost estimate  
        record(est_lev = int(context.cum_lev))  
        #Leverage as percent of total portfolio  
        record(lev_as_pct_eq = context.cum_lev/context.portfolio.portfolio_value)  
        #portfolio net liquidation value estimate  
        context.liquidation_value=int(context.portfolio.portfolio_value - context.cum_lev)  
        record(net_liq_val = int(context.liquidation_value))  
        #bet size  
        record(bet_size = int(context.portfolio.portfolio_value / int((longs + shorts))))

2 responses

One thing most might not realize from the above code is how large their actual bet size becomes.

The objective of any trading strategy is, evidently, to grow as much as it can and still remain tradable. However, when the bet size is proportional to the total equity, as in a fixed fraction of equity setting, this bet size will grow at the portfolio's growth rate over the duration of the simulation period. It has some advantages, for instance, if the equity goes down, the bet size goes down thereby tending to reduce risks. The bet size is adjusting to the portfolio's performance level (up and down). The formula to evaluate this is simply: bet_size = F(t) / j, where F(t) is the portfolio's total liquidating value, and j the number of stocks.

Some, at times, are afraid of leveraging and its potential consequences but will not mind putting huge bets on the table when the riskier of the two might just be the size of the bet taken. Especially if j is small and the initial stake is large.

Anyway, the above code gives an idea as to how much leveraging will cost and what is the average bet size as the strategy progresses along its timeline.

Your program will not show any difference that you hug the 1.0 leverage line since it is not accounted for, but your broker surely will and will charge you for any excursion above that 1.0 line.

For those that like to set leverage at a max of 1.0 and think that they will not incur leveraging fees, I would suggest lowering your expectations to something giving you some leeway like 0.98, 0.95, or even 0.90. This way almost making sure that your program stays under your 1.0 leveraging limit. Note that by limiting the leveraging to below 1.0 puts less of the capital at work and should produce less on average after all frictional costs are accounted for.

BTW, the above code can also help in determining the opportunity cost of changing brokers due to the margin rate. For instance, IB might charge 3.8% on leverage while Fidelity charges 8.075%. Over the long term and starting with an initial $10M stake it could make quite a difference even when using low to medium leverage settings since this drag on performance is compounded as given in the portfolio's equation above. You could analyze the impact of even higher rates like 10% to 15% to simulate higher inflation periods.

It is sufficient to run a strategy twice, once with the higher leveraging rate and then with the lower one to see the difference it might make to the net_liq_val .

If there is no leveraging used, then there should be no charges made. It, therefore, becomes a way to verify if leveraging was ever used even if the program was clearly directed not to use it at all.

Margin fees might be charged daily but they are also charged over the weekends. Therefore, you might wish to add a slight adjustment. I opted for context.IB_margin = (0.04/365)*(7/5) , this way the charges, on a yearly basis, would come closer to the actual charges, even if it will still be an estimate.

Ignoring leveraging costs in a simulation does not make them go away. Only designing code that will not transgress the 1.0 leverage barrier will.

Nonetheless, a strategy can benefit from some leveraging as long as the alpha generated is higher than its cost, meaning: \( α > |– fc\%| + |– lc\%| \).