How to stop continuous Buy/Sell signal from PiBridge thru Amibroker?

I am using PiBridge as a interface between PI and Amibroker. I had written a simple EMA crossover script in AFL and backtested it using AMI, it worked fine. But when I tried to take it ‘Live’ using PI, PiBridge is generating multiple continuous signal every second and sending it to PI. I have placed the AFL script below for your reference. Can you please provide me resolution for the same?

EMA CROSSOVER SCRIPT

FastMALength = 5;
SlowMALength = 13;

FastMA = MA( C, FastMALength );
SlowMA = MA( C, SlowMALength );

Buy = Cross( FastMA, SlowMA );
Sell = Cross( SlowMA, FastMA );
Cover = Buy;
Short = Sell;

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

RequestTimedRefresh(15, False);
brd=Null;
if(IsNull(brd)) brd = CreateStaticObject(“pibridge.Bridge”);
if(!brd.GetConnectionStatus()) brd.Reconnect();

if (LastValue(Buy)) brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-B”, 1, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);

if (LastValue(Sell)) brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-S”, 2, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);

Hi MayankJain,

You Can refer the below link to know why it is firing continuous buy/sell orders from amibroker.

http://zerodha.com/z-connect/tradezerodha/pi-bridge/pi-bridge-for-amibroker

and Alternately U can download the PiBridge AFL from here and Follow the Instructions in it..This AFL will fire only one Order Per signal and It Includes Symbol Mapper.

https://drive.google.com/uc?export=download&id=0B-AWKNHhYByLZmVEVFNxRVBuNUU

Many thanks for your reply.
I have not understood few things in the AFL script shared by you.

  1. Why condition “BuyVar != BuyVar1” is being checked? As per my understanding, this condition will always be true, since both BuyVar and BuyVar1 shall always hold the different values. Kindly confirm.
  2. What is the purpose of using StaticVarGetText function in the script? For me, without the usage of this function, the value of BuyVar will remain same. Please correct me if I am wrong.
  3. Most important question, which part of the script is exactly stopping the generation of multiple signals. Because with the first glance, I couldn’t locate the logic which will only send one Buy/Sell/Cover/Short signal to PiBridge.
    I hope I am clear in my questions.

