Help with avoiding For Loop and Issues with inconsistent Buy/Sell Signals in scanner

Hi All,

I am not a programmer and I am facing 2 issue with my AFL strategy hence seeking help here.

  1. I have a strategy and it is working fine when applied to a chart or when backtested however when I run it using scanner with auto-repeat (For 1 or 2 recent bars) on with AR interval of 1 Sec this is not generating signals. If Auto Repeat is stopped and backtest is run immediately it show all trade signals including stops (Entry and Exit) Both.
  2. This has a for loop and I was wondering if there is anyway this can be achieved without a for loop ? As I understood from reading the forum that Array based approach is much faster and efficient as compared to loop but unfortunately I am not able to achieve it.

I want to optimize the input parameters and apply stop variables before implementing this strategy and intended use is for 1 symbol for Intraday trade on 1/2 or 3 minute timeframe for auto trading using a third party app which reads Buy/Sell Signal and fires relevant order to the trading terminal. Any help with resolving the above two issues will be highly appreciated.

Here is my AFL code for reference.

_SECTION_BEGIN("RSI Divergence CrudeOil");
GraphXSpace=7;
//n=Param("% Reverse ",12,0,100,1);
n=Param("ZIG CrudeOil",28,5,65,1);
per=Param("rsi CrudeOil",16,4,17,1);
Buy=Sell=Short=Cover=0;
Var = Zig(RSI(per), n); 
t= Trough(RSI(per), n, 1); 
p= Peak(RSI(per), n, 1); 
x[0] =Var[0];
price[0] = C[0];
j=0;

_SECTION_BEGIN("VolumeHigh CrudeOil");

	CurrentPeriodVolumeCrudeOil = Param( "CurrentVolumeAverage CrudeOil", 6, 4, 7, 1 );
	AverageVolumePeriodCrudeOil =Param( "AverageVolumePeriod CrudeOil", 148, 140, 150, 1);

	VolumeHighCrudeOil = IIf((DEMA(V, AverageVolumePeriodCrudeOil) < DEMA(V, CurrentPeriodVolumeCrudeOil)),1,0);

_SECTION_END();

// bearish divergence
for ( i=0; i<BarCount; i++) 
{
if(Var[i] == p[i])
{

j++;
x[j] =Var[i];
price[j] =C[i];
if(x[j] <x[j-1] && price[j-1]< price[j]) 
Short[i] =1 && VolumeHighCrudeOil[i];
}
}

// bullish divergence
for ( i=0; i<BarCount; i++) 
{
if(Var[i] == t[i])
{
j++;
x[j] =Var[i];
price[j] =C[i];
if(x[j] >x[j-1] && price[j]<price[j-1]) 
Buy[i] =1 && VolumeHighCrudeOil[i];
}
}

Plot(Var, "", 39); 
PlotShapes ( IIf(Short, shapeSmallCircle, shapeNone), colorRed, 0 , Var,0);
PlotShapes( IIf(Buy, shapeSmallCircle, shapeNone),  colorBrightGreen, 0, Var,0);

Title ="RSI Divergence CrudeOil" ;
tn = TimeNum();
CrudeOilstartTime = Param("CrudeOil Start Time",90000,90000,110000,15); // start in HHMMSS format
CrudeOilendTime = Param("CrudeOil End Time",231400,220000,234500,15);  // end in HHMMSS format
timeOK = tn >= CrudeOilstartTime AND tn <= CrudeOilendTime;

		Cover = Cross(tn,CrudeOilendTime);
		Sell= Cross(tn,CrudeOilendTime);

CrudeOilSL= Optimize("CrudeOilSL",16,12,24,1);
CrudeOilPL= Optimize("CrudeOilPL",10,10,25,1);

ApplyStop(Type=0,Mode=2,CrudeOilSL,1);
ApplyStop(Type=1,Mode=2,CrudeOilPL,1);

_SECTION_END();

I am really struggling to get this working so please help me get it into action. Thanks in advance for any guidance anyone can offer on this.

Thanks,
Ganesh

