Download MetaTrader 5
To add comments, please log in or register
Sell your CPU capacity and earn money!
Michael
500
Michael 2016.12.02 08:24 

Good news is I'm trying to do this in only 1 way.  C# managed program to MQL4.

Now, when the DLL code is this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;

namespace DLLTest
{
    public class DataEx
    {
        struct MyStruct
        {
            
            public double num1;
            public double num2;
        }

        static MyStruct DataSet;

        [DllExport]
        public static double GoForNums(out double n1, out double n2)
        {
            n1 = DataSet.num1;
            n2 = DataSet.num2;
            return (DataSet.num1 * DataSet.num2);
        }

        [DllExport]
        public static double GetData()
        {
            return (DataSet.num1);
        }

        public static bool PutGoForNums(double n1, double n2)
        {
            DLLTest.DataEx.DataSet.num1 = n1;
            DLLTest.DataEx.DataSet.num2 = n2;
            return (true);
        }
    }
}

 ..And the C# code is this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleDotNet
{
    class Program
    {
        static void Main(string[] args)
        {
            bool my = false;
            my=DLLTest.DataEx.PutGoForNums(5, 3);
            double data1, data2;
            double results = DLLTest.DataEx.GoForNums(out data1, out data2);
            Console.WriteLine("{0} and {1}", data1, data2);
            Console.WriteLine("Enter");
            Console.ReadLine();
        }
    }
}

 I can easily transfer data back and forth with the C# program to and from itself; not with the EA.

Change the one DLL statement to:

        public static bool PutGoForNums(double n1, double n2)
        {
            DLLTest.DataEx.DataSet.num1 = n1;
            DLLTest.DataEx.DataSet.num2 = n2;
            return (true);
        }

to this:

        [DllExport]
        public static bool PutGoForNums(double n1, double n2)
        {
            DLLTest.DataEx.DataSet.num1 = n1;
            DLLTest.DataEx.DataSet.num2 = n2;
            return (true);
        }

 ...And the mql4 EA can talk back and forth to the EA to and from itself; not with the C# program.

But I can't get the EA to work with first DLL code above.  I can't remember what I'm missing.

EA Code:

//+------------------------------------------------------------------+
//|                                                     test dll.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#import "DLLTest.dll"
double GoForNums(double &n1,double &n2);
#import
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double num1=0, num2=0, result=0;
   result=GoForNums(num1,num2);
   Print("result:",result,". num1:",num1,". num2:",num2);
  }
//+------------------------------------------------------------------+

 TIA!

-Non 

Alain Verleyen
Moderator
29607
Alain Verleyen 2016.12.02 09:23  

Forum on trading, automated trading systems and testing trading strategies

C# expert advisors, don't waste your time

Matthew Colter, 2016.11.27 05:01

I've spent a lot of time looking around at different options for writing expert advisors in C# and I can tell you with certainty that all of the available solutions are terrible. Wasting your time attempting to write expert advisors in any language besides MQL is a terrible idea. I know, you want to use a modern programming language that lets you do routine things without rewriting common algorithms that were pretty well thought out over a decade ago, well too bad. You're stuck using this domain specific language, with all it's limitations and bugs, and the only solutions out there are basically wrappers that pass information back to MQL functions anyway. Skip the whole mess of debugging the language you choose, the wrapper layer, and then the MQL layer, just to get Linq, third party libraries that work, garbage collection, expert systems, etc. oh... and Try {} Catch {}, you don't need any of that.

Basically, there are two flavors of wrapper out there in any sort of useful state:

1. Create a server wrapping every MQL function in an expert advisor, script, or indicator, then have the C# expert advisor post messages that the MQL code reads and executes in a loop.

2. Create an unmanaged dll exporting every MQL function, call those unmanaged functions in managed code and deal with marshaling, disposing, and basically managing the unmanaged code... but hey, you're still going to need an expert advisor, script, or indicator that loads the unmanaged dll and initiates the whole process so... basically messages and loops that end up in MQL again.

You just can't escape the DSL here, so stop trying. There is no client API, no UI plugin system, no UI extension system. You can just create unmanaged C++ dll and consume them in your MQL expert advisors. Don't cry, that's just how it is, and the deeper you look the more you can see that it is completely intentional. You will write code, and you will be locked into this platform, end of story.

If you want a trading platform that allows you to code in C# and trade with reputable brokers, just google it. If you love Metatrader, learn it's language.


Michael
500
Michael 2016.12.02 18:27  
Alain Verleyen:

Thanks for the opinion.  But not helpful at all.  The EA is in MQL 4.  C# is just a data source.

Please read the post. 

Blahtech Limited
3548
James Cater 2016.12.02 20:12  
Michael:
 

 ...And the mql4 EA can talk back and forth to the EA to and from itself; not with the C# program.

