Avoid multiple triggers from same candle

Hi,

I am working on a strategy, which will generate a buy or a sell signal according to the logic. if the signal is generated then I am posting signal to service (external service). All of that is working fine. How to avoid multiple signal generated at the current candle. Till the candle completes program keeps on calling to external service. How to avoid that effectively? Below is the code where I am calling to service.

#include_once "Formulas\Include\ServiceLib20.afl";

/************** Begin Parameters *************/
SEND_ORDERS = 1;
SERVICE_URI = "http://localhost:50607/api/messages";
SERVICE_STRATEGY_CODE = "GUD01";
/************** End Parameters *************/

if(SEND_ORDERS) {
	
	if(LastValue(Buy)) {
		SendBuyOrder(SERVICE_URI, SERVICE_STRATEGY_CODE);
	} else if(LastValue(Sell)) {
		SendSellOrder(SERVICE_URI, SERVICE_STRATEGY_CODE);
	} else if(LastValue(Short)) {
		SendShortOrder(SERVICE_URI, SERVICE_STRATEGY_CODE);
	} else if(LastValue(Cover)) {
		SendCoverOrder(SERVICE_URI, SERVICE_STRATEGY_CODE);
	}
}

Here is my own implementation of avoiding multiple signals. Some scenarios, it's failing which I am not able to figure out. Any help would be appreciated. Below is the code of "ServiceLib20.AFL"


function ServiceCall(symbolName, orderType, tradeType, SERVICE_URI, SERVICE_STRATEGY_CODE) {
	
	uri = SERVICE_URI + "?StrategyCode=" + SERVICE_STRATEGY_CODE + 
			"&SymbolName=" + symbolName + "&TradeType=" + tradeType + "&OrderType=" + orderType;
	uri = uri + "&nocache=" + 100 * mtRandom();
	
	_TRACE(uri);
	
	ih = InternetOpenURL( uri ); 
	if( ih ) 
	{ 	
		 while( ( str = InternetReadString( ih ) ) != "" ) 
		 { 
			 printf( "%s", str ); 
		 } 
		 InternetClose( ih ); 
	}
}

function SendBuyOrder(SERVICE_URI, SERVICE_STRATEGY_CODE) {
	local SymbolName, type;
	SymbolName=Name();
	type="Buy";
	ALERT_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "Alert";
	ALERT_BAR_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "AlertBar";

	if (LastValue(ValueWhen(Ref(Buy, 0), BarIndex()) == BarIndex()) AND (Nz(StaticVarGet(ALERT_NAME)) == 0 ))
	{
		_TRACE("BEGINING TO SEND BUY ORDER FOR " + SymbolName);
		ServiceCall(SymbolName, 1, 1, SERVICE_URI, SERVICE_STRATEGY_CODE);
		StaticVarSet(ALERT_BAR_NAME, LastValue(TimeNum()));
		_TRACE("BUY ORDER SENT FOR " + SymbolName);
	}
	
	if (LastValue(TimeNum()) == StaticVarGet(ALERT_BAR_NAME))
	{
		StaticVarSet(ALERT_NAME, 1); //alert was triggered, no more alerts on this bar		
	}
	else
	{
		StaticVarSet(ALERT_NAME, 0); // new bar formed, and alerts can be trigered.
	}
	
}

function SendSellOrder(SERVICE_URI, SERVICE_STRATEGY_CODE) {
	local SymbolName, type;
	
	SymbolName=Name();
	type="Sell";
	ALERT_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "Alert";
	ALERT_BAR_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "AlertBar";
	
	if (LastValue(ValueWhen(Ref(Sell, 0), BarIndex()) == BarIndex()) AND (Nz(StaticVarGet(ALERT_NAME)) == 0 ))
	{
		_TRACE("BEGINING TO SEND SELL ORDER FOR " + SymbolName);
		ServiceCall(SymbolName, 2, 1, SERVICE_URI, SERVICE_STRATEGY_CODE);
		StaticVarSet(ALERT_BAR_NAME, LastValue(TimeNum()));
		_TRACE("SELL ORDER SENT FOR " + SymbolName);
	}

	if (LastValue(TimeNum()) == StaticVarGet(ALERT_BAR_NAME))
	{
		StaticVarSet(ALERT_NAME, 1); //alert was triggered, no more alerts on this bar
	}
	else
	{
		StaticVarSet(ALERT_NAME, 0); // new bar formed, and alerts can be trigered.
	}
}

