MT4をLinuxで動かす[Debian9, MT4DLL]


概要

MT4をWindowsVPS風にLinuxで動かしました。
ついでにDLLの動作確認とかもしました。

とりあえずコード

https://github.com/jacob327/linuxMT4

概要・動機とか

別段、特別なことはしていません。Windowsで動かせるものがLinuxで動かない訳がないので動かせるようにした備忘録です。
ただ、MT4という2005年リリースのソフトが未だに使われていて(MT5がだいぶ前にリリースされたにもか関わらず!)、まだまだニーズもあるようなので、とりあえず動くものの雛形を作りました。

※サーバはメモリ2GB以上推奨です。0.6GBで実験したらapt installすらできなくなりました。
ちなみにMT4一台あたりのメモリ上限は2GBです。

コード

mql4

5秒毎にTestMessageをDLLに渡して、DLLから::from DLLを追記して返してもらうプログラムです。

TestAlert.mq4
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#import "MT4DllTester.dll"
    string TestFunction(string);
#import

int OnInit() {
    EventSetTimer(5);
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
    EventKillTimer();
}

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
    return(rates_total);
}

void OnTimer() {
    Alert(TestFunction("TestMessage "));
}

DLL

MT4のstringはWCHAR*型で渡してあげないとうまく解釈してくれないのでWCHAR*にしています。
ただ、今回のプログラムはランダムで文字化けが発生します。これはメモリ云々の話なんでしょうが、今回は割愛します。文字列を正確に渡してあげたい場合は素直にcharの方が良いかもしれません。
この辺の事情はフォーラムが詳しいです

MT4DllTester.cpp
#include "pch.h"
#include "MT4DllTester.h"
#include <codecvt>

MT4_EXPFUNC const WCHAR* __stdcall TestFunction(WCHAR* input)
{
        std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> cv;

        std::wstring w_inp(input);
        std::string s_out = cv.to_bytes(w_inp);

        s_out.append("::from DLL");

        std::wstring w_out = cv.from_bytes(s_out);

        const WCHAR* ret = w_out.c_str();
        return ret;
}

エクスポートする関数を教えてあげます。

Source.def
LIBRARY MT4DllTest
EXPORTS
        TestFunction

VSC++で最初からプロジェクトを作る場合はx86, releaseモードにするのを忘れないでください。
ref) https://www.mql5.com/en/forum/96970

(※C++はよく分かってないのでコードおかしかったら教えてください(´・ω・`))

サーバ側

debian 9(CUIのみ)をインストールした段階を前提とします。

MT4を動かすためのwineとxfce4(デスクトップ環境・xfceは軽いらしいので)、
リモートから接続するためのvnc周りをインストールします。
rootで実行してください

init.sh
#!/usr/bin/env bash

dpkg --add-architecture i386 &&\
apt install -y software-properties-common apt-transport-https &&\
wget -qO - https://dl.winehq.org/wine-builds/winehq.key|apt-key add - &&\
apt-add-repository https://dl.winehq.org/wine-builds/debian/ &&\
apt update &&\
apt install -y --install-recommends winehq-stable winbind &&\
DEBIAN_FRONTEND=noninteractive apt install -y keyboard-configuration &&\
#apt install -y task-xfce-desktop &&\
apt install -y xfce4 xfce4-goodies gnome-icon-theme &&\
apt install tightvncserver &&\
echo '[ALL DONE]

インストールが終わったら以下コマンドでvncサーバが立ちます。
色々聞かれるのでパスワードとかを設定しましょう。

start.sh
vncserver :1 -geometry 800x600 -depth 24

止めるときはこっちです。

stop.sh
vncserver -kill :1

クライアント側

VNCクライアントで接続します。
krdcなら
{ユーザ名}@{IP_OR_HOST名}:{ポート名}
です。
例)[email protected]:5901 (5901: VNCのデフォルトポート)

こんな感じ

※右半分はdstatの出力です。メモリ1.7GBのサーバでこのぐらいでした。

確認したこと

  • DLLは読み込める
  • VNC接続を落としても稼働し続ける
  • VNCサーバを落とすと一緒に落ちる(この辺はよく分かってませんがpsでも落ちてました)

商用利用時に気になること

  • wineの(おなじみの)大量のwarning
  • localhostでDB接続できるか
  • localhostでWebSocket通信できるか