MT4のEAをcTraderのcBotに置き換える作業の全記録

   2015/04/19

(まさかの)手動変換です!

変換サイトを使おうとしたものの失敗に終わったので1つずつ調査しながら変換していきます・・・。

前回の記事:MetaTrader4のEAをcTraderのcBotへ移植した・・・いや、してみたい。

おな、この記事は「MetaTrader4のEA(MQL4)が読める。C#の知識は無い。」という前提で書いています。

(とりあえずC#を覚えなくてもなんとかなるのではないかと。詳細は少しずつ覚えていけばいいと思います。)

新規作成

WS000475

cAlgo.APIとかをusingしておくことでcAlgo用の機能を呼び出せるんでしょう。

Linqとか必要だろうか?・・・まだ良く分かりませんのでこの辺りは触れません。

namespaceもこのままでいいのでしょう。

Public class EA名 : Robot というのが出てきました。これもC言語ベースのMQL4には無いですね・・・。

C#はオブジェクト指向言語です。PublicクラスをEA_Nameという名前で宣言、Robotクラスを継承している・・・のですが、とりあえず、あまりオブジェクト指向を気にしなくても書けるんじゃないかなーって思いますw(たぶんですけど)

パラメーター

MetaTrader4(以下MT4)では以下のように記述します。

extern int hoge = 123456;

cAlgoではこのようにします。

[Parameter(“hoge”, DefaultValue = 123456)] public int hoge { get; set; }

見てだいたいわかりますね?

hogeというパラメーターを規定値123456で宣言。 publicをつけて宣言するとClassの外からでも設定できます。get; set; と書いているので外部から値の読み書きが可能ということでしょう。

MT4では宣言したパラメーター名がそのまま設定画面に表示されていましたが、cAlgoでは表示用の名前とプログラムで使用する変数名を別に定義しているので、使う人が分かりやすい表示にできます。

[Parameter(“Take Profit (pips)”, DefaultValue = 40)] public int TakeProfitInPips { get; set; }

使う人に見えるのは「Take Profit(pips)」で、プログラム内で使用する変数はTakeProfitInPipsになります。

さて・・・これをパラメーターの数だけ定義していきます・・・。

グローバル変数

関数外(大抵はパラメーターの下あたり)に定義していた「どの関数からも参照できる変数(グローバル変数)」は、MT4で以下のように定義します。(関数の外に変数を定義)

bool IsTrade = false;

cAlgoでも同じように書けます。

bool IsTrade = false;

c#ではこの変数を「グローバル」と呼びませんが。(そもそもグローバルじゃない) 細かいことは気にしない方針です。

関数

WS000476

MT4にはOnInit()、OnDeinit()、OnTick()という関数がありましたが、それに対応するのがこれらの関数(C#ではメソッド) です。

OnStart()とOnInit()が同じ、OnStop()とOnDeinit()が同じ、OnTick()は名前も同じです。それぞれ対応するメソッドに処理を移植していけばOKでしょう。

ちなみにMT4 Build600より前のバージョンではinit()、deinit()、start()の3種類でした。

独自関数の呼び出し

int value = Hogehoge(); int Hogehoge() { return(0); }

MT4の記述がそのまま使えます。 四則演算や分岐(if)、ループ(forなど)もそのまま移植できる・・・はずです。

インジケーター

インジケーターの使い方は全然違いました。以下のコードは最初から入っていたサンプルソースの一部です。

private RelativeStrengthIndex rsi; rsi = Indicators.RelativeStrengthIndex(Source, Periods);

RSIを使いたい場合にはIndicators.RelativeStrengthIndexメソッドを実行して、結果をRelativeStrengthIndexクラスで受け取ります。

SourceはDataSeriesでどの値を使用するか(OpenとかCloseとか)を指定しています。

MT4でいうところのPRICE_CLOSEとかですね。

例えば、CCIを使いたければ RelativeStrengthIndexをCommodityChannelIndexに変えればOKでしょう。

「そんな長い名称覚えられないよ!」

大丈夫!VisualStudio(やMetaTrader)同様インテリセンスがありますから、最初の数文字を覚えていればなんとかなります(笑) WS000477

RSIの値を使いたい場合には

if (rsi.Result.LastValue < 30)

このように書くようです。ちょっと面倒ですね・・・。

後ろに.Result.LastValueをつければOKと覚えておけば(とりあえず)大丈夫でしょう。(たぶん)

簡単なcAlgoの注文処理

現在の注文情報取得

ほとんどのEAで「現在の注文数」を取得します。ほぼ必須です。 MT4では以下のように取得します。

int orderTotal = OrdersTotal();

しかし、これだとEAの種類や通貨ペアに限らず全部取ってきてしまいます。

実際に使用する場合にはマジックナンバーが一致しているか?も見る必要があるので・・・

for(int i=0; i<=OrdersTotal()-1; i++){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderMagicNumber()!=Magic || OrderSymbol()!=Symbol()) continue;
count++;
}

こんな感じになるでしょうか。

取得した数が0だったら注文無し(ポジション無し)、1以上なら有りです。 これがcAlgoではこんな簡単に書けちゃいます!

Positions.FindAll(Comment, Symbol);

Commentを引数に渡していますが、マジックナンバーと読み替えても良いです。(cBotでは番号でなく文字列で判断します。サンプルではEA名が入っていました)

「同じEAで、同じシンボルのポジションを探して!」という命令文です。

ポジションの有無を調べるだけなら・・・

if(Positions.FindAll(Comment, Symbol).Length == 0) {

これでOKです。0だったらポジション無し。 買いポジションだけを探したければ

Positions.FindAll(Comment, Symbol, TradeType.Buy);

こうなります。簡単ですね!

発注処理(オープン)

MT4の発注処理は(クローズより)簡単でした。

OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,0,0,””,Magic,0,Blue);

OrderSend関数一発です。 cAlgoだとこんな感じ

var volumeInUnits = Symbol.QuantityToVolume(LotSize); ExecuteMarketOrder(TradeType.Buy,Symbol,volumeInUnits,Comment);

ロットサイズは0.1Lotのように渡すのではなく、10000(通貨)といった値を渡すようです。

Symbol.QuantityToVolumeで変換できます。

QuantityToVolumeでコンパイルエラー(2015/4/19追記)

IC Marketsが日本撤退となりまして、FX Proに乗り換えようしたところQuantityToVolumeでコンパイルエラーになりました。

QuantityToVolumeは0.1Lotを10000(通貨)に変えているだけなので・・・

long volumeInUnits = (long)(100000 * LotSize);

のようにすれば回避できます。これで大抵はいけると思いますが単位が異なる場合(商品市場とか?)は別の計算式が必要になるかもしれません。

cTraderが古いだけのようなので、FX Proが最新のcTraderに対応すればエラーにならないはずなのですが・・・。

注文のクローズ

MT4のクローズ処理はちょっと面倒でした。

for(int i=0; i<=OrdersTotal()-1; i++){
if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
OrderClose(OrderTicket(),OrderLots(),Bid,OrderSlippage,Navy)
}

こんな・・・感じ?(かなり適当に書いてるので動かないかもw)

全注文の中から該当するマジックナンバー、該当する通貨ペアのポジションを探してクローズしています。

これが、cAlgoだと以下のようになります。

foreach (var position in Positions.FindAll(Comment, Symbol))
ClosePosition(position);

一瞬目を疑いました(笑)単純に成行でクローズだけならこれで良いようです。

上記以外の注文処理(指値や逆指値での発注、注文の変更など)は以下のサイトでご確認ください。 Trading API (英語)

その他

Symbolオブジェクトが便利

色々な情報を持っています。たとえばスプレッドが知りたいときはSymbol.Spreadとすれば取れます、 他にもSymbol.Digits、Symbol.PipSizeなど良く使う値がSymbolオブジェクトから取れるようです。

日時の取得

MT4では現在の時刻をHour()やMinute()などの関数で取得していました。cAlgoでは以下のように書きます。

Server.Time.Hour Server.Time.Minute

これを使ってトレード時刻の制限(ロンドンオープンから開始、等)ができますね。

ビルド通りました!さぁ、バックテストです!

記事書きながら作っていたら半日以上費やしていました!

なんとか変換できたので実行してみます。

WS000478

はい。全然動いていません!

そんな気はしてた・・・

そりゃそうだろうw

そしてここで更なる追い討ち!

デバッグ機能が無い!

嘘だろ・・・いまどき、MT4でも付いてるぜ・・・?(MT4のデバッグ機能は微妙だけど無いより大分マシ)

まぁ、慌てんなw

これを見ろw

How to debug cBots or Custom Indicators in Visual Studio

なにこれ?VS使えってこと?

そういうことじゃね?

なんだそれ・・・!!

VisualStudio Community 2013でcBotをデバッグ

VisualStudio Community 2013のインストール

VisualStudio Express 2013はインストールしていたのですが、ExpressはcAlgoのデバッグ機能が使えません。

幸いなことにprofessional相当の機能をもつ無償版(小規模企業・個人利用に限る)のVS Community 2013が去年の11月に出ていますのでこれを利用します。

ありがとう!Microsoft!今日だけは感謝する!

以下のサイトからダウンロード&インストールしてください。(※かなり時間かかります!)

Visual Studio Community 2013 Update 4

インストールが終わったら横にある言語パックも(必要に応じて)インストールします。

起動すると英語になっているので、上部メニューのTOOLS>Options…>International Settings>の日本語を選択してOKボタン。

VisualStudioを再起動すると日本語化されます。(cAlgoでしか使わないのであれば、英語のままでも良い気もします。)

WS000480

cAlgoからVisualStudio2013を起動

WS000481

cAlgoのデバッグしたいcBotの上で右クリック(または▼)をクリックしてメニューを表示。 そこからEdit in Viulas Studioを選択します。

WS000479

VSIXインストーラーが起動するので、右下のインストールボタンをクリック。

これでVisualStudioでcBotを開発・デバッグする準備が完了しました。

cBotのデバッグ実行

Edit in Viulas Studioで開くとVisualStudio上にcBotのコードが表示されていますが、「実行」してもエラーになります。

デバッグ実行する場合には以下の手順で「アタッチ」しなければいけません。 メニューのデバッグ>プロセスにアタッチ

WS000482

cAlgo.exeを選択>アタッチボタン

WS000483

忘れずにブレークポイントを置いておきましょう。

WS000484

そして、cAlgo側からcBotを実行!

WS000486

WS000485

すると先ほどのブレークポイントで動作が一時停止します。

あとはVisualStudioを操作して変数の値を確認するなどして、バグを突き止めて叩き潰してやりましょうっ!

debug

やった!お疲れ様でした!

まだ終わってねぇよ!これからだよ!

バグを潰して再実行

VSでアタッチしてからcAlgoで実行。バグ発見したら両方止めて修正、リビルド。

そしてアタッチしてからcAlgoで実行・・・すごく・・・面倒です・・・。

WS000488

動いた!動きましたよ! 期間は2014年1月26日から2015年3月25日です。ほぼ同期間のMT4と比較すると・・・

TesterGraph

うーん・・・動きに違いがありますね・・・。

プログラム側に問題があるのか、データの違いによるものなのか。詳しいことは今後調べていきますが・・・

MT4のEA移植作業記録は以上となります!お疲れ様でした!

※今後も気がついたことがあればこのページに追記していく予定です。

  • このエントリーをはてなブックマークに追加
  • Pocket

コメント一覧

  1. Moo より:

    毎度です。
    改めて読ませて頂いてるところです。

    >デバッグ実行する場合には以下の手順で「アタッチ」しなければいけません
    これってつまりDLLのデバッグ手順って感じなんですか?
    と言う事は、cAlgoがアプリで、cBotはDLLである。

    もしただのDLLであるなら、VisualStudio上でコーディングしてビルドして、出来上がったDLLをcAlgo.exeの有るフォルダにコピーしてから、cAlgoを起動してやればOK?

    コピーしたりなんだりの処理はこちらの記事を参考にすれば良いかなとか思うのですが、実際に自分ではやってないのでアヤフヤですが・・・
    http://c-loft.com/blog/?p=1793

    こちらの方法が良いのかも?
    http://www.atmarkit.co.jp/fdotnet/chushin/vsdebug_03/vsdebug_03_01.html

    少しでも効率的にやりたいですよね~

    • emija より:

      これは公式ページに記載されていたデバッグ方法で・・・それ以外の方法は試していませんのでわかりません。

      C#には違いないのでVSでビルドして・・・というのも不可能ではなさそうな気はしますが、試していないのでなんとも・・・;;
      (私は現在、cBotの開発をしていないので試す気はありません… AxioryでcTrader対応したら考えるかも・・・です。)

  2. Moo より:

    了解です。
    環境が整ったら試して報告に来ます。

  3. […] 専門知識がないと難しいだろう。(参考:MT4のEAをcTraderのcBotに置き換える作業の全記録) […]

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。