[help] ApplyStop stopTypeTrailing does not 'Price Bound Check' right

Hello forum members and support

I'm trying to develop a trading system that uses built-in ApplyStop stopTypeTrailing

As you can see in this exemple
TrailingStopParam = 400 points
HHV of current candle is 87080
Trailing Stop was 86680 (87080 - 400) at the bar close

I cant figure how to make amibroker understand to Price bound check the right way.

The software closes the position because the open of current bar is below of the value that stopTypeTrailing will be at bar close. So it "think" at some point the price trailing stop was touched, but this is not the case.


ApplyStop stopTypeTrailing do not Price Bound Check Monitoring

So how to make the trailing stop work properly and "Price bound check" right?

I've tried to change this option to see if the prices may fall within the High-Low range and mask this pricing errors without success, apparently this function is not used in stopTypeTrailing

Please can anyone help me to figure it out, I'm forwarding attached system code.

I'm forwarding my sample data also, please download it and change file extension to .csv file.

Sample Data Symbol : WIN
WIN.afl (210.9 KB)

I really appreciate any help you can provide.

TradeSystem Code

_SECTION_BEGIN( "goldencross" );

SetBarsRequired( sbrAll, sbrAll );
//OptimizerSetEngine( "cmae" );

//+------------------------------------------------------------------+
//|       SymbolSettings                                             |
//+------------------------------------------------------------------+

/* BACKTESTER_SYMBOL_SETTINGS */
SYMBOL_SETTINGS_LOTSIZE = 5;
SYMBOL_SETTINGS_SLIPPAGE = 0;
SYMBOL_SETTINGS_COMMISSION = 0;

RoundLotSize = 1; // 0 for Funds, 100 for Stocks
TickSize = 5; // 0 for no min. size
MarginDeposit = 250;
PointValue = .2; // For futures

SetPositionSize( SYMBOL_SETTINGS_LOTSIZE, spsShares );
entryDelay=1;
SetTradeDelays( entryDelay, 0, entryDelay, 0 );

ShortPrice = Open - SYMBOL_SETTINGS_SLIPPAGE;
SellPrice = Open - SYMBOL_SETTINGS_SLIPPAGE;

BuyPrice = Open + SYMBOL_SETTINGS_SLIPPAGE;
CoverPrice = Open + SYMBOL_SETTINGS_SLIPPAGE;

/* */
SetOption( "InitialEquity", SYMBOL_SETTINGS_LOTSIZE * 10000 );
SetOption( "MinShares", 1 );
SetOption( "MinPosValue", 0 );
SetOption( "FuturesMode", True );
SetOption( "AllowPositionShrinking", False );
//SetBacktestMode ( backtestRegular ) ;

SetOption( "ActivateStopsImmediately", True ) ;
SetOption( "PriceBoundChecking", True );
SetOption( "EveryBarNullCheck", True );

SetOption( "ReverseSignalForcesExit", False );
SetOption( "AllowSameBarExit", False );
SetOption( "CommissionMode", 2 );
SetOption( "CommissionAmount", SYMBOL_SETTINGS_COMMISSION*SYMBOL_SETTINGS_LOTSIZE * 2 );
SetOption( "InterestRate", 0 );
SetOption( "MarginRequirement", 100 );
SetOption( "MaxOpenPositions", 1 );

/* Not in settings */
SetOption( "WorstRankHeld", 0 );
SetOption( "UsePrevBarEquityForPosSizing", True );
SetOption( "UseCustomBacktestProc", False );
SetOption( "DisableRuinStop", True );
//SetOption( "EveryBarNullCheck", False );
SetOption( "HoldMinBars", 0 );
SetOption( "HoldMinDays", 0 );
SetOption( "EarlyExitBars", 0 );
SetOption( "EarlyExitDays", 0 );
SetOption( "EarlyExitFee", 0 );
SetOption( "SeparateLongShortRank", False );
SetOption( "MaxOpenLong", 0 );
SetOption( "MaxOpenShort", 0 );

SetStopPrecedence( stopTypeNBar, stopTypeLoss, stopTypeTrailing, stopTypeProfit ) ;

FirstEntryTm = 090000;
LastEntryTm = TimeEx = 173000;

Time = TimeNum();
TimeOK = Time >= FirstEntryTm and Time < LastEntryTm;

EndOfDay = Cross( Hour() == 17, Hour() == 18 );

//+------------------------------------------------------------------+
//|       TradeSystem                                                |
//+------------------------------------------------------------------+
function ParamOptimize( pname, defaultval, minv, maxv, step )
{
    return Optimize( pname,
                     Param( pname, defaultval, minv, maxv, step ),
                     minv, maxv, step );
}

