Sterling API Developer Thread

Discussion in 'Trading Software' started by mnx, Apr 25, 2008.

  1. http://www.sterlingtechnologiesinc.com/Support.aspx go to Project Examples
     
    #111     Dec 16, 2008
  2. Euler

    Euler

    I had the CLSID problems once when I moved the Sterling directories around (got rid of the useless \Sti\ directory, etc.). Tried editing the registry, but I was only able to partially fix the problem. The only way I was able to solve it was to uninstall/reinstall Sterling where I really wanted it -- this was actually quite easy considering all the other things I tried.
     
    #112     Dec 17, 2008
  3. sesimm

    sesimm

    I had to disable the UAC(User Account Control) in Vista to avoid getting the error, just to let y'all know,
     
    #113     Dec 17, 2008
  4. Hi I am signing up for an intro to programming class at the local community college, but in the meantime I was wondering if anybody could tell me how they go about canceling orders. It looks lke there are 2 different ways to do it. The Client order ID or record ID. There is very little documentation on how to do this. In the order example Sterling gives, it looks like they reference it by simply which order you select in the grid. It doesn’t actually explain how to call the order. In the manual it just says to call the order and then cancel it. Even if I were to be able to call it, since every order has a new id, how do I know which id is linked to which order? Basically what I’m trying to do is place a stop and limit together and have one get filled and the other cancel. Also often when I try some cancel code, the whole Sterling platform has an error and shuts down. The only other way I thought of doing this is if I could send a hot key from the VB to sterling. I could just tell it to send the ALT+A keystroke to cancel all orders. Thanks for any help.

    Here are the declarations:

    Option Explicit
    Dim WithEvents m_STIEvents As SterlingLib.STIEvents
    Dim m_STIOrderMaint As SterlingLib.STIOrderMaint

    ' WinAPI declarations
    Private Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
    Private Type SYSTEMTIME
    wYear As Integer
    wMonth As Integer
    wDayOfWeek As Integer
    wDay As Integer
    wHour As Integer
    wMinute As Integer
    wSecond As Integer
    wMilliseconds As Integer
    End Type

    Here is the submitted order. Obviously the account name would be changed.

    Private Sub Command3_Click()
    Dim order As STIOrder
    Set order = New STIOrder

    order.Side = "B"
    order.Symbol = "UYG"
    order.Quantity = 100
    order.Account = "ACCOUNTNAMEHERE"
    order.Destination = "NSDQ"
    order.Tif = "D"
    ' order.PriceType = ptSTILmt
    order.PriceType = ptSTISvrStp
    'order.LmtPrice = 100
    order.StpPrice = 6.5

    Dim theTime As SYSTEMTIME
    GetLocalTime theTime
    order.ClOrderID = " ACCOUNTNAMEHERE " & theTime.wYear & theTime.wMonth & theTime.wDay & theTime.wHour & theTime.wMinute & theTime.wSecond & theTime.wMilliseconds
    'order.SubmitOrder

    'Could check for return code: OK = 0
    Dim intRet As Integer
    intRet = order.SubmitOrder()
    If intRet <> 0 Then
    MsgBox "Order Properties Invalid: " & Str(intRet)
    End If

    'Release order
    Set order = Nothing

    End Sub
    ----------------------------
    Here is the way the Sterling VB6 order example cancels the order. It just looks like they reference it by where the mouse clicks on the grid on the application.
    ----------------------------
    Private Sub Command4_Click()
    Dim SelectedRow As Integer
    Dim OldClOrdId As String
    Dim RecordID As Long

    If (OpenOrders.Row > OpenOrders.Rows - 2) Then
    Exit Sub
    'End If

    SelectedRow = OpenOrders.Row
    OldClOrdId = OpenOrders.TextArray(OpenOrders.Row * OpenOrders.Cols)
    RecordID = OpenOrders.TextArray(OpenOrders.Row * OpenOrders.Cols + 1)

    Dim theTime As SYSTEMTIME
    Dim ClOrdId As String
    GetLocalTime theTime
    ClOrdId = " ACCOUNTNAMEHERE " & theTime.wYear & theTime.wMonth & theTime.wDay & theTime.wHour & theTime.wMinute & theTime.wSecond & theTime.wMilliseconds

    If OptRecordID.Value = True Then 'use RecordID
    m_STIOrderMaint.CancelOrder " ACCOUNTNAMEHERE ", RecordID, "", ""
    Else If ClOrdId <> "" Then 'use Client Provided OrderIDs
    m_STIOrderMaint.CancelOrder " ACCOUNTNAMEHERE ", 0, OldClOrdId, ClOrdId
    End If
    End Sub
     
    #114     Jan 7, 2009
  5. When you generate an order and a Client order ID for it you need to save that ID somewhere for use later. This somewhere is called a variable. Preferably you need to use an array or maybe a hashtable. I store it as part of an object I created. Regardless, it needs to be some sort of data structure that you can access so you can cancel the order later.

    Right after they specify the order.clOrderID = ...... you need the following:

    MyVariable = order.ClOrderID

    Don't forget to declare MyVariable.

    Good luck.
     
    #115     Jan 7, 2009
  6. Euler

    Euler

    What Shreddog said is correct. Especially that you need to specify WHICH order it is you're trying to cancel. However, depending on what you're doing (e.g., how fast you're sending orders), you may not necessarily need to store the ID's yourself, since Sterling keeps them for you and sends them back in the callbacks, and it may be obvious from these callbacks "which order is which", or else you may not even care.

    Of course, in any event, you need to be able to ID the order, and if nothing's in RecordID = OpenOrders.TextArray(OpenOrders.Row * OpenOrders.Cols + 1) in your code, then nothing's going to work. I can't tell based on the snippets of code whether that's the case. But you can do a Console.writeline(RecordID) -- and similarly with whatever other variables are of interest -- in an effort to debug this.

    Also, in my experience, cancelling by way of nOrderRecordID was to be buggy (i.e., it just did nothing), whereas cancelling by way of ClOrderId worked. Not sure if this is still true (or whether I had made an error of my own).

    (The fact that there is more than one ID per order is a source of further confusion, but this is common in the more "sophisticated" API's.)

    Hope that helps (rather than confuses :D)
     
    #116     Jan 8, 2009
  7. bespoke

    bespoke

    Anyone have problems cancelling S-STP orders using clientIDs? All my other types of orders cancel fine, it's just these. Really annoying cause I like to create OCOs but the S-STPs only cancel about 60% of the time even if I send multiple cancels for it. I have to be glued to the computer to make sure they cancel properly.
     
    #117     Jan 8, 2009
  8. Holy moly. Shreddog and Euler, if you guys were here I’d buy you a beer. That worked perfectly. Why didn’t Sterling suggest storing the unique dated id as a variable? That’s brilliant. Because they say when you use the api generated id, you can’t use it again. So how can you repeatedly use the same id and then cancel it? Use the date stamp and store it in a variable of course. I still had to work with it a little. The manual says to do it wrong.

    It says to.

    Dim this:

    Dim m_STIOrderMaint As STIOrderMaint

    Then declare this in the new procedure:

    Set m_STIOrderMaint = New STIOrderMaint

    ThenCall the id, which they don’t tell you how to do.

    Then cancel it with this:
    m_STIOrderMaint.CancelOrder “<Account>”, 0, “<Client Order Id of Order to cancel>”, “<Client Order Id of new cancel order record>”

    So it would look like
    " < ACCOUNTNAMEHERE > ", 0, " < MyVariable > ", " < MyVariable2 > "


    First off the quotation marks they use are not even recognized by VB. You have to change those. But after that it still didn’t work. So I looked at the sterling order example VB and they actually do it differently.

    They do it like this:

    m_STIOrderMaint.CancelOrder "ACCOUNTNAMEHERE", 0, OldClOrdId, ClOrdId

    Notice there’s no < > and the id is not in “”. So I just put it like in the example and it came out like this.

    Private Sub Command5_Click()
    Set m_STIOrderMaint = New STIOrderMaint
    m_STIOrderMaint.CancelOrder " ACCOUNTNAME ", 0, MyVariable, MyVariable
    End Sub


    Now they say the second id has to be a new one because that is the id of the cancel, but it worked fine by naming it the same MyVariable. But in order to do it right I put in a new variable and named it MyVariableCancel. So it looks like this.


    Declarations
    Dim MyVariable
    Dim MyVariableCancel

    Private Sub Command5_Click()
    Set m_STIOrderMaint = New STIOrderMaint
    m_STIOrderMaint.CancelOrder "ACCOUNTNAME", 0, MyVariable, MyVariableCancel
    End Sub


    At first when I tried it, it didn’t work. But then after I kept clicking the cancel, it did. I remember reading somewhere that it doesn’t allow an API cancel until after 10 seconds. But the first method, I could cancel immediately. So unless there’s a big difference, I will not rename the cancel because I don’t want to wait 10 seconds.

    Boy there is nothing more frustrating than trying to get something to work, and nothing that feels better than finally getting it to work. I know this is all basic stuff to you, but I really appreciate the help. After all this work, I actually have to figure out a way to actually make money now.
     
    #118     Jan 8, 2009
  9. I’ve been doing it all day in my demo account fine, but not my real one. When I place 2 server orders in the demo and then manually OCO them and then API cancel them, they both cancel. I use the server stops in my real account all the time and OCO link them all the time. Usually before I can see one of the orders is filled, it cancels the other. It’s very efficient. The OCO was just added by Sterling within the past year they said. So there is nothing about it in the manual. Is there an API function where you can link the orders in the Sterling system, and not by your API? That would be ideal Thanks
     
    #119     Jan 8, 2009
  10. bespoke

    bespoke

    That's right, there's no function in the API for OCO. What you have to do is in the m_STIEvents_OnSTIOrderUpdateMsg subroutine:

    If oSTIOrderUpdateMsg.ClOrderID = exitOrderID Then
    If oSTIOrderUpdateMsg.OrderStatus = osSTIFilled Then
    CancelSTPOrder....
    End If
    End If

    But it doesn't work all the time. Have no idea why. But it seems to work the other way around all the time (s-stp order gets hit first). Maybe it has something to do the exit orders getting filled partially to completion? I don't see why it would though. And I believe I still have the same problem if I were to trade with 100 shares.

    Heres my beef. It should either work 100% of time or 0% of the time. I'll guess I'll try using recordids. Will report back
     
    #120     Jan 8, 2009