@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);
}
