How to ignore Buy/Short signals if Sell/Cover were not triggered by Stop Loss

Hey guys,
Here is something I can't figure out.
I am using cross of WMA(10) colorGold and WMA (50) colorAqua as an entry signals:

Buy = Cross (WMA (Close, 10), WMA (Close, 50));
Short = Cross (WMA (Close, 50), WMA (Close, 10));

Also I want to use stoploss (for example 50 points):

ShortStopArray 	= IIf((!InTrade), LowestSince(Short, Low) + 50, Null);

Now if Long trade been started I would like to ignore any Short or Long signals, generated by WMA cross.

Once in trade I want my system to react only to the price crossing the stoploss line.
So as I imagine I should add something like this to check if price is crossing stoploss:

Sell = Cross (Close,  LongStopArray);
Cover = Cross (CLose, ShortStopArray);

I've tried to experiment with ExRem function, but no success so far:

Sell	= ExRem	( Sell,		Buy		);
Short	= ExRem	( Short,	Cover	);
Cover	= ExRem	( Cover,	Short	);

Would you recommend me to spend more time with ExRem or should I look into adding some sort of IIF instead?

Also will backtest be able to work with such logic?
Thank you, highly appreciate any tip or advice.

This task turned out to be trickier than I thought ^^'
So I decided to solve the most troublesome part first.

WMAFast 	= Param("Fast WMA", 		10, 	1, 	50,  1);	// Fast WMA period
WMASlow 	= Param("Slow WMA", 		50, 	1, 	150, 1);	// Slow WMA period
ShortStop	= Param("Short Stop Loss", 	50, 	1, 	150, 1);    // Short Stop Loss

AllWMACrossBuySignals 	= Cross	(WMA (Close, WMAFast) , WMA (Close, WMASlow));
AllWMACrossShortSignals = Cross	(WMA (Close, WMASlow) , WMA (Close, WMAFast));

ShortStopArray	= LowestSince(AllWMACrossShortSignals, Low) + (ShortStop); // Array with short trailing stop loss values
Cover	= Cross (Close, ShortStopArray); // Cover when price crosses short trailing stop loss
Plot (ShortStopArray, "\nShort stop (trail)", colorRed, styleLine | styleNoRescale);

As a result I get a trailing stoploss line which resets on every Short trade (orange arrows).

What can I do to ignore any further Short signals if Cover haven't happened (price crossed stoploss)?

I couldn't solve this with ExRem so far because trailing stop loss line is based on Short signals which already occurred. And I am trying to get rid of those signals if price have crossed stoploss...Which is stupid ^^'

You have to still read a bit more about how AFL works.

In layman terms, just think of it as if AFL code runs once for each candle (or bar in that TF).
Ofcourse that's not exactly how, with Array processing all is concurrent but that's the effect.

Anyway, if your code for any reason does not provide state information for a previous candle, the way you say, if you're short once, and you don't want to go short 2nd time unless a cover occurs,
sometimes this can be achieved in a well written code but otherwise you have to use static variables.

You can use https://www.amibroker.com/guide/afl/staticvarsettext.html
initialize it to 0, set variable to 1 in the first instance of a short and then keep checking subsequently.

Every time a cover occurs, reset it.

Technically, ExRem should work but if it doesnt, then the code has been structured in a way that's not suiting it, hence the static variables.

2 Likes

That was my hope, but yeah. Didnâ€™t work for me yet.
Guess Iâ€™ll have to do it good old static var way.

I Have this feeling that it can be done with a smart combination of IIf, ExRem, Flip and maybe something else (keep discovering new afl tricks all the time). Just failed so far I think itâ€™s a great brain teaser though )))

Sure, turns out I am quite a slow learner, but itâ€™s getting better I prefer a video training, which is quite rare for Amibroker unfortunately.

@travick thank you for supporting me on this challenging journey! )))

Here are a few more reading assignments which you may find helpful:

3 Likes