Hi MayankJain,
1.Yaa,…This Condition is always true for all Bars except when there is signal in that Bar…
2.It’s nearly impossible to create a automated system without Static variable…
Its must Bcoz,in AFL all variables recalculated every time,the chart refreshes and are assigned fresh value…
Execpt,Static Variable Values…Its Values will not change on Chart Refresh, until unless U assign a new Value…
3. BuyVar != BuyVar1, SellVar != SellVar1, ShortVar != ShortVar1, CoverVar != CoverVar1…
This the code that restrict the continuous Firing of Orders for a Single Signal…
If U Understand Why it is firing continuous orders to Pi…
then U can easily understand the purpose of Static Variables…
Assuming…
Chart Interval is 1min
Ur using ur above AFL…
Amibroker Chart Refreshes every second
( Can be set in Prefrences window…
So U donot need the code “RequestTimedRefresh(15, False);” in Your AFL
RequestTimedRefresh Function will overide the Prefrences Settings and Ur Chart will be refreshed
only in every 15sec in your case…thus u will get delayed signal…More over U should not use this
function in Live Trading system)
Whenever the amibroker Chart refreshes…
Ur AFL codes is executed line by line from top to Bottom…
Suppose U got a Buy Signal at 10:00:05 am on 12 May 15 Ticker NIFTY.
So in 1Min, Ur Current Bar covers Time From 10:00:00am to 10:00:59am
As soon as the Buy Condition is met at Current Bar
the lastvalue(Buy) = True so it places a buy order in pi
at 10:00:06 am (Again Chart Refeshes…Thus code Executed again)
Now also the lastvalue(Buy) = True so it places a buy order in pi
and it keeps on going until the lastvalue(Buy) = Flase…
LastValue(Buy) will become false only on or after 10:01:00am i.e. Next bar
Same way for other signals also…
Bcoz of this Only, it places continuous orders to pin Until the Signal bar Closes…
So Our requirement is… It sholud place only one order at 10:00:05am…
and all others should be ignored.
Here comes the use of Static variables…
Our aim is as soon as the first order is fired…we need to assign a unique value to a static variable
and use that value to restrict continuous order…It may confuse u…But Explain with example will make it clear
My Code
DT = LastValue(DateNum(),1);
TT = LastValue(TimeNum(),1);(assume U have selected Start Time of Interval in Prefrences -->IntraDay )
BuyVar = StaticVarGetText(Name()+"-Buy"); (It gets the value of a Static Variable NIFTY-Buy)
BuyVar1 = Name()+"-Buy-"+NumToStr(DT,1.0)+"-"+NumToStr(TT,1.0)+"-"+NumToStr(GetChartID(),1.0);
BuyL = LastValue(Buy);
if (BuyL AND BuyVar != BuyVar1 )
{brd = CreateStaticObject(“pibridge.Bridge”);
brd.PlaceOrder (Exch,TrdSym,StrLeft(Sym,10),“LONG”,1,Qty,0,TrdPrice,0,ORdType,ProdType,ClientId,Val);
StaticVarSetText(Name()+"-Buy",BuyVar1);}
OutPut of my code at 10:00:00am
DT = 1150512
TT = 100000
BuyVar = Empty (Assume no buy signal is generated till 10000am)
BuyVar1 = NIFTY-Buy_1150512-100000-1003
BuyL = 0 (False)
OutPut of my code at 10:00:05am (Buy Condition is met)
DT = 1150512
TT = 100000
BuyVar = Empty (Assume no buy signal is generated till 10000am)
BuyVar1 = NIFTY-Buy_1150512-100000-1003
BuyL = 1 (True)
Now BuyL is true and BuyVar is Not Equal to BuyVar1
So if Condition is Executed…i.e.
It Creates a Static Object
It Places order to pi
It assign the value of BuyVar1(NIFTY-Buy_1150512-100000-1003) to StaticVariable (NIFTY-Buy)
OutPut of my code at 10:00:06am
DT = 1150512
TT = 100000
BuyVar = NIFTY-Buy_1150512-100000-1003
BuyVar1 = NIFTY-Buy_1150512-100000-1003
BuyL = 1 (True)
Now eventhough BuyL is true, but BuyVar is Equal to BuyVar1
So if Condition is not Executed…thus preventing continuous orders…

Now U might have got better idea on continuous firing and static variable.
If U have further query pls comment…

This was really a very good explanation. thanks.
I have modified my script to use the static functions. But still I am receiving multiple signals at PI. I am really not sure wats going wrong now. Here is my modified script:
FastMALength = 5;
SlowMALength = 13;
FastMA = MA( Close, FastMALength );
SlowMA = MA( Close, SlowMALength );
Buy = Cross( FastMA, SlowMA );
Cover = Buy;
Sell = Cross( SlowMA, FastMA );
Short = Sell;
DT = LastValue(DateNum(),1);
TT = LastValue(TimeNum(),1);
BuyVar = StaticVarGetText(Name()+"-Buy");
BuyVar1 = Name()+"-Buy-"+NumToStr(DT,1.0)+"-"+NumToStr(TT,1.0)+"-"+NumToStr(GetChartID(),1.0);
BuyL = LastValue(Buy);
SellVar = StaticVarGetText(Name()+"-Sell");
SellVar1 = Name()+"-Sell-"+NumToStr(DT,1.0)+"-"+NumToStr(TT,1.0)+"-"+NumToStr(GetChartID(),1.0);
SellL = LastValue(Sell);
ShortVar = StaticVarGetText(Name()+"-Short");
ShortVar1 = Name()+"-Short-"+NumToStr(DT,1.0)+"-"+NumToStr(TT,1.0)+"-"+NumToStr(GetChartID(),1.0);
ShortL = LastValue(Short);
CoverVar = StaticVarGetText(Name()+"-Cover");
CoverVar1 = Name()+"-Cover-"+NumToStr(DT,1.0)+"-"+NumToStr(TT,1.0)+"-"+NumToStr(GetChartID(),1.0);
CoverL = LastValue(Cover);
brd = CreateStaticObject(“pibridge.Bridge”);
if(!brd.GetConnectionStatus()) brd.Reconnect();
if (BuyL AND BuyVar != BuyVar1)
{
brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-B”, 1, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);
StaticVarSetText(Name()+"-Buy",BuyVar1);
}
if (SellL AND SellVar != SellVar1)
{
brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-S”, 2, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);
StaticVarSetText(Name()+"-Sell",SellVar1);
}
if (CoverL AND CoverVar != CoverVar1)
{
brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-C”, 1, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);
StaticVarSetText(Name()+"-Cover",CoverVar1);
}
if (ShortL AND ShortVar != ShortVar1)
{
brd.PlaceOrder(“NFO”, “NIFTY15MAYFUT”, “NIFTY”,“STRATEGY-Sh”, 2, 1, 1, 0, 0, “MKT”, “NRML”, “RB0799”,“Day”);
StaticVarSetText(Name()+"-Short",ShortVar1);
}
can you please help me ??

