C#とMetaTrader（MQL4）の連携方法その2

# 目的
C#とMetaTraderでデータのやり取りをして、トレードパネルを作る。

# データのやり取りに関する実現方法について
データのやり取りに関する実現方法については，主に3種類あると考えられます。

1. 共有メモリを使用する方法
1. ソケット通信による方法
1. ファイルによる方法

恐らく３番目が一番実装しやすいのではないでしょうか。
ただし，３番目の場合，ファイルアクセスのルールを決めないといけないため，少しコードの工夫が必要です。

本稿では，共有メモリによる実装方法について検討したいと思います。

# 共有メモリによるC#とMetaTraderの連携方法について

このあたりもわかりやすいです。

https://corgi-lab.com/programming/csharp-memory-mapped-file/

C＃側からは共有メモリにアクセスしやすいですが、MetaTrader側が厄介です。
基本的にそういった関数は用意されていないので、DLLを介して共有メモリにアクセスする必要があります。

[ふぁい](https://fai-fx.hatenadiary.org/entry/20100207/1265474800)さんが作られたMemMap.dllを改良したものがどっかに落ちていて、昔それをどこかのサイトから頂いたのですが、どのサイトか忘れました。GitHubに置いておきます・・・。



# コード
## C#側

C#側でSellボタンやBuyボタンを押したときは次のようにしています。

```C#

        private void buyBtn_Click(object sender, RoutedEventArgs e)
        {
            int tp;
            int sl;
            double lot;
            tp = (bool)(tpCbx.IsChecked) ? int.Parse(tpTbx.Text) : 0;
            sl = (bool)(slCbx.IsChecked) ? int.Parse(slTbx.Text) : 0;
            lot = double.Parse(lots.Text);
            MemoryMappedViewAccessor accessor = shareMemOrder.CreateViewAccessor();
            // buyは0
            // Write data to shared memory
            string str = "0," + lot + ",,," + sl + "," + tp + ",PANEL," + (DateTime.Now).Millisecond;
            //Trace.WriteLine(str);
            char[] data = str.ToCharArray();
            accessor.Write(0, data.Length);
            accessor.WriteArray<char>(0, data, 0, data.Length);

            // Dispose accessor
            accessor.Dispose();

            //setMemorryString(pushTAG + ".order", str);
            orderFlag = true;
        }

        private void sellBtn_Click(object sender, RoutedEventArgs e)
        {
            //int RequestOrder(string mySymbol,int orderSB,double lot,double value,double sp,double SL,double TP,string comment,int mgno,int orderLimit,color orderColor)
            //Trace.WriteLine("SELL button");
            int tp;
            int sl;
            double lot;
            tp = (bool)(tpCbx.IsChecked) ? int.Parse(tpTbx.Text) : 0;
            sl = (bool)(slCbx.IsChecked) ? int.Parse(slTbx.Text) : 0;
            lot = double.Parse(lots.Text);
            MemoryMappedViewAccessor accessor = shareMemOrder.CreateViewAccessor();
            // sellは1
            // Write data to shared memory
            string str = "1," + lot + ",,," + sl + "," + tp + ",PANEL,"+(DateTime.Now).Millisecond+",";
            //Trace.WriteLine(str);
            char[] data = str.ToCharArray();
            accessor.Write(0, data.Length);
            accessor.WriteArray<char>(0, data, 0, data.Length);

            // Dispose accessor
            accessor.Dispose();

            //setMemorryString(pushTAG + ".order", str);
            orderFlag = true;
        }
```
共有メモリへのアクセスはこの辺ですね！
```C#
MemoryMappedViewAccessor accessor = shareMemOrder.CreateViewAccessor();
// sellは1
// Write data to shared memory
string str = "1," + lot + ",,," + sl + "," + tp + ",PANEL,"+(DateTime.Now).Millisecond+",";
//Trace.WriteLine(str);
char[] data = str.ToCharArray();
accessor.Write(0, data.Length);
accessor.WriteArray<char>(0, data, 0, data.Length);
```

また、MT4→C#/C#→MT4での上下のやり取りがごっちゃにならないように、
```C#
//MT4からC#
share_mem = MemoryMappedFile.CreateNew(pushTAG+".symbol", 256, MemoryMappedFileAccess.ReadWriteExecute);
//C#からMT4
shareMemOrder = MemoryMappedFile.CreateOrOpen(pushTAG+".order", 256, MemoryMappedFileAccess.ReadWriteExecute);
```

として、MT4からC#への返答とC#からMT4への返答の交通整理をしています。

## MQL4

MQL4側は，[ここ](https://github.com/InvestorX/MQL4TradePanelW/tree/master/MQL4)を参考にしながら実装していければと思います。

# 完成品

GitHubにトレードパネルがあるので、みんなで改良していきましょう！

https://github.com/InvestorX/MQL4TradePanelW

# REFERENCEs

https://www.mql5.com/ja/articles/115

https://qiita.com/_T_E_T_R_A_/items/bdd310714fea63474a7b

https://www.ipentec.com/document/csharp-use-memory-mapped-file

https://www.mql5.com/en/articles/1540

https://www.mql5.com/en/code/8577

# さいごに

投資は自己責任！

カレンダー参加者募集してます！

https://qiita.com/advent-calendar/2022/mql

Have a good MQL Life!!!