# How to combine 2 applystop as 1 function ( to make array)

Hi everyone,

because applystop return NOTHING and work in backtest, I have some idea (own reason) to code applystop with another way.

I modified the code from here : https://www.amibroker.com/kb/2007/03/24/how-to-plot-a-trailing-stop-in-the-price-chart/comment-page-1/

this code is for low level :

``````Plot (C, "", colorAqua, styleLine);
StopLevel = 1 - Param(" stop %", 1, 0.1, 10, 0.1)/100;

Buy 		= Cross( MACD(), Signal() );
Sell 		= 0;
trailARRAY 	= Null;
trailARRAY2 = Null;
trailstop 	= 0;
trailstop2 	= 0;

for( i = 1; i < BarCount; i++ ){
if( trailstop == 0 AND Buy[ i ] ) {
trailstop = C[ i ] * stoplevel;
}
else Buy[ i ] = 0; // remove excess buy signals

/////////////////////////////////////////////////////////////

if( trailstop > 0 AND C[ i ] < trailstop ){
Sell[ i ] = 1;
SellPrice[ i ] = trailstop;
trailstop = 0;
}
if( trailstop > 0 ){
trailARRAY[ i ] = trailstop;

//////////////////////////////////////////////////////////
}}
PlotShapes(Buy*shapeUpArrow,colorGreen,0,Low);
PlotShapes(Sell*shapeDownArrow,colorRed,0,High);
Plot( trailARRAY,"trailing stop level", colorRed );
``````

And This one for up level

``````Plot (C, "", colorAqua, styleLine);
StopLevel = 1 - Param("trailing stop %", 1, 0.1, 10, 0.1)/100;

Buy 		= Cross( MACD(), Signal() );
Sell 		= 0;
trailARRAY 	= Null;
trailARRAY2 = Null;
trailstop 	= 0;
trailstop2 	= 0;

for( i = 1; i < BarCount; i++ ){
if( trailstop2 == 0 AND Buy[ i ] ) {
trailstop2 = C[ i ] / stoplevel;
}
else Buy[ i ] = 0; // remove excess buy signals
/////////////////////////////////////////////////////////////

if( trailstop2 > 0 AND C[ i ] > trailstop2 ){
Sell[ i ] = 1;
SellPrice[ i ] = trailstop2;
trailstop2 = 0;
}
if( trailstop2 > 0 ){
trailARRAY2[ i ] = trailstop2;

//////////////////////////////////////////////////////////
}}

PlotShapes(Buy*shapeUpArrow,colorGreen,0,Low);
PlotShapes(Sell*shapeDownArrow,colorRed,0,High);
Plot( trailARRAY2,"trailing stop level", colorRed );
``````

some body can help how to combine it ? please,
Thank you

1 Like

I think you misunderstood ApplyStop()

It doesn't need to return anything because it updates all the concerned trade variables like Buy, Sell, Short, Cover and even the price variables.

For the chart, you can use the Equity() function to evaluate your signals and update the trade variables.
In this case your Sell variable will have two conditions combined with OR, otherwise better just use ApplyStop() with trailing option and other for stop loss option.

infact, the Equity() function will even mark the status or type of exit also.
https://www.amibroker.com/guide/afl/equity.html

1 - regular exit
2 - max. loss
3 - profit target
4 - trailing
5 - n-bar stop
6 - ruin stop

See, now why re-invent the wheel writing the code.

Thanks for your advise.

In this case your Sell variable will have two conditions combined with OR

I will try your advice as much as possible, it is very difficult for me who do not have a basic programming even it looks so simple.

now why re-invent the wheel writing the code.

I need that to combine with ShortSignal, but with a fixed profit/loss level from BuySignal not shortSignal

I found another possible way here Sell price = Buying Price * x% and modify it. but it's still wrong in the results

``````SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );

function BuyExitInProfitOnly( LongEntry, percent ) {
/// code source:
/// @link https://forum.amibroker.com/t/sell-price-buying-price-x/1358/29
/// derived from:
/// @link https://www.amibroker.com/kb/
/// (commercial use prohibited!)
global Buy, Sell, BuyPrice, SellPrice;
local i, buyentryprice,buyentryprice2, BuyPrice_array, SellSignal,SellSignal2 ;
buyentryprice = 0;
buyentryprice2 = 0;
BuyPrice_array = Null;
pcnt_level = 1 + percent/100;

for ( i = 0; i < BarCount; i++ ) {
if ( LongEntry[ i ] && buyentryprice == 0 ) {
Buy[ i ] = 1;
BuyPrice[i] = Close[i];
buyentryprice = BuyPrice[ i ] * pcnt_level;
}

if ( LongEntry[ i ] && buyentryprice2 == 0 ) {
Buy[ i ] = 1;
BuyPrice[i] = Close[i];
buyentryprice2 = BuyPrice[ i ] / pcnt_level;
}

// exit if close is higher than buyprice
SellSignal = Close[ i ] > buyentryprice;
if ( SellSignal && buyentryprice > 0 ) {
Sell[ i ] = 1;
SellPrice[i] = Close[i];
buyentryprice = 0;
}
if ( buyentryprice > 0 )
BuyPrice_array[i] = buyentryprice;

// exit if close is lower than buyprice
SellSignal2 = Close[ i ] < buyentryprice2;
if ( SellSignal2 && buyentryprice2 > 0 ) {
Sell[ i ] = 1;
SellPrice[i] = Close[i];
buyentryprice2 = 0;
}
if ( buyentryprice2 > 0 )
BuyPrice_array[i] = buyentryprice2;

}
return BuyPrice_array;
}

