Thursday, October 25, 2012

Harness the Power of Machine Learning in MT4 to Create a Metatrader Indicator with Encog

This step by step guide shows how to create and test an Encog machine learning method using inputs from MT4 indicators to create an indicator that can be used in Metatrader. By using machine learning methods such as neural networks, genetic algorithms, support vector machines and other machine learning methods Encog allows an ensemble approach to design of machine learning indicators that may be used in MT4.

This looks very interesting!

Creating a MQL4 Indicator with Encog

Monday, September 17, 2012

C# ZeroMQ Install Step by Step for Visual Studio.

ZeroMQ is a socket library that has many uses and claims to be faster than TCP for clustered products and supercomputing. Sounds interesting! In attempting to install ZeroMQ for C# in Visual Studio, I found that the documentation was not very clear, and nowhere could I find a step by step guide for installing C# ZeroMQ.

This post is made so I can recall the ZeroMQ C# installation steps for future reference, and in hopes that someone else might have an easier path to ZeroMQ installation in Visual Studio.

The easiest way to get ZeroMQ working for C# is by using a Visual Studio Extension called NuGet. To download NuGet from within Visual Studio, use the Tools / Extension Manager menus.

From within Visual Studio's Extension Manager, click on Updates and wait for the list to populate. Select NuGet Package Manager, and wait for the package to download and install.

To display the NuGet Package Manager select View / Other Windows / Package Manager Console from the menus. Make sure your Visual Studio project is set to either x64 or x86 from the Project / Properties menu in Visual Studio, then install the appropriate package from the link above

The installation package for ZeroMQ is clrzmq 2.2.5 or clrzmq-x64 for x86 or x64 projects respectively.

In Visual Studio's Project Manager Console type one of the following in:

PM> Install-Package clrzmq -Version 2.2.5
PM> Install-Package clrzmq-x64

This command will install the appropriate version in your package. I created an x64 project with the command directly above. This created a new directory under my project.

Open up Windows Explorer and find your project's folder. You should see a new subfolder called packages\clrzmq-x64.2.2.5\content that contains the libzmq.dll library if you are doing an x64 project.

Copy libzmq.dll to your \bin\Debug or \bin\Release directory so that your project can find the dll.

Prepare one of the sample codes that are available on github for C#.

For your next project you will need to once again use the Package Manager Console to build the libzmq.dll and create the clrzmq and clrzmq-ext References in C#, so make a note of the installation command and file copying procedure for future reference:


PM> Install-Package clrzmq -Version 2.2.5
PM> Install-Package clrzmq-x64


As a post script, the ZeroMQ Windows installation doesn't seem to be necessary for C# users. In fact, I uninstalled it and was still able to run my demo project. The installation contains some executables and dlls, as well as a number of help documents that may be of interest to developers.

Tuesday, September 11, 2012

Writing A Chunk of Data to File in C# and VB6

In Visual Basic 6 / VBA it is possible to quickly write a lot a data to file in just a couple of steps. By creating a user defined type that contains the data, and then using an array of user defined types, all that data can be loaded from and saved to disk in a very easy manner. Below is some pseudo code melded from a couple of my VB6 projects to illustrate the point for loading all data in one shot:
VB6 Code:
' declarations
' 16 byte data storage
Private Type TimeSales5
    ntSymNum As Byte
    ntDay As Byte
    ntMonth As Byte
    ntYear As Integer
    ntHour As Byte
    ntMinute As Byte
    ntSecond As Byte
    ntBid As Long
    ntAsk As Long
End Type
VB6 Code:
' Main Load Routine
Sub LoadFromFile(ByVal sName as string)
    dim uTick() as TimeSales5
    iFreeTSFile = FreeFile
    Open "C:CompleteData2\" & sName & ".ts3" For Binary As #iFreeTSFile
    cLen = LOF(iFreeTSFile)

    lRecords = cLen / 16 - 1
    If lRecords >= 0 Then
        ' size the uTick type to receive all the file's records
        ReDim uTick(lRecords) 
        Get #iFreeTSFile, , uTick ' load all the data
        ' code to assign the fields from uTick to native 
        ' types (double, long etc)
    End If
End Sub
Simple VB6 code to save all data in a user defined type one line of code based on the snippet above might be:
Put #iFreeTSFile, , uTick

Is there an equivalent to VB6 binary file writing of user defined types in C#? I searched quite a bit for a simple yet elegant solution to reading and writing custom file formats in C#.  The answer, it seems is using C#'s Stream object for file access and BinaryFormatter to serialize a custom data class to and from disk.