function SendShortOrder(SERVICE_URI, SERVICE_STRATEGY_CODE) {
	local SymbolName, type;
	
	SymbolName=Name();
	type="Short";
	ALERT_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "Alert";
	ALERT_BAR_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "AlertBar";

	if (LastValue(ValueWhen(Ref(Short, 0), BarIndex()) == BarIndex()) AND (Nz(StaticVarGet(ALERT_NAME)) == 0 ))
	{
		_TRACE("BEGINING TO SEND SHORT ORDER FOR " + SymbolName);
		ServiceCall(SymbolName, 3, 2, SERVICE_URI, SERVICE_STRATEGY_CODE);
		StaticVarSet(ALERT_BAR_NAME, LastValue(TimeNum()));
		_TRACE("SHORT ORDER SENT FOR " + SymbolName);
	}

	if (LastValue(TimeNum()) == StaticVarGet(ALERT_BAR_NAME))
	{
		StaticVarSet(ALERT_NAME, 1); //alert was triggered, no more alerts on this bar
	}
	else
	{
		StaticVarSet(ALERT_NAME, 0); // new bar formed, and alerts can be trigered.
	}
}

function SendCoverOrder(SERVICE_URI, SERVICE_STRATEGY_CODE) {
	local SymbolName, type;
	
	SymbolName=Name();
	type="Cover";
	ALERT_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "Alert";
	ALERT_BAR_NAME = SERVICE_STRATEGY_CODE + SymbolName + type + "AlertBar";

	if (LastValue(ValueWhen(Ref(Cover, 0), BarIndex()) == BarIndex()) AND (Nz(StaticVarGet(ALERT_NAME)) == 0 ))
	{
		_TRACE("BEGINING TO SEND COVER ORDER FOR " + SymbolName);
		ServiceCall(SymbolName, 4, 2, SERVICE_URI, SERVICE_STRATEGY_CODE);
		StaticVarSet(ALERT_BAR_NAME, LastValue(TimeNum()));
		_TRACE("COVER ORDER SENT FOR " + SymbolName);
	}

	if (LastValue(TimeNum()) == StaticVarGet(ALERT_BAR_NAME))
	{
		StaticVarSet(ALERT_NAME, 1); //alert was triggered, no more alerts on this bar
	}
	else
	{
		StaticVarSet(ALERT_NAME, 0); // new bar formed, and alerts can be trigered.
	}
}

Thanks,
Vinay

Avoid multiple triggers from same candle

Take a look for Status("lastbarend") and with example here
https://www.amibroker.com/kb/2015/11/29/how-to-execute-part-of-the-formula-only-when-new-bar-is-added/

function NewBarJustArrived()
{
  /// code source:
  /// @link https://groups.yahoo.com/neo/groups/amibroker/conversations/messages/190177
  vname = "lbe"+GetChartID();
  prev = Nz( StaticVarGet( vname ) );
  curr = Status("lastbarend");
  
  StaticVarSet( vname, curr );
  
  return curr != prev;
}

if( NewBarJustArrived() )
  Title = "New bar just arrived (previous is complete)";
else
  Title = "Old bar";
4 Likes

I would suggest you strongly read here
http://www.amibroker.org/userkb/category/real-time-afl-applications/page/4/

http://www.amibroker.org/userkb/2007/07/14/preventing-repeat-orders-and-whipsaws/
There are so many points/techniques covered and implement what suits you.

3 Likes

Thank you.. That worked. Finally ended up code shown like below.

function CheckIfNewBarFormed(ALERT_NAME) {
	local newBar;
	newBar = False;
	lastBartime = Status("lastbarend");
	recordedTimestamp = Nz(StaticVarGet(ALERT_NAME));
	if(lastBartime != recordedTimestamp)
	{
		// record new bar datetime
		StaticVarSet(ALERT_NAME, lastBartime);
		newBar = True;
	}
	return newBar;
}
2 Likes