StocksDeveloper_AutoTraderWeb
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pritesh-StocksDeveloper

//@version=5

library("StocksDeveloper_AutoTraderWeb")

// IST timezone constant
IST = "Asia/Kolkata"

// @function Returns current time (HH:mm:ss) in Indian timezone
// @returns current time (HH:mm:ss) in Indian timezone
export timeIST() =>
    tm = timenow
    formatted = str.tostring(hour(tm, IST), "00:") + 
     str.tostring(minute(tm, IST), "00:") + 
     str.tostring(second(tm, IST), "00")
    formatted

// @function Additional properties like ticker, price, time etc.
// @param comments Comments
// @returns additional properties like ticker, time etc.
export prepareAdditionalProperties(string comments = "") =>
    ticker = '"ticker": "' + syminfo.ticker + '",'
    price = '"price": "' + str.tostring(close) + '",'
    tm = '"time": "' + timeIST() + '",'
    cm = '"comments": "' + comments + '"'
    ticker + price + tm + cm

// @function Prepare a place order json
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param tradeType Trade type [BUY, SELL]
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param quantity Quantity (Default: 1)
// @param price Price (Default: 0)
// @param orderType Order type [MARKET, LIMIT, STOP_LOSS, SL_MARKET] (Default: MARKET)
// @param productType Product type [INTRADAY, DELIVERY, NORMAL] (Default: INTRADAY)
// @param triggerPrice Trigger price (Default: 0)
// @param variety Variety [REGULAR, BO, CO] (Default: REGULAR)
// @param validity Validity [DAY, IOC] (Default: DAY)
// @param disclosedQuantity Disclosed quantity (Default: 0)
// @param target Target (for Bracket order only) (Default: 0)
// @param stoploss Stoploss (for Bracket order only) (Default: 0)
// @param trailingStoploss (for Bracket order only) Trailing Stoploss (Default: 0)
// @param amo Set it to true for AMO (After Market Order) (Default: false)
// @returns A json message for the given order data
export preparePlaceOrderJson(string account, string symbol, string tradeType, 
     bool group = false, string exchange = "NSE", int quantity = 1,
	 float price = 0, string orderType = "MARKET", 
	 string productType = "INTRADAY", float triggerPrice = 0, 
	 string variety = "REGULAR", string validity = "DAY", 
	 int disclosedQuantity = 0, float target = 0, float stoploss = 0, 
	 float trailingStoploss = 0, bool amo = false) =>
    acc = '"account": "' + account + '",'
    grp = '"group": ' + str.tostring(group) + ','
    vart = '"variety": "' + variety + '",'
    vald = '"validity": "' + validity + '",'
    ex = '"exchange": "' + exchange + '",'
    syb = '"symbol": "' + symbol + '",'
    tt = '"tradeType": "' + tradeType + '",'
    ot = '"orderType": "' + orderType + '",'
    pt = '"productType": "' + productType + '",'
    qty = '"quantity": ' + str.tostring(quantity) + ','
    dqty = '"disclosedQuantity": ' + str.tostring(disclosedQuantity) + ','
    prc = '"price": ' + str.tostring(price) + ','
    tprc = '"triggerPrice": ' + str.tostring(triggerPrice) + ','
    tgt = '"target": ' + str.tostring(target) + ','
    sl = '"stoploss": ' + str.tostring(stoploss) + ','
    tsl = '"trailingStoploss": ' + str.tostring(trailingStoploss) + ','
    am = '"amo": ' + str.tostring(amo)
    orderJson = '{' + acc + grp + ex + syb + tt + qty + prc + ot + pt + tprc
     + vart + vald + dqty + tgt + sl + tsl + am +'}'
    orderJson

// @function Prepare a place order alert message using order json array
// @param orderJsonArray Order json (can contain one or more orders)
// @param comments Comments
// @returns A complete alert message to place orders
export preparePlaceOrderAlertUsingJson(string orderJsonArray, 
     string comments = "") =>
    props = prepareAdditionalProperties(comments)
	alertJson = '{ "command": "PLACE_ORDERS", "orders": ['
	 + orderJsonArray + '],' + props + '}'
	alertJson

