Rajandran R Founder of Marketcalls and Co-Founder Algomojo. Full-Time Derivative Trader. Expert in Designing Trading Systems (Amibroker, Ninjatrader, Metatrader, Python, Pinescript). Trading the markets since 2006. Mentoring Traders on Trading System Designing, Market Profile, Orderflow and Trade Automation.

Algomojo Index Straddle/Strangle Execution Module with Intraday Stoploss

7 min read

This tutorial focus on how to automate your index straddle/strangle strategy with intraday stop-loss levels with time-based entry and exits using Algomojo Platform and Amibroker.

Trading ActivityOrders to be Placed
Time Based EntryEnter Straddle/Strangle at 9.30a.m (Two legged Order)
Calculate the Short Call Average PriceCalculate the Short call Stoploss
Calculate the Short Put Average PriceCalculate the Short Put Stoploss
Place Stoploss OrdersPlace the Stoploss for both Short call and Short Put if the entry order status is completed
Check Open PositionsCheck the Open Positions for the Qty traded
Time Based ExitSquare of Short Call and Short Put legs for the qty present in the open positions around 3.15p.m.

upported Brokers : Aliceblue, Tradejini, Zebu
Supported Trading Instruments : Index Options

To Build this module we need 2 components

1)Header Option Execution Module that needs to be placed inside the Amibroker\Formulas\Include folder
2)Main Option Execution Module that needs to be drag and dropped over the Blank Chart

1)Header Include Option Execution Module

Copy the Header Execution Module to Amibroker\Formulas\include folder. Save the AFL under the name algomojostraddle.afl

//////////////////////////////////////////////
//Multi Broker Amibroker Option Straddle Execution Module
//Coded by Rajandran - Algomojo Co-Founder
//Date : 18/01/2021
//////////////////////////////////////////////



//Use this code only for Single Legged Long Only Options and Exiting Long Only Options


_SECTION_BEGIN("Algomojo Multi legged Options");


uid = ParamStr("Client ID","TS2499");
user_apikey = ParamStr("user_apikey","86cbef19e7e61ccee91e497690d5814e"); //Enter your API key here
api_secret = ParamStr("api_secret","4a94db82ea4fa140afaa2f039efffd18"); //Enter your API secret key here
s_prdt_ali = "BO:BO||CNC:CNC||CO:CO||MIS:MIS||NRML:NRML";
prctyp = ParamList("prctyp","MKT|L|SL|SL-M",0);
Pcode = ParamList("Pcode","NRML|CO|MIS",2);
Price = ParamList("Price","0");
TrigPrice = ParamList("TrigPrice","0");
exch = "NFO"; //Exchange
Ret = "DAY"; //Retention
AMO = "NO"; //AMO Order

stgy_name = ParamStr("Strategy Name", "Options");
broker = ParamStr("Broker","ab"); //Broker Short Code - ab - aliceblue, tj - tradejini, zb - zebu, en - enrich
ver = ParamStr("API Version","1.0");
fpath = ParamStr("Symbol Filepath", "C:\\Program Files (x86)\\AmiBroker\\Formulas\\Algomojo\\");
timer = 1; //3 seconds for providing delay after placing order

RequestTimedRefresh(1,False);

function placestoplossorder(SLTsym,orderaction,averageprice,stoppercent,orderqty)
{
	//rounded of to nearest tick
	TickSize = 0.05;
	
	slprice = int(StrToNum(averageprice) + (StrToNum(averageprice) * stoppercent/100));
	slprice = Prec(slprice,2);
	rem = slprice % TickSize;
	slprice = slprice - rem;  //rounded of to nearest tick size	


	algomojo=CreateObject("AMAMIBRIDGE.Main");
    api_data ="{\"stgy_name\":\""+stgy_name+"\",\"s_prdt_ali\":\""+s_prdt_ali+"\",\"Tsym\":\""+SLTsym+"\",\"exch\":\""+exch+"\",\"Ttranstype\":\""+orderaction+"\",\"Ret\":\""+Ret+"\",\"prctyp\":\""+"SL-M"+"\",\"qty\":\""+orderqty+"\",\"discqty\":\""+"0"+"\",\"MktPro\":\""+"NA"+"\",\"Price\":\""+"0"+"\",\"TrigPrice\":\""+slprice+"\",\"Pcode\":\""+Pcode+"\",\"AMO\":\""+AMO+"\"}";
    _TRACE("");
    _TRACE("API Request"+api_data);
    resp=algomojo.AMDispatcher(user_apikey, api_secret,"PlaceOrder",api_data,broker,ver);
    Say( "Stoploss Order is Placed" ); 
    return resp;


}