Now that the table has been set, it's time for a paradigm shift from the VB6 mentality of writing binary files to the C# way of writing data to file via Serialization. There are other ways to write data to file in C# but using C# Serialization and DeSerialization for file writing and reading  seems most similar to writing a VB6 user defined type to file in one shot or reading from file in one shot.

Code from SaveFormat class
C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyNamespace {
    [Serializable()]
    class SaveFormat {
        private static int MAXROWS = 1000;
        private static int MAXTABS = 50;
        public DateTime[] dateTime = new DateTime[MAXROWS];
        public double[, ,] EquityCurve = new double[4, MAXTABS, MAXROWS];
        public int[] EquityCurveIndex = new int[MAXROWS];
    }
}
Note the [Serializable()] attribute which tells C# that the SaveFormat class may be written to and read from a file. The class can contain any data format you need to store and retrieve, including as in the above example, multidimensional arrays.

Code from SaveFile class
C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace MyNamespace {
    class SaveFile {
        public static void SaveMultiA(SaveFormat Data, string name) {
            try {
                using (Stream stream = File.Open (name  ,  FileMode.Create)) {
                    BinaryFormatter bin = new BinaryFormatter();
                    bin.Serialize(stream,  Data);
                }
            } catch (IOException ex) {
                MessageBox.Show("Error Saving SaveFormat Storage Class : " 
                 + ex.ToString());
            }
        }
    }
}
The SaveFile class essentially just creates a new C# Stream object with the specified file name and the FileMode.Create option. This stream object is then plugged into a new BinaryFormatter object using the Serialize method. The entire SaveFormat class (and this could be any format) is then serialized to disk via BinaryFormatter.

And finally this is the LoadFile class
C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace MyNamespace {
    class LoadFile {
        public static void LoadMultiA(ref SaveFormat Data, string name) {
            try {
                if (!File.Exists(name)) return;
                using (Stream stream = File.Open (name  ,  FileMode.Open)) {
                    BinaryFormatter bin = new BinaryFormatter();
                    Data = (SaveFormat)bin.Deserialize(stream);
                }
            } catch (IOException ex) {
                MessageBox.Show("Error Loading SaveFormat Storage Class : " 
                 + ex.ToString());
            }
        }
    }
}
The LoadFile class just does this in reverse. Again a new Stream object is created with a valid file name, using the FileMode.Open option. The stream object is then plugged in again to the BinaryFormatter object using the Deserialize method. the Data is cast as (SaveFormat) to ensure the proper translation of the bits.

Allow me to pause for a moment to admire the beauty of the C# code I just posted. While this may seem like a lot of code, sans the using statements, this is just a few lines of actual code in C# and it gives me that good feeling I get from the pithy VB6 code being able to read and write in one swift, decisive operation. Beautiful!

Tuesday, August 14, 2012

Calling R From C# .NET (CSharp DotNet)

As mentioned in a previous post about Calling R From VB6 VBA, I've been using 7Bit's very useful utility to call R from VB6. It is so useful that I needed to have the same capability in C#. So I took my VB6 interface and translated it to C#.

Originally the mt4R.dll tool was created to interface to R from Metatrader. Knowing that this is a windows DLL, therefore mt4R can be accessed from a number of languages, including VB6 and now C#, if a suitable interface is used.

A simple class interface was born in C# that allows .NET users to access R via calls to the mt4R dll. I'm about to embark on a project that will use this newly minted interface in C#.

I've been using this for some time in VB6 but as I'm moving more of my development to C#, and I've decided it was time to share with everyone else. So I put together a simple demo application that shows how to access mt4R.dll in a simple C# Windows form application.

You can download Calling R From CSharp DotNet. (Please follow the instructions on that page) for use in your own projects.

C# / .NET developers don't need to worry about transposing matrices to get them to work in R. R and C# arrays are set up the same way:

A[row, column]

Please let me know if you have any comments, questions or problems getting this code to work.

Calling R From VB6 VBA

I've been using 7Bit's very useful utility to call R from VB6. Originally the mt4R.dll tool was created to interface to R from Metatrader. Knowing that this is a windows DLL, therefore mt4R can be accessed from a number of languages, including VB6, and C# if a suitable interface is used.

To that end I translated the existing Metatrader interface to a simple drop-in VB6 class that may be accessed in Visual Studio, or from VBA from Excel. This handy interface in conjunction with 7Bit's dll allows a VB6 / VBA developer to access the power of the R project directly from code.

I've been using this for some time but decided it was time to share with everyone else. So I put together a simple demo application that shows how to access mt4R.dll in a simple VB6 form application.

