Help request for Portfolio switch out

Good morning Sirs,
I am new to forum. I tried to find solution to my problem googling and searching over the forum.
My AB version is 6.30.5
What I would like to implement is a very simple portfolio strategy on monthly basis.
Here it is:

At month's end I could be invested in only two assets: stock (SPY) and bonds (TLT). The weight is 50-50% if condition for Stocks is met. Otherwise, only Bonds. Never in cash.
If stocks are above its 10m MA at the end of the very first month, I will invest 50% of cash in SPY and the other 50% in TLT. If not, all 100% goes to TLT.
I will check the condition at every month's end.
If holding position in SPY and by month's end SPY is below its 10m MA, I will close SPY and switch to TLT.
In simple words, every month stocks could be 0 or 50% and bonds 50 or 100%. No others weightings allowed.
My knowledge leads me to create this code but I am unable to get what I wish. It is missing the "switch out/switch in" rule. For sure the SetPositionSize is not correctly set, at least for Bonds switch in.
Could you help me to find the correct way to code this strategy?
Thanks in advance,
TT

SetTradeDelays(0,0,0,0);
SetOption("initialequity",10000);
SetOption("MaxOpenPositions",2);
SetOption("allowsamebarexit", True);
SetOption("allowpositionshrinking",true);
SetPositionSize(50, spsPercentOfEquity);
SetBacktestMode(backtestRegular);
RefMA = Optimize("MA", 10, 1, 12, 1);

Buy = Cross(Close, MA(Close,refma));

Sell = Cross(MA(Close,refma), Close);

BuyPrice = SellPrice = Close;

You may use scale-in/out for TLT and Sell for SPY.

Following code appears to work for me.
NOTE: I have enabled detailed log via SetOption. Also I added delay as it is more realistic to enter/exit at next bar.

//At month's end I could be invested in only two assets: stock (SPY) and bonds (TLT). 
//The weight is 50-50% if condition for Stocks is met. Otherwise, only Bonds. Never in cash.
//If stocks are above its 10m MA at the end of the very first month, 
//I will invest 50% of cash in SPY and the other 50% in TLT. If not, all 100% goes to TLT.
/// @link https://forum.amibroker.com/t/help-request-for-portfolio-switch-out/18938
SetTradeDelays(0,0,0,0);
SetOption("initialequity",10000);
SetOption("allowsamebarexit", True);
SetOption("allowpositionshrinking",true);
SetBacktestMode(backtestRegular);

SetOption("MaxOpenPositions", Max_pos = 2);
SetPositionSize(100/Max_pos, spsPercentOfEquity);

// detailed log to check scale-in/out
SetOption("PortfolioReportMode", 1); 

period = Optimize("MA Period", 10, 1, 12, 1);

BuyPrice = SellPrice = Open;
Buy = Sell = Short = Cover = 0;

/// @link https://forum.amibroker.com/t/help-request-for-portfolio-switch-out/18938/2
/// Buy, Sell for SPY
/// Buy, scale-in/out for TLT 
/// by fxshrat@gmail.com
if ( Name() == "TLT" OR Name() == "SPY" ) {	
	mth = Month();
	new_mth = mth != Ref(mth, -1);

	stocks = Foreign("SPY", "C");
	above_ma = stocks > MA(stocks,period); 
	
	Buy1 = Sell2 = Ref(above_ma, -1) AND new_mth;
	Buy2 = Sell1 = Ref(NOT above_ma, -1) AND new_mth;	
	Buy = Buy1;
	
	if ( Name() == "SPY" ) {		
		Sell = Sell1; 
	}
	
	if ( Name() == "TLT" ) {
		Buy = Buy + sigScaleIn * Buy2 + sigScaleOut * Sell2; 
		SetPositionSize( 50, spsPercentOfEquity * ( Buy == sigScaleIn ) ); // scale in 50% TLT
		SetPositionSize( 50, spsPercentOfEquity * ( Buy == sigScaleOut ) ); // scale out 50% TLT
	}	
}

