MT5 取引履歴をCSVでExportするインジケータのサンプルコード 無料
どうも、ひろぽんです。仮想通貨とか為替でMT5とか自動売買のプログラム書いて動かしてたりしてます。
さて、今回は取引履歴からcsv吐き出して処理するプログラム書いたら、いい感じだったので報告します。適当にコードも載せておくので、同じようにマニアックにMQL沼にハマっている方に刺さればいいかなって思います。
間違ってるとことか、こうした方がええやんってアイデアなどありましたらTwitterにDM飛ばしてください。めちゃめちゃ喜びます。
Twitterアカウントのアドレスをnoteにコピペするとこんな感じで表示されるって知りませんでした。。。
いつも通りの駄文ですが、読んでもらえるとうれしいです。えーと、最後まで無料です。
取引履歴をExportする理由
モチベーション
みなさん自分自身のトレード履歴って検証されたりしてるはりますか?恥ずかしながら、僕自身ほとんどしてなかったです。
正確には、バックテストとフォワードの乖離が生じた時とかは、データ擦り切れるまで検証するんですけど、それなりに成績良かったらほったらかしにしてしまいがちなんですよね。
そもそも面倒くさがりなので自動売買をしているってのもあるんですが。。。
で、いろいろとTwitterの名立たるトレーダーさんを見ていると多くの勝ちトレーダーは、自分自身のトレードを見つめ直し改善することを繰り返してるんですよね。もちろん一部の天才は除きますが。
エントリーからイグジットまで次に生かす材料にされてるんですよ。すごいですわ。
自分もせなあかんなって思いながら、ジブラルタルさん主催のトレード大会に参加。為替のEAを動かしていい感じの結果が得られました。
次はサーモンズカップなので、さらに改善しようってモチベーションで、コードを書き始めました。
次は今大会の上位3名くらいの利益率を目指したいなぁって思っています。
単純に倍以上なので、Lotを倍にしてEAが耐えるのであれば、ワンチャン行けると思っています。これが今回のモチベですね。
MT5の取引履歴は使いにくい
取引履歴が出せるやんってお思いの方もいらっしゃると思いますが、あれって見にくくないですか?
こんなやつですね。なかなかにひどい残高曲線ですが、そこは無視してください。
これってその期間の通貨ペアは全部まとめられてますし、個別の一個一個を確認しようと思えば、エクセルでcsvを開きなおしてゴニョゴニョしなおしたり面倒ですよね。
私は面倒くさがりなので、できれば手間暇かけずに数十分くらいで作業は終わらせたいんですよね。
コードを書いて実現したかったこと
MT5のヒストリカルデータから未実現の最大利益を知ること
MT5のヒストリカルデータから最大DDを計算すること
CSVファイルにExportすること
今、動かしてる為替EAは、時間経過でCloseする設定にしています。時間経過中に含み益が最大化するも決済時点では縮小することもありますし、逆に含み損が増大する場面もあります。
これらのデータが分れば、利益の最大化を狙うTakeProfitを設定することもできますし、最大DDから証拠金に対するLot枚数の増加を計算することもできます。
ただ、この為替EAは複数の通貨ペアで動かしているので、それぞれの通貨ペアにおける値を見る必要があるので、インジケータ化してcsvでExportできるようにしました。
取引履歴からcsv吐き出して処理するコードの動き
ポジション保有期間の最大値と最小値取得
色のセンスが絶望的にないですね。青の四角で囲まれたエリアがポジション保有期間と価格の最大値、最小値です。上記の場合、含み損含み益、大きな含み益を経て微益で終了しています。かなりもったいないですね。
取引履歴をExport
うーんひどい取引履歴。。。maxPipsが実現可能だった最大利益、DDPipsが最大含み損、ProfitPipsが実際の利益Pipsです。
上から2行目は、109.3Pipsの含み益があったにもかかわらず、12.7Pipsで終わってます。ほんと終わってますね。。。
DDPipsだけを見ると、最大の含み損は101.8Pipsだったようです。この値を参考にLot枚数を調整できそうですね。
*ちなみに、トレード大会の取引履歴ではありません。別の試作EAの死骸ですので、この取引履歴は何の参考にもならないと思います。
今後の追加予定
データをExportさせずに、MT5上で計算結果を表示したりもできるので、勝率であったり、RRであったりを表示するツールにすることを最終目標にコードを膨らませていこうかなって考えてます。
取引履歴からcsv吐き出して処理するコード
全コード書いてもいいのですが、コピペされてどっかで売られても嫌なので、コードわかる人の参考になるような感じで書いていきます。
// いつからいつまでの取引履歴を見るか、Inputで指定
input datetime from_time = D'15.11.2022';
input datetime to_time = D'20.11.2022';
とりあえず、inputで取引履歴の期間指定。
// 取引履歴の内容をCSVに保存する配列の構造体を作成
struct DATAs
{
datetime EntryTime;
double EntryPrice;
datetime ExitTime;
double ExitPrice;
double maxPips;
double DDPips;
double ProfitPips;
double Profit;
double Lots;
string BuySell;
};
DATAs arr[];
structで辞書型を作成すると、構造体が作れます。それぞれの要素を型指定できるます。double arr[]とかだと全部double型になっちゃいますが、上記の方法だと、1列目がdatetime、2列目がdoubleのような個別の型を設定できます。
僕は知りませんでした。
ここからOnCalcurate内です。
// いつからいつまでの取引履歴からバー本数を取得
int bar_num = MathRound((to_time - from_time)/60);
to_timeもfrom_timeも秒数で表示されるので、60で割って1分足の本数に変換しています。(本コードは1分足に表示することを前提としています。)
// 取引履歴の行数初期化
int ent_num = 0;
// 保存するファイルを展開
filehandle = FileOpen("TradeData.csv",FILE_WRITE|FILE_ANSI|FILE_CSV,",");
// 列名を書き込み
FileWrite(filehandle,"EntryTime","EntryPrice","ExitTime","ExitPrice","maxPips","DDPips","ProfitPips","Profit","Lots","BuySell");
今回は「TradeData.csv」って名前で保存。同名の既存ファイルがあれば上書き、無ければ新規作成されます。保存先は、MT5のファイルの「files」野中です。delimiterとして区切り文字にカンマを設定しています。
// 取引履歴を取得する範囲を選択
HistorySelect(from_time, end_time);
ここで結構沼りました。HistoryDealsTotal()で全取引履歴を引っ張ってくると思いきや、先にHistorySelectで日付範囲を指定しないといけないようです。これで結構時間を食いました。
// 通貨ペアごとに取引したチケットを取得
int sym_arr[];
int sym_count = 0;
for(int i=0; i<HistoryDealsTotal(); i++)
{
ulong ticket = HistoryDealGetTicket(i);
if(HistoryDealGetString(ticket,DEAL_SYMBOL)==_Symbol)
{
ArrayResize(sym_arr,sym_count+1);
sym_arr[sym_count] = i;
sym_count++;
}
}
複数通貨ペアで同時に取引をしていた場合、新規と決済の注文が順番にならないことがあります。
USDJPYのエントリー
AUDNZDのエントリー
AUDNZDの決済
USDJPYの決済
みたいな感じです。これをticket順でエントリー決済って選んでるとおかしなことになってしまいます。そこで、USDJPYだけのticketの配列を先に作成し、その配列を使って新規と決済を紐づけていきます。(チャートを表示しているSymbolだけを拾うようにしています。)
ArraySizeは動的に増やしてます。
// チャート表示通貨ペアの配列で繰り返し処理
for(int i=ArraySize(sym_arr)-1; i>0; i--)
{
// チケット番号取得
ulong ticket = HistoryDealGetTicket(sym_arr[i]);
// 決済注文を取得
if(HistoryDealGetInteger(ticket,DEAL_ENTRY)==1)
{
// ひとつ前がエントリ注文
ulong EntTicket = HistoryDealGetTicket(sym_arr[i-1]);
今回は同一通貨ペアでの複数ポジは想定していないので、決済の一つ前が必ずエントリー履歴になります。複数ポジの場合は、決済と新規の紐づけがややこしくなりますが、できると思いますが、私は単ポジで不要なので。。。
// チケット番号から時間取得し、バー番号に直したりする。価格取得も可能
int EntBar = Bars(_Symbol,PERIOD_CURRENT,end_time,HistoryDealGetInteger(EntTicket,DEAL_TIME));
int ExitBar = Bars(_Symbol,PERIOD_CURRENT,end_time,HistoryDealGetInteger(ticket,DEAL_TIME));
double OpenPrice = HistoryDealGetDouble(EntTicket,DEAL_PRICE);
ここまできたらバー番号も価格も取得できるので、なんでもできますね。/
// 構造体配列に順番に保存していく
arr[ent_num].EntryTime = Time[EntBar];
arr[ent_num].EntryPrice = OpenPrice;
arr[ent_num].ExitTime = Time[ExitBar];
arr[ent_num].ExitPrice = ClosePrice;
// FileWriteにハンドルと配列を渡していく
FileWrite(filehandle,arr[ent_num].EntryTime,arr[ent_num].EntryPrice,・・・
CSV保存したいデータを順番に並べるだけ。
}
// 繰り返し処理の配列番号を1ずつ増やす
ent_num += 1;
}
}
// 最後にファイルを閉じる
FileClose(filehandle);
以上です。
ある程度MT5できる人なら、簡単につないで作れると思います。そもそもそんな人は自分でこんなの作れると思いますが。。。
ここに記載していない内容として、Rectangleでチャートに表示する部分とか、売り買い方向の判定とかですが、書き忘れただけなので気が向けば足します。
大会取引履歴の検証
で、実際にcsvをExportして、通貨ペアごとにExcelで検証してみました。
通貨ペア①の場合
maxPipsに対してif文を設定。ある値(TakeProfitPips)を超えた場合はある値を結果列に、そうでない場合はProfitPipsの値を結果列に保存し、合計値がProfitPipsの合計値を超えるか検証しました。
要するに、TakeProfitに15Pipsとか50Pipsとか設定した方が、現状より良くなったか調べました。
通貨ペア①に関しては改善は見られませんでした。そのままの設定が良いようです。
なお、最大DDが40Pipsなので、4万円の含み損が許容されるなら1Lotまで設定できそうですね。
通貨ペア②の場合
このペアも同様の検証をしましたが、TakeProfitの設定では改善が見られませんでした。
こちらも最大DDが40Pipsなので、4万円の含み損が許容されるなら1Lotまで設定できそうですね。
通貨ペア③の場合
このペアはTakeProfitを10Pipsで設定した方が結果が改善されました。そこで、本EA作成時に使った過去データを用いてTakeProfitを設定した場合を再検証しました。結果は悪化でした。
確かに結果を得るにはフォワード期間が短すぎます。直近にフィッティングしているだけの結果と考え、引き続きTakeProfit設定はなしでEAを動かすこととしました。
なおこの期間の最大DDが80Pipsですので、4万円の含み損許容であれば、0.5Lotまでの計算になります。
まとめ
取引履歴をCSVでExportするコードを紹介しました。
取引履歴は自在に操れそうなので、今後は裏で計算してチャート上に表示するなどの改善を図ろうと思います。現在運用中の為替EAに関しては、DDを加味した結果もう少しLotを伸ばせそうなので、少し調整してみることにします。
倍は無理でも、Lotを1.5倍にできれば500%くらいは利益率狙えるかなぁ。。。
お知らせ
来週くらいからサーモンさん主催のトレード大会「サーモンズカップ」が始まります。上位10名に入れば賞品がもらえます。MacBookProとかiPadProとか。ほんま毎回豪華すぎます。感謝です。
今回、私も参加させていただくのですが、まだ参加者が50名くらいとのことで、これって逆にチャンスなんじゃないかなって思ったのでお知らせしときます。前回とか170名参加ですからね。
私はiPadProがほしいです。狙っています。誰か3位になったら譲ってください。
エントリーが23日までらしいので、参加してみようって方は急いだ方がいいですよ。
なお、こんだけ検証とか言いながら、Lot上げすぎで序盤に脱落してたら「あほやな」って笑ってください。
以上ですが、ご指摘やご質問などありましたら、TwitterにDM飛ばしてください。お願いします。ではでは。
この記事が気に入ったらサポートをしてみませんか?