function getnestorderno(response)
{

NOrdNo = "";


if(StrFind(response,"NOrdNo")) //Matches the orderstatus
{
NOrdNo = StrTrim( response, "{\"NOrdNo\":" );
NOrdNo = StrTrim( NOrdNo, "\",\"stat\":\"Ok\"}" );
}

return NOrdNo;
}

function getorderhistory(orderno)
{

algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{\"uid\":\""+uid+"\",\"NOrdNo\":\""+orderno+"\",\"s_prdt_ali\":\""+s_prdt_ali+"\"}";
resp=algomojo.AMDispatcher(user_apikey, api_secret,"OrderHistory",api_data,broker,ver);

return resp;


}


function getsymbol(orderno)
{

ordresp = getorderhistory(orderno);

data = "";
Trsym="";

for( item = 0; ( sym = StrExtract( ordresp, item,'{' )) != ""; item++ )
{

sym = StrTrim(sym," "); //Trim Whitespaces




if(StrFind(sym,"complete") OR StrFind(sym,"rejected")) //Matches the orderstatus
{

flag = 1; //turn on the flag

data = sym;

for( jitem = 0; ( ohistory = StrExtract( data, jitem,',' )) != ""; jitem++ )
{

if(Strfind(ohistory,"Trsym"))
  {
   Trsym = StrExtract(ohistory,1,':');
   Trsym = StrTrim(Trsym,"\"");
   
  }

}

}

}

return Trsym;

}

function getaverageprice(orderno)
{

ordresp = getorderhistory(orderno);

data = "";
averageprice="";

for( item = 0; ( sym = StrExtract( ordresp, item,'{' )) != ""; item++ )
{

sym = StrTrim(sym," "); //Trim Whitespaces




if(StrFind(sym,"complete") OR StrFind(sym,"rejected")) //Matches the orderstatus
{

flag = 1; //turn on the flag

data = sym;

for( jitem = 0; ( ohistory = StrExtract( data, jitem,',' )) != ""; jitem++ )
{

if(Strfind(ohistory,"averageprice"))
  {
   averageprice = StrExtract(ohistory,1,':');
   averageprice = StrTrim(averageprice,"\"");
   
  }

}

}

}

if(averageprice=="0.0")
{
averageprice = "100";
}

return averageprice;

}


function getorderstatus(orderno)
{
orderstatus="";
ordresp = getorderhistory(orderno);

data = "";

for( item = 0; ( sym = StrExtract( ordresp, item,'{' )) != ""; item++ )
{

sym = StrTrim(sym," "); //Trim Whitespaces


if(StrFind(sym,"complete") OR StrFind(sym,"rejected")) //Matches the orderstatus
{

flag = 1; //turn on the flag

data = sym;

for( jitem = 0; ( ohistory = StrExtract( data, jitem,',' )) != ""; jitem++ )
{

if(Strfind(ohistory,"Status"))
  {
   orderstatus = StrExtract(ohistory,1,':');
   orderstatus = StrTrim(orderstatus,"\"");
   
  }

}

}

}

return orderstatus;
}//end function


function gettoken(symbol)
{
stoken="";
algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{\"s\":\""+symbol+"\"}";
resp=algomojo.AMDispatcher(user_apikey, api_secret,"fetchsymbol",api_data,broker,ver);

for( item = 0; ( sym = StrExtract( resp, item,'{' )) != ""; item++ )
{

sym = StrTrim(sym," "); //Trim Whitespaces

data = sym;

for( jitem = 0; ( ofetch = StrExtract( data, jitem,',' )) != ""; jitem++ )
{

if(Strfind(ofetch,"symbol_token"))
  {
   stoken = StrExtract(ofetch,1,':');
   stoken = StrTrim(stoken,"\"");
   
  }

}

}
return stoken;
}

function writetofile(filepath,ordno,symbol,ostatus,averageprice)
{
    result =0;
	if(ostatus=="complete" OR ostatus=="rejected")
	{
    fh = fopen( filepath, "w"); //Filepath of csv file with symbols
	if(fh)
    {
		
		fputs(ordno + ",", fh);
		fputs(symbol + ",", fh);
		fputs(ostatus+",", fh);
		fputs(averageprice+",", fh);
		fclose(fh);
		result =1;
    } 
    }
    
    return result; 
}

function placeoptionorder(spot_sym,expiry_dt,strike_int,qty,Ttranstype,opt,off,leg,stoppercent)
{

algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{\"strg_name\":\""+stgy_name+"\",\"spot_sym\":\""+spot_sym+"\",\"expiry_dt\":\""+expiry_dt+"\",\"opt_type\":\""+opt+"\",\"Ttranstype\":\""+Ttranstype+"\",\"prctyp\":\""+prctyp+"\",\"qty\":\""+qty+"\",\"Price\":\""+Price+"\",\"TrigPrice\":\""+TrigPrice+"\",\"Pcode\":\""+Pcode+"\",\"strike_int\":\""+strike_int+"\",\"offset\":\""+off+"\"}";
resp=algomojo.AMDispatcher(user_apikey, api_secret,"PlaceFOOptionsOrder",api_data,broker,ver);
_TRACE("\n"+api_data);
//Get Nest Order Number
nestorderno = getnestorderno(resp);
_TRACE("\nNest Order No : "+nestorderno);

tradetime=GetPerformanceCounter()/1000; 

while ((GetPerformanceCounter()/1000 - tradetime) < timer)
{            

//Get Trading Symbol
Tsym = getsymbol(nestorderno);
}
_TRACE("\nTrading Symbol : "+Tsym);

//Get Order Status
orderstatus = getorderstatus(nestorderno);
_TRACE("\nOrder Status : "+orderstatus);


if(orderstatus=="complete" OR orderstatus=="rejected")
{
averageprice = getaverageprice(nestorderno);
_TRACE("Average Price: "+averageprice);
}

if(orderstatus=="complete") //changed to complete in a live environment and rejected for testing purpose
{
//Stoploss order x% from the average price

slresponse = placestoplossorder(Tsym,"B",averageprice,stoppercent,qty);
_TRACE("Leg "+leg+" Stoploss Response: "+slresponse);
}





//Get Token Number
//token = gettoken(Tsym);
//_TRACE("\nSymbol Token : "+token);
if(opt=="CE")
{
path = fpath+leg+"AlgomojoCE.csv";
}
if(opt=="PE")
{
path = fpath+leg+"AlgomojoPE.csv";
}

writestatus = writetofile(path,nestorderno,Tsym,orderstatus,averageprice);
_TRACEF(WriteIf(writestatus,"\nWriting to File - Success","\nWriting to File - Failure"));
//resp = resp+"\nNest Order No : "+nestorderno+"\nTrading Symbol : "+Tsym+"\nOrder Status : "+orderstatus+"\nSymbol Token : "+token;
return Tsym;

}


function getquantity(Tsym)
{

algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data ="{\"uid\":\""+uid+"\",\"actid\":\""+uid+"\",\"type\":\""+"NET"+"\",\"s_prdt_ali\":\""+s_prdt_ali+"\"}";
resp=algomojo.AMDispatcher(user_apikey, api_secret,"PositionBook",api_data,broker,ver);

//Initialization
flag = 0;
possym = "";
posNetqty =0;


for( item = 0; ( sym = StrExtract( resp, item,'{' )) != ""; item++ )
{

sym = StrTrim(sym," ");
Tsym = StrTrim(Tsym," ");

if(Strfind(sym,Tsym) AND StrFind(sym,Pcode)) //Matches the symbol and //Matches the Order Type
{

flag = 1; //turn on the flag

data = sym;

_TRACE(" Position Book  : " +data);

for( jitem = 0; ( posdetails = StrExtract( data, jitem,',' )) != ""; jitem++ )
{

  if(Strfind(posdetails,"Netqty"))
  {
   posdetails = StrExtract(posdetails,1,':');
   posNetqty = StrToNum(StrTrim(posdetails,"\""));
   _TRACE("\nNetQty : "+posNetqty);
  }
  

} //end of for loop
}

}//end of for loop

if(flag==0)
{
_TRACE("\nTrading Symbol Not Found");
}

return posNetqty;

}


function squareoffoptions(opt,Ttranstype,leg)
{

ttype="";

if(Ttranstype=="B")
{

ttype = "S";

}

if(Ttranstype=="S")
{

ttype = "B";

}


ordno = "";
Symbol = "";
ostatus ="";

	if(opt=="CE")
	{
	fpath = fpath+leg+"AlgomojoCE.csv";
	}
	if(opt=="PE")
	{
	fpath = fpath+leg+"AlgomojoPE.csv";
	}
	
	fh = fopen(fpath, "r"); 
	if(fh)
	{
		
		read = fgets(fh);
		ordno = StrTrim(StrExtract(read,0)," ");
		Symbol = StrTrim(StrExtract(read,1)," ");
		ostatus = StrTrim(StrExtract(read,2)," ");
		averageprice = StrTrim(StrExtract(read,3)," ");
					
		fclose(fh);
	}
	
	exitqty = getquantity(Symbol);
	_TRACE("Net Quantity in the OrderBook for the Symbol : "+Symbol+" is : "+exitqty);
	
	if(ostatus=="complete" AND exitqty!=0)
	{
	algomojo=CreateObject("AMAMIBRIDGE.Main");
	api_data = "{\"strg_name\":\""+stgy_name+"\",\"s_prdt_ali\":\""+s_prdt_ali+"\",\"Tsym\":\""+Symbol+"\",\"exch\":\""+"NFO"+"\",\"Ttranstype\":\""+ttype+"\",\"Ret\":\""+"DAY"+"\",\"prctyp\":\""+prctyp+"\",\"qty\":\""+exitqty+"\",\"discqty\":\""+"0"+"\",\"MktPro\":\""+"NA"+"\",\"Price\":\""+"0"+"\",\"TrigPrice\":\""+"0"+"\",\"Pcode\":\""+Pcode+"\",\"AMO\":\""+"NO"+"\"}";
	resp=algomojo.AMDispatcher(user_apikey, api_secret,"PlaceOrder",api_data,broker,ver);
	//Get Nest Order Number
	nestorderno = getnestorderno(resp);
	_TRACE("\nNest Order No : "+nestorderno);

	tradetime=GetPerformanceCounter()/1000; 

	while ((GetPerformanceCounter()/1000 - tradetime) < timer)
	{            

	//Get Trading Symbol
	Tsym = getsymbol(nestorderno);
	}
	_TRACE("\nTrading Symbol : "+Tsym);

	//Get Order Status
	orderstatus = getorderstatus(nestorderno);
	_TRACE("\nOrder Status : "+orderstatus);
	
	}
	else
	{
	
	resp = "Not Squared Off. Either No Open Position Exist or Prev Signal Status Not in Completed State";
	
	}
	
	return resp;
}
_SECTION_END();

3)Main Option Execution Module

Copy the Main Execution Module to Amibroker\Formulas\Algomojo Platform. Save the AFL under the name Short Straddle - Strangle Execution.afl

Now drag and Drop the Module on top of your Charting with Buy/Sell Trading System

_SECTION_BEGIN("Algomojo - Time Based Short Straddle/Strangle Execution Module with Stoploss");


#include < algomojostraddle.afl >


RequestTimedRefresh(1, False);

function GetSecondNum()
{
    Time = Now( 4 );
    return Time;
}

EntryTime = ParamTime("Execution Time", "09:30:00", 0);
SqOffTime = ParamTime("SquareoffTime", "15:15:00", 0);

spot_sym = ParamStr("spot_sym","NIFTY"); //Enter the symbol name here
strike_int = ParamStr("strike_int","50");
lotsize = Param("Symbol Lot Size",75,1,50000);


leg1expiry_dt = ParamStr("Leg 1 expiry_dt", "28JAN21");
leg1qty = Param("Leg 1 Lot Size",1)*lotsize;
leg1Ttranstype = ParamList("Leg 1 Transaction Type","S");
leg1opt_type = ParamList("Leg 1 Option Type","PE",0);
leg1offset = ParamStr("Leg 1 Offset","0"); 


leg2expiry_dt = ParamStr("Leg 2 expiry_dt", "28JAN21");
leg2qty = Param("Leg 2 Lot Size",1)*lotsize;
leg2Ttranstype = ParamList("Leg 2 Transaction Type","S");
leg2opt_type = ParamList("Leg 2 Option Type","CE",0);
leg2offset = ParamStr("Leg 2 Offset","0"); 

SL = Param("Stop Percentage", 20,1,100,1);



stgy_name = ParamStr("Strategy Name","Test Strategy Chart");
static_name = Name()+GetChartID()+interval(2)+stgy_name;
static_name_algo = Name()+GetChartID()+interval(2)+stgy_name+"algostatus";


tradedelay = Param("Trade Delay",0);
EnableAlgo = ParamList("Algo Mode","Disable|Enable",0); // Algo Mode


static_name_ = Name()+GetChartID()+interval(2)+stgy_name;

//StaticVarSet(static_name_algo, -1); 
GfxSelectFont( "BOOK ANTIQUA", 14, 100 );
GfxSetBkMode( 1 );
if(EnableAlgo == "Enable")
{
AlgoStatus = "Algo Enabled";
GfxSetTextColor( colorGreen ); 
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40); 
if(Nz(StaticVarGet(static_name_algo),0)!=1)
{
_TRACE("Algo Status : Enabled");
StaticVarSet(static_name_algo, 1);
}
}
if(EnableAlgo == "Disable")
{
AlgoStatus = "Algo Disabled";
GfxSetTextColor( colorRed ); 
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40); 
if(Nz(StaticVarGet(static_name_algo),0)!=0)
{
_TRACE("Algo Status : Disabled");
StaticVarSet(static_name_algo, 0);
}
}
if(EnableAlgo == "LongOnly")
{
AlgoStatus = "Long Only";
GfxSetTextColor( colorYellow ); 
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40); 
if(Nz(StaticVarGet(static_name_algo),0)!=2)
{
_TRACE("Algo Status : Long Only");
StaticVarSet(static_name_algo, 2);
}
}
if(EnableAlgo == "ShortOnly")
{
AlgoStatus = "Short Only";
GfxSetTextColor( colorYellow ); 
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40); 
if(Nz(StaticVarGet(static_name_algo),0)!=3)
{
_TRACE("Algo Status : Short Only");
StaticVarSet(static_name_algo, 3);
}
}



