SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Mon Dec 16, 2019 9:13 am

All times are UTC + 3 hours




Post new topic Reply to topic  [ 46 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Wed Jan 15, 2014 8:02 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
Hi everyone.

I see a lot of people are interested in connecting to Sterling Trader Pro API and so am I. I have been able to write this code and send orders to Sterling. The orders reach Sterling and are live. The problem is the events are not getting called. I have written to Sterling API in other programs and I get event messages when an order update happens but it is not working in the current code. Can somebody please help?

Thanks

Brian

Code:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;

using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
using SterlingLib;
using OpenQuant.API;


namespace SterlingTest
{
    public class Sterling : OpenQuant.API.Plugins.UserProvider
    {
        // Sterling Class
        public SterlingLib.STIApp app;
        public STIAcctMaint Maint;
        public STIOrderMaint Omaint;
        public ISTIPosition Pos;
        public STIEvents events;
        public STIOrder STIOrdersend;

       
        // Store Orders
        private Dictionary<string, Order> pendingOrders;
        private Dictionary<string, Order> workingOrders;


        public Sterling()
        {
            base.name = "Sterling";
            base.description = "Sterling Order Entry";
            base.id          = 150;

            pendingOrders = new Dictionary<string, Order>();
            workingOrders = new Dictionary<string, Order>();

           
        }
        public void LoadEvents()
        {
            MessageBox.Show("Loading Events");

            app = new STIApp();
            Maint = new STIAcctMaint();
            Omaint = new STIOrderMaint();
            Pos = new STIPosition();
            events = new STIEvents();

           

            events.OnSTITradeUpdate += new _ISTIEventsEvents_OnSTITradeUpdateEventHandler(events_OnSTITradeUpdate);
            events.OnSTIOrderUpdate += new _ISTIEventsEvents_OnSTIOrderUpdateEventHandler(events_OnSTIOrderUpdate);
            events.OnSTIOrderReject += new _ISTIEventsEvents_OnSTIOrderRejectEventHandler(events_OnSTIOrderReject);

            //events.OnSTIOrderRejectMsg += new _ISTIEventsEvents_OnSTIOrderRejectMsgEventHandler(events_OnSTIOrderRejectMsg);

            events.SetOrderEventsAsStructs(true);
            //events.OnSTIOrderRejectMsg += new _ISTIEventsEvents_OnSTIOrderRejectMsgEventHandler(events_OnSTIOrderRejectMsg);
            //events.OnSTIOrderUpdateMsg += new _ISTIEventsEvents_OnSTIOrderUpdateMsgEventHandler(events_OnSTIOrderUpdateMsg);

            Array accs = Array.CreateInstance(typeof(string), 1);

            int count = Maint.GetAccountList(ref accs);

            MessageBox.Show("Accounts= " + count.ToString());
           
        }

        void events_OnSTIOrderRejectMsg(STIOrderRejectMsg oSTIOrderRejectMsg)
        {
            MessageBox.Show("Order Reject msg");
            throw new NotImplementedException();
        }

        void events_OnSTIOrderUpdateMsg(STIOrderUpdateMsg oSTIOrderUpdateMsg)
        {
            MessageBox.Show("Order Update msg");
            //throw new NotImplementedException();
        }

        #region Connect/Disconnect

        protected override void Connect()
        {
            if (base.isConnected)
                return; // already connected           

            try
            {
                app = new STIApp();
                bool running = app.IsApiEnabled();
                if (running == true)
                {

                    LoadEvents();
                    base.isConnected = true;
                    base.EmitConnected();
                }
                else
                {
                    base.isConnected = false;
                }

            }
            catch (Exception e)
            {
                base.EmitError(e.ToString());
            }
        }

        protected override void Disconnect()
        {
            if (!base.isConnected)
                return; // not connected


        }

        protected override void Shutdown()
        {
            Disconnect();
        }

        #endregion

        #region Orders

        protected override void Send(Order order)
        {
            if (!IsConnected)
            {
                EmitError("Not connected.");

                return;
            }

            // Create an order
            STIOrdersend = new STIOrder();

            STIOrdersend.ClOrderID = "Test" + System.Guid.NewGuid().ToString();
            order.OrderID = STIOrdersend.ClOrderID;

            STIOrdersend.Destination = "CBOE";
            STIOrdersend.Account = "TestAccount";
            STIOrdersend.Symbol = order.Instrument.AltSource;
            STIOrdersend.Quantity = 1;
            STIOrdersend.PriceType = STIPriceTypes.ptSTILmt;
            STIOrdersend.LmtPrice = order.Price;
            STIOrdersend.Side = "B";
            STIOrdersend.Tif = "D";
           

            // futures & options           
            if (order.Instrument.Type == InstrumentType.Futures)
            {

            }
            if (order.Instrument.Type == InstrumentType.Option)
            {
                // Strike
                STIOrdersend.StrikePrice = order.Instrument.Strike;
                // Underlying
                STIOrdersend.Underlying = order.Instrument.AltSymbol.ToString();

                // Type
                STIOrdersend.Instrument = "O";  // Option type

                // Expiration Date
                string expDate = order.Instrument.Maturity.ToString("yyyyMMdd");
                STIOrdersend.Maturity = expDate;
                // Put Call
                if (order.Instrument.PutCall == PutCall.Call)
                {
                    STIOrdersend.PutCall = "C";
                }
                else if (order.Instrument.PutCall == PutCall.Put)
                {
                    STIOrdersend.PutCall = "P";
                }

            }

            // send order
            int status;
            status = STIOrdersend.SubmitOrder();

            //
            if (status == 0)
            {
                workingOrders.Add(STIOrdersend.ClOrderID, order);

            }
            else
            {
                base.EmitRejected(order, status.ToString());
            }
        }

        protected override void Cancel(Order order)
        {
            if (!IsConnected)
            {
                EmitError("Not connected.");

                return;
            }

            string orderNumber = null;

            foreach (KeyValuePair<string, Order> pair in workingOrders)
            {
                if (pair.Value == order)
                {
                    orderNumber = pair.Key;

                    break;
                }
            }

            if (orderNumber == null)
            {
                base.EmitError("Cannot cancel unknown order.");
            }
            else
            {
                Omaint = new STIOrderMaint();
                // Cancel order
                string newID = "X" + order.OrderID.ToString();

                Omaint.CancelOrder(order.Account.ToString(), 0, order.OrderID.ToString(), newID);
                base.EmitPendingCancel(order);
            }
        }

        #endregion

        #region Callbacks

        public void events_OnSTITradeUpdate(ref structSTITradeUpdate tradeUpdateInfo)
        {

        }
        internal void events_OnSTIOrderReject(ref structSTIOrderReject reject)
        {
            EmitError("Order Reject");
            MessageBox.Show("Order Reject");
           
        }
        public void events_OnSTIOrderRejectMsg()
        {
            MessageBox.Show("Order Reject Msg");

        }

        //private delegate void ordersupdatedelegate(ref SterlingLib.structSTIOrderUpdate orderUpdateInfo);
        internal void events_OnSTIOrderUpdate(ref structSTIOrderUpdate orderUpdateInfo)
        {
                 
            EmitError("Order Update");
            MessageBox.Show("Order Update");
           
        }


        #endregion

    }
}



Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 6:42 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
Brian (sorry if this is not your name :))