// @function Prepare a place order alert json message
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param tradeType Trade type [BUY, SELL]
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param quantity Quantity (Default: 1)
// @param price Price (Default: 0)
// @param orderType Order type [MARKET, LIMIT, STOP_LOSS, SL_MARKET] (Default: MARKET)
// @param productType Product type [INTRADAY, DELIVERY, NORMAL] (Default: INTRADAY)
// @param triggerPrice Trigger price (Default: 0)
// @param variety Variety [REGULAR, BO, CO] (Default: REGULAR)
// @param validity Validity [DAY, IOC] (Default: DAY)
// @param disclosedQuantity Disclosed quantity (Default: 0)
// @param target Target (for Bracket order only) (Default: 0)
// @param stoploss Stoploss (for Bracket order only) (Default: 0)
// @param trailingStoploss (for Bracket order only) Trailing Stoploss (Default: 0)
// @param amo Set it to true for AMO (After Market Order) (Default: false)
// @param comments Comments
// @returns A complete alert message to place orders
export preparePlaceOrderAlertMessage(string account, string symbol, string tradeType, 
     bool group = false, string exchange = "NSE", int quantity = 1,
	 float price = 0, string orderType = "MARKET", 
	 string productType = "INTRADAY", float triggerPrice = 0, 
	 string variety = "REGULAR", string validity = "DAY", 
	 int disclosedQuantity = 0, float target = 0, float stoploss = 0, 
	 float trailingStoploss = 0, bool amo = false, string comments = "") =>
    orderJson = preparePlaceOrderJson(account, symbol, tradeType, group,
     exchange, quantity, price, orderType, productType, triggerPrice, variety,
     validity, disclosedQuantity, target, stoploss, trailingStoploss, amo)
	alertJson = preparePlaceOrderAlertUsingJson(orderJson, comments)
	alertJson

// @function Prepare a place order alert json message for 2 orders
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param tradeType Trade type [BUY, SELL]
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param quantity Quantity (Default: 1)
// @param price Price (Default: 0)
// @param orderType Order type [MARKET, LIMIT, STOP_LOSS, SL_MARKET] (Default: MARKET)
// @param productType Product type [INTRADAY, DELIVERY, NORMAL] (Default: INTRADAY)
// @param triggerPrice Trigger price (Default: 0)
// @param account2 Pseudo or Group account number [for order 2]
// @param symbol2 AutoTrader Web's stock/derivative symbol [for order 2]
// @param tradeType2 Trade type [BUY, SELL] [for order 2]
// @param group2 Set it to true if you are using a group account (Default: false) [for order 2]
// @param exchange2 Symbol's exchange [NSE, BSE, MCX] (Default: NSE) [for order 2]
// @param quantity2 Quantity (Default: 1) [for order 2]
// @param price2 Price (Default: 0) [for order 2]
// @param orderType2 Order type [MARKET, LIMIT, STOP_LOSS, SL_MARKET] (Default: MARKET) [for order 2]
// @param productType2 Product type [INTRADAY, DELIVERY, NORMAL] (Default: INTRADAY) [for order 2]
// @param triggerPrice2 Trigger price (Default: 0) [for order 2]
// @param comments Comments
// @returns A complete alert message to place 2 orders
export preparePlaceOrderAlertMessageForTwoOrders(string account, string symbol, 
     string tradeType, bool group = false, string exchange = "NSE", 
     int quantity = 1, float price = 0, string orderType = "MARKET", 
	 string productType = "INTRADAY", float triggerPrice = 0,
	 string account2, string symbol2, string tradeType2, 
     bool group2 = false, string exchange2 = "NSE", int quantity2 = 1,
	 float price2 = 0, string orderType2 = "MARKET", 
	 string productType2 = "INTRADAY", float triggerPrice2 = 0,
	 string comments = "") =>
    orderJson = preparePlaceOrderJson(account = account, symbol = symbol, 
     tradeType = tradeType, group = group, exchange = exchange, 
     quantity = quantity, price = price, orderType = orderType, 
     productType = productType, triggerPrice = triggerPrice)
    orderJson2 = preparePlaceOrderJson(account = account2, symbol = symbol2, 
     tradeType = tradeType2, group = group2, exchange = exchange2, 
     quantity = quantity2, price = price2, orderType = orderType2, 
     productType = productType2, triggerPrice = triggerPrice2)
	orderJsonArray =  orderJson + ',' + orderJson2
	alertJson = preparePlaceOrderAlertUsingJson(orderJsonArray, comments)
	alertJson