But I can't get the EA to work with first DLL code above.  I can't remember what I'm missing. TIA!

Michael,

When you call the DLL from the MQL4 EA all you get is a copy of that compiled code in your MQL4 application space. It's not much different to writing the method directly in MQL4.

You do NOT get a C# application that starts up in managed space and somehow miraculously attaches to the MQL4 code.

If you want to communicate between an MQL4 application and another application you have to setup the inter process communications somewhere.

You could do this with MQL4 sending HTML to a C# or any other language web service. Alternatively your could setup the communications inside the C# client dll, but this still has to communicate with a separate C#  service of some description.

This is not trivial whichever route you take, and unless you have a 10k lines of C# in a library that you must use I suspect it'll be 10x quicker to implement the functionality in MQL4

Michael
500
Michael 2016.12.02 21:33  
James Cater:

Michael,

When you call the DLL from the MQL4 EA all you get is a copy of that compiled code in your MQL4 application space. It's not much different to writing the method directly in MQL4.

You do NOT get a C# application that starts up in managed space and somehow miraculously attaches to the MQL4 code.

If you want to communicate between an MQL4 application and another application you have to setup the inter process communications somewhere.

You could do this with MQL4 sending HTML to a C# or any other language web service. Alternatively your could setup the communications inside the C# client dll, but this still has to communicate with a separate C#  service of some description.

This is not trivial whichever route you take, and unless you have a 10k lines of C# in a library that you must use I suspect it'll be 10x quicker to implement the functionality in MQL4

Thanks.  I wish I could implement it all in MQL4 but the data source is a c# application.  Said c# application is the data I'm trying to get to MQL4.
Blahtech Limited
3548
James Cater 2016.12.02 22:34  
Michael:
Thanks.  I wish I could implement it all in MQL4 but the data source is a c# application.  Said c# application is the data I'm trying to get to MQL4.

Well the three easiest ways to integrate are

1) Write the results from C# to a file and load them into your EA periodically

2) Create a web service for the C# app and call the web service from MQL4 using HTML

3) Implement c# dll that actually connects to your existing app and pulls out the data. Then pass the data values back as simple strings and doubles to the MQL4 caller

Michael
500
Michael 2016.12.03 01:01  
James Cater:

Well the three easiest ways to integrate are

1) Write the results from C# to a file and load them into your EA periodically

2) Create a web service for the C# app and call the web service from MQL4 using HTML

3) Implement c# dll that actually connects to your existing app and pulls out the data. Then pass the data values back as simple strings and doubles to the MQL4 caller

Thanks again James.  #3 is actually what I was thinking now.  2 c# dll's; dll1 for mql4 to talk to.  this dll, when triggered by mql4, would communicate with dll 2 that would store the values from the application. 

Or just use pipes.  But I see collisions abound with that option.  :) 

Michael
500
Michael 2016.12.07 00:32  
James Cater:

Well the three easiest ways to integrate are

1) Write the results from C# to a file and load them into your EA periodically

2) Create a web service for the C# app and call the web service from MQL4 using HTML

3) Implement c# dll that actually connects to your existing app and pulls out the data. Then pass the data values back as simple strings and doubles to the MQL4 caller

James, I tried the first 2.

1) caused a lot of collisions (both sides trying to read the files at the same time).

2) got this to work, but opened up a whole new can of worms from a security perspective.  Not feasible for what the target it.

3) I'm trying to figure this one out.  The first part would be the DLL pulling the data from the app, it would be the app sending the data to the DLL.  Unless I implement 2 DLL's.  One that the c# app puts the data in (DLL a).  One that MQL4 calls (DLL b) to go get the data in DLL a.  But how?  I don't see how the exported procedure in DLL b can call the one in DLL a.  Any ideas?

Blahtech Limited
3548
James Cater 2016.12.07 01:17  
Michael:

James, I tried the first 2.

1) caused a lot of collisions (both sides trying to read the files at the same time).

2) got this to work, but opened up a whole new can of worms from a security perspective.  Not feasible for what the target it.

3) I'm trying to figure this one out.  The first part would be the DLL pulling the data from the app, it would be the app sending the data to the DLL.  Unless I implement 2 DLL's.  One that the c# app puts the data in (DLL a).  One that MQL4 calls (DLL b) to go get the data in DLL a.  But how?  I don't see how the exported procedure in DLL b can call the one in DLL a.  Any ideas?

You only need one DLL that the MQL4 client uses. This client side DLL would be implemented in C#.

However you must create a server side application in C# that the DLL code can attach to. This can either be run on the command line or as a service.

The C# client DLL communicates with the server using C# object serialisation which is all built into the .NET environment. (you can even choose the transport mechanism from configuration files)

This is all standard C# client server stuff, but it does take a bit of work to set it up in the first place. (There should be many examples on Google)

/
To add comments, please log in or register