Stop_Loss   = ParamOptimize( "Stop_Loss", 400, 200, 600, 20 ); // Stop Loss
Take_Profit = 0; // Take Profit (pips)
Ind0Param0 = ParamOptimize( "Ind0Param0", 22, 10, 30, 2 ); // Fast MA period
Ind0Param1 = ParamOptimize( "Ind0Param1", 46, 30, 60, 2 ); // Slow MA period


fastMa = MA( Close, Ind0Param0 );
slowMa = MA( Close, Ind0Param1 );

Buy = Cross( fastMa, slowMa ) AND Hour() < 17;
Short = Cross( slowMa, fastMa ) AND Hour() < 17;

Sell = EndOfDay;
Cover = EndOfDay;

Buy = exrem( Buy, Sell );
Sell = exrem( Sell, Buy );

Short = exrem( Short, Cover );
Cover = exrem( Cover, Short );

ApplyStop( stopTypeTrailing, stopModePoint, Stop_Loss, ExitAtStop = 1, Volatile = False, ReentryDelay = 1, ValidFrom = 1, -1 );

Equity( 1, 0 ); //evaluate stops, all quotes


//+------------------------------------------------------------------+
//|       Charts                                                     |
//+------------------------------------------------------------------+

GraphXSpace = Param( "graphxspace", 5, 0, 100, 1 );
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( Flip( Buy, Ref( Sell, -1 ) ), "", ParamColor( "BUY BACKGROUND", colorPaleGreen ), styleArea | styleOwnScale | styleNoLabel, Null, Null, 0, -1, Null );
Plot( Flip( Short, Ref( Cover, -1 ) ), "", ParamColor( "SHORT BACKGROUND", colorRose ), styleArea | styleOwnScale | styleNoLabel, Null, Null, 0, -1, Null );

bi = Barindex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

for( i = fvb; i <= lvb; i++ )
{
    if( Buy[i] ) PlotText( "BUY: \n" + BuyPrice[ i + 1 ], i, L[ i ], colorGreen, Null, -37 );

    if( Sell[i] ) PlotText( "SELL: \n" + SellPrice[ i ], i, H[ i ], colorRed, Null, 37 );

    if( Short[i] ) PlotText( "SHORT: \n" + ShortPrice[ i + 1 ], i, H[ i ], colorGreen, Null, 50 );

    if( Cover[i] ) PlotText( "COVER: \n" + CoverPrice[ i ], i, L[ i ], colorRed, Null, -50 );
}


InTrade = IIf( BarsSince( Flip( Buy, Sell ) ) < BarsSince( Flip( Short, Cover ) ), Flip( Buy, Sell ), Flip( Short, Cover ) ) ;

PlotShapes( InTrade && Buy*shapeUpArrow, colorGreen, 0, Low, Null, entryDelay );
PlotShapes( InTrade && Sell*shapeDownArrow, colorYellow, 0, High, Null, entryDelay  );
PlotShapes( InTrade && Short*shapeDownArrow, colorRed, 0, High, Null, entryDelay  );
PlotShapes( InTrade && Cover*shapeUpArrow, colorYellow, 0, Low, Null, entryDelay  );


trailingStopLine = IIf( InTrade, IIf( BarsSince( Flip( Buy, Sell ) ) < BarsSince( Flip( Short, Cover ) ), HighestSince( Buy, High - Stop_Loss ), LowestSince( Short, Low + Stop_Loss ) ), Null );

Plot( trailingStopLine, "trailing stop line", colorRed, styleStaircase, Null, Null, 0, 1, 1 );