Buy = Sell = Short = Cover = 0;
LongEntry = Cross( MACD(), Signal() );

pab = BuyExitInProfitOnly( LongEntry, percent = 3 );
Plot( pab, "pab", colorgreen );
PlotShapes( Buy * shapeCircle + Sell * shapeCircle, IIf( Buy, colorWhite, colorYellow ), layer = 0, y = IIf( Buy, C, C ));
``````

@ibenxs,
Please listen, the code you copied from is working correctly.
If you copy code and modify it then you should comment the modification but should not give impression that original code is incorrect. It is your modifications being incorrect.
Also the original code serves different purpose... to exit in profit only (so ignoring drawdowns and loss of money). Also the code you copied exits at Close and if Close is larger level. So of course it will not exit at exact level mostly. Please try to understand what something is doing.

To exit at exact intrabar level violation you have to check via High and Low price.

``````procedure BuyProfitLossStop(pab1, pab2, percent ) {
/// code sources:
/// @link https://forum.amibroker.com/t/sell-price-buying-price-x/1358/29
/// @link https://tinyurl.com/y74e8k56
/// derived from:
/// @link https://www.amibroker.com/kb/
/// (commercial use prohibited!)
global Buy, Sell, BuyPrice, SellPrice;
local i, tgt_level, stp_level, pcnt_level1, pcnt_level2;
local BuyPrice_array1, BuyPrice_array2, SellSignal1, SellSignal2;
tgt_level = stp_level = 0;
BuyPrice_array1 = BuyPrice_array2 = Null;
pcnt_level1 = 1 + percent/100;
pcnt_level2 = 1 - percent/100;
for ( i = 0; i < BarCount; i++ ) {
// exit if low is lower than stop level
SellSignal2 = L[ i ] < stp_level;
if ( SellSignal2 && stp_level > 0 ) {
Sell[ i ] = 1;
SellPrice[ i ] = Min(O[ i ], stp_level[ i ]);
tgt_level = stp_level = 0;
}
// exit if high is higher than target level
SellSignal1 = H[ i ] > tgt_level;
if ( SellSignal1 && tgt_level > 0 ) {
Sell[ i ] = 1;
SellPrice[ i ] = Max(O[ i ],tgt_level[ i ]);
tgt_level = stp_level = 0;
}
//
if ( Buy[ i ] && tgt_level == 0 && stp_level == 0) {
tgt_level = BuyPrice[ i ] * pcnt_level1;
stp_level = BuyPrice[ i ] * pcnt_level2;
} else Buy[ i ] = 0;
//
if ( tgt_level > 0 )
BuyPrice_array1[ i ] = tgt_level;
if ( stp_level > 0 )
BuyPrice_array2[ i ] = stp_level;
}
VarSet(pab1, BuyPrice_array1);
VarSet(pab2, BuyPrice_array2);
}

Buy = Cross( MACD(), Signal() );
BuyPrice = Close;
Sell = Short = Cover = 0;

BuyProfitLossStop("tgt_arr", "stp_arr", percent = 3);

SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}",
O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot( tgt_arr, "tgt_arr", colorgreen );
Plot( stp_arr, "stp_arr", colorRed );
color = IIf( Buy, colorWhite, colorYellow );
y = IIf( Buy, BuyPrice, SellPrice );
PlotShapes( (Buy + Sell) * shapeSmallCircle, color, layer = 0, y, offset = 0);
``````

So that one does work properly for that stop/target exit purpose.
Note that you will still see higher percent profit/loss if there are opening gaps!

Now... you can reach same goal via ApplyStop() function also

``````/// @link https://forum.amibroker.com/t/how-to-combine-2-applystop-as-1-function-to-make-array/18842/5
/// @link https://www.amibroker.com/kb/2007/03/24/how-to-plot-a-trailing-stop-in-the-price-chart
SetOption("ActivateStopsImmediately", False);
SetTradeDelays(0,0,0,0);

Buy = Cross( MACD(), Signal() );
BuyPrice = Close;
Sell = Short = Cover = 0;