// bearish divergence
cond1 = var==p;
p_x = ValueWhen(cond1, var);
p_price = ValueWhen(cond1, C);
Short = p_x < Ref(p_x,-1) AND p_price > Ref(p_price,-1); 
Short = Ref(Short,-1) AND VolumeHighCrudeOil; 
 
// bullish divergence
cond2 = var==t;
t_x = ValueWhen(cond2, var);
t_price = ValueWhen(cond2, C);
Buy = t_x > Ref(t_x,-1) AND t_price < Ref(t_price,-1); 
Buy = Ref(Buy,-1) AND VolumeHighCrudeOil; 

So, ->

_SECTION_BEGIN("RSI Divergence CrudeOil");
GraphXSpace=7;
//n=Param("% Reverse ",12,0,100,1);
n=Param("ZIG CrudeOil",28,5,65,1);
per=Param("rsi CrudeOil",16,4,17,1);

Buy=Sell=Short=Cover=0;

my_RSI = RSI(per);
Var = Zig(my_RSI, n); 
t= Trough(my_RSI, n, 1); 
p= Peak(my_RSI, n, 1); 

_SECTION_BEGIN("VolumeHigh CrudeOil");

	CurrentPeriodVolumeCrudeOil = Param( "CurrentVolumeAverage CrudeOil", 6, 4, 7, 1 );
	AverageVolumePeriodCrudeOil =Param( "AverageVolumePeriod CrudeOil", 148, 140, 150, 1);

	VolumeHighCrudeOil = IIf((DEMA(V, AverageVolumePeriodCrudeOil) < DEMA(V, CurrentPeriodVolumeCrudeOil)),1,0);

_SECTION_END();


// bearish divergence
cond1 = var==p;
p_x = ValueWhen(cond1, var);
p_price = ValueWhen(cond1, C);
Short = p_x < Ref(p_x,-1) AND p_price > Ref(p_price,-1); 
Short = Ref(Short,-1) AND VolumeHighCrudeOil; 
 
// bullish divergence
cond2 = var==t;
t_x = ValueWhen(cond2, var);
t_price = ValueWhen(cond2, C);
Buy = t_x > Ref(t_x,-1) AND t_price < Ref(t_price,-1); 
Buy = Ref(Buy,-1) AND VolumeHighCrudeOil; 

Plot(Var, "", 39); 
PlotShapes ( IIf(Short, shapeSmallCircle, shapeNone), colorRed, 0 , Var,0);
PlotShapes( IIf(Buy, shapeSmallCircle, shapeNone),  colorBrightGreen, 0, Var,0);

Title ="RSI Divergence CrudeOil" ;
tn = TimeNum();
CrudeOilstartTime = ParamTime("CrudeOil Start Time","09:00"); // start in HHMMSS format
CrudeOilendTime = ParamTime("CrudeOil End Time","23:14");  // end in HHMMSS format
timeOK = tn >= CrudeOilstartTime AND tn <= CrudeOilendTime;

Cover = Cross(tn,CrudeOilendTime);
Sell= Cross(tn,CrudeOilendTime);

CrudeOilSL= Optimize("CrudeOilSL",16,12,24,1);
CrudeOilPL= Optimize("CrudeOilPL",10,10,25,1);

ApplyStop(Type=0,Mode=2,CrudeOilSL,1);
ApplyStop(Type=1,Mode=2,CrudeOilPL,1);

_SECTION_END();
2 Likes

@fxshrat Thank you very much. That was a very quick response. I will try implementing the revised approach suggested by you. Hopefully it will also resolve the inconsistent signals issue? Auto Repeat scan is missing signals where as normal scan or backtest is showing those signals. I am assuming it was due to the for loop and assignment to a specific element of Buy and Short array. Or is it being caused because of use of the look-ahead indicator/function? I can test if the issue is resolved only when there is RT data running during live market.

Please suggest if anything else is required to resolve the AR scan missing signal issue.

Thanks again,
Ganesh

ApplyStop is a backtester function. Please read carefully from top to bottom here.

