LoginSignup
1
0

More than 1 year has passed since last update.

MT4のトレードパネル

Posted at

目的

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

前提条件

(おさらい)データのやり取りに関する実現方法について

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

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

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

共有メモリを使ってトレードパネルを実装していきたいと思います!!!

画面構成

こんな感じで作りこんでいきます。
image.png

Lotにカーソル合わせると・・・
image.png

あとはどんだけ作りこむかだけなので、実装次第でなんとでもなります。

GitHubに置いてあるのを一番下のリンクに貼りますが、MQL4ファイルがどっからか持ってきたやつのままで、このままだとC#と全然つながりません。(だれもpull requestとかissue上げてくれなかったのはこのせい?と勝手に思っている!!!)

C#

前提条件の記事にあるように

//共有メモリにアクセスするためのメンバ
MemoryMappedFile share_mem;
MemoryMappedFile shareMemOrder;
//MT4->C#/C#->MT4の区別をつけるためのタグ
String pullTAG = "mtexe";
String pushTAG = "exemt";

が大事だと思ってます。

このほかThreadingTimerを使って、200msec毎にMT4から新しいメッセージが来ていないかチェックしています。

Windowがロードされたタイミングで、MT4が起動しているか確認します。

一応、MT4側からは、自分の口座情報的(通貨ペアなど)なものを共有メモリに既に書き込んで置いてあるイメージです。

C#側からこの口座情報的なものを最初に読みます。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    orderFlag = false;
    mt4Status.Text = "未連携";
    Trace.WriteLine("mtexe:" + getMemorryString(pullTAG) + ":");
    Trace.WriteLine(getMemorryString(pullTAG+".array"));
    String getSymbol = getMemorryString("mtexe").Trim().Replace("\0", "");

    share_mem = MemoryMappedFile.CreateNew(pushTAG+".symbol", 256, MemoryMappedFileAccess.ReadWriteExecute);

    shareMemOrder 
       = MemoryMappedFile.CreateOrOpen(pushTAG+".order", 256, MemoryMappedFileAccess.ReadWriteExecute);

    //シンボルがあればMT4との連携ができているものとし、
    //定期実行用のThreadingTimerを動かす。
    if (getSymbol != null && getSymbol.Length > 0)
    {
        timerDelegate = new TimerCallback(requestMTStatus);
        timer = new Timer(timerDelegate, null, 0, 200);
        statusBorder.Background = Brushes.LightGreen;
        mt4Status.Text = "連携済み";
    }
    if (getMemorryString(pullTAG+ ".array") != null && getMemorryString(pullTAG +".array").Length > 0)
    {
        int selectedItem = 0;
        int i = 0;
        String[] sep = { "," };
        String[] f = getMemorryString(pullTAG+".array").Split(sep, StringSplitOptions.RemoveEmptyEntries);
        Trace.WriteLine("\r\nMT4通貨:" + getSymbol);
        foreach (String str in f)
        {
            if (str.IndexOf(getSymbol) > -1)
            {
                selectedItem = i;
            }
            else
            {
                i++;
            }
            comboBox.Items.Add(str);
        }

        //Trace.WriteLine("MT4側の選択されている通貨は?" + selectedItem);
        comboBox.SelectedItem = selectedItem;
        comboBox.Text = getSymbol;
    }
}

次に定期実行されるrequestMTStatusですが、requestMTStatus内では、MT4側から流れてくるであろうBidとAskの価格を表示させるようにします。

スプレッドもついでに表示させます。


private void requestMTStatus(object state)
{

    this.Dispatcher.Invoke(() =>
    {
        try
        {
            //
            String orderEnable = getMemorryString(pullTAG + ".order");
            orderEnable = orderEnable.Replace("\0", "");
            if (orderEnable.Length > 0)
            {
                if (orderFlag)
                {
                    Trace.WriteLine("o:" + orderEnable);
                    MemoryMappedViewAccessor accessor = shareMemOrder.CreateViewAccessor();
                    // sellは1
                    // Write data to shared memory
                    string orderStr = "";
                    char[] data = orderStr.ToCharArray();
                    accessor.Write(0, data.Length);
                    accessor.WriteArray<char>(0, data, 0, data.Length);

                    // Dispose accessor
                    accessor.Dispose();
                    orderFlag = !orderFlag;
                }
            }


            String val = getMemorryString(pullTAG+".value");
            //Trace.WriteLine(val);
            textBlock.Text = val;
            String[] sep = { "," };
            String[] sep2 = { "." };
            String[] str = val.Split(sep, StringSplitOptions.RemoveEmptyEntries);

            //Trace.WriteLine(str[0]+","+str[1]);
            String[] bid = str[0].Split(sep2, StringSplitOptions.RemoveEmptyEntries);
            String[] ask = str[1].Split(sep2, StringSplitOptions.RemoveEmptyEntries);

            int digits = int.Parse(str[2].Replace("\0", ""));
            digits = digits - 3 < 0 ? 0 : digits - 3;
            int index = str[0].IndexOf(".");

            selltextBlock.Text = "";
            Underline underline = new Underline();
            Run run = new Run();
            run.Text = "SELL\n";
            run.Foreground = Brushes.White;
            run.FontSize = 16;
            underline.Inlines.Add(run);
            underline.Foreground = Brushes.White;

            this.selltextBlock.Inlines.Add(underline);
            selltextBlock.TextAlignment = TextAlignment.Right;
            this.selltextBlock.Inlines.Add(bid[0] + "." + bid[1].Substring(0, digits));
            run = new Run();
            run.Text = bid[1].Substring(digits, 2);
            run.FontSize = 24;
            this.selltextBlock.Inlines.Add(run);
            //int qr = digits - 2;
            this.selltextBlock.Inlines.Add(bid[1].Substring(digits + 2, 1));
            sellBtn.Content = selltextBlock;

            //buyの処理
            buytextBlock.Text = "";
            Underline underline2 = new Underline();
            Run run2 = new Run();
            run2.Text = "BUY\n";
            run2.Foreground = Brushes.White;
            run2.FontSize = 16;
            underline2.Inlines.Add(run2);
            underline2.Foreground = Brushes.White;

            this.buytextBlock.Inlines.Add(underline2);
            buytextBlock.TextAlignment = TextAlignment.Left;

            this.buytextBlock.Inlines.Add(ask[0] + "." + ask[1].Substring(0, digits));
            run2 = new Run();
            run2.Text = ask[1].Substring(digits, 2);
            run2.FontSize = 24;
            this.buytextBlock.Inlines.Add(run2);
            this.buytextBlock.Inlines.Add(ask[1].Substring(digits + 2, 1));
            buyBtn.Content = buytextBlock;

            spreadTbk.Text = "";
            Run run3 = new Run();
            run3.Text = "Spread\n" + str[3];
            run3.FontSize = 18;
            this.spreadTbk.Inlines.Add(run3);
            this.spreadTbk.TextAlignment = TextAlignment.Center;



        }
        catch (Exception ex)
        {
            Trace.WriteLine(ex.ToString());
        }

    });

}

あとは、BUYボタン押したときやSELLボタン押したときの処理をMT4側に流してあげれば良いです。

MQL側

ソースコード探してます。

///ソース見つかったら更新します!!!

完成品

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

REFERENCEs

さいごに

投資は自己責任!

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

Have a good MQL Life!!!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0