This tutorial focus on how to automate your time-based index straddle/strangle management with intraday stop-loss levels with time-based entry and exits using Algomojo Platform and Amibroker. Modern Internal memory management is used to speed up the execution and management of Index Straddle.

Trading Activity | Orders to be Placed |
Time Based Entry | Enter Straddle/Strangle at 9.30a.m (Two legged Order) |
Calculate the Short Call Average Price | Calculate the Short call Stoploss |
Calculate the Short Put Average Price | Calculate the Short Put Stoploss |
Place Stoploss Orders | Place the Stoploss for both Short call and Short Put if the entry order status is completed |
Check Open Positions | Check the Open Positions for the Qty traded |
Time Based Exit | Square of Short Call and Short Put legs for the qty present in the open positions around 3.15p.m. |
Supported Brokers : Upstox
Supported Algo Platform: Algomojo Platform
Supported Amibroker Version: Amibroker 6.0 or Higher
Supported Trading Instruments: Index Options
Intraday Straddle Management – Amibroker AFL Code
_SECTION_BEGIN("Upstox - Broker Controls");
//Static Variables will be saved in Amibroker every 30 seconds once
SetOption("StaticVarAutoSave",60);
// Send orders even if Amibroker is minimized or Chart is not active
RequestTimedRefresh(1, False);
EnableTextOutput(False);
//Creating Input Controls for Setting Order Related Information
broker = ParamStr("Broker","up");
ver = ParamStr("API Version","1.0");
client_id = ParamStr("Client ID","xxxxxxx");
apikey = ParamStr("APIKey","xxxxxx");
apisecret = ParamStr("APIsecret","xxxxxxx");
_SECTION_END();
_SECTION_BEGIN("Upstox - Order Controls");
stgy_name = ParamStr("Strategy Name","Intraday Short Straddle");
entrytime = ParamTime("Entry Time","09:20:00");
exittime = ParamTime("Exit Time","15:15:00");
stopsenabled = ParamToggle("Stoploss Controls","Enable|Disable",0);
stoppercentage = Param("Stoploss Percentage",30,10,100,1);
stoplossslippagebuffer = Param("Stoploss Slippage Buffer",2,0.25,100,0.25);
spot_sym = ParamList("Spot Symbol","NIFTY|BANKNIFTY");
expiry_date = ParamStr("Expiry Date","22421");
transtype = Paramlist("Options Transaction Type","S",0);
exchange = "NSE_FO";
duration = "DAY";
MktPro = "NA";
price = "0";
disclosed_quantity = "0";
trigger_price = "0";
is_amo = "NO";
if(spot_sym == "NIFTY")
{
lotsize = 50;
strike_interval = 50;
}
if(spot_sym == "BANKNIFTY")
{
lotsize = 25;
strike_interval = 100;
}
quantity = Param("Quantity(Lots)",1,1,10000,1)*lotsize;
order_type = "MKT";
productType = ParamList("Product Type","MIS|NRML",0); //MIS - Intraday, NRML - Carryforward
price = "0";
trigger_price = "0";
if(productType=="MIS")
{
product = "I";
}
if(productType=="CNC" OR productType=="NRML")
{
product = "D";
}
// Offset = 0 -> ATM, Offset = +ve number -> OTM, Offset = -ve -> ITM
OffsetCE = Param("CE Offset",0,-20,20,1);
OffsetPE = Param("PE Offset",0,-20,20,1);
Entrydelay = Param("Entry Delay",0,0,1); // 0 - Execution with No Delay after a signal, 1- Execution at the end of the candle
Exitdelay = Param("Exit Delay",0,0,1);
EnableAlgo = ParamList("Algo Mode","Disable|Enable|LongOnly|ShortOnly",0); // Algo Mode
clear = ParamTrigger("Clear Static Variables","Clear");
static_var_options = "staticvar_options"+Name()+Interval(2)+GetChartID() + stgy_name;
if(clear)
{
StaticVarRemove("staticvar_options*");
_TRACE("Static Variables Cleared");
}
function removeinteralmemory(typeoforder,opt_type,legno)
{
StaticVarRemove(static_var_options+typeoforder+"Options_Trans"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_OrderNo"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_Symbol"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_OrderStatus"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_NetQty"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_AveragePrice"+opt_type+legno);
StaticVarRemove(static_var_options+typeoforder+"Options_ExecutionTime"+opt_type+legno);
}
//Internal Memory
opt_type="CE";
legno = 1;
printf("\n---------------Leg 1 CE Orders (Main) Internal Memory----------");
printf("\nOrderType : "+StaticVarGetText(static_var_options+"Options_Trans"+opt_type+legno));
printf("\nOrderNo : "+StaticVarGetText(static_var_options+"Options_OrderNo"+opt_type+legno));
printf("\nSymbol : "+StaticVarGetText(static_var_options+"Options_Symbol"+opt_type+legno));
printf("\nStatus : "+StaticVarGetText(static_var_options+"Options_OrderStatus"+opt_type+legno));
printf("\nNetQty : "+StaticVarGetText(static_var_options+"Options_NetQty"+opt_type+legno));
printf("\nAveragePrice : "+StaticVarGetText(static_var_options+"Options_AveragePrice"+opt_type+legno));
printf("\nExecutionTime : "+StaticVarGetText(static_var_options+"Options_ExecutionTime"+opt_type+legno));
opt_type="CE";
legno = 1;
printf("\n---------------Leg 1 CE Orders (Stoploss) Internal Memory----------");
printf("\nOrderType : "+StaticVarGetText(static_var_options+"SLOptions_Trans"+opt_type+legno));
printf("\nOrderNo : "+StaticVarGetText(static_var_options+"SLOptions_OrderNo"+opt_type+legno));
printf("\nSymbol : "+StaticVarGetText(static_var_options+"SLOptions_Symbol"+opt_type+legno));
printf("\nStatus : "+StaticVarGetText(static_var_options+"SLOptions_OrderStatus"+opt_type+legno));
opt_type="PE";
legno = 2;
printf("\n---------------Leg 2 PE Orders Internal Memory----------");
printf("\nOrderType : "+StaticVarGetText(static_var_options+"Options_Trans"+opt_type+legno));
printf("\nOrderNo : "+StaticVarGetText(static_var_options+"Options_OrderNo"+opt_type+legno));
printf("\nSymbol : "+StaticVarGetText(static_var_options+"Options_Symbol"+opt_type+legno));
printf("\nStatus : "+StaticVarGetText(static_var_options+"Options_OrderStatus"+opt_type+legno));
printf("\nNetQty : "+StaticVarGetText(static_var_options+"Options_NetQty"+opt_type+legno));
printf("\nAveragePrice : "+StaticVarGetText(static_var_options+"Options_AveragePrice"+opt_type+legno));
printf("\nExecutionTime : "+StaticVarGetText(static_var_options+"Options_ExecutionTime"+opt_type+legno));
opt_type="PE";
legno = 2;
printf("\n---------------Leg 2 PE Orders (Stoploss) Internal Memory----------");
printf("\nOrderType : "+StaticVarGetText(static_var_options+"SLOptions_Trans"+opt_type+legno));
printf("\nOrderNo : "+StaticVarGetText(static_var_options+"SLOptions_OrderNo"+opt_type+legno));
printf("\nSymbol : "+StaticVarGetText(static_var_options+"SLOptions_Symbol"+opt_type+legno));
printf("\nStatus : "+StaticVarGetText(static_var_options+"SLOptions_OrderStatus"+opt_type+legno));
function GetSecondNum()
{
Time = Now(4);
return Time;
}
function PlaceOrder(EntrySymbol,TransType,order_type,LimitPrice,stoplevel)
{
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
//Preparing the API data
api_data = "{
\"stgy_name\": \""+stgy_name+"\",
\"symbol\":\""+EntrySymbol+"\",
\"exchange\":\""+exchange+"\",
\"transaction_type\":\""+TransType+"\",
\"duration\":\""+duration+"\",
\"order_type\":\""+order_type+"\",
\"quantity\":\""+quantity+"\",
\"disclosed_quantity\":\""+disclosed_quantity+"\",
\"MktPro\":\""+MktPro+"\",
\"price\":\""+LimitPrice+"\",
\"trigger_price\":\""+stoplevel+"\",
\"product\":\""+productType+"\",
\"is_amo\":\""+is_amo+"\"
}";
_TRACE("Broker API Request"+api_data);
resp=algomojo.AMDispatcher(apikey, apisecret,"PlaceOrder",api_data,broker,ver);
_TRACE("API Response : "+resp);
_TRACE("Strategy Name : "+stgy_name+" AlgoStatus : "+ EnableAlgo);
_TRACE("Chart Symbol : "+ Name() +" Trading Symbol : "+ EntrySymbol +"Trading Interval : "+Interval(2)+" Chard Id : "+ GetChartID());
Say( "Order Placed" );
return resp;
}
function GetOrderNo(resp)
{
OrderNo = "";
sym = StrExtract( resp, 2,'{' );
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(StrFind(posdetails,"order_id") AND !StrFind(posdetails,"exchange_order_id")
AND !StrFind(posdetails,"parent_order_id"))
{
OrderNo = StrExtract(posdetails,1,':');
OrderNo = StrTrim(OrderNo,"\""); //Trim if any extra white space
_TRACE("\nOrderNo : "+OrderNo);
}
} //end of for loop
return OrderNo;
}
function GetSymbol(resp)
{
Symbol = "";
OrderNo = "";
sym = StrExtract( resp, 2,'{' );
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(StrFind(posdetails,"symbol") AND !StrFind(posdetails,"trading_symbol"))
{
Symbol = StrExtract(posdetails,1,':');
Symbol = StrTrim(Symbol,"\""); //Trim if any extra white space
_TRACE("\nSymbol : "+Symbol);
}
}
return Symbol;
}
function GetOrderHistory(OrderNo)
{
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{
\"order_id\": \""+OrderNo+"\"
}";
_TRACE("OrderHistory API Request"+api_data);
//Sending The Broker Request for NetOpenPositions
resp=algomojo.AMDispatcher(apikey, apisecret,"OrderHistory",api_data,broker,ver);
_TRACE("OrderHistory API Response : "+resp);
return resp;
}
function GetOrderStatus(OrderNo) //OrderHistory for OrderStatus
{
OrderStatus = "";
resp = GetOrderHistory(OrderNo);
sym = StrExtract( resp, 2,'{' );
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(StrFind(posdetails,"status"))
{
OrderStatus = StrExtract(posdetails,1,':');
OrderStatus = StrTrim(OrderStatus,"\""); //Trim if any extra white space
_TRACE("\nOrderStatus : "+OrderStatus);
}
}
return OrderStatus;
}
function GetPositionsBook()
{
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{ }";
_TRACE("PositionBook API Request"+api_data);
//Sending The Broker Request for NetOpenPositions
resp=algomojo.AMDispatcher(apikey, apisecret,"Positions",api_data,broker,ver);
_TRACE("PositionBook API Response : "+resp);
return resp;
}
function NetOpenPos(Symbol)
{
flag = 0;
resp = GetPositionsBook();
posNetqty ="0";
productmsg="";
for( item = 1; ( sym = StrExtract( resp, item,'{' )) != ""; item++ )
{
if(Strfind(sym,Symbol) AND StrFind(sym,product)) //Matches the symbol and //Matches the Order Type
{
flag = 1; //turn on the flag
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(Strfind(posdetails,"product"))
{
productmsg = StrExtract(posdetails,1,':');
productmsg = StrTrim(productmsg,"\""); //Trim if any extra white space
}
if(productmsg == product AND Strfind(posdetails,"net_quantity"))
{
posNetqty = StrExtract(posdetails,1,':');
posNetqty = StrTrim(posNetqty,"\""); //Trim if any extra white space
_TRACE("\nNetqty : "+posNetqty);
}
} //end of for loop
}
}//end of for loop
if(flag==0)
{
_TRACE("\nTrading Symbol Not Found");
//posNetqty =0;
_TRACE("\nNetQty : "+posNetqty);
}
return posNetqty;
}
function GetExecTime(Symbol)
{
flag = 0;
resp = GetPositionsBook();
ExecTime = "Not Executed";
productmsg="";
for( item = 1; ( sym = StrExtract( resp, item,'{' )) != ""; item++ )
{
if(Strfind(sym,Symbol) AND StrFind(sym,product)) //Matches the symbol and //Matches the Order Type
{
flag = 1; //turn on the flag
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(Strfind(posdetails,"product"))
{
productmsg = StrExtract(posdetails,1,':');
productmsg = StrTrim(productmsg,"\""); //Trim if any extra white space
}
if(productmsg == product AND Strfind(posdetails,"exchange_time"))
{
exchange_time = StrExtract(posdetails,1,':');
exchange_time = StrTrim(exchange_time,"\""); //Trim if any extra white space
_TRACE("\nexchange_time : "+exchange_time);
}
} //end of for loop
}
}//end of for loop
if(flag==0)
{
_TRACE("\nTrading Execution Time Not Available and Trading Symbol Not Found");
}
return ExecTime;
}
function GetAveragePrice(OrderNo) //OrderHistory for OrderStatus
{
AveragePrice = "";
resp = GetOrderHistory(OrderNo);
sym = StrExtract( resp, 2,'{' );
for( jitem = 0; ( posdetails = StrExtract( sym, jitem,',' )) != ""; jitem++ )
{
if(StrFind(posdetails,"average_price"))
{
AveragePrice = StrExtract(posdetails,1,':');
AveragePrice = StrTrim(AveragePrice,"\""); //Trim if any extra white space
_TRACE("\nAverage Price : "+AveragePrice);
}
}
return AveragePrice;
}
function PlaceSLOptionsOrder(EntrySymbol, opt_type,legno,AveragePrice)
{
_TRACE("Place Stoploss Order");
if(stopsenabled)
{
//stoploss computation and stoploss order placement logic,
//stoploss computation
stoplevel = StrToNum(AveragePrice) * (1+ stoppercentage/100);
//round off to the nearest ticksize
TickSz = 0.05;
stoplevel = TickSz * round( stoplevel / TickSz );
LimitPrice = stoplevel + stoplossslippagebuffer; //slippage is restricted to 2 points (Slippage Buffer)
resp = PlaceOrder(EntrySymbol,"B","SL",LimitPrice,stoplevel);
Trans = "B";
StaticVarSetText(static_var_options+"SLOptions_Trans"+opt_type+legno,Trans,True);
OrderNo = GetOrderNo(resp);
StaticVarSetText(static_var_options+"SLOptions_OrderNo"+opt_type+legno,OrderNo,True);
Symbol = GetSymbol(resp);
StaticVarSetText(static_var_options+"SLOptions_Symbol"+opt_type+legno,Symbol,True);
Orderstatus = GetOrderStatus(OrderNo); //Get the Orderstatus from OrderHistory
StaticVarSetText(static_var_options+"SLOptions_OrderStatus"+opt_type+legno,Orderstatus,True);
}
return 0;
}
function PlaceOptionsOrder(spot_sym,expiry_date,strike_int,TransType, opt_type, offset,legno)
{
if(opt_type=="PE")
{
offset = -offset; //changing the polarity
}
//create the Trading Bridge
algomojo = CreateObject("AMAMIBRIDGE.Main"); //calling the bridge dll
//Prepart the API data
api_data = "{
\"stgy_name\":\""+stgy_name+"\",
\"spot_sym\":\""+spot_sym+"\",
\"expiry_dt\":\""+expiry_date+"\",
\"opt_type\":\""+opt_type+"\",
\"transaction_type\":\""+TransType+"\",
\"order_type\":\""+order_type+"\",
\"quantity\":\""+quantity+"\",
\"price\":\"0\",
\"trigger_price\":\"0\",
\"product\":\""+productType+"\",
\"strike_int\":\""+strike_int+"\",
\"offset\":\""+offset+"\"
}";
_TRACE("Broker API Request"+api_data);
resp = algomojo.AMDispatcher(apikey,apisecret,"PlaceFOOptionsOrder",api_data,broker,ver);
_TRACE("Broker API Respone"+resp);
//Store the Transaction Type, OrderNo,Trading Symbol,OrderStatus,Netqty
Trans = TransType;
StaticVarSetText(static_var_options+"Options_Trans"+opt_type+legno,Trans,True);
OrderNo = GetOrderNo(resp);
StaticVarSetText(static_var_options+"Options_OrderNo"+opt_type+legno,OrderNo,True);
Symbol = GetSymbol(resp);
StaticVarSetText(static_var_options+"Options_Symbol"+opt_type+legno,Symbol,True);
Orderstatus = GetOrderStatus(OrderNo); //Get the Orderstatus from OrderHistory
StaticVarSetText(static_var_options+"Options_OrderStatus"+opt_type+legno,Orderstatus,True);
NetQty = NetOpenPos(Symbol); //Get the Netqty from the Positions Book
StaticVarSetText(static_var_options+"Options_NetQty"+opt_type+legno,NetQty,True);
AveragePrice = GetAveragePrice(OrderNo);
StaticVarSetText(static_var_options+"Options_AveragePrice"+opt_type+legno,AveragePrice,True);
ExecutionTime = GetExecTime(Symbol); //Get the Execution Time from OrderHistory
StaticVarSetText(static_var_options+"Options_ExecutionTime"+opt_type+legno,ExecutionTime,True);
//follow thro stoploss order
//Testing Purpose
//PlaceSLOptionsOrder(Symbol, opt_type,legno,"100");
//Live Trading Purpose
PlaceSLOptionsOrder(Symbol, opt_type,legno,AveragePrice);
}
function cancelorder(OrderNo)
{
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
api_data = "{
\"order_id\": \""+OrderNo+"\"
}";
_TRACE("Cancel API Request"+api_data);
//Sending The Broker Request for NetOpenPositions
resp=algomojo.AMDispatcher(apikey, apisecret,"CancelOrder",api_data,broker,ver);
_TRACE("Cancel API Response : "+resp);
}
function cancelSLorders()
{
opt_type = "CE";
legno = 1;
CEorderid = StaticVarGetText(static_var_options+"SLOptions_OrderNo"+opt_type+legno);
cancelorder(CEorderid);
removeinteralmemory("SL",opt_type,legno);
opt_type = "PE";
legno = 2;
PEorderid = StaticVarGetText(static_var_options+"SLOptions_OrderNo"+opt_type+legno);
cancelorder(PEorderid);
removeinteralmemory("SL",opt_type,legno);
}
function SquareOffPosition(opt_type,legno)
{
resp ="";
TType = "";
ExitSymbol = StaticVarGetText(static_var_options+"Options_Symbol"+opt_type+legno);
Netqty = StrToNum(NetOpenPos(ExitSymbol));
if(StaticVarGetText(static_var_options+"Options_Trans"+opt_type+legno)=="B")
{
TType = "S";
}
if(StaticVarGetText(static_var_options+"Options_Trans"+opt_type+legno)=="S")
{
TType = "B";
}
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
//Preparing the API data
api_data = "{
\"stgy_name\": \""+stgy_name+"\",
\"symbol\":\""+ExitSymbol+"\",
\"exchange\":\""+exchange+"\",
\"transaction_type\":\""+TType+"\",
\"duration\":\""+duration+"\",
\"order_type\":\""+order_type+"\",
\"quantity\":\""+Netqty+"\",
\"disclosed_quantity\":\""+disclosed_quantity+"\",
\"MktPro\":\""+MktPro+"\",
\"price\":\""+price+"\",
\"trigger_price\":\""+trigger_price+"\",
\"product\":\""+productType+"\",
\"is_amo\":\""+is_amo+"\"
}";
_TRACE("Squareoff API Request"+api_data);
//Testing
//if(Netqty==0 AND ExitSymbol!="")
//Live Trading Purpose
if(Netqty!=0 AND ExitSymbol!="")
{
resp=algomojo.AMDispatcher(apikey, apisecret,"PlaceOrder",api_data,broker,ver);
removeinteralmemory("",opt_type,legno);
}
if(resp!="")
{
_TRACE("Squareoff API Response : "+resp);
}
else
{
_TRACE("Squareoff Order Not Triggered");
}
return resp;
}
//straddletrigger = ParamTrigger("Straddle Entry Trigger","Place Straddle Options");
//exittrigger = ParamTrigger("Straddle Exit Trigger","Exit Straddle");
//if(straddletrigger)
//{
//PlaceOptionsOrder(spot_sym,expiry_date,strike_interval,TransType, "CE", offsetCE,1);
//PlaceOptionsOrder(spot_sym,expiry_date,strike_interval,TransType, "PE", offsetPE,2);
//}
//if(exittrigger)
//{
//cancelSLorders();
//SquareOffPosition("CE",1);
//SquareOffPosition("PE",2);
//}
if(EnableAlgo != "Disable")
{
//if the time set as per the parameter control is reached
if(GetSecondNum() == entrytime AND StaticVarGet(static_var_options + entrytime) == 0)
{
//send the straddle orders
StaticVarSet(static_var_options + entrytime,1);
PlaceOptionsOrder(spot_sym,expiry_date,strike_interval,TransType, "CE", offsetCE,1);
PlaceOptionsOrder(spot_sym,expiry_date,strike_interval,TransType, "PE", offsetPE,2);
}
//reset the static variable if the otime is not matching
else if(GetSecondNum() != entrytime)
{
StaticVarSet(static_var_options + entrytime,0);
}
//if the time set as per the parameter control is reached
if(GetSecondNum() == exittime AND StaticVarGet(static_var_options + exittime) == 0)
{
//send the straddle orders
StaticVarSet(static_var_options + exittime,1);
cancelSLorders();
SquareOffPosition("CE",1);
SquareOffPosition("PE",2);
}
//reset the static variable if the otime is not matching
else if(GetSecondNum() != exittime)
{
StaticVarSet(static_var_options + exittime,0);
}
}//end of Main if loop
SetChartOptions(0, chartShowArrows | chartShowDates); //x-Axis will be plottted
//plot the candles
Plot(Close,"Close",colorDefault,GetPriceStyle() | styleNoTitle);
How to Setup Intraday Straddle Module?
1)Apply the AFL Code with proper Algomojo API Key and API secret key and Stoploss controls , Set the Entry and Exit time

2)Press Clear Static Variables to clear the temporary memory
3)Temporary Multi Legged Memory Management can be seen at Amibroker -> Window -> Interpretation Box as shown below

Expiry Symbol Format
For Aliceblue Account holders weekly Option Symbol Format: NIFTY2242117200CE
Hence the Expiry Date needs to be entered as 22421
Upstox - Symbol Format4)Ensure Log Window is open to capture the Trace Logs
5)Bingo Now you have setup the complete end to end automated straddle/strangle execution. Straddle/Strangle Control can be controlled via offset parameters.
6)Code is designed such a way that stoploss is placed for individual price legs and not for the combined premium of Straddle/Strangle Spreads
7)Make the Algo Enable and send time based straddle execution (Supports both entry and exit conditions).