Hi,
Your Static variable Part is Correct.
Is this Ur Full Code? Then
Just Ensure the following Settings in Amibroker.
Tools -->> Preferences -->> Intraday -->> Tick "Align Minute Bars to Regular Market Hours"
Tools -->> Preferences -->> Intraday -->> Select "Start Time Of Interval"
If The above settings are already there then
What U get in PI is not continuous order for a single signal instead U have multiple signal in Amibroker.
For that,
U Should use EXREM function to remove excess signals for repeated condition.
U should include the below code after line Short=Sell;
Buy = ExRem(Buy,Sell);
Short=Exrem(Short,Cover);
Note:-
Whenever U want to check AFL for Continuous order Firing for single signal using BarReplay,
Use Chart time interval greater than 1Minute.(5min is Recommended)
This is Bcoz, when U Bar Replay with 1min each bar will play for 1 Sec…so U always have one order per signal Bar.But in Live,Each bar will cover 60sec, so U may get continuous order in live.
If U use 5min interval in BarReplay,Each bar will play for 5Sec, So Ur AFL can be effectively checked for
continuous order firing for single Signal.

Hello again,
I tried with BarReplay on 5/15 min chart, continuous signals problem doesn’t seem to be there. Thanks a lot. I will try once with live data to be very sure.
I have few questions further:

  • What does ExRem function do exaclty?
  • If MA crossover happens multiple times while 15 minute candle is being formed, because CLOSE value keeps changing it gives signals at every cross during that 15 min period. To avoid this I tried MA crossover taking CLOSE value of previous 15-min candle (instead of current candle). But it is not working. Here is the code snippet:
    FastMA = MA( Ref(Close, -1), 5 );
    SlowMA = MA( Ref(Close,-1), 13 );
    Can you please validate it?

Hi,
U should use like this…
FastMA = Ref(MA(C,5),-1);
SlowMA = Ref(MA(C,13),-1);
Otherwise…
in your above code after line Short==Sell;
Insert the below code
Buy = Ref(Buy,-1);
Sell = Ref(Sell,-1);
Short = Ref(Short,-1);
Cover = Ref(Cover,-1);
This will ensure that the condition is fulfilled correctly.
Use of EXREM Function:
Ex:- Buy Condition is When Close > Previous Hour High
Suppose Prv Hr High is 152 and Now Close is 151.85
At 10:00 am Close is 152.05…Now Buy Condition is fulfilled…So U Got a Buy Signal
at 10:01 am close is 152.35, now also Buy condition is fulfilled…So U Got again a Buy Signal
and it continues till close comes below 152 in this case
To remove the second and further repeated signals we use EXREM function
For Example:-
BStop = Timenum()==093000;//This condition will be fulfiled only once in a Trading session
Buy = C > Ref(HHV(H,60),-1);
Buy = Exrem(Buy,BStop);
Now what will happen, at 1000am First Buy condition is met…and Buy Signal is generated
For Second Buy Signal,there should be one BStop condition is fulfilled after the First Buy condition is met.But BStop Condition will never come again in Todays Trading session…
So even buy condition is met after 1000am, second and further buy signal will not be generated throughout today’s trading session.

@botany02 I am having similar problem, can you help me fix it?

@botany02 After using exrem function, I am calling lastvalue(buy) and lastvalue(sell) but they are not coming rather they are coming in wrong positions.

superb great explanation, i overlooked this few years back now realize the importance. Thanks