Sending Option Orders and Exiting Option Orders in Algomojo Platform using Amibroker

This tutorial helps you to understand the options trading module and the requirements to set up and send and exit option orders from Amibroker in a systematic way. This coding framework provides the basic foundation to entry and exit option order from Amibroker for Algomojo Trading Platform

Understanding PlaceFOOptionsOrder API

PlaceFOOptionsOrder api is used to send ATM, ITM, OTM Options Order. Currently PlaceFOOptionsOrder is supported by brokers like Aliceblue,Tradejini,Zebu & Enrich.

Here is the sample request and response for PlaceFOOptionsOrder

For detailed information on Algomojo API’s visit the API Documentation section

Request example :

{
    "api_key":"c1997d92a3bb556a67dca7d1446b70",
    "api_secret":"5306433329e81ba41203653417063c",
    "data":
      {
        "strg_name":"Test Strategy",
        "s_prdt_ali":"BO:BO||CNC:CNC||CO:CO||MIS:MIS||NRML:NRML",
        "Tsym":"NIFTY07JAN2114000CE",
        "exch":"NFO",
        "Ttranstype":"B",
        "Ret":"DAY",
        "prctyp":"MKT",
        "qty":"75",
        "discqty":"0",
        "MktPro":"NA",
        "Price":"0",
        "TrigPrice":"0",
        "Pcode":"NRML",
        "AMO":"NO"
      }
}

Response example :

{
    "NOrdNo": "200810000277991",
    "stat": "Ok"
}

Option Offset Control

one can use the offset to select the ATM, ITM,OTM Options.

In order to make the execution logic smoother and smarter following Execution Logic is preferred for Option Order Entry and Exit. One can modify the Execution Logic to their comfort. The below logic is just a prototype.

Execution Logic is coded only for

1) Long Call Option Entry,
2) Long Put Option Entry
3) Exit Long Call Option (Square off Based on the Qty from Position Book)
4) Exit Long Put Option (Square off Based on the Qty from Position Book)

Execution Logic for Placing Options Order

Execution Logic for Exiting Options Order

Setting up the Options Test Execution AFL File

1)Copy the AFL under the name Algomojo Options Test Module.afl and keep it under Amibroker\Formulas\Algomojo folder

#include < algomojooptions.afl >


_SECTION_BEGIN("Algomojo Options Test Module");

trigger = ParamTrigger("Place Option Order","PRESS");
longcall = ParamTrigger("Place Long Call Order","PRESS");
longput = ParamTrigger("Place Long Put Order","PRESS");
exitcall = ParamTrigger("Exit Call","PRESS");
exitput = ParamTrigger("Exit Put","PRESS");

spot_sym = ParamStr("spot_sym","NIFTY"); //Enter the symbol name here
expiry_dt = ParamStr("expiry_dt", "28JAN21");
strike_int = ParamStr("strike_int","50");
Ttranstype = ParamList("Transaction Type","B|S");
opt_type = ParamList("opt_type","CE|PE",0);
offset = ParamStr("Offset","0"); //No. of strikes away from ATM Strike
EnableAlgo = ParamList("Algo Mode","Disable|Enable",0); // Algo Mode

static_name_ = Name()+GetChartID()+interval(2)+stgy_name;
static_name_algo = Name()+GetChartID()+interval(2)+stgy_name+"algostatus";
//StaticVarSet(static_name_algo, -1); 
GfxSelectFont( "BOOK ANTIQUA", 14, 100 );
GfxSetBkMode( 1 );
if(EnableAlgo == "Enable")
{
SetChartBkColor(ColorBlend(colorGrey40,colorBlack));
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 == "Enable"){

if (trigger) 
{
//Place Options Order
orderresponse = placeoptionorder(spot_sym,expiry_dt,strike_int,Ttranstype,opt_type,offset);
_TRACEF("\nExecuted Symbol :"+orderresponse);
}


if (longcall) 
{
//Place Options Order
orderresponse = placeoptionorder(spot_sym,expiry_dt,strike_int,"B","CE",offset);
_TRACEF("\nExecuted Symbol :"+orderresponse);
}


if (longput) 
{
//Place Options Order
orderresponse = placeoptionorder(spot_sym,expiry_dt,strike_int,"B","PE",offset);
_TRACEF("\nExecuted Symbol :"+orderresponse);
}

if (Exitcall) 
{
//Place Options Order
sqoffstatus = squareoffoptions("CE");
_TRACEF("\nExit Call Response :"+sqoffstatus);
}


if (ExitPut) 
{
sqoffstatus = squareoffoptions("PE");
_TRACEF("\nExit Put Response :"+sqoffstatus);
}

}


_SECTION_END();


_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();

2)Copy the AFL under the name algomojooptions.afl under the path Amibroker\formulas\include folder

//////////////////////////////////////////////
//Multi Broker Amibroker Option Execution Module
//Coded by Algomojo
//Date : 30/12/2020
//////////////////////////////////////////////



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


_SECTION_BEGIN("Algomojo 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");
qty = Param("Quatity",75,0,100000,1); 
stgy_name = ParamStr("Strategy Name", "Options");
broker = ParamStr("Broker","tj"); //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 = 3; //3 seconds for providing delay after placing order

RequestTimedRefresh(1,False);


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 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)
{
    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);
		fclose(fh);
		result =1;
    } 
    }
    
    return result; 
}

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

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);

//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);
//Get Token Number
//token = gettoken(Tsym);
//_TRACE("\nSymbol Token : "+token);
if(opt=="CE")
{
path = fpath+"AlgomojoCE.csv";
}
if(opt=="PE")
{
path = fpath+"AlgomojoPE.csv";
}

writestatus = writetofile(path,nestorderno,Tsym,orderstatus);
_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\":\""+"DAY"+"\",\"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)
{

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

	if(opt=="CE")
	{
	fpath = fpath+"AlgomojoCE.csv";
	}
	if(opt=="PE")
	{
	fpath = fpath+"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)," ");
					
		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\":\""+"S"+"\",\"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. Prev Signal Status Not in Completed State";
	
	}
	
	return resp;
}
_SECTION_END();

3)Apply the Algomojo Options Test Module.afl on the Charts

4)Now right click over the charts and set the Client ID, user_apikey, api_secretkey 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.

AlgomojoCE.csv and AlgomojoPE.csv will be saved separately only if the execution status is in complete mode. If the order is rejected then the file will not be saved with an executed symbol.

6)Enable the Algo Mode

Aliceblue Monthly Option Expiry Settings

Aliceblue Weekly Option Expiry Settings

And If in case you are using Aliceblue Weekly Options then you have to use YYMDD format

Now you can send Long Call and Long Put Orders from the press of the button from the properties box and also exit the positions by pressing the Exit Call and Exit Put Buttons which will eventually squareoff the positions based on current open positions.

Leave a Comment

Your email address will not be published. Required fields are marked *