13


14


15


16


17

5 Likes

@fxshrat thanks a lot for your kind assistance. Much appreciated.
By the way, this is for backtest purpose only. Anyway, using monthly data I need to open positions on the same bar close otherwise I will invest one month later.
Tried to set same bar entry/exit but I get no trade.
Could you please use same bar close entry/exit?
Thanks in advance
TT

The previous code had some flaws (e.g. excessive scales) as it was just an initial idea.

Below is an update:

  1. It works on daily and monthly interval (added TimeFrameSet for EOD)
  2. You can change delay via delay variable (default: zero)
  3. It removes excessive scale-in/outs
  4. Added AccountMargin line to have enough buying power for 100% invested (avoiding insufficient funds without shrinking size)
    (Or decrease size e.g. 50/max_pos)
  5. Added some commenting
//At month's end I could be invested in only two assets: stock (SPY) and bonds (TLT). 
//The weight is 50-50% if condition for Stocks is met. Otherwise, only Bonds. Never in cash.
//If stocks are above its 10m MA at the end of the very first month, 
//I will invest 50% of cash in SPY and the other 50% in TLT. If not, all 100% goes to TLT.
/// @link https://forum.amibroker.com/t/help-request-for-portfolio-switch-out/18938
SetTradeDelays(0,0,0,0);
SetOption("initialequity",10000);
SetOption("accountmargin", 50);
SetOption("allowsamebarexit", True);
SetOption("allowpositionshrinking",false);
SetBacktestMode(backtestRegular);

SetOption("MaxOpenPositions", max_pos = 2);

size = 100/max_pos;
size_mode = spsPercentOfEquity;
SetPositionSize(size, size_mode);

// detailed log to check scale-in/out
SetOption("PortfolioReportMode", 1); 

period = Optimize("MA Period", 10, 1, 12, 1);

delay = 0;
Buy = Sell = Short = Cover = 0;

/// @link https://forum.amibroker.com/t/help-request-for-portfolio-switch-out/18938/4
/// Version 1.1
/// Buy, Sell for SPY
/// Buy, scale-in/out for TLT 
/// by fxshrat@gmail.com
if ( Name() == "TLT" OR Name() == "SPY" ) {	
	mth = Month();
	if ( delay > 0 ) {
		BuyPrice = SellPrice = Open;
		new_mth = mth != Ref(mth, -1);
	} else {	
		BuyPrice = SellPrice = Close;
		new_mth = mth != Ref(mth, 1);
	}
	//
	SetForeign( "SPY" );
	TimeFrameSet( inMonthly );
		stocks = C;
		above_ma = stocks > MA(stocks,period); 
	TimeFrameRestore();
	above_ma = TimeFrameExpand(above_ma, inMonthly);
	
	// SPY & TLT entry and scale-out TLT signal
	Buy1 = Ref(above_ma, -delay) AND new_mth;
	// SPY exit and scale-in TLT signal
	Buy2 = Sell1 = Ref(NOT above_ma, -delay) AND new_mth;
	
	// SPY & TLT entry signal
	Buy = Buy1;	
	// scale-in TLT if SPY has Sell1 signal
	scale_in = ExRem(Buy2, Buy);
	// scale-out TLT just one time after last scale-in
	scale_out = ExRem(Buy, scale_in);
	//
	if ( Name() == "SPY" ) {		
		Sell = Sell1; 
	}
	
	if ( Name() == "TLT" ) {			
		Buy = Buy + sigScaleIn * scale_in + sigScaleOut * scale_out; 
		SetPositionSize( size, size_mode * (Buy == sigScaleIn)); // scale in 50% TLT
		SetPositionSize( size, size_mode * (Buy == sigScaleOut)); // scale out 50% TLT
	}	
	
	Plot( C, "Price", colorDefault, styleBar );
	Plot( MA(stocks,period), "MA", colorRed);
}

13


14

6 Likes

You Da Man!
It works as it should!
God bless you,
TT

1 Like