Ok, after spending more time, I've finally got some progress.
Stop loss (white curves) behave the way I wanted.
Now I just need to figure out how to ignore White Buy/Short signals if current trade is not over yet.

Also I don't know how to get the same result but in a more tidy way code-wise.

WMAFast 		= Param("Fast WMA", 				10, 	1, 		50, 	1);	// Fast WMA
WMASlow 		= Param("Slow WMA", 				50, 	1, 		150, 	1);	// Slow WMA
LongStop		= Param("Long Stop Loss", 			50, 	1, 		150, 	1);
ShortStop		= Param("Short Stop Loss", 			50, 	1, 		150, 	1);

Sig1Buy 	= Cross	(WMA (Close, WMAFast) , WMA (Close, WMASlow)); // Raw Buy signal (happens on every WMA cross (10, 50))
Sig1Short 	= Cross	(WMA (Close, WMASlow) , WMA (Close, WMAFast)); // Raw Short signal (happens on every WMA cross (50, 10))
PlotShapes(Sig1Buy		*	shapeUpArrow,	colorGreen,	0,	Low-10);
PlotShapes(Sig1Short	*	shapeDownArrow,	colorDarkRed,	0,	High+10);

Sig1BuyStopArray	= HighestSince(Sig1Buy, High) - (LongStop); // trailing stop loss for Long trade based on Raw signals
Sig1ShortStopArray	= LowestSince(Sig1Short, Low) + (ShortStop); // trailing stop loss for Short trade based in Raw signals
Plot (Sig1BuyStopArray, "\nSig1Long stop (trail)", colorGreen, styleLine | styleNoRescale, Null, Null, Null, -10);
Plot (Sig1ShortStopArray, "\nSig1Short stop (trail)", colorDarkRed, styleLine | styleNoRescale, Null, Null, Null, -10);

Sig1Sell	= Cross (Low, Sig1BuyStopArray); // dummy sell signal
Sig1Cover	= Cross (High, Sig1ShortStopArray); // dummy cover signal

Sig2Short	= ExRem (Sig1Short, Sig1Cover); // limit Short to first stoploss hit
PlotShapes(Sig2Buy		*	shapeUpArrow,	colorBrightGreen,	0,	Low-20);
PlotShapes(Sig2Short	*	shapeDownArrow,	colorRed,	0,	High+20);

Sig2ShortStopArray 	= LowestSince(Sig2Short, Low) + (ShortStop); // Stop Loss based only on the first Short signal
Plot (Sig2BuyStopArray, "\nSig2Long stop (trail)", colorBrightGreen, styleLine | styleNoRescale, Null, Null, Null, -9);
Plot (Sig2ShortStopArray, "\nSig2Short stop (trail)", colorRed, styleLine | styleNoRescale, Null, Null, Null, -9);

Cover	= Cross (High, Sig2ShortStopArray); // Cover when stop loss is hit
Cover	= ExRem (Cover, Sig2Short); // remove extra Cover signals till the next Short
PlotShapes(Cover	*	shapeDownArrow,	colorGold,	0,	High+20);

Sell	= Cross (Sig2BuyStopArray, Low); // Sell when stop loss is hit
Sell	= ExRem (Sell, Sig2Buy); // remove extra Sell signals till next Long
PlotShapes(Sell		*	shapeUpArrow,	colorGold,	0,	Low-20);

Sig3Short	= ExRem(Sig1Short, Cover);

Short = Sig3Short;

PlotShapes(Buy		*	shapeUpArrow,	colorWhite,	0,	Low-30);
PlotShapes(Short	*	shapeDownArrow,	colorWhite,	0,	High+30);

Sig3ShortStopArray 	= IIf ((ShortTrade), LowestSince(Short, Low) + (ShortStop), Null);
Plot (Sig3BuyStopArray, "\nSig3Long stop (trail)", colorWhite, styleLine | styleNoRescale, Null, Null, Null, -8);
Plot (Sig3ShortStopArray, "\nSig3Short stop (trail)", colorWhite, styleLine | styleNoRescale, Null, Null, Null, -8);

