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.

Tuesday, October 18, 2011

Misc VB6 to C# Commands

Quick reference VB6 to C#

Q: How do you replicate VB6's Debug.Print in C#?
A: In C#, Add using System.Diagnostics; to the top of the project. Then it is possible to use:

   Debug.Print("debug text");
   Debug.Write("writes without adding the newline character");
   Debug.WriteLine("writes with adding the newline character");

All three methods write to the Immediate window in C# just as Debug.Print does in VB6.

----------------------------------------------------------------
Q: How do you replicate the VB6 mid$ function in C#?
   VB6: mid$("ABCDEFG12345", 7, 2)
returns "G1"

   C# Debug.Print("ABCDEFG1234".Substring(6, 2));
returns "G1"
(note how in VB6 strings the first string's (A in the string above) reference is 1, while in C# the first string's reference is 0.)
----------------------------------------------------------------
Q: How do you call a routine in C# or why do I get the error: 

Only assignment, call, increment, decrement, and new object expressions can be used as a statement


VB6: Call myRoutine or
         myRoutine

C#: myRoutine(); // you must add the () at the end of the routine in C#!

Thursday, August 18, 2011

MT4 to R Project

I stumbled upon an interesting interface written to connect Metatrader (MT4) to the R project for statistical computing. If you have an active R installation, you can access R through MT4 via the mt4R.dll. mt4R.dll was created as an interface to wrap the functions of Rterm.exe, a component of the R project that is meant to allow batch mode access to the R terminal. mt4R.dll is a wrapper for Rterm.exe that exposes the R functionality in a well documented and intuitive manner.

Metatrader is a charting package for trading forex. If you like Metatrader, you will like the R for MetaTrader project, where you can download mt4R.dll as well as sample MT4 code to interface MT4 with R. There is a discussion about R for Metatrader on Forex Factory.

I plan to use mt4R.dll to interface VB6 to R, thus saving me from having to implement my own interface. In this effort I have found partial success, though I'm still struggling with a matrix conversion issue of the original interface, and may post more on a VB6 wrapper for mt4R.dll as time goes by.

Tuesday, August 2, 2011

Write C# DLL for Metatrader (CSharp)

Those C# developers who would like to write a DLL in C# for Metatrader instead of in C++ now have a path to that end. There is a very interesting article titled "Exposing C# code to MQL5 using unmanaged exports" that I've just read. I use MT4 (MQL4) instead but the idea is still valid.

Read/skim the article and read section 2.5 onward.
Exposing C# code to MQL5 using unmanaged exports - MQL5 Articles

Read the directions, then download the Template for C# "Unmanaged Export Library" and place the zip file in the right directory (by following the directions on that page):
C# Project Template for Unmanaged Exports

Load Microsoft Visual Studio 2010 (or  Microsoft Visual C# 2010 Express) and select the "Unmanaged Export Library" template. Follow the code samples. Hope this helps somebody!

You can find sample code for creating a C# dll with the Unmanaged Export Library here  including  a download for the visual studio solution and the MT4 sample script.