You can download Calling R From VB6 VBA. (Please follow the instructions on that page) for use in your own projects.

A note for VB6 / VBA developers:

The array structure of R and VB is not the same. Whereas in R the arrays are arranged as:

A[row, column]

In VB6 / VBA the arrays are declared as follows

Dim A(column, row) as double

When transferring this matrix via Rm (the matrix operation) it will send the data in the correct format if the array in VB is declared as above.

Please let me know if you have any comments, questions or problems getting this code to work.

Tuesday, April 3, 2012

Code to Export C# DLL to Metatrader

Note: updated build 600+ code can be found at Code to Export C# DLL to Metatrader Build 600+.

I worked up a simple sample C# DLL that is properly exported for use with Metatrader. I made use of the template that can be downloaded from C# Project Template for Unmanaged Exports.

C# Code for "testUMD.dll" below using R. Giesecke's template:
Code:
using System;
using System.Text;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace testUnmanagedDLL
{
   class Test
   {
 
        [DllExport("AddInteger", CallingConvention = CallingConvention.StdCall)]
        public static int AddInteger(int Value1, int Value2) {
            MessageBox.Show("Add Integers: " + Value1.ToString() + " " + Value2.ToString());
            return (Value1 + Value2);
        }

        [DllExport("AddDouble", CallingConvention = CallingConvention.StdCall)]
        public static double AddDouble(double Value1, double Value2) {
            MessageBox.Show("AddDouble: " + Value1.ToString() + " " + Value2.ToString());
            double Value3 = Value1 + Value2;
            return (Value3);
        }

        [DllExport("AddDoubleString", CallingConvention = CallingConvention.StdCall)]
        public static string AddDoubleString(double  Value1, double Value2) {
            MessageBox.Show("AddDoubleString: " + Value1.ToString() + " " + Value2.ToString());
            double Value3 = Value1 + Value2;
            return (Value3.ToString() );
        }

        [DllExport("returnString", CallingConvention = CallingConvention.StdCall)]
        public static string returnString(string Input) {
            MessageBox.Show("Received: " + Input);
            return ("SEND to MT4");
        }

        // many thanks to anonymous for the code sample below!
        [DllExport("ReturnDouble2", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        static double ReturnDouble2() {
            return 4.5;
        }

   }


MT4 Script 'testDLL' code below: File testUMD.dll added to experts/libraries folder
Code:
#import "testUMD.dll"
   int AddInteger(int Value1, int Value2);
   double AddDouble(double Value1, double Value2);
   string AddDoubleString(double Value1, double Value2);
   string returnString(string Input);
   double ReturnDouble2(); 
#import
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Print("AddInteger: " + AddInteger(250, 750));
   double a = AddDouble(250,750);
   Print("AddDouble: " + NormalizeDouble(a,4));

   double d = StrToDouble(AddDoubleString(250, 750));
   Print("AddDoubleString: " + NormalizeDouble(d,4));
   string temp = "Send to DLL";
   string recv = returnString(temp);
   Print(recv);
   double dd = ReturnDouble2();
   Print("Returning Double from C#: " + NormalizeDouble(dd, 4));
//----
   return(0);
  }

Cursory Summary: Integer passing = success, double passing MT4 to C# = success, double passing from C# to MT4 = fail, string passing = success. I haven't experimented with arrays. Sample code written with VS 10 .NET 4.0.

If anyone knows how to successfully get doubles to pass from C# to MT4 without conversion to a string, please leave a comment!

------------
Edit: thanks for the feedback from anonymous! The code has been updated to reflect passing a double from C# to Metatrader.

By the way, you must use the 32 bit version of the DLL. The 64 bit version and the "Any CPU" version both failed with error #127 in Metatrader. This is understandable considering MT4 is a 32 bit program. 

As per g3ro's suggestion I have made available for download both the testUnamanagedDLL Visual Studio solution and the testDLL MT4 script. Download testUnmanagedDLL VS solution

Monday, April 2, 2012

Export C# DLL to Metatrader

I've recently learned several methods for exporting a C# DLL for use outside .NET and specifically to Metatrader. The first method was alluded to in the article:
Write CSharp (C#) DLL for Metatrader.

This is a template created to make things simpler.

C# Project Template for Unmanaged Exports

The template method works but you have to delete the default function and use a slightly different syntax. (see next post).

I've seen two other articles that I haven't yet had time to fully explore but that I've heard work for simplifying the export of a C# DLL.

Simple Method of DLL Export without C++/CLI

How to Automate Exporting .NET Function to Unmanaged Programs

This second article looks not too difficult and I've heard good feedback on its implementation.