I'm very interested in Sterling plug-in and would do my best to help. Unfortunately I'm not familiar with Sterling API yet. But I'm willing to help. So I'm sorry in advance if my questions will be silly.

Do I understand correctly - you don't get your callbacks invoked from Sterling API? I.e. after calling STIOrdersend.SubmitOrder() you expect one of your callbacks to be invoked and they don't?



P.S. I only have version 3.5.0 of OpenQuant so if you have something newer, whatever I'll do not sure it will be totally compatible but neither I'm sure it will be very different.


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 7:29 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
Hi

Yes my name is brian.

So when i send the order you should get a code back from Sterling saying Sterling accepted the order but has not been sent to the exchange. If Sterling says all fields are ok you will get a 0 when you send the order.

example

int status;
status = STIOrdersend.SubmitOrder();

if status equals something other than 0 then one of your fields is incorrect.

if you do get a 0 the order will be sent to the destination.
if the destination accepts the order you will get an orderupdateevent and the order status will become 13 meaning new order.

I am not getting the orderupdateevent. But i see the order live in the market place. Trying to figure out why the orderupdateevent is not being called.

I am using OQ 3.9 64bit

Hope that helps.

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 7:36 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
Glad to meet you, Brian.

It might take a while for me to install Sterling demo and play with it, so here is another question. If you copy the same exact code as it is to a separate EXE and send an order, will you get callback?

