How to use Custom Tag with UpstoxNet


  • Technology Partner

    Now, the PlaceOrder Functions(Simple, Amo, OCO, CO) accepts additional optional parameter 'cTag'.This is a Tagging mechanism for orders and implemented at application level.So, all tagging information resides in the user system.

    Tagging is useful, when you want to manipulate orders based on another order like
    *Place a Target if entry order is complete
    *cancel stoploss order if Target hit etc.

    Why can't use order id directly?
    Of-course, you can use the order id directly to fulfill the above like example,but since the order id is generated by OMS, you need to have codes in place to store and use the order id, this will be little overhead.
    On other hand, Tags are created by you, so you know which tag is sent, and easy to remember.

    Example:
    Say you just placed a order in AXISBANK,
    If you want to check the status of the order;
    Option 1 :
    Store the order id returned by the PlaceOrder function and use the same to get the status.If you store the order id in memory, it will be lost when your app closes,
    if store in text file, you need to associate each order id with respective symbol otherwise simply storing the order id, will be of no use, as you will not know which
    order id belong to which symbol.The above is little complicated.

    Option 2 :
    Say you passed a cTag 'LongEntry' while placing the order.
    You can just get the order id by calling GetOrderCTag("NSE_EQ","AXISBANK","LongEntry")

    How it works?
    When you pass a cTag with PlaceOrder Function, UpstoxNet will save that cTag along with the Order Id received from Upstox Server.This details also saved in a text file, so that if you restart Excel or .Net App, this details will be read back into memory from the text file, so the Tag will work like persistent.

    Below is the modified functions to Place Orders.

    Public Function PlaceSimpleOrder ( 
    	Exch As String,
    	TrdSym As String,
    	Trans As String,
    	OrdType As String,
    	Qty As Integer,
    	ProdType As String,
    	Optional LmtPrice As Double = 0,
    	Optional TrgPrice As Double = 0,
    	Optional val As String = "DAY",
    	Optional cTag As String = Nothing,
    	Optional DiscQty As Integer = 0
    ) As String
    
    Public Function PlaceAmo ( 
    	Exch As String,
    	TrdSym As String,
    	Trans As String,
    	OrdType As String,
    	Qty As Integer,
    	ProdType As String,
    	Optional LmtPrice As Double = 0,
    	Optional TrgPrice As Double = 0,
    	Optional val As String = "DAY",
    	Optional cTag As String = Nothing,
    	Optional DiscQty As Integer = 0
    ) As String
    
    Public Function PlaceCO ( 
    	Exch As String,
    	TrdSym As String,
    	Trans As String,
    	Qty As Integer,
    	stoploss_Price As Double,
    	Optional OrdType As String = "M",
    	Optional LmtPrice As Double = 0,
    	Optional cTag As String = Nothing
    ) As String
    
    Public Function PlaceOCO ( 
    	Exch As String,
    	TrdSym As String,
    	Trans As String,
    	Qty As Integer,
    	LmtPrice As Double,
    	SqOffValue As Double,
    	StoplossValue As Double,
    	Optional TrailTicks As Integer = 0,
    	Optional OrdType As String = "L",
    	Optional TrgPrice As Double = 0,
    	Optional cTag As String = Nothing
    ) As String
    

    Requirements:
    Tag should be

    • Alphanumeric, allowed special characters - : _.
    • Min 3 and Max 20 characters.
    • Unique within each trade symbol, means you can use the same Tag for different symbols, but not on the same symbol.
      Note: Tag is case-insensitive means 'HeLlo' == 'HELLO' == 'hello'

    Example:
    Say you got a buy entry signal in 'AXISBANK'.
    You can create a custom tag for this signal like 'LongEntry' and pass it to PlaceOrder functions. UpstoxNet will save the cTag and OrderId.Whenever you need the order id just call
    GetOrderCTag("NSE_EQ","AXISBANK","LongEntry")

    You can customize the cTag as required, but generally, the tag should contain entry and strategy identification if running multiple strategies, like 'Long-
    MyStgy'.

    What will happen if the same tag is used?
    Say in the above example, if you passed the same cTag to another order in AXISBANK (Like Short),
    Now, the GetOrderCTag("NSE_EQ","AXISBANK","LongEntry") will return the last order id associated i.e. latest order placed.
    So do not use same tag within the symbol.

    You can pass the same Tag on different symbol.
    Like 'LongEntry' tag may passed to AxisBank, IciciBank etc.

    Note:
    The standard, recommended and efficient way to Restricting multiple orders is to use static variables to store the order status and read the status before placing next order, you can read more at https://upstox.com/forum/topic/190/restrict-multiple-order-firing-in-excel.
    This is not only for excel, applies to all programming language.

    Of-course, you can use Tag to restrict orders, but not recommended.
    Make sure you are using Unique tag for each orders otherwise, the tag is of no use.

    Misc:
    As you know excel will (re)calculate the formula only when there is a change in the referenced/passed value.This is because, if there is no change, then output will be same as last calculation, its so simple, why waste resources.

    Example:
    A1 = 5
    A2 = 3
    A3 = Sum(A1 + A2)
    Excel will (re)calculate Sum Formula in A3, only when A1 or A2 or both value changes.If A1 & A2 is not changed, the the last SUM hold good.
    

    This is the wonderful thing implemented by excel, it knows which are the cell value is changed, what formulas affected and calculate only affected formulas. By this way excel performs calculation in very efficient manner and preserves/uses less resources, otherwise everyone need big computer to run excel.

    But sometimes, we need Excel to work opposite way.
    The GetOrder* Functions in Excel takes only Order Id as parameter, since the order id is static, Excel will not (re)calculate after the initial calculation, so user will see the same order status in the cell even-though the order status is changed. This is because, since the order id is same (unlike Ltp or something where the price changes), excel thoughts (re)calculation is unnecessary, but Excel does't aware that this function returns data from outside.
    What we do?
    Option 1:

    Modify the UDF to accept additional dynamic dummy parameter say Ltp, so that whenever LTP changes, excel (re)calculates the GetOrder* Function

    Example:

    ***Original Function***
    Public Function GetOrderStatus(ByVal OrderId As String) As Variant
        On Error GoTo ErrHandler:
        GetOrderStatus = Upstox.GetOrderStatus(OrderId)
        Exit Function
    ErrHandler:
        GetOrderStatus = Err.Description
    End Function
    
    ***Modified***
    Public Function GetOrderStatus(ByVal OrderId As String, ByVal Ltp as Double) As Variant
        On Error GoTo ErrHandler:
        GetOrderStatus = Upstox.GetOrderStatus(OrderId)
        Exit Function
    ErrHandler:
        GetOrderStatus = Err.Description
    End Function
    

    Option 2:
    Adding Application.Volatile to UDF.
    This will force the Excel to calculate even when there is no change.
    You can read more here https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-volatile-method-excel
    This method affect the Excel performance as it always (re)calculates
    Example:

    ***Original Function***
    Public Function GetOrderStatus(ByVal OrderId As String) As Variant
        On Error GoTo ErrHandler:
        GetOrderStatus = Upstox.GetOrderStatus(OrderId)
        Exit Function
    ErrHandler:
        GetOrderStatus = Err.Description
    End Function
    
    ***Modified***
    Public Function GetOrderStatus(ByVal OrderId As String) As Variant
        Application.Volatile
        On Error GoTo ErrHandler:
        GetOrderStatus = Upstox.GetOrderStatus(OrderId)
        Exit Function
    ErrHandler:
        GetOrderStatus = Err.Description
    End Function
    

    You can use any option as per your requirements.



  • @HowUTrade One small question. If uptox server is restarted in between trading hours then would the custom tag be retained in this case ?


  • Technology Partner

    @ganesh

    Yes, the Tag and associated order id is stored in the user system.
    So, it work good even if Upstox server restarts or your app is reopened.
    The only thing, you should take care is passing 'Unique Tag' for every order within a symbol.



  • @HowUTrade

    Wow! Had I known this earlier, I would have saved lot of efforts on work around circuses I did to get the order ids using Dictionaries.

    I used Ctag and worked like magic. Thanks for the detailed explanation.

    Few queries

    1. For testing purpose, I placed order for a stock with two different cTags. It did give two different order ids for the both cTags. Both orders are executed. When I tried getting order filled price( using GetOrderFilledPrice), I get the order filled price for one order Id. For another order id, I get 0. I tried couple of times , manually typed the order id also. Still I get 0 only. I clicked Calculate Excel, Refresh RTD buttons. Still no use. How to resolve this please?

    2. Can I use this UDF "GetOrderCTag" more frequently and more places where it is needed? Will it affect the performance? Because, I need to replace few dictionaries with GetOrderCTag since dictionary does not store order ids when the app/laptop is closed for some reason.

    3. Say I place order using Ctag on April 9th, I would use the same cTag on April 10th. When I fetch order id on April 10th after placing order, will I get April 9th's order id or April 10th's order id?


  • Technology Partner

    @velu

    1. The GetOrderFilledPrice is assigned with initial value as zero and it is updated with the actual filled price once the order update is received on websocket. We guess you might be missed the order update. You can fetch the order book which will reconcile all orders and you will get correct information. As long as you receive all order updates the GetOrder* functions will return correct data.

    In case if you missed any updates due to network disconnection at your end or updates is not sent from API server or any other issues like app hangs etc, fetching the OrderBook will reconcile all orders.

    1. Yes you can use cTag everywhere, there will be no performance impact.

    2. cTag's are valid for that day only. If you fetch order id using cTag on 10th April you will get order id of 10th April only.

    Key Points to remember:
    cTag is locally manipulated by UpstoxNet, the Tag and order details are stored in the user computer in text files.

    cTag must be minimum 3 characters and maximum 20 characters, alphanumeric.

    Should be unique within a symbol, if same tag is used then, tag will hold the last order id placed.
    Example:
    You can use 'MYTAG' as cTag in AxisBank and ICICIBank, but if you use the same tag for multiple orders in AxisBank, then the tag will hold the last/latest order id placed.

    Since, it is locally stored, it will not be available if you try in another computer.
    Example:
    Suppose you placed a Buy order in AxisBank with cTag as 'MYTAG' in computer 'A' and if you call GetOrderCTag in this computer, it will return the associated order id.

    If you call GetOrderCTag in computer 'B', this will return empty string as the Tag details are stored in Computer 'A'.



  • @HowUTrade

    Nicely explained. Thanks many for the reply.



  • Hi, Say i am running various strategies in my account. And i want to use ctag to mark different strategies and later on want to use it to identify the performance of different strategies. In such a case how to use it?

    As u mentioned that a ctag can be used only once for a symbol... What if i place 2 orders in axisbank for the same strategy... will it get rejected?

    I basically want a way to run multiple strategies in a same account.. and at the end of the day want to analyse the performance of each strategy seperately...


  • Technology Partner

    @guest

    CTag is meant to retrieve particular OrderId for further actions like modifying cancel etc. These are locally implemented by UpstoxNet.



  • helloo @HowUTrade

    i tried to use ctag in place oco and try to restrict multiple order. the issue is the retrive order id with ctag coloumn is not refreshing and geting value. so it fire order again. i need to manuly go to the coloumn and presf2+enter to rereive id. pls help.


  • Technology Partner

    @lekshmivinod

    GetOrderCTag is a function.
    You need to call the function to get the result. It will not refresh on its own.
    You need to make the UDF volatile or add a dynamic dummy parameter to make it mimic refresh.



  • @howutrade

    Hello

    I have modified like this

    Public Function GetOrderStatus(ByVal OrderId As String) As Variant
    Application.Volatile
    On Error GoTo ErrHandler:
    GetOrderStatus = Upstox.GetOrderStatus(OrderId)
    Exit Function
    ErrHandler:
    GetOrderStatus = Err.Description
    End Function

    is it the correct function. pls help


  • Technology Partner

    @lekshmivinod

    Yes, it looks correct.
    Also make ```GetOrderCTag`` UDF too as volatile.
    Request you to go through this link first.



  • @howutrade

    Still the the function =GetOrderCTag("NSE_EQ",B84,AT84)
    not retrieving id automatically. i need to press f2+enter


  • Technology Partner

    @lekshmivinod

    You can try the other method i.e. passing dynamic dummy parameter.