So Scan is not backtest.
So you will not get Applystop exit signals output outside backtest environment if you do not evaluate stops via Equity function there (read Equity() function link carefully too).

So add following two lines at the end (after ApplyStop calls).

// evaluate stops in Scan via Equity() function
if ( Status("action") == actionScan )
	eq = Equity(1,-1); // single security backtester function

@fxshrat Probably I was not able to articulate my issue # 1 clearly. I am familiar about ApplyStop being a backtester function and I am managing exit for live trades outside of AFL. The real issue is Entry signals are missing. i.e. When I do a scan (one time scan) or backtest I see all the entry signals (Buy or Short) or if I have a chart even then I see all Entry signals with RT data but when the same AFL is run in Auto Repeat Scan with (RT data) entry signals are missed. Is is repainting or something else is wrong? :thinking: Not sure what the issue is:-(

Do you listen what I "said"?

And no, you are not familiar with ApplyStop because you did not read carefully.

If you do not evaluate stops via Equity() outside backtester environment of analysis then exits by Applystop are ignored there and as such you will also get missing entry signals or in short different sequence of signals.

You should really listen better and apply things mentioned.

First backtest -> 14 entries and 14 exits
6

Now Scan output...

  1. using Equity() function
    and we get same number of entry and exit signals -> 2*14 and same times as in backtester result list.

(Note: prices at exit are different at times (at stop exits) because your stops don't exit at close but at set targets. Scan only outputs Close price column. For other things you may use Exploration which is advanced scan.)
7

  1. And now again Scan but different outcome within same time range but without evaluating stops via Equity().
    Now only your regular exits are applied using Cross() function in your code.
    So you get different number of entry/exit signals / different sequence / different times.
    8

Now it should also be clear that if you update data / backfill data then in addition it may occur that data may change that is being provided by data vendor. So signals may change too then.

EDIT: and also ZIG(), Peak And Trough functions in your code are forward looking functions (looking "into the future"). So it will cause repainting.

@fxshrat Thank you very much for the detailed explanation, Its really helpful. I have implemented changes suggested by you (eliminating for loop and evaluation of stops via Equity()). I will be able to test it during live market on the next trading session and hopefully now AR scan should work as desired to match backtest results.

Regarding your comment on forward looking functions and repainting. Is there a way to avoid repainting?

I read here that the results of backtest might be inflated if we are using forward looking functions. I did Walk-Forward optimization and at least for this Symbol the In sample and out of sample results are very much similar in terms of win rate and other parameters. This still appears to be worry, please suggest if this can be addressed?

Thanks,
Ganesh

Hi @fxshrat this solution worked for me as described by exiting all ApplyStop and shows the Sell signal in the scanner.

One question regarding the documentation for Equity function since it says that its only there for backwards compatibility and we should be using Foreign("~~~EQUITY", "C") instead.

Question: For the example you provided, do you think it is still safe to still use the Equity function?

This function isn't going away in a future release is it? Thank you.

Tomasz Janeczko is not Microsoft.
Tomasz Janeczko is not politician.
Tomasz Janeczko is not....

Tomasz Janeczko is a man who stands by his words (speaking from my experience).
And for sure he is not a guy who would break old formula files of users. Never.

If it says it is there for backward compatibility then it will stay there for backward compatibility in the future also.
Now, I am not AmiBroker but speaking from my experience of having been using AmiBroker for many many years I can say that so far there have not ever been broken any backward compatibility in the past. I am not aware of any case where it happened. (Look... for example even old analysis window is still integrated and accessible. Also look at coexistence of functions IsEmpty() (old) / IsNull() and WriteVal() (old) / NumToStr() and other ones...)

@fxshrat ha, thank you. I feel like there should be some music playing in the background... Always good to not have to deal with politicians. And I now understand that backwards compatibility has always been part of Amibroker. Good to know.

With that said, Equity is still using the old backtester, so is there any newer function that produces the same results to evaluate the ApplyStop and show the Sell signals in the scanner? Given your statement above, it might not be necessary if the old backtester will always remain. But using the newer backtester will be more performant. I don't see an alternative to the Equity function, do you?