Occasional use of margin

Hello,

I am testing a combination of 2 strategies. One is in the market all of the time, with a 90% account equity allocation, and the other one (mean reversion) trades only on occasion (in the market 10% of the time), with an allocation of 30%. This means that I will only have to use margin on those occasions.

My understanding of the margin concept and setting in AFL is that all trades are "executed "with the supplied margin percentage, regardless of whether the account equity has been exhausted, or not. This also seems to include margin interest.

I am looking for a way to calculate margin interest only when margin actually needs to be used.

But my question may be based on not fully understanding AFL options. I did read the manual carefully, but could not find an answer to my question.

Thanks in advance for any corrections/suggestions,

Robert

No, it does not charge margin interest if you have cash. Switch to "Detailed log", run backtest and you will see. How do I debug my formula?

Tomasz,

Thanks! Also for pointing me towards the "Detailed Log" (forgot it existed - was using Explore only ...).

Tried setting margin to a value other than 100 for a simpler formula, and I still get the use of margin for "SetPositionSize(50,spsPercentOfEquity) and one position only.

Must be doing something wrong ... below is the code, and further below the detailed log message for the first buy.

If you have a second to point me in the right direction, that would be great.

Robert

Code:

/**************************************************************************************************************************
**
** --- Global Equities Momentum (GEM) --- 
**
** Designed for daily data
** 
** Sources:	Dual Momentum Investing (book) by Gary Antonacci
**			Risk Premia Harvesting Through Dual Momentum - Gary Antonacci
**
** Website: http://www.optimalmomentum.com/index.html
**
** Notes: The monthly returns posted on Antonacci's site obey the rules of P98. Data used by Antonacci:
**	- S&P 500: Ibbotson Large Cap Total Return (all the way to today)
**	- ACWI ex US: MSCI ex US until 1987, ACWI ex US afterwards
**	- Aggregate Bonds: Ibbotson Intermediate Govt Bond Total Return until Dec 1975, then Barclays US Aggregate Bond Index
**
** The tickers used for this formula use available ETFs (SPY, VEU and AGG) since their start date to better approximate real
** performance
**
****************************************************************************************************************************/

// --- Parameters and initialization ---
USEqu 			= "SPY";
NonUSEqu 		= "VEU";
Bonds 			= "AGG";
TBills 			= "BIL";

LookBackMonths	= Param("LookBack Months",12,1,18,1);
Rules = ParamList("Rules","P98|P101");
SetOption("MaxOpenPositions", 1);
SetOption("AccountMargin", 50);
SetPositionSize(50,spsPercentOfEquity);
SetTradeDelays(0,0,0,0);

// --- Function to calculate ROC based on a variable period (array input) ---
function VarROC( array, periods )
{
  prev = Ref( array, -periods );
  return 100*(array - prev)/prev;
}

// --- Detect the rebalance day (last trading day of the month) ---
// --- Calculate lookback days ---
// During the month, look back to the month end that will be used on the last day of
// the month, so that in Explore the buy signal converges as the end of the month approaches) 
BarNumber = Cum(Status("barinrange"));
LastDayOfMonth = IIf(Month() != Ref(Month(),1), 1 , 0);
LookBackDays = BarNumber - ValueWhen(LastDayOfMonth == 1, BarNumber, LookBackMonths + 1);
LookBackDays2 = BarNumber - ValueWhen(LastDayOfMonth == 1, BarNumber, LookBackMonths);
LookBackDays = IIf(LastDayOfMonth == 1, LookBackDays, LookBackDays2);

// --- Get symbol list ---
wlnum = GetOption( "FilterIncludeWatchlist" ); 
List = CategoryGetSymbols( categoryWatchlist, wlnum ) ; 

