Announcement

Collapse
No announcement yet.

Calling DLL functions from EFS

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Calling DLL functions from EFS

    Hi guys,
    I have been working on a DLL which makes use of DAS trader API to place orders. Now, for couple of days, I have been trying to call a simple function from a EFS file. But every time I reload the script, I keep on getting the following error message:

    Internal Error : DLL.call can not locate (testFunction)

    Following is my efs code.

    Code:
    var DASdll = null;
    
    function loadDASDLL()
    {
        if(DASdll == null)
        {
            DASdll = new DLL("C://Users//0004//Documents//Visual Studio 2010//Projects//ESignalDASConnector//ESignalDASConnector//bin//Release//ESignalDASConnectorx64.dll");
            DASdll.AddFunction("testFunction",DLL.STRING,DLL.STDCALL,"testFunction");
        }
    }
    
    function preMain()
    {
        loadDASDLL();
    }
    
    
    function main()
    {
         if(getBarState() == BARSTATE_NEWBAR)
         {
            var str = DASdll.call("testFunction");
            debugPrintln(str);     
         }
         
    }

    Following is my DLL file code :
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using daslibrary;
    
    namespace ESignalDASConnector
    {
        public class Connector
        {
            private int masterTraderID; // Need to get it from DAS
            private int brokerID;
            private string mrrno;
            private SocketOrderServer sOS;
            private SocketQuoteServer quoteServer = null;
            private itemTrader itemtrader = null;
            private string orderServer = "";
            private string quoteServerAddress = "";
            private string masterTraderName;
            private int orderPort = 0;
            private int quotePort = 0;
            private const int waitSeconds = 5;
            private int masterAccountID = 53; // will change
            private string username = ""; // will change
            private string password = ""; // will change
            
            private itemOrder CreateOrder(string symbol, int qty, double askPrice, double bidPrice, double executionPrice, bool isBuyOrder, bool isMarketOrder, string route, byte exch, int accid)
            {
                
                itemOrder iOrder = new itemOrder();
                iOrder.mstatus = 0;
    
                this.getSocketOrderServer();
    
                if (isMarketOrder == true)
                {
                    iOrder.mstatus |= 1 << 9; // placing market order
    
                    if (isBuyOrder == true)
                    {
                        iOrder.mstatus |= 1 << 6;
                        iOrder.mprice = askPrice;
                    }
                    else
                    {
                        iOrder.mprice = bidPrice;
                    }
                }
                else
                {
                    if (isBuyOrder == true)
                    {
                        iOrder.mstatus |= 1 << 6;
                    }
                    iOrder.mprice = executionPrice;
                    iOrder.mtmforce = 65535;
    
                }
    
                iOrder.msecsym = symbol;
                iOrder.mqty = qty;
                iOrder.mroute = route;
                iOrder.maccid = accid;
                iOrder.mtrid = this.masterTraderID;
                iOrder.mbrid = this.brokerID;
                iOrder.mrrno = this.mrrno;
                iOrder.mexchange = exch;
    
                return iOrder;
            }
    
    
            private void connectSocketOrderServer()
            {
                sOS = new SocketOrderServer();
                sOS.Connect(orderServer, orderPort);
                sOS.PkgLongin(username, password, orderServer);
    
                int timeout = 0;
                while (timeout <= waitSeconds * 1000) // wait waitseconds(default =3) seconds
                {
                    timeout += 500;
                    System.Threading.Thread.Sleep(500);
                    itemtrader = sOS.sitemTrader.FindItemByName(username);
    
                    if (itemtrader != null)
                    {
                        System.Console.WriteLine("Connection established");
                        try
                        {
                            this.connectQuoteServer();
                            masterTraderName = username;
                            masterTraderID = itemtrader.mtrid;
                            brokerID = itemtrader.mbrid;
                            mrrno = sOS.sitemAccount.FindItem(masterAccountID).mitemifo.mrrno;
                            System.Console.WriteLine("MasterID " + masterTraderID);
                        }
                        catch (Exception e)
                        {
                            System.Console.WriteLine(e.StackTrace);
                        }
                        break;
                    }
                }
    
                if (timeout > waitSeconds * 1000)
                {
                    System.Console.WriteLine("Connection problem and timed out");
                    Environment.Exit(0);
                }
    
            }
    
            private void connectQuoteServer()
            {
                if (quoteServer == null)
                {
                    quoteServer = new SocketQuoteServer(sOS);
                    quoteServer.Connect(quoteServerAddress, quotePort);
                    quoteServer.PkgLogin(username, password, quoteServerAddress);
                }
            }
    
            public SocketOrderServer getSocketOrderServer()
            {
                if (this.sOS == null || !this.sOS.IsConnected())
                {
                    this.connectSocketOrderServer();
                    this.connectQuoteServer();
                }
                return sOS;
            }
    
            public bool sendOrder(string symbol, int qty, double askPrice, double bidPrice, double executionPrice, bool isBuyOrder, bool isMarketOrder, string route, byte exch, int accid)
            {
                string errmsg = "";
                long morig = -1;
                long timeout = 0;
    
                itemOrder iOrder = CreateOrder(symbol, qty, askPrice, bidPrice, executionPrice, isBuyOrder, isMarketOrder, route, exch, accid);
                if (itemOrder.LSendOrder(iOrder, ref errmsg, true, this.sOS, ref morig) == 0)
                {
                    itemOrder myorder = null;
                    while (timeout <= 60000)
                    {
                        timeout += 1000;
                        System.Threading.Thread.Sleep(1000);
                        myorder = sOS.sitemOrder.FindItemBymorig((int)morig);
                        if (myorder != null)
                        {
                            if (!(((myorder.mstatus & (1 << 4)) != 0) || ((myorder.mstatus & (1 << 1)) != 0))) continue;
    
                            if ((myorder.mstatus & (1 << 1)) != 0)
                            {
                                System.Console.WriteLine("Order Executed");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 2)) != 0)
                            {
                                System.Console.WriteLine("Order Canceled");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 3)) != 0)
                            {
                                System.Console.WriteLine("Order Rejected");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 4)) != 0)
                            {
                                System.Console.WriteLine("Order Accepted");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 5)) != 0)
                            {
                                System.Console.WriteLine("Order Timeout");
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
           [B] public String testFunction()
            {
                return "Hello world";
            }[/B]
        }
    }
    I am trying to call "testFunction" from my efs. Can any one tell me why am I getting this error. Any help/advice will be greatly appreciated.

    Thanks and Regards,
    Vipin

  • #2
    Vipin
    You may want to review the information in this article in the EFS KnowledgeBase
    Alex


    Originally posted by naboutboul View Post
    Hi guys,
    I have been working on a DLL which makes use of DAS trader API to place orders. Now, for couple of days, I have been trying to call a simple function from a EFS file. But every time I reload the script, I keep on getting the following error message:

    Internal Error : DLL.call can not locate (testFunction)

    Following is my efs code.

    Code:
    var DASdll = null;
    
    function loadDASDLL()
    {
        if(DASdll == null)
        {
            DASdll = new DLL("C://Users//0004//Documents//Visual Studio 2010//Projects//ESignalDASConnector//ESignalDASConnector//bin//Release//ESignalDASConnectorx64.dll");
            DASdll.AddFunction("testFunction",DLL.STRING,DLL.STDCALL,"testFunction");
        }
    }
    
    function preMain()
    {
        loadDASDLL();
    }
    
    
    function main()
    {
         if(getBarState() == BARSTATE_NEWBAR)
         {
            var str = DASdll.call("testFunction");
            debugPrintln(str);     
         }
         
    }

    Following is my DLL file code :
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using daslibrary;
    
    namespace ESignalDASConnector
    {
        public class Connector
        {
            private int masterTraderID; // Need to get it from DAS
            private int brokerID;
            private string mrrno;
            private SocketOrderServer sOS;
            private SocketQuoteServer quoteServer = null;
            private itemTrader itemtrader = null;
            private string orderServer = "";
            private string quoteServerAddress = "";
            private string masterTraderName;
            private int orderPort = 0;
            private int quotePort = 0;
            private const int waitSeconds = 5;
            private int masterAccountID = 53; // will change
            private string username = ""; // will change
            private string password = ""; // will change
            
            private itemOrder CreateOrder(string symbol, int qty, double askPrice, double bidPrice, double executionPrice, bool isBuyOrder, bool isMarketOrder, string route, byte exch, int accid)
            {
                
                itemOrder iOrder = new itemOrder();
                iOrder.mstatus = 0;
    
                this.getSocketOrderServer();
    
                if (isMarketOrder == true)
                {
                    iOrder.mstatus |= 1 << 9; // placing market order
    
                    if (isBuyOrder == true)
                    {
                        iOrder.mstatus |= 1 << 6;
                        iOrder.mprice = askPrice;
                    }
                    else
                    {
                        iOrder.mprice = bidPrice;
                    }
                }
                else
                {
                    if (isBuyOrder == true)
                    {
                        iOrder.mstatus |= 1 << 6;
                    }
                    iOrder.mprice = executionPrice;
                    iOrder.mtmforce = 65535;
    
                }
    
                iOrder.msecsym = symbol;
                iOrder.mqty = qty;
                iOrder.mroute = route;
                iOrder.maccid = accid;
                iOrder.mtrid = this.masterTraderID;
                iOrder.mbrid = this.brokerID;
                iOrder.mrrno = this.mrrno;
                iOrder.mexchange = exch;
    
                return iOrder;
            }
    
    
            private void connectSocketOrderServer()
            {
                sOS = new SocketOrderServer();
                sOS.Connect(orderServer, orderPort);
                sOS.PkgLongin(username, password, orderServer);
    
                int timeout = 0;
                while (timeout <= waitSeconds * 1000) // wait waitseconds(default =3) seconds
                {
                    timeout += 500;
                    System.Threading.Thread.Sleep(500);
                    itemtrader = sOS.sitemTrader.FindItemByName(username);
    
                    if (itemtrader != null)
                    {
                        System.Console.WriteLine("Connection established");
                        try
                        {
                            this.connectQuoteServer();
                            masterTraderName = username;
                            masterTraderID = itemtrader.mtrid;
                            brokerID = itemtrader.mbrid;
                            mrrno = sOS.sitemAccount.FindItem(masterAccountID).mitemifo.mrrno;
                            System.Console.WriteLine("MasterID " + masterTraderID);
                        }
                        catch (Exception e)
                        {
                            System.Console.WriteLine(e.StackTrace);
                        }
                        break;
                    }
                }
    
                if (timeout > waitSeconds * 1000)
                {
                    System.Console.WriteLine("Connection problem and timed out");
                    Environment.Exit(0);
                }
    
            }
    
            private void connectQuoteServer()
            {
                if (quoteServer == null)
                {
                    quoteServer = new SocketQuoteServer(sOS);
                    quoteServer.Connect(quoteServerAddress, quotePort);
                    quoteServer.PkgLogin(username, password, quoteServerAddress);
                }
            }
    
            public SocketOrderServer getSocketOrderServer()
            {
                if (this.sOS == null || !this.sOS.IsConnected())
                {
                    this.connectSocketOrderServer();
                    this.connectQuoteServer();
                }
                return sOS;
            }
    
            public bool sendOrder(string symbol, int qty, double askPrice, double bidPrice, double executionPrice, bool isBuyOrder, bool isMarketOrder, string route, byte exch, int accid)
            {
                string errmsg = "";
                long morig = -1;
                long timeout = 0;
    
                itemOrder iOrder = CreateOrder(symbol, qty, askPrice, bidPrice, executionPrice, isBuyOrder, isMarketOrder, route, exch, accid);
                if (itemOrder.LSendOrder(iOrder, ref errmsg, true, this.sOS, ref morig) == 0)
                {
                    itemOrder myorder = null;
                    while (timeout <= 60000)
                    {
                        timeout += 1000;
                        System.Threading.Thread.Sleep(1000);
                        myorder = sOS.sitemOrder.FindItemBymorig((int)morig);
                        if (myorder != null)
                        {
                            if (!(((myorder.mstatus & (1 << 4)) != 0) || ((myorder.mstatus & (1 << 1)) != 0))) continue;
    
                            if ((myorder.mstatus & (1 << 1)) != 0)
                            {
                                System.Console.WriteLine("Order Executed");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 2)) != 0)
                            {
                                System.Console.WriteLine("Order Canceled");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 3)) != 0)
                            {
                                System.Console.WriteLine("Order Rejected");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 4)) != 0)
                            {
                                System.Console.WriteLine("Order Accepted");
                                return true;
                            }
                            else if ((myorder.mstatus & (1 << 5)) != 0)
                            {
                                System.Console.WriteLine("Order Timeout");
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
           [B] public String testFunction()
            {
                return "Hello world";
            }[/B]
        }
    }
    I am trying to call "testFunction" from my efs. Can any one tell me why am I getting this error. Any help/advice will be greatly appreciated.

    Thanks and Regards,
    Vipin

    Comment


    • #3
      The short answer:

      eSignal doesn't support the .Net Framework.

      You can only load standard DLLs, not a .Net generated DLL.

      The long answer:

      What you want to do is easy. Create DDEOutput objects in the EFS and send your signals over to a C# program which includes this code you wanted to pull into the EFS originally as a library. In your C# program, capture the DDE trade signals by using the free C# DDE library at ndde.codeplex.com.

      If you want to send info on the status BACK to your EFS script then you can create a standard C DLL and create a shared data area within it so that your C# program writes to the status variables and the EFS side reads them. I wouldn't recommend communicating through a an EFS File object unless you are using an SSD drive.

      Really, the most dead simple way to do it if the communication is a little involved is to use 2 variables in the C DLL shared memory:

      1. 1st variable is an int which is set to 1 on the C# side to notify the EFS to look at the 2nd variable.

      2. 2nd variable is an array of strings which act as a queue. This way, if you have multiple messages hitting at once, the EFS can catch and process the series over several passes. Remember, you have price ticks lining up to come in and that has to stay timely so grab 1 message and get the next on another trip into the EFS. The 1st variable will always let you know if something is still in the queue to process.

      [For the queue inside the C DLL, use an int to act as an index and increment that for each new message you want to add to the array. You index into the array of strings with a modulus (of the index variable) so it will always wrap around to the beginning of the array once you get to the last element.]

      Keep everything on the eSignal side "stupid" and everything on the C# program side "smart". You use the eSignal part to generate signals and show pretty lines and arrows and such for the outcomes of what the C# program is managing. The C# program is under your total control when talking to the trading engine you want to use and that's a Good Thing (tm).

      You can do it...stay frosty.
      Last edited by SteveH; 09-19-2013, 09:49 AM.

      Comment


      • #4
        Originally posted by SteveH View Post
        The short answer:

        eSignal doesn't support the .Net Framework.

        You can only load standard DLLs, not a .Net generated DLL.

        The long answer:

        What you want to do is easy. Create DDEOutput objects in the EFS and send your signals over to a C# program which includes this code you wanted to pull into the EFS originally as a library. In your C# program, capture the DDE trade signals by using the free C# DDE library at ndde.codeplex.com.

        If you want to send info on the status BACK to your EFS script then you can create a standard C DLL and create a shared data area within it so that your C# program writes to the status variables and the EFS side reads them. I wouldn't recommend communicating through a an EFS File object unless you are using an SSD drive.

        Really, the most dead simple way to do it if the communication is a little involved is to use 2 variables in the C DLL shared memory:

        1. 1st variable is an int which is set to 1 on the C# side to notify the EFS to look at the 2nd variable.

        2. 2nd variable is an array of strings which act as a queue. This way, if you have multiple messages hitting at once, the EFS can catch and process the series over several passes. Remember, you have price ticks lining up to come in and that has to stay timely so grab 1 message and get the next on another trip into the EFS. The 1st variable will always let you know if something is still in the queue to process.

        [For the queue inside the C DLL, use an int to act as an index and increment that for each new message you want to add to the array. You index into the array of strings with a modulus (of the index variable) so it will always wrap around to the beginning of the array once you get to the last element.]

        Keep everything on the eSignal side "stupid" and everything on the C# program side "smart". You use the eSignal part to generate signals and show pretty lines and arrows and such for the outcomes of what the C# program is managing. The C# program is under your total control when talking to the trading engine you want to use and that's a Good Thing (tm).

        You can do it...stay frosty.
        Well I don't want to send any status back to my EFS file. So, in that case I am better off using DDE for inter-process communication. I will follow your suggestion on creating DDE object in my efs and sending signals to my C# program.

        Thanks again for your help. I will work on this now and will keep you updated.

        Regards,
        Vipin

        Comment


        • #5
          Originally posted by naboutboul View Post
          Well I don't want to send any status back to my EFS file. So, in that case I am better off using DDE for inter-process communication. I will follow your suggestion on creating DDE object in my efs and sending signals to my C# program.

          Thanks again for your help. I will work on this now and will keep you updated.

          Regards,
          Vipin
          Hi,
          I have been playing with NDde API for couple of days and it seems I am facing problems while trying to connect to my server ("eSignal"). It seems, I am not providing the right service or topic string to the function.

          Here is the eSignal code where I have created DDE objects.
          Code:
          var ddeOpen = new DDEOutput("pbOpen");
          var ddeHigh = new DDEOutput("pbHigh");
          var ddeLow = new DDEOutput("pbLow");
          var ddeClose = new DDEOutput("pbClose");
          
          function preMain() {
              setPriceStudy(true);
              setStudyTitle("DDE OHLC");
              setShowCursorLabel(false);
          }
          
          function main() {
              var vO = open();
              var vH = high();
              var vL = low();
              var vC = close(0);
              
              if(vO != null) ddeOpen.set(vO);
              if(vH != null) ddeHigh.set(vH);
              if(vL != null) ddeLow.set(vL);
              if(vC != null) ddeClose.set(vC);
              
              return;
          }

          Here is my C# code
          Code:
          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Text;
          using NDde.Client;
          
          namespace ESignalDASConnectorDDE
          {
              class ESignalDASConnectorDDEClient
              {
                  private DdeClient client;
                  public void runClient(string service, string topic)
                  {
                      client = new DdeClient(service,topic);
                      client.Disconnected += OnDisconnected;
                      client.Connect();
                      client.BeginRequest(topic, 1, OnRequestComplete, client);
          
                  }
          
                  private static void OnExecuteComplete(IAsyncResult ar)
                  {
                      try
                      {
                          DdeClient client = (DdeClient)ar.AsyncState;
                          client.EndExecute(ar);
                          Console.WriteLine("OnExecuteComplete");
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("OnExecuteComplete: " + e.Message);
                      }
                  }
          
                  private static void OnPokeComplete(IAsyncResult ar)
                  {
                      try
                      {
                          DdeClient client = (DdeClient)ar.AsyncState;
                          client.EndPoke(ar);
                          Console.WriteLine("OnPokeComplete");
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("OnPokeComplete: " + e.Message);
                      }
                  }
          
                  private static void OnRequestComplete(IAsyncResult ar)
                  {
                      try
                      {
                          DdeClient client = (DdeClient)ar.AsyncState;
                          byte[] data = client.EndRequest(ar);
                          Console.WriteLine("OnRequestComplete: " + Encoding.ASCII.GetString(data));
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("OnRequestComplete: " + e.Message);
                      }
                  }
          
                  private static void OnStartAdviseComplete(IAsyncResult ar)
                  {
                      try
                      {
                          DdeClient client = (DdeClient)ar.AsyncState;
                          client.EndStartAdvise(ar);
                          Console.WriteLine("OnStartAdviseComplete");
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("OnStartAdviseComplete: " + e.Message);
                      }
                  }
          
                  private static void OnStopAdviseComplete(IAsyncResult ar)
                  {
                      try
                      {
                          DdeClient client = (DdeClient)ar.AsyncState;
                          client.EndStopAdvise(ar);
                          Console.WriteLine("OnStopAdviseComplete");
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine("OnStopAdviseComplete: " + e.Message);
                      }
                  }
          
                  private static void OnAdvise(object sender, DdeAdviseEventArgs args)
                  {
                      Console.WriteLine("OnAdvise: " + args.Text);
                  }
          
                  private static void OnDisconnected(object sender, DdeDisconnectedEventArgs args)
                  {
                      Console.WriteLine(
                          "OnDisconnected: " +
                          "IsServerInitiated=" + args.IsServerInitiated.ToString() + " " +
                          "IsDisposed=" + args.IsDisposed.ToString());
                  }
                  
                  static void Main(string[] args)
                  {
                      ESignalDASConnectorDDEClient client = new ESignalDASConnectorDDEClient();
                      [B]client.runClient("eSignal", "EFS!pbClose");[/B]
                  }
              }
          }
          Here is the exception I am getting while running C#

          Code:
          Unhandled Exception: NDde.DdeException: The client failed to connect to "eSignal
          |EFS!pbClose".  Make sure the server application is running and that it supports
           the specified service name and topic name pair. ---> NDde.Foundation.DdemlExcep
          tion: The client failed to connect to "eSignal|EFS!pbClose".  Make sure the serv
          er application is running and that it supports the specified service name and to
          pic name pair.
             at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate meth
          od, Object[] args, Boolean synchronous)
             at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
             at NDde.Advanced.DdeContext.DdeThread.Invoke(Delegate method, Object[] args)
             at NDde.Client.DdeClient.Connect()
             --- End of inner exception stack trace ---
             at NDde.Client.DdeClient.Connect()
             at ESignalDASConnectorDDE.ESignalDASConnectorDDEClient.runClient(String servi
          ce, String topic) in C:\Users\0004\documents\visual studio 2010\Projects\ESignal
          DASConnectorDDE\ESignalDASConnectorDDE\Program.cs:line 16
             at ESignalDASConnectorDDE.ESignalDASConnectorDDEClient.Main(String[] args) in
           C:\Users\0004\documents\visual studio 2010\Projects\ESignalDASConnectorDDE\ESig
          nalDASConnectorDDE\Program.cs:line 107
          Press any key to continue . . .
          Any suggestions on who this can be solved?

          Thanks and Regards,
          Vipin

          Comment


          • #6
            Start your EFS script first, then just use StartAdvise. For every new value that the item gets in your EFS, your OnAdvise callback will be invoked on the C# side and then you get the value from args.Text. [If you want your C# program to start first, have fun with the try block exception coding. My stuff isn't commercial so I know the service, topic and items are always there.]

            If all you're sending over is OHLC values at the same time then you can create one item, concat the open/high/low/close values on the EFS side separate by commas (or spaces) and the C# side can split them apart like this:

            string[] msg = args.Text.Split(", ".ToCharArray()); // msg[0] is open value as a string, etc.

            You can create one DdeClient and then StartAdvise each item. The same OnAdvise function gets called for every item but there's an args.Item string you can check to tell which one. Another way is to create multiple clients and have a separate OnAdvise callback for each item. Your choice.

            service is "eSignal"
            topic is "EFS"
            item is "pbOpen"

            Code:
            if (client == null)
            {
              client = new DdeClient(service, topic);
              client.Connect();
              client.Advise += OnAdvise;
            }
            client.StartAdvise(item, 1, true, 60000);

            Comment


            • #7
              Originally posted by SteveH View Post
              Start your EFS script first, then just use StartAdvise. For every new value that the item gets in your EFS, your OnAdvise callback will be invoked on the C# side and then you get the value from args.Text. [If you want your C# program to start first, have fun with the try block exception coding. My stuff isn't commercial so I know the service, topic and items are always there.]

              If all you're sending over is OHLC values at the same time then you can create one item, concat the open/high/low/close values on the EFS side separate by commas (or spaces) and the C# side can split them apart like this:

              string[] msg = args.Text.Split(", ".ToCharArray()); // msg[0] is open value as a string, etc.

              You can create one DdeClient and then StartAdvise each item. The same OnAdvise function gets called for every item but there's an args.Item string you can check to tell which one. Another way is to create multiple clients and have a separate OnAdvise callback for each item. Your choice.

              service is "eSignal"
              topic is "EFS"
              item is "pbOpen"

              Code:
              if (client == null)
              {
                client = new DdeClient(service, topic);
                client.Connect();
                client.Advise += OnAdvise;
              }
              client.StartAdvise(item, 1, true, 60000);
              Hi its working now. Thank you so much for your help. Really appreciate it.

              Comment


              • #8
                Hi Steve,
                This is Vipin again. I have been working on this DDE client thing for extracting data from eSignal but at times my client application crashes with this exception "Client failed to initiate an advise loop". What boggles my mind is couple of weeks ago this same code was running fine. But one day when I restarted my system and tried to execute the program, it gave me the "failed to initiate advise loop exception" and since then I have not been able to run my program.

                Error seems to be coming from "client.StartAdvise(item, 1, true,60000)" marked in bold letters. I just feel there is some thing I am missing out.

                Please help me out in this as I am really facing some stiff deadlines.

                Thanks and Regards,
                Vipin Anand

                Code:
                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Text;
                using NDde.Client;
                using daslibrary;
                
                namespace ESignalDASConnectorDDE
                {
                    class ESignalDASConnectorDDEClient
                    {
                        private DdeClient client;
                        private const int waitSeconds = 5;
                        [NonSerialized()]
                        private itemTrader itemtrader = null;
                        [NonSerialized()]
                        private EventHandler<OrderActiveArgs> orderEvent = null;
                        [NonSerialized()]
                        private EventHandler<Lv1Args> lv1Event = null;
                        [NonSerialized()]
                        private EventHandler<TradeArgs> tradeEvent = null;
                
                        public static Dictionary<String, ESignalDASConnectorDDEClient> clientMap = new Dictionary<string, ESignalDASConnectorDDEClient>();
                
                        private static SocketOrderServer sOS;
                        private static SocketQuoteServer quoteServer = null;
                        private static int masterTraderID;
                        private static string mrrno;
                        private static string masterTraderName;
                        private static int brokerID;
                        private static string route = "ARCA";
                        private static int masterAccountID = 53;
                        private static string username = "####";
                        private static string password = "#####";
                        private static int orderPort = 6500;
                        private static int quotePort = 9510;
                        private static string orderServer = "####";
                        private static string quoteServerAddress = "#####";
                
                        private double askPrice = 0;
                        private double bidPrice = 0;
                        private long bidSize = 0;
                        private long askSize = 0;
                        private double lastTradedPrice = 0;
                        private string symbol = "";
                        private byte exch;
                        private bool isQuoteSet = false;
                
                    
                        //Async event call mechanism for handling level1 quotes
                        private void Lv1Handler(object sender, Lv1Args la)
                        {
                            if (la.TheIssuIfo.secsym.Equals(this.symbol))
                            {
                                this.askPrice = la.TheIssuIfo.l1_AskPrice;
                                this.bidPrice = la.TheIssuIfo.l1_BidPrice;
                                this.bidSize = la.TheIssuIfo.l1_BidSize;
                                this.askSize = la.TheIssuIfo.l1_AskSize;
                                this.lastTradedPrice = la.TheIssuIfo.l1_lastPrice;
                                this.exch = la.TheIssuIfo.PrimExch;
                                isQuoteSet = true;
                            }
                        }
                
                        public void OrderActiveHandler(object sender, OrderActiveArgs oa)
                        {
                
                        }
                
                        public void TradeActiveHandler(object sender, TradeArgs ta)
                        {
                
                        }
                
                        public ESignalDASConnectorDDEClient(string service, string topic, string item)
                        {
                            client = new DdeClient(service, topic);
                            this.symbol = item.Substring(item.IndexOf("_") + 1);
                           
                            if (ESignalDASConnectorDDEClient.sOS == null || !ESignalDASConnectorDDEClient.sOS.IsConnected())
                            {
                                this.connectSocketOrderServer();
                            }
                            this.orderEvent = new EventHandler<OrderActiveArgs>(OrderActiveHandler);
                            this.lv1Event = new EventHandler<Lv1Args>(Lv1Handler);
                            this.tradeEvent = new EventHandler<TradeArgs>(this.TradeActiveHandler);
                            sOS.eventPool.Subscribe("Trade", this.tradeEvent);
                            sOS.eventPool.Subscribe("Order", this.orderEvent);
                            sOS.eventPool.Subscribe("Lv1", this.lv1Event);
                            client.Disconnected += OnDisconnected;
                            client.Connect();
                            client.Advise += OnAdvise;
                            runClient(service, topic, item);
                        }
                
                        private void connectSocketOrderServer()
                        {
                            sOS = new SocketOrderServer();
                            sOS.Connect(orderServer, orderPort);
                            sOS.PkgLongin(username, password, orderServer);
                
                            int timeout = 0;
                            while (timeout <= waitSeconds * 1000) // wait waitseconds(default =3) seconds
                            {
                                timeout += 500;
                                System.Threading.Thread.Sleep(500);
                                itemtrader = sOS.sitemTrader.FindItemByName(username);
                
                                if (itemtrader != null)
                                {
                                    System.Console.WriteLine("DAS Connection established");
                                    try
                                    {
                                        quoteServer = new SocketQuoteServer(sOS);
                                        quoteServer.Connect(quoteServerAddress, quotePort);
                                        quoteServer.PkgLogin(username, password, quoteServerAddress);
                                        masterTraderName = username;
                                        masterTraderID = itemtrader.mtrid;
                                        System.Console.WriteLine("MasterID " + masterTraderID);
                                        brokerID = itemtrader.mbrid; //Ask Don for brokerid
                                        System.Console.WriteLine("BrokerID " + brokerID);
                                        mrrno = sOS.sitemAccount.FindItem(masterAccountID).mitemifo.mrrno; //Ask why at times this gives out null reference exception
                                        
                                    }
                                    catch (Exception e)
                                    {
                                        System.Console.WriteLine(e.StackTrace);
                                    }
                                    break;
                                }
                            }
                
                            if (timeout > waitSeconds * 1000)
                            {
                                System.Console.WriteLine("Connection problem and timed out");
                                Environment.Exit(0);
                            }
                
                        }
                
                        private void runClient(string service, string topic, string item)
                        {
                            if (client != null)
                            {
                               [B]client.StartAdvise(item, 1, true,60000);[/B]
                            }
                            
                        }
                
                        private static void OnExecuteComplete(IAsyncResult ar)
                        {
                            try
                            {
                                DdeClient client = (DdeClient)ar.AsyncState;
                                client.EndExecute(ar);
                                Console.WriteLine("OnExecuteComplete");
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("OnExecuteComplete: " + e.Message);
                            }
                        }
                
                        private static void OnPokeComplete(IAsyncResult ar)
                        {
                            try
                            {
                                DdeClient client = (DdeClient)ar.AsyncState;
                                client.EndPoke(ar);
                                Console.WriteLine("OnPokeComplete");
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("OnPokeComplete: " + e.Message);
                            }
                        }
                
                        private static void OnRequestComplete(IAsyncResult ar)
                        {
                            try
                            {
                                DdeClient client = (DdeClient)ar.AsyncState;
                                byte[] data = client.EndRequest(ar);
                                Console.WriteLine("OnRequestComplete: " + Encoding.ASCII.GetString(data));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("OnRequestComplete: " + e.Message);
                            }
                        }
                
                        private static void OnStartAdviseComplete(IAsyncResult ar)
                        {
                            try
                            {
                                DdeClient client = (DdeClient)ar.AsyncState;
                                client.EndStartAdvise(ar);
                                Console.WriteLine("OnStartAdviseComplete");
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("OnStartAdviseComplete: " + e.Message);
                            }
                        }
                
                        private static void OnStopAdviseComplete(IAsyncResult ar)
                        {
                            try
                            {
                                DdeClient client = (DdeClient)ar.AsyncState;
                                client.EndStopAdvise(ar);
                                Console.WriteLine("OnStopAdviseComplete");
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("OnStopAdviseComplete: " + e.Message);
                            }
                        }
                
                        private static void OnAdvise(object sender, DdeAdviseEventArgs args)
                        {
                            Console.WriteLine("OnAdvise: " + args.Text);
                            string[] splitString = args.Text.Split(new char[] {','});
                            bool isMarketOrder = splitString[0].Equals("MARKET") ? true : false;
                            double tradePrice = Double.Parse(splitString[1]);
                            int lotSize = Int32.Parse(splitString[2]);
                            bool isBuyOrder = (splitString[3].Equals("LONG") || splitString[3].Equals("Cover")) ? true : false;
                            ESignalDASConnectorDDEClient.quoteServer.WLSTAddWatch(splitString[4]);
                            while (!ESignalDASConnectorDDEClient.clientMap[splitString[4]].isQuoteSet);
                            ESignalDASConnectorDDEClient.quoteServer.WLSTRemoveWatch(splitString[4]);
                            itemOrder iOrder = ESignalDASConnectorDDEClient.clientMap[splitString[4]].createOrder(splitString[4], lotSize, tradePrice, isBuyOrder,isMarketOrder);
                            String errMsg = "";
                            long mOrig = -1;
                            itemOrder.LSendOrder(iOrder, ref errMsg, true, ESignalDASConnectorDDEClient.sOS, ref mOrig);
                        }
                
                        private static void OnDisconnected(object sender, DdeDisconnectedEventArgs args)
                        {
                            Console.WriteLine(
                                "OnDisconnected: " +
                                "IsServerInitiated=" + args.IsServerInitiated.ToString() + " " +
                                "IsDisposed=" + args.IsDisposed.ToString());
                            
                        }
                
                        private itemOrder createOrder(string symbol, int qty, double executionPrice, bool isBuyOrder, bool isMarketOrder)
                        {
                            itemOrder iOrder = new itemOrder();
                            iOrder.mstatus = 0;
                
                            if (isMarketOrder == true)
                            {
                                iOrder.mstatus |= 1 << 9; // placing market order
                
                                if (isBuyOrder == true)
                                {
                                    iOrder.mstatus |= 1 << 6;
                                    iOrder.mprice = this.askPrice;
                                }
                                else
                                {
                                    iOrder.mprice = this.bidPrice;
                                }
                            }
                            else
                            {
                                if (isBuyOrder == true)
                                {
                                    iOrder.mstatus |= 1 << 6;
                                }
                                iOrder.mprice = executionPrice;
                                iOrder.mtmforce = 65535;
                            }
                
                            iOrder.msecsym = symbol;
                            iOrder.mqty = qty;
                            iOrder.mroute = route;
                            iOrder.maccid = masterAccountID;
                            iOrder.mtrid = masterTraderID;
                            iOrder.mbrid = brokerID;
                            iOrder.mrrno = mrrno;
                            iOrder.mexchange = this.exch;
                
                            return iOrder;
                        }
                
                        static void Main(string[] args)
                        {
                            ESignalDASConnectorDDEClient []client = new ESignalDASConnectorDDEClient[6];
                            String[] builder = {"TNA"};/*,"FAS","GLD","SPY"};*/
                            int i = 0;
                            while (true)
                            {
                                if(client[i] == null && i < builder.Length)
                                {
                                    client[i] = new ESignalDASConnectorDDEClient("eSignal", "EFS", "DASConnector_" + builder[i]); //DASConnector_
                                    clientMap.Add(builder[i], client[i]);
                                    i++;
                                }
                            }
                        }
                    }
                }

                Comment


                • #9
                  Hey Vipin,

                  Sorry, I haven't been coming around here much and just saw your post.

                  You'll get a StartAdvise exception if there's nothing to advise. In other words, the item doesn't exist. You got past the Connect() which means the DDE service ("eSignal") and the topic ("EFS") exist. Now, the full exception message you reported is:

                  The client failed to initiate an advise loop for "eSignal|EFS!yourname", where the item, "yourname" is the problem.

                  So, in your EFS scripts, check to make sure all of your item names from the DDEOutput calls match up with what you're checking for in your C# code. Next, make sure all of those EFS scripts are actually running on some chart. For debug purposes, you can bring up Excel and make some DDE cells to check on the values being output. If you don't get values for all of your items then you know that's the problem. [If you don't have Excel, then the free LibreOffice or OpenOffice spreadsheets can do the same thing with slightly different syntax...google this if you don't know how to to do it. Off the top of my head, with Excel, I think you enter for a cell, =service|topic!item (=eSignal|EFS!item) and the current value from the last set call from your eSignal script will show up in the cell.

                  Like I mentioned before, for pro stuff, you need to catch and report the exceptions for Connect() and StartAdvise() in a non-scary way (lol) so your C# program doesn't blow up...and your benefactor's patience in the process.

                  Hope that fixes it. Good luck!

                  Comment

                  Working...
                  X