I mean - you don't get the call back because you run from within OQ?

Ed

P.S. Another question - I didn't look at that yet, but the Sterling API - is it ActiveX?

Another question :). If the API is ActiveX, do you compile plug-in for 32 bit? I know that there might be a problem using ActiveX in 64 bit environment.


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 7:45 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
I believe if you call Sterling is should be no problem to get a demo account.

Yes the API is activeX. I didn't know that about 64bit and activeX. All the previous .Net programs i have written to the Sterling API have been 32bit and I have had no problems. I will try a 32bit build of the dll.

Thanks

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 7:50 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
I just checked and I was building it as a 32bit.

But I am running 64bit OQ...would that be a problem?

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 7:55 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
Also I am building the dll with Visual Studio 2010.

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 8:04 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
I am building it using AnyCPU and when I change it to x86 build then the OpenQuant.API dll can't be found. So I have to download the 32 bit version and get the OpenQuant.API dll from that one so I can build a 32bit dll. That is going to take me a while.

Thanks for you help on the activeX problem

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 8:21 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
Brian,

I'll do my best to help since I'm interested to connect to Sterling as one of our clients insists.
I do have their Demo - it is just a matter of setting up everything on my development computer.
It's been a while since I worked with ActiveX but I'll do my best.

Meanwhile, maybe one of SmartQuant's gentlemen can help us

Just in case - my Skype is "edwardgonen". I don't promise to answer there immediately but will try.


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 9:12 pm 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
Ok so i downloaded the 32bit version of OQ and used the OpenQuant.API dll in the reference to build a 32bit dll for sterling information. Still able to send an order into the market place using the new dll and the 32bit version of OQ but didn't receive an event call.

So a little confused unless I am still building the dll wrong.

Thanks

Brian


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 10:38 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
I'll try to play with that also today and tomorrow. Will update about my progress if any.


Top
 Profile  
 
PostPosted: Thu Jan 16, 2014 10:43 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
I also looked at another provider I tried to write few months ago. It also hosted ActiveX. In order to get events I had to create a singleton class that inherits from Form. I'm not sure this is the right solution but I'll try it with that code.

Here is the link https://www.dropbox.com/s/3ninkxd1e3fgh89/UBankProvider.zip to my project mentioned above. I think you can try to use it as a skeleton replacing my code by calls to Sterling.

Otherwise I can try tomorrow myself the Sterling API

Ed


Top
 Profile  
 
PostPosted: Fri Jan 17, 2014 1:48 am 
Offline

Joined: Tue Jan 14, 2014 7:51 pm
Posts: 13
Thanks for the code.

I replaced everything for use with sterling and still can send an order to the market place but no events are called.

Brian


Top
 Profile  
 
PostPosted: Fri Jan 17, 2014 10:14 am 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
Ok, I'll try to install the API and see if I can get the events working.


Top
 Profile  
 
PostPosted: Fri Jan 17, 2014 2:30 pm 
Offline

Joined: Mon Oct 04, 2010 5:13 pm
Posts: 362
Brian,

Did you try the QuoteExampleXML code from Sterling samples? I've just created my own OQ Sterling provider project, but I didn't check send orders - first I wanted to be sure that events work in general. So on Connect I subscribed to BAC symbol and immediately got call back with data. Now it is too early to check orders as the trading is not active yet. Maybe in couple of hours I'll also add the Send Order.

Ed


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 46 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group