resp = "";


if(EnableAlgo == "Enable")
{
SetChartBkColor(colorDarkGrey);
if(GetsecondNum() == EntryTime AND StaticVarGet(static_name + EntryTime) == 0)
{
	//Entry Short Straddle/Strangle at the Entry Time
    StaticVarSet(static_name + EntryTime, 1);
    leg1response = placeoptionorder(spot_sym,leg1expiry_dt,strike_int,leg1qty,leg1Ttranstype,leg1opt_type,leg1offset,1,SL);
    _TRACE("Leg 1 Short Order Placed Successfully");
    leg2response = placeoptionorder(spot_sym,leg2expiry_dt,strike_int,leg2qty,leg2Ttranstype,leg2opt_type,leg2offset,2,SL);
    _TRACE("Leg 2 Short Order Placed Successfully");
    
}
else if(GetsecondNum() != EntryTime)
{
     StaticVarSet(static_name + EntryTime, 0);
}


if(GetsecondNum() == SqOffTime AND StaticVarGet(static_name + SqOffTime) == 0)
{

	//Exit Short Straddle / Short Strangle
    StaticVarSet(static_name + SqOffTime, 1);
    sqoff1status = squareoffoptions(leg1opt_type,leg1Ttranstype,1);
	_TRACE("Leg 1 Exit Response :"+sqoff1status);
	
	sqoff2status = squareoffoptions(leg2opt_type,leg2Ttranstype,2);
	_TRACE("Leg 2 Exit Response :"+sqoff2status);
    
}
else if(GetsecondNum() != SqOffTime)
{
     StaticVarSet(static_name + SqOffTime, 0);
}


}

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