// @function Prepare a square-off position json
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param category Position category [NET, DAY]
// @param type Position type [MIS, CNC, NRML, BO, CO]
// @returns A json message for the square-off position request
export prepareSqOffPositionJson(string account, string symbol, 
     bool group = false, string exchange = "NSE", string category = "NET",
	 string type = "MIS") =>
    acc = '"account": "' + account + '",'
    syb = '"symbol": "' + symbol + '",'
    grp = '"group": ' + str.tostring(group) + ','
    ex = '"exchange": "' + exchange + '",'
    cat = '"category": "' + category + '",'
    typ = '"type": "' + type + '"'
    sqOffJson = '{' + acc + syb + grp + ex + cat + typ +'}'
    sqOffJson

// @function Prepare a square-off position alert message using positions json array
// @param posJsonArray Position json (can contain one or more positions)
// @param comments Comments
// @returns A complete alert message to square-off position
export prepareSqOffPositionAlertUsingJson(string posJsonArray, 
     string comments = "") =>
    props = prepareAdditionalProperties(comments)
	alertJson = '{ "command": "SQUARE_OFF_POSITION", "positions": ['
	 + posJsonArray + '],' + props + '}'
	alertJson

// @function Prepare a square-off position alert json message
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param category Position category [NET, DAY]
// @param type Position type [MIS, CNC, NRML, BO, CO]
// @param comments Comments
// @returns A complete alert message to square-off position
export prepareSqOffPositionAlertMessage(string account, string symbol, 
     bool group = false, string exchange = "NSE", string category = "NET",
	 string type = "MIS", string comments = "") =>
    posJson = prepareSqOffPositionJson(account, symbol, group,
     exchange, category, type)
	alertJson = prepareSqOffPositionAlertUsingJson(posJson, comments)
	alertJson

// @function Prepare a square-off position alert json message for two positions
// @param account Pseudo or Group account number
// @param symbol AutoTrader Web's stock/derivative symbol
// @param group Set it to true if you are using a group account (Default: false)
// @param exchange Symbol's exchange [NSE, BSE, MCX] (Default: NSE)
// @param category Position category [NET, DAY]
// @param type Position type [MIS, CNC, NRML, BO, CO]
// @param account2 Pseudo or Group account number [for order 2]
// @param symbol2 AutoTrader Web's stock/derivative symbol [for order 2]
// @param group2 Set it to true if you are using a group account (Default: false) [for order 2]
// @param exchange2 Symbol's exchange [NSE, BSE, MCX] (Default: NSE) [for order 2]
// @param category2 Position category [NET, DAY] [for order 2]
// @param type2 Position type [MIS, CNC, NRML, BO, CO] [for order 2]
// @param comments Comments
// @returns A complete alert message to square-off of two positions
export prepareSqOffPositionAlertMessageForTwoPositions(string account, 
     string symbol, bool group = false, string exchange = "NSE", 
     string category = "NET", string type = "MIS", string account2, 
     string symbol2, bool group2 = false, string exchange2 = "NSE", 
     string category2 = "NET", string type2 = "MIS",
	 string comments = "") =>
    posJson = prepareSqOffPositionJson(account, symbol, group,
     exchange, category, type)
    posJson2 = prepareSqOffPositionJson(account2, symbol2, group2,
     exchange2, category2, type2)
	posJsonArray =  posJson + ',' + posJson2
	alertJson = prepareSqOffPositionAlertUsingJson(posJsonArray, comments)
	alertJson

// @function Prepares future symbol for AutoTrader Web
// @param underlier Underlier symbol (Ex. BANKNIFTY, USDINR, CRUDEOIL)
// @param expiry Expiry date in (DD-MMM-YYYY) format
// @returns future symbol as per AutoTrader Web's format
export prepareFutureSymbol(string underlier, string expiry) =>
    underlier + '_' + expiry + '_FUT'

// @function Prepares option symbol for AutoTrader Web
// @param underlier Underlier symbol (Ex. BANKNIFTY, USDINR, CRUDEOIL)
// @param expiry Expiry date in (DD-MMM-YYYY) format
// @param optionType Option type [CE, PE]
// @param strike Strike price
// @returns option symbol as per AutoTrader Web's format
export prepareOptionSymbol(string underlier, string expiry, string optionType, 
     int strike) =>
    underlier + '_' + expiry + '_' + optionType + '_' + str.tostring(strike)

// @function Calculates the closest option strike price as per the given 
// underlier price
// @param underlierPrice The underlier's price
// @param gap The gap between option strikes
// @returns the closest option strike price
export calcClosestStrike(float underlierPrice, int gap) => 
    math.round(underlierPrice / gap) * gap
