How to implement multiple exits on the following code

I'm planning to implement the MA cross trade system with scalein function. The system structure is based on Connors TPS - ETFs.afl and will have two exits: 1. SHORT MA cross long MA 2. 2ATR maximum points exit. I'm confused to how to implement the second exit as I have tried several methods to make the 2ATR work. But I still failed. I also explored the formula. It seems that sell2 always equal 0. Could you please help on the issue. Many thanks.

 Sell1	= Cross(MA(Close,Longperiod),MA(Close, Shortperiod));
 sell2       =  IIf((BuyPrice- 2*ATR(20)) > L, 1,0);
 Sell        = Sell1 OR Sell2;
//buy scale in rule;
FirstEntry = Cross(MA(Close,Shortperiod),MA(Close, Longperiod));;
InFirstPos = Flip(FirstEntry, Sell);
FirstTrigger = ExRem(InFirstPos, Sell);
BarsSinceFirstTrigger = BarsSince(FirstTrigger);
FirstTrigerInterval = ScaleInIntervalMul*Ref(ATR(20),-BarsSinceFirstTrigger) ;
FirstTriggerPrice = Ref(C,-BarsSinceFirstTrigger);

SecondEntry = ...

ThirdEntry    = ...

FourthEntry  = ...

  Buy = IIf( FirstTrigger, 1, 
             IIf( SecondTrigger OR ThirdTrigger OR FourthTrigger, sigScaleIn, 0  ) );

  BuyPrice = IIf(InFourthPos ,FourthTriggerPrice ,
				 IIf(InThirdPos ,ThirdTriggerPrice ,
					IIf(InSecondPos,SecondTriggerPrice,
						IIf(InFirstPos,FirstTriggerPrice, 0 ))));



Check this function out ApplyStop()
https://www.amibroker.com/guide/afl/applystop.html

You can use multiple ApplyStop() each with different stopType to specify different exit like Profit or SL and can even trail.

The benefit is It will calculate your stopType based on the entry price.

You most likely will have to restructure your current code.

1 Like

Thanks travick. I tried Applystop(); It seems that ApplyStop only clear the position when it is triggered. But it doesn't writeback the sell with value 1. So the current code cannot refresh buy/sell cycle. Then how could it be done when ApplyStop triggered with sell set "1"?

 Sell = Cross(MA(Close,Longperiod),MA(Close, Shortperiod));
 
//buy scale in rule;
FirstEntry = Cross(MA(Close,Shortperiod),MA(Close, Longperiod));;
InFirstPos = Flip(FirstEntry, Sell);
FirstTrigger = ExRem(InFirstPos, Sell);
BarsSinceFirstTrigger = BarsSince(FirstTrigger);
FirstTrigerInterval = ScaleInIntervalMul*Ref(ATR(20),-BarsSinceFirstTrigger) ;
FirstTriggerPrice = Ref(C,-BarsSinceFirstTrigger);

SecondEntry = ...

ThirdEntry    = ...

FourthEntry  = ...

  Buy = IIf( FirstTrigger, 1, 
             IIf( SecondTrigger OR ThirdTrigger OR FourthTrigger, sigScaleIn, 0  ) );

  BuyPrice = IIf(InFourthPos ,FourthTriggerPrice ,
				 IIf(InThirdPos ,ThirdTriggerPrice ,
					IIf(InSecondPos,SecondTriggerPrice,
						IIf(InFirstPos,FirstTriggerPrice, 0 ))));
  SellPrice = IIf(sell1,MA(Close,Longperiod) ),
		IIf(Sell2, BuyPrice - 4*FirstTrigerInterval, 0));

StopBuyAmount = IIf(InFourthPos, FirstBuyStopInterval -3*FirstTrigerInterval,
				IIf(InThirdPos ,FirstBuyStopInterval -2*FirstTrigerInterval,
					IIf(InSecondPos,FirstBuyStopInterval -FirstTrigerInterval,
						IIf(InFirstPos,FirstBuyStopInterval , 0 ))));


ApplyStop(stopTypeLoss,stopModePoint,StopBuyAmount,True,True,1); 

You also need to understand the Equity() function, it processes all the stops and even marks the bar with the specific exit condition.

https://www.amibroker.com/guide/afl/equity.html

It should be called after all the other variables and ApplyStop() codes have been set.

Be sure to read all the comments, it explains even multiple usage but the order is important.

3 Likes

Thanks a lot for your quick response. Actually I have tried equity before. When I called equity at the end. The system will not execute scalein function when backtest. If only I removed equity then it will work. I'm quite confused. So I paste the whole codes here. Hope to get your guidance. Thanks.