4)Now right-click over the charts and set the Client ID, user_apikey, api_secretkey,broker and set the required quantity

5)Ensure the Symbol File Path Exists. This is the path where the executed symbols CE and PE Options will get saved in a CSV file for later squareoff.

Ensure while entering the Option Expiry Format. Login to Algomojo Terminal and check out the weekly and monthly option format and enter the expiry date accordingly.

For Aliceblue account holders Monthly Option Symbol Format: NIFTY21JAN14500CE

Hence the Expiry Date needs to be entered as 21JAN

For Aliceblue Account holders weekly Option Symbol Format: NIFTY2111414500CE

Hence the Expiry Date needs to be entered as 21114

For Tradejini and Zebu Account Holders Monthly Option Symbol Format: NIFTY28JAN2114500CE

Hence the Expiry Date needs to be entered as 28JAN21

For Tradejini and Zebu Account Holders Monthly Option Symbol Format: NIFTY14JAN2114500CE

Hence the Expiry Date needs to be entered as 14JAN21

1AlgomojoCE.csv and 1AlgomojoPE.csv and 2AlgomojoCE.csv and 2AlgomojoPE.csv will be saved whenever the straddle or strangle are executed and files will be saved only if the execution status is in complete or in rejected mode

7)Ensure Log Window is open to capture the Trace Logs