// --- Calculate buy signals ---
if ( Status("stocknum") == 0 )
{ 
    StaticVarRemove( "returns*" );
    for ( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++    ) 
    { 
        SetForeign ( symbol );
        returns = IIf(BarNumber > LookBackDays, VarROC(C,LookBackDays), 0); //Calculated on the close
        RestorePriceArrays(); 
        StaticVarSet (  "returns"  +  symbol, returns ); 
        _TRACE( symbol ); 
    }
    returnsBonds = StaticVarGet("returns" + Bonds); 
    returnsUSEqu = StaticVarGet("returns" + USEqu);
    returnsNonUSEqu = StaticVarGet("returns" + NonUSEqu);
    returnsTBills = StaticVarGet("returns" + TBills);
    
	buysignal = 0;
	
	for ( n = 0; ( Symbol = StrExtract( List, n ) )  != "";  n++    ) 
	{ 
		switch( Symbol )
		{
		case Bonds:
			if ( rules == "P98" )
				buysignal = IIf (returnsUSEqu < returnsTBills, 1, 0);
			else
				buysignal = IIf ((returnsUSEqu < returnsTBills) AND (returnsNonUSEqu < returnsTBills), 1, 0);
			break;
		case USEqu:
			buysignal = IIf((returnsUSEqu >= returnsNonUSEqu) AND (returnsUSEqu >= returnsTBills), 1, 0);
			break; 
		case NonUSEqu:
			if ( rules == "P98" )
				buysignal = IIf((returnsNonUSEqu > returnsUSEqu) AND (returnsUSEqu >= returnsTBills), 1, 0);
			else
				buysignal = IIf((returnsNonUSEqu > returnsUSEqu) AND (returnsNonUSEqu >= returnsTBills), 1, 0);
			break;
		default: //applied for TBills
			buysignal = 0;
			break;
		} 
		StaticVarSet("buy" + symbol, buysignal);
    } 
 }
 
symbol = Name();
buysignal = StaticVarGet("buy" + symbol);

Buy = buysignal AND lastdayofmonth;
Sell = NOT buysignal AND lastdayofmonth;

BuyPrice = Close;
SellPrice = Close;

// --- Exploration ---
ExploreFilter = ParamToggle( "ExploreFilter", "LastBarInTest|All", 1 );
if ( ExploreFilter )
	Filter = LastDayOfMonth;
else
	Filter = Status( "LastBarInTest" );
	
if ( Status( "actionex" ) == actionExplore ) 
{
	SetOption( "NoDefaultColumns", True );
	AddTextColumn( symbol, "Ticker" );
	AddColumn( DateTime(), "Date  ", formatDateTime, colorDefault, colorDefault, 135);
	SetSortColumns(-2);
	
	bgdcolor = IIf(Buy == 1, colorGreen, colorWhite);
	fgdcolor = IIf(Buy == 1, colorWhite, colorDefault);
	AddColumn(Buy, "Buy ", -4.0, fgdcolor, bgdcolor , 70);
	
	AddColumn(Close, "Close  ");
	
	returns = StaticVarGet("returns" + symbol);
	AddColumn(returns, "Return", 1.2, fgdcolor,bgdcolor, 80);
	AddColumn(lookbackdays, "Lookback");
 }

And the first buy message from the detailed log:

01/31/2008
Entry signals(score):SPY=Buy(1),
Exit signals:
Enter Long, SPY, Price: 107.8685, Shares: 463, Commission: 0, Rank: 1, Equity 100000, Margin Loan: 24971.57, Fx rate: 1
1 Open Positions: , SPY (+463), Market Value: 49943.14, Equity: 100000.00, Cash: 75028.43, Margin: -24971.57, Net Cash Balance: 50056.86,
- adding interest on cash balance: net cash 50056.86, 0% rate, 1 night(s), value = 0.00

1 Like

Yes it reports margin but does not charge interest because it uses NET cash balance for interest. Your net cash is positive and you would actually earn money if your settings had > 0.0% interest rate on cash.

Ok, thanks for the clarification.

Looking closer at the backtest report, I conclude that the risk-adjusted returns and the exposure are scaled by the margin percentage. So, if I want to get the exposure and risk adjusted return with respect to my actual capital, I need to divide these figures by 0.5 if the margin percentage is 50.

Getting back to my original post: if I have several strategies running side-by-side and (after adjusting by the margin percentage as outlined in the previous paragraph) my exposure is 110%, this would mean that -on average- I am using 10% margin. This is the figure I was looking for.

Correct?