SetBarsRequired(10000,10000); /* this ensures that the charts include all bars AND NOT just those on screen */
SetFormulaName("test system"); /*name it for backtest report identification*/
SetOption( "initialequity", 1000000 ); /* starting capital */
MaxPos = 10;
SetOption( "MaxOpenPositions", MaxPos );
SetTradeDelays( 0, 0, 0, 0 );
 
Longperiod = 160;
Shortperiod = 60;
STOPVariable = 6;
ATRPeriod = 100;
Riskvariable = 2; 
ScaleInIntervalMul = 1.5;

Sell = Cross(MA(Close,Longperiod),MA(Close, Shortperiod));
 
//buy scale in rule;
FirstEntry = Cross(MA(Close,Shortperiod),MA(Close, Longperiod));;
InFirstPos = Flip(FirstEntry, Sell);
FirstTrigger = ExRem(InFirstPos, Sell);
BarsSinceFirstTrigger = BarsSince(FirstTrigger);
FirstTrigerInterval = ScaleInIntervalMul*Ref(ATR(ATRPeriod),-BarsSinceFirstTrigger) ;
FirstBuyStopInterval = STOPVariable * Ref(ATR(ATRPeriod),-BarsSinceFirstTrigger);
FirstTriggerPrice = Ref(C,-BarsSinceFirstTrigger);

SecondEntry = (H > FirstTriggerPrice+FirstTrigerInterval)  AND InFirstPos AND Ref(InFirstPos,-1) ;
SecondTriggerPrice = FirstTriggerPrice+FirstTrigerInterval;
InSecondPos = Flip(SecondEntry, Sell);
SecondTrigger = ExRem(InSecondPos, Sell);
BarsSinceSecondTrigger = BarsSince(SecondTrigger);


ThirdEntry = (H > FirstTriggerPrice+2*FirstTrigerInterval) AND InSecondPos AND Ref(InSecondPos,-1);
ThirdTriggerPrice = FirstTriggerPrice+2*FirstTrigerInterval;
InThirdPos = Flip(ThirdEntry, Sell);
ThirdTrigger = ExRem(InThirdPos, Sell);
BarsSinceThirdTrigger = BarsSince(ThirdTrigger );

FourthEntry = (H > FirstTriggerPrice+3*FirstTrigerInterval) AND InThirdPos AND Ref(InThirdPos,-1);
FourthTriggerPrice = FirstTriggerPrice+3*FirstTrigerInterval;
InFourthPos = Flip(FourthEntry, Sell); 
FourthTrigger = ExRem(InFourthPos, Sell);
BarsSinceFourthTrigger = BarsSince(FourthTrigger);

  Buy = IIf( FirstTrigger, 1, 
             IIf( SecondTrigger OR ThirdTrigger OR FourthTrigger, sigScaleIn, 0  ) );

  BuyPrice = IIf(InFourthPos ,FourthTriggerPrice ,
				 IIf(InThirdPos ,ThirdTriggerPrice ,
					IIf(InSecondPos,SecondTriggerPrice,
						IIf(InFirstPos,FirstTriggerPrice, 0 ))));
  SellPrice = MA(Close,Longperiod);
		

StopBuyAmount = IIf(InFourthPos, FirstBuyStopInterval -3*FirstTrigerInterval,
							IIf(InThirdPos ,FirstBuyStopInterval -2*FirstTrigerInterval,
								IIf(InSecondPos,FirstBuyStopInterval -FirstTrigerInterval,
									IIf(InFirstPos,FirstBuyStopInterval , 0 ))));

////////////////////////PositionSize setting
PositionRisk = Riskvariable;
PointValue = 10;
// position size calculation
PctSize =  PositionRisk * IIf (Buy, BuyPrice, ShortPrice)/ (FirstBuyStopInterval* PointValue);
SetPositionSize(PctSize, 

                IIf( Buy > 0, spsPercentOfEquity, spsNoChange ) );

//set applyStop
ApplyStop(stopTypeLoss,stopModePoint,StopBuyAmount,True,True,1); 

Equity(1);

Whatever you started off with in this topic has been addressed in AB before.

Now, it seems, you are unravelling bit by bit which becomes a challenge for others.

Have you seen this?
https://www.amibroker.com/guide/h_pyramid.html Read in detail

IMPORTANT: Please note that backtester treats trade that you scale-in/out as SINGLE trade (i.e. will show single row in trade list).
If you want to see details about scaling you have to run backtest in "DETAIL LOG" mode as only then you will see how scaling-in /out works and how average prices are calculated.

Note also that scaling-in/-out and multiple-currency support is available only in portfolio backtester. Old backtester as well as Equity() function do NOT handle scaling-in/out nor multiple currencies (they simply ignore scaling commands).

Maybe you can restructure around the methodology here.

2 Likes

Get it. Many thanks for your information.

:+1: see Example 4, can't get better code than that.

2 Likes

I have solved the issue. Really appreciate your great support. And Happy New Year in advance.

1 Like