8)Bingo Now you have setup the complete end to end automated straddle/strangle execution. Straddle/Strangle Control can be controlled via offset parameters.

9)Code is designed such a way that stoploss is placed for individual price legs and not for the combined premium of Straddle/Strangle Spreads

10)Make the Algo Enable and send time based straddle execution (Supports both entry and exit conditions).

Rajandran R Founder of Marketcalls and Co-Founder Algomojo. Full-Time Derivative Trader. Expert in Designing Trading Systems (Amibroker, Ninjatrader, Metatrader, Python, Pinescript). Trading the markets since 2006. Mentoring Traders on Trading System Designing, Market Profile, Orderflow and Trade Automation.

Multi Broker – Multi Client Algomojo Trading – Amibroker…

Here are simple Amibroker AFL - Button-based Trading modules which help traders to route their orders to different brokers simultaneously. Here is the prototype...
Rajandran R
4 min read

Single Broker Multi-Client Amibroker Trading Module

Got frequent requirements from many traders to automate Amibroker based trading system where one single generation from charts could punch orders in multiple accounts...
Rajandran R
5 min read

How to Calculate the Order Execution Response time using…

To send automated orders using Amibroker usually one uses the API-based trading solutions. API works on the concept of request and response. Every Place...
Rajandran R
2 min read

2 Replies to “Algomojo Index Straddle/Strangle Execution Module with Intraday Stoploss”

  1. How to keep a stop loss for say 10% SL of combined premium, and it should trial SL for every 10% fall in premium

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More