Plot( fastMa, "fastMa", colorGreen, styleLine, Null, Null, 0, 1, 1 );
Plot( slowMa, "slowMa", colorBlue, styleLine , Null, Null, 0, 1, 1 );
_SECTION_END();```
1 Like

You are looking at a single candle with the following properties:

  • Open: 86660
  • High: 87080
  • Low: 86655
  • Close: 86695

You might be tempted to assume that because the close is higher than the open, that the low was hit before the high. But in fact, you have no way to know what happened inside the candle. Maybe the price shot up from the open, achieved the high, then fell all the way to the low, and then recovered before the close.

Because the low of the bar is less than the trailing stop price, AmiBroker will exit at the trailing stop price, just as you have told it to. If you want your stop price to trail behind the previous bar's high instead of the current bar's high, then I believe you would need to use a solution other than the ApplyStop() function.

2 Likes

In fact I can because I have 1 minute data proving it.

How to make amibroker understand use stopTypeTrailing referring the past candle? like this assuming that the first bar it will use "open - trailing points" and others it will use "ref( HHV( H - trailingPoints, BarsSince(Buy)), -1)"

I have the system in MQL5 but I can't code it in amibroker -.-
Something is wrong...

Encounter the similar scenarios in "Loop based Trailing Stop" too and 'm thinking of using cross() instead of < or >, not tried yet. Dunno how we can do that with "ApplyStop" though.

1 Like

Hi,

I didn't check the code, but from your description, one way to solve that, could be to test the system on 1 minute bars and use time frame functions to build your indicators on 15 min bars.

2 Likes

@mradtke explanation is correct and @pmxgs is right too. If you have 1-minute data - USE THEM. When you test on 15-minute it DOES NOT check 1-minute data. If you test on 15-minute data it works ONLY on 15-minute data. So if you want to utilize knowledge from 1-minute bars you have to use 1-minute bars as testing interval.

Also you really need to check the docs http://www.amibroker.com/guide/afl/applystop.html There are different scenarios supported. Read them. From what you wrote you are looking for ExitAtStop = 2 (i.e. previous bar H-L range causes exit at next bar). Your code is not using that.

2 Likes

I've tested with 1 minute time frame and it "works", thank you Tomasz

Attached its the code, ver 1.01

Golden Cross with Trailing Stop
for Mini Indice Bovespa ( Bovespa Futures Index ) WIN$D WINFUT

_SECTION_BEGIN( " Golden Cross WIN$D " );
/*
* Golden Cross WIN$D - Mini Indice Futuro
* Author: Vinicius B Pereira
* http://forum.amibroker.com/u/vinipereira
*/

SetBarsRequired( sbrAll, sbrAll );
//OptimizerSetEngine( "cmae" );

//+------------------------------------------------------------------+
//|       Symbol Settings                                            |
//+------------------------------------------------------------------+

/* BACKTESTER_SYMBOL_SETTINGS */
SYMBOL_SETTINGS_LOTSIZE = 5;
SYMBOL_SETTINGS_SLIPPAGE = 5;
SYMBOL_SETTINGS_COMMISSION = 0;

RoundLotSize = 1; // 0 for Funds, 100 for Stocks
TickSize = 5; // 0 for no min. size
MarginDeposit = 250;
PointValue = .2; // For futures

SetPositionSize( SYMBOL_SETTINGS_LOTSIZE, spsShares );
entryDelay = 0;
SetTradeDelays( entryDelay, 0, entryDelay, 0 );

ShortPrice = Open - SYMBOL_SETTINGS_SLIPPAGE;
SellPrice = Open - SYMBOL_SETTINGS_SLIPPAGE;

BuyPrice = Open + SYMBOL_SETTINGS_SLIPPAGE;
CoverPrice = Open + SYMBOL_SETTINGS_SLIPPAGE;

SetOption( "InitialEquity", SYMBOL_SETTINGS_LOTSIZE * 20000 );
SetOption( "MinShares", 1 );
SetOption( "MinPosValue", 0 );
SetOption( "FuturesMode", True );
SetOption( "AllowPositionShrinking", False );
//SetBacktestMode ( backtestRegular ) ;
SetOption( "ActivateStopsImmediately", True ) ;
SetOption( "PriceBoundChecking", True );
SetOption( "EveryBarNullCheck", True );
SetOption( "ReverseSignalForcesExit", False );
SetOption( "AllowSameBarExit", False );
SetOption( "CommissionMode", 2 );
SetOption( "CommissionAmount", SYMBOL_SETTINGS_COMMISSION*SYMBOL_SETTINGS_LOTSIZE * 2 );
SetOption( "InterestRate", 0 );
SetOption( "MarginRequirement", 100 );
SetOption( "MaxOpenPositions", 1 );

/* Not in settings */
SetOption( "WorstRankHeld", 0 );
SetOption( "UsePrevBarEquityForPosSizing", True );
SetOption( "UseCustomBacktestProc", False );
SetOption( "DisableRuinStop", True );
SetOption( "HoldMinBars", 0 );
SetOption( "HoldMinDays", 0 );
SetOption( "EarlyExitBars", 0 );
SetOption( "EarlyExitDays", 0 );
SetOption( "EarlyExitFee", 0 );
SetOption( "SeparateLongShortRank", False );
SetOption( "MaxOpenLong", 0 );
SetOption( "MaxOpenShort", 0 );

SetStopPrecedence( stopTypeNBar, stopTypeLoss, stopTypeTrailing, stopTypeProfit ) ;

FirstEntryTm = 090000;//	{ Earliest allowable trade entry time=HHMM) }
LastEntryTm = TimeEx = 170000;//	{ Latest allowable trade entry time=HHMM) }

Time = TimeNum();
TimeOK = Time >= FirstEntryTm and Time < LastEntryTm;

BarDates = DateNum();
// uses 'future leak' price to ensure to close at end of session
EndOfDay = Day() != Ref( Day(), 2 ) OR Hour() >= 17;

//+------------------------------------------------------------------+
//|       TradeSystem                                                |
//+------------------------------------------------------------------+
function ParamOptimize( pname, defaultval, minv, maxv, step )
{
    return Optimize( pname,
                     Param( pname, defaultval, minv, maxv, step ),
                     minv, maxv, step );
}

Stop_Loss   = ParamOptimize( "Stop_Loss", 400, 100, 600, 20 ); // Stop Loss
Take_Profit = 0; // Take Profit (pips)
Ind0Param0 = ParamOptimize( "Ind0Param0", 22, 10, 30, 1 ); // Fast MA period
Ind0Param1 = ParamOptimize( "Ind0Param1", 46, 30, 60, 1 ); // Slow MA period

TimeFrameSet( in15Minute );
fastMa = MA( Close, Ind0Param0 );
slowMa = MA( Close, Ind0Param1 );
TimeFrameRestore();

fastMa =    TimeFrameexpand( fastMa, in15Minute );
slowMa =   TimeFrameexpand( slowMa, in15Minute );

Buy = Ref( Cross( fastMa, slowMa ), -1 ) AND TimeOK;
Short = Ref( Cross( slowMa, fastMa ), -1 ) AND TimeOK;

Sell = EndOfDay;
Cover = EndOfDay;

Buy = exrem( Buy, Sell );
Sell = exrem( Sell, Buy );

Short = exrem( Short, Cover );
Cover = exrem( Cover, Short );

ApplyStop( stopTypeLoss, stopModePoint, Stop_Loss, ExitAtStop = 1, Volatile = False, ReentryDelay = 1, ValidFrom = 0, -1 );
ApplyStop( stopTypeTrailing, stopModePoint, Stop_Loss, ExitAtStop = 1, Volatile = False, ReentryDelay = 1, ValidFrom = 1, -1 );

Equity( 1, 0 ); //evaluate stops, all quotes


//+------------------------------------------------------------------+
//|       Charts                                                     |
//+------------------------------------------------------------------+

GraphXSpace = Param( "graphxspace", 5, 0, 100, 1 );
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat("by Vinicius Pereira\nExpert Advisor Generator Online https://robotrading.com.br\n\n")+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( Flip( Buy, Ref( Sell, -1 ) ), "", ParamColor( "BUY BACKGROUND", colorPaleGreen ), styleArea | styleOwnScale | styleNoLabel, Null, Null, 0, -1, Null );
Plot( Flip( Short, Ref( Cover, -1 ) ), "", ParamColor( "SHORT BACKGROUND", colorRose ), styleArea | styleOwnScale | styleNoLabel, Null, Null, 0, -1, Null );

bi = Barindex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

for( i = fvb; i <= lvb; i++ )
{
    if( Buy[i] ) PlotText( "BUY: \n" + BuyPrice[ i + 1 ], i, L[ i ], colorGreen, Null, -37 );
    if( Sell[i] ) PlotText( "SELL: \n" + SellPrice[ i ], i, H[ i ], colorRed, Null, 37 );
    if( Short[i] ) PlotText( "SHORT: \n" + ShortPrice[ i + 1 ], i, H[ i ], colorGreen, Null, 50 );
    if( Cover[i] ) PlotText( "COVER: \n" + CoverPrice[ i ], i, L[ i ], colorRed, Null, -50 );
}


InTrade = IIf( BarsSince( Flip( Buy, Sell ) ) < BarsSince( Flip( Short, Cover ) ), Flip( Buy, Sell ), Flip( Short, Cover ) ) ;

PlotShapes( InTrade && Buy*shapeUpArrow, colorGreen, 0, Low, Null, entryDelay );
PlotShapes( InTrade && Sell*shapeDownArrow, colorYellow, 0, High, Null, entryDelay );
PlotShapes( InTrade && Short*shapeDownArrow, colorRed, 0, High, Null, entryDelay );
PlotShapes( InTrade && Cover*shapeUpArrow, colorYellow, 0, Low, Null, entryDelay );

trailingStopLine = IIf( InTrade, IIf( BarsSince( Flip( Buy, Sell ) ) < BarsSince( Flip( Short, Cover ) ), HighestSince( Buy, High - Stop_Loss ), LowestSince( Short, Low + Stop_Loss ) ), Null );

Plot( trailingStopLine, "trailing stop line", colorRed, styleStaircase, Null, Null, 0, 1, 1 );

Plot( fastMa, "fastMa", colorGreen, styleLine, Null, Null, 0, 1, 1 );
Plot( slowMa, "slowMa", colorBlue, styleLine , Null, Null, 0, 1, 1 );
_SECTION_END();

Do you have any newer version of this afl?

I applied your above afl with my 5 & 20 ema crossover stratergy , but I am not getting the signals (buy, sell, short, cover ) properly.

Moreover, when sell and cover is done by applystop code ----how to calculate the sellprice and cover price for other calculations like profit / loss made or even just say simply printing the price on the chart at which sell / cover happened.

Please guide.