// Disable all UI stops before
for ( i = 0; i <= 3; i++)
ApplyStop( i, 0, 0, 0 );

percent = 3;
ApplyStop( stopTypeLoss, stopModePercent, loss_amount = percent, exitatstop=1);
ApplyStop( stopTypeProfit, stopModePercent, tgt_amount = percent, exitatstop );

if ( Status("action" ) == actionIndicator ) {
eq = Equity(1, 0); //evaluate stops in chart pane

pcnt_level1 = 1 + percent/100;
pcnt_level2 = 1 - percent/100;
tgt_arr = ValueWhen(Buy, BuyPrice*pcnt_level1);
stp_arr = ValueWhen(Buy, BuyPrice*pcnt_level2);
in_trade = Flip(Buy, Sell);
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}",
O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot( IIf(in_trade, tgt_arr, Null), "tgt_arr", colorGreen );
Plot( IIf(in_trade, stp_arr, Null), "stp_arr", colorRed );
color = IIf( Buy, colorWhite, colorYellow );
y = IIf( Buy, BuyPrice, SellPrice );
PlotShapes( (Buy + (Sell>0)) * shapeSmallCircle, color, layer = 0, y, offset = 0);
}
``````

And if you want to combine Long and Short with different modes then you can do like this.
And you do not need to combine anything via `OR` operator.
And to enable one stop mode only by array condition then use IIf() function and for `false` case set high percentage e.g. 99 percent to disable. Has been discussed here already.

``````/// @link https://forum.amibroker.com/t/how-to-combine-2-applystop-as-1-function-to-make-array/18842/5
/// @link https://forum.amibroker.com/t/applystop-with-an-extra-condition/17726/2
/// @link https://www.amibroker.com/kb/2007/03/24/how-to-plot-a-trailing-stop-in-the-price-chart
SetOption("ReverseSignalForcesExit", 0);
SetOption("ActivateStopsImmediately", False);
SetTradeDelays(0,0,0,0);

BuyPrice = C;
ShortPrice = C;

Buy = Cross(MACD(), Signal());
Sell = 0;

Short = Cross(Signal(), MACD());
Cover = 0;

// Disable all UI stops before
for ( i = 0; i <= 3; i++)
ApplyStop( i, 0, 0, 0 );

percent = 3;
loss_amount = percent;
tgt_amount = percent;
trail_amount = percent;

/// @link https://forum.amibroker.com/t/applystop-with-an-extra-condition/17726/2
ApplyStop( stopTypeLoss, stopModePercent, IIf(Buy, loss_amount, 99), exitatstop=1, 0, reentrydelay = 1);
ApplyStop( stopTypeProfit, stopModePercent, IIf(Buy, tgt_amount, 99), exitatstop, 0, reentrydelay );
ApplyStop( stopTypeTrailing, stopModePercent, IIf(Short, trail_amount, 99), exitatstop, 0, reentrydelay );

if ( Status("action" ) == actionIndicator ) {
eq = Equity(1, 0); //evaluate stops in chart pane

pcnt_level1 = 1 + percent/100;
pcnt_level2 = 1 - percent/100;
tgt_arr = ValueWhen(Buy, BuyPrice*pcnt_level1);
stp_arr = ValueWhen(Buy, BuyPrice*pcnt_level2);
in_long = Flip(Buy, Sell);

SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}",
O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot( IIf(in_long, tgt_arr, Null), "tgt_arr", colorgreen );
Plot( IIf(in_long, stp_arr, Null), "stp_arr", colorRed );
PlotShapes (Buy*shapeSmallUpTriangle, colorGreen, 0, L, -15 );
PlotShapes ((Sell>0)*shapeDownArrow, colorOrange, 0, H, -25);

/// derived from
/// @link https://www.amibroker.com/kb/2007/03/24/how-to-plot-a-trailing-stop-in-the-price-chart
in_short = Flip(Short, Cover);
SetOption("EveryBarNullCheck", True );
trail_line = IIf( in_short, LowestSince( Short, Low ) * pcnt_level1, Null );
Plot( trail_line, "trail_line", colorRed );
PlotShapes (Short*shapeSmallDownTriangle, colorRed, 0, H, -15 );
PlotShapes ((Cover>0)*shapeUpArrow, colorAqua, 0, L, -25);
}
``````

9 Likes

There are two small code typos in `BuyProfitLossStop` function of first code example.
`stp_level[ i ]` and `tgt_level[ i ]` can be changed to just `stp_level` and `tgt_level`.
It does not do harm but... they are not type array.

wow ..... great and complete explanation form @fxshrat, I will learn a lot from this.

It is your modifications being incorrect.

yes this is whats i mean, my modification is incorrect, sorry for my bad writing word and meaning sentences. thanks a lot

1 Like