for (i = 0; i < BarCount; i++)
{
if (Sell[i]) 	PlotText ("Sell " 	, i, L[i]-50, colorRed);
if (Cover[i]) 	PlotText ("Cover "	, i, H[i]+50, colorGold);
if (Short[i]) 	PlotText ("Short "	, i, H[i]+50, colorWhite);
}

Intuitively I think I need to use IIf to solve this. But yeah, no luck so far ^^'

1 Like

Alright, maybe I it's too early to celebrate, but seems, like I've done it =)

Only white 3Buy/3Short and orange 3Sell/3Cover signals are the ones I am going to use. Others are for "debugging" mostly.

Sorry code is not commented yet.

Plot( C, "Close", colorDefault, styleNoLabel | styleNoTitle );

WMAFast 		= Param("Fast WMA", 				10, 	1, 		50, 	1);
WMASlow 		= Param("Slow WMA", 				50, 	1, 		150, 	1);
LongStop		= Param("Long Stop Loss", 			50, 	1, 		150, 	1);
ShortStop		= Param("Short Stop Loss", 			50, 	1, 		150, 	1);

Sig1Buy 			= Cross	(WMA (Close, WMAFast) , WMA (Close, WMASlow)); // Raw Buy signal (happens on every WMA cross (10, 50))
Sig1Short 			= Cross	(WMA (Close, WMASlow) , WMA (Close, WMAFast)); // Raw Short signal (happens on every WMA cross (50, 10))
Sig1BuyStopArray	= HighestSince(Sig1Buy, High) - (LongStop); // trailing stop loss for Long trade based on Raw signals
Sig1ShortStopArray	= LowestSince(Sig1Short, Low) + (ShortStop); // trailing stop loss for Short trade based in Raw signals
Sig1Sell			= Cross (Sig1BuyStopArray, Low); // dummy sell signal
Sig1Cover			= Cross (High, Sig1ShortStopArray); // dummy cover signal

Sig1Short 	= ExRem (Sig1Short, Sig1Cover);
Sig1Cover 	= ExRem (Sig1Cover, Sig1Short);

PlotShapes(Sig1Buy		*	shapeUpArrow,	colorGrey40,		0,	Low-10);
PlotShapes(Sig1Short	*	shapeDownArrow,	colorGrey40,		0,	High+10);
PlotShapes(Sig1Sell		*	shapeUpArrow,	colorDarkRed,		0,	Low-10);
PlotShapes(Sig1Cover	*	shapeDownArrow,	colorDarkRed,		0,	High+10);

Plot (Sig1BuyStopArray, "\nSig1Long stop (trail)", colorGreen, styleDashed | styleNoRescale, Null, Null, Null, -10);
Plot (Sig1ShortStopArray, "\nSig1Short stop (trail)", colorDarkRed, styleDashed | styleNoRescale, Null, Null, Null, -10);

Sig2Short = Sig1Short;
Sig2ShortStopArray	= LowestSince(Sig2Short, Low) + (ShortStop);
Sig2Cover			= Cross (High, Sig2ShortStopArray);

Sig2Short 	= ExRem (Sig2Short, Sig2Cover);
Sig2Cover 	= ExRem (Sig2Cover, Sig2Short);

PlotShapes(Sig2Buy		*	shapeUpArrow,	colorGrey50,		0,	Low-20);
PlotShapes(Sig2Short	*	shapeDownArrow,	colorGrey50,		0,	High+20);
PlotShapes(Sig2Sell		*	shapeUpArrow,	colorRed,		0,	Low-20);
PlotShapes(Sig2Cover	*	shapeDownArrow,	colorRed,		0,	High+20);

Sig2ShortStopArray	= IIf(Short2TradeArray, LowestSince(Sig2Short, Low) + (ShortStop), Null);

