How to make a variable freeze after first occurrence

Hello,

This is my first query and a long searched one, Hence i decided to join this forum to get some help.

I have a BuySignal which i use to alert before the buy happens (below is just an example)

SignalBuy=BarsSince( Volume>(2.5*Ref(Volume,-1)) AND Close>Open);
//Volume is 2.5x of the previous volume and close is greater than open

Buy=High>Ref(High,-SignalBuy)+1
//Buy when Price> 1+ High of (SignalBuy-Bar)

is there a way to lock the "Signalbuy" condition the first time it occurs, as it seems to change if this condition occurs again ? this way i want to avoid the signals coming after that and i use the first occurrence as the trigger point for Buy. (please note Exrem does not work for this, it works with reserved variables like "buy","Short"). Any help to write this AFL is appreciated. Thanks

Sure ExRem works for every variable. If you just want first occurrence and no more you just write

SignalBuy = ExRem( SignalBuy, 0 ); // nothing but very first occurrence
5 Likes

Thanks Tomasz, Not sure what i am missing iam getting zero/No results in backtester. Below is my code please help!

Period=BarsSince(DateNum()!=Ref(DateNum(),-1))+1;
PR=IIf(Open-Close<0,Close-Open,Open-Close); //Range of price
MPR=MA(PR,Period); //Moving Avg of Price Range

upCrssDate=ValueWhen(Cross(WMA(C,36),MA(C,50)),DateNum(),1); //Cross between WMA and MA
dwncrossdate=ValueWhen(Cross(MA(C,50),WMA(C,36)),DateNum(),1); // Cross between MA and WMA


SignalBuy=BarsSince(PR>(1.5*MPR) AND Volume>(1.5*Ref(Volume,-1)) AND Close>Open AND DateNum()==upCrssDate AND TimeNum()>=092900 AND TimeNum()<=150000); // AND Ref(high,1)>High+1; 		
SignalShort=BarsSince(PR>(1.5*MPR) AND Volume>(1.5*Ref(Volume,-1)) AND Close<Open AND DateNum()==dwncrossdate AND TimeNum()>=092900  AND TimeNum()<=150000); // AND Ref(Low,1)<Low-1;


SignalBuy=ExRem(SignalBuy,0);
SignalShort=ExRem(SignalShort,0);

Barsxday=BarsSince(Ref(DateNum(),-1)!=DateNum())+1; //Bars since intraday(day) start


Buy=SignalBuy<Barsxday AND High>Ref(High,-SignalBuy)+1 AND Close>Open AND DateNum()==upCrssDate AND TimeNum()>=092900 AND TimeNum()<=150000 ;
Short=SignalShort<Barsxday AND Low<Ref(Low,-SignalShort)-1 AND Close<Open AND DateNum()==dwncrossdate AND TimeNum()>=092900  AND TimeNum()<=150000;
Sell=TimeNum()>=151000;
Cover=TimeNum()>=151000;  


BuyPrice=Ref(High,-SignalBuy)+1;
ShortPrice=Ref(Low,-SignalShort)-1;

@George-The-Trader you might want to review this post to see if you can solve the problem yourself: How do I debug my formula?

Problem seems to be in this line "SignalBuy = ExRem( SignalBuy, 0 );" if i remove this it works fine, but i dont get the first occurrence of the signal instead it it always the recent one before the buy is triggered. Need help to get the first occurrence of the signal.

You problem is quite apparent but you are not debugging your arrays and that is why you are not able to get around.

You are trying to trade intraday but your code quoted above isn't doing that and you are using this
Ref(DateNum(),-1)!=DateNum() all over the place.
If you look inside this Array, you will have a 1 at every first bar for the day, everyday, not just today.

You have to assert the present or most recent day like this for intra bars:

todayOnly = DateNum() == LastValue( DateNum());

This Array is true only for the most recent bar, on which you can then further apply other conditions of SignalBuy or SignalShort

Now, if you apply ExRem() as suggested by TJ, you will get first occurrence of Buy in the current day.

1 Like

Let me make it simple, to summarize all i want is a the first Barsince an condition as occurred in Intraday. Lets say below code i am saying if volume is more that 1.5x of previous bar and close is greater than open and time is > than 9:20AM. I want the result of variable "Signalbuy" to remain static after the first occurrence. so i am able to reference it for triggering Buy .

SignalBuy=BarsSince(Volume>(1.5*Ref(Volume,-1)) AND Close>Open and TimeNum()>=092900);

If you want one signal PER DAY (not what you originally asked for), try something like this:

dn = DateNum();
isEndOfDay = dn  != Ref(dn ,1);

SignalBuy =  Volume>(1.5*Ref(Volume,-1) AND 
             Close>Open AND
             TimeNum()>=092900);

FirstSignalBuy = ExRem(SignalBuy, isEndOfDay);

BarsSinceBuySignal = BarsSince(FirstSignalBuy );

3 Likes

Try Matt's code

Also check this out

Then use hold()
https://www.amibroker.com/guide/afl/hold.html

1 Like

thanks guys (really appreciate the quick response). I am getting there almost but have a slight problem. I want all my trades to close at end of intraday hours 15:15 PM. However with the below exrem some of my trades close when FirstSignalShort happens. is there a way to Keep the first signal (buy or short) going till we reach 15;15PM (EOD) as well as avoid closing of buy when short signal happens and viseversa?

FirstSignalBuy = ExRem(SignalBuy, isEndOfDay);

When you have made changes to your code after taking inputs from other, you should first post your complete code.
Its unreasonable for you to expect every helping member to go through the whole thread each time you have a problem and understand the flow of the thread.

1 Like

apologies, here you go..

Period=BarsSince(DateNum()!=Ref(DateNum(),-1))+1;
PR=IIf(Open-Close<0,Close-Open,Open-Close); //Range of price
MPR=MA(PR,Period); //Moving Avg of Price Range
dn = DateNum();
isEndOfDay = dn!= Ref(dn ,1);
SignalBuy=PR>(1.5*MPR) AND Volume>(1.5*Ref(Volume,-1)) AND Close>Open and AND TimeNum()>=092900 AND TimeNum()<=150000
SignalShort=PR>(1.5*MPR) AND Volume>(1.5*Ref(Volume,-1)) AND Close<Open AND TimeNum()>=092900  AND TimeNum()<=150000;

FirstSignalBuy=ExRem(SignalBuy, isEndOfDay);
FirstSignalShort=ExRem(SignalShort, isEndOfDay);

BSSignalBuy= BarsSince(FirstSignalBuy);
BSSignalShort= BarsSince(FirstSignalShort);

Buy= SignalBuy AND High>Ref(High,-BSSignalBuy)+1 AND Close>Open AND  TimeNum()>=092900 AND TimeNum()<=150000 ;
Short= SignalShort AND Low<Ref(Low,-BSSignalShort)-1 AND Close<Open AND  TimeNum()>=092900  AND TimeNum()<=150000; 
Sell=TimeNum()>=151000;
Cover=TimeNum()>=151000; 
BuyPrice=Ref(High,-BSSignalBuy)+1;
ShortPrice=Ref(Low,-BSSignalShort)-1;

Look at backtester setting "Reverse signal forces exit".

2 Likes

thanks @fxshrat. that solved my problem