Plot (Sig2BuyStopArray, "\nSig2Long stop (trail)", colorBrightGreen, styleLine | styleNoRescale, Null, Null, Null, -9);
Plot (Sig2ShortStopArray, "\nSig2Short stop (trail)", colorRed, styleLine | styleNoRescale, Null, Null, Null, -9);

Sig3ShortStopArray	= LowestSince(Sig3Short, Low) + (ShortStop);
Sig3Cover			= Cross (High, Sig3ShortStopArray);

Sig3Short 	= ExRem (Sig3Short, Sig3Cover);
Sig3Cover 	= ExRem (Sig3Cover, Sig3Short);

PlotShapes(Sig3Buy		*	shapeUpArrow,	colorWhite,		0,	Low-30);
PlotShapes(Sig3Short	*	shapeDownArrow,	colorWhite,		0,	High+30);
PlotShapes(Sig3Sell		*	shapeUpArrow,	colorWhite,		0,	Low-30);
PlotShapes(Sig3Cover	*	shapeDownArrow,	colorWhite,		0,	High+30);

Sig3ShortStopArray	= IIf(Short3TradeArray, LowestSince(Sig3Short, Low) + (ShortStop), Null);

Plot (Sig3BuyStopArray, "\nSig3Long stop (trail)", colorWhite, styleLine | styleNoRescale, Null, Null, Null, -8);
Plot (Sig3ShortStopArray, "\nSig3Short stop (trail)", colorWhite, styleLine | styleNoRescale, Null, Null, Null, -8);

for (i = 0; i < BarCount; i++)
{
if (Sig1Sell[i]) 			PlotText ("1Sell " 	, i, L[i]-50, colorDarkRed);
if (Sig1Cover[i]) 			PlotText ("1Cover "	, i, H[i]+50, colorDarkRed);
if (Sig1Short[i]) 			PlotText ("1Short "	, i, H[i]+40, colorGrey40);
if (Sig2Short[i]) 			PlotText ("2Short "	, i, H[i]+50, colorGrey50);
if (Sig2Sell[i]) 			PlotText ("2Sell " 	, i, L[i]-60, colorBrown);
if (Sig2Cover[i]) 			PlotText ("2Cover "	, i, H[i]+60, colorBrown);
if (Sig3Short[i]) 			PlotText ("3Short "	, i, H[i]+60, colorWhite);
if (Sig3Sell[i]) 			PlotText ("3Sell " 	, i, L[i]-70, colorGold);
if (Sig3Cover[i]) 			PlotText ("3Cover "	, i, H[i]+70, colorGold);
if (Long1TradeArray[i]) 	PlotText ("|"		, i, L[i]-90, colorGreen);
if (Short1TradeArray[i]) 	PlotText ("|"		, i, H[i]+90, colorDarkRed);
if (Long2TradeArray[i]) 	PlotText ("|"		, i, L[i]-100, colorBrightGreen);
if (Short2TradeArray[i]) 	PlotText ("|"		, i, H[i]+100, colorRed);
if (Long3TradeArray[i]) 	PlotText ("|"		, i, L[i]-110, colorWhite);
if (Short3TradeArray[i]) 	PlotText ("|"		, i, H[i]+110, colorWhite);
}

//---------------------------------PLOT PRICE FAST AND SLOW WMA--------------------------------------
Plot( WMA (Close, WMAFast), "\nWMA Fast", colorGold, styleLine |styleNoLabel );
Plot( WMA (Close, WMASlow), "\nWMA Slow", colorAqua, styleLine |styleNoLabel );
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} \nOpen %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", colorDefault, styleNoTitle | GetPriceStyle() );

_SECTION_END();

Would be awesome to somehow "compress" this formula, but I am glad that it even works as is. It's been quite a challenge so far.

1 Like

ExRem() is not for this task. ExRem only works if you have no circular references (self-referencing).

@mradtke is right - just use the loop code from here http://www.amibroker.com/kb/2007/03/24/how-to-plot-a-trailing-stop-in-the-price-chart/ and you will be getting what you need. This is actually the simplest solution.

2 Likes