* MT5のEAの学習メモ [#m278a141]

#contents

*なぜMT4ではなくMT5なのか? [#zaedf66a]
デイトレするときにポジションをまとめてクローズすることができていいよ。と知人におしえてもらったからです。詳しいことはこれから勉強します。


*MT5ダウンロード [#v597b129]
以下の証券会社から無料でダウンロードできます。いまのところ日本の証券会社はMT4だけの場合が多い印象です。


EXNESSはオーストラリアの会社?だそうです。間違ってたらすいません。

https://exn.fxsignup.com/trading-tool/

住所の証明がちょっと大変でした。免許書と公共料金の支払いの紙が証明で必要でした。


* 移動平均を使った売買 [#l9444cb4]
はじめてMQT5でEAを作ってみました。

移動平均のクロスでエントリーして、ストップロスと、テークプロフィットを決めるロジックです。

いろいろ、間違っています。はい。

パラメータは、日足でUSD/JPYでよさげになるように調節してあります。

 #property copyright "Copyright 2023, Hayashi Kuniyuki"
 #property link      "https://java.boy.jp/pukiwiki/index.php?MT5%20EA"
 #property version   "1.00"
 #property strict
 //+------------------------------------------------------------------+
 //| Include                                                          |
 //+------------------------------------------------------------------+
 #include <Trade\trade.mqh>
 
 //+------------------------------------------------------------------+
 //| Expert initialization function                                   |
 //+------------------------------------------------------------------+
 
 // グローバル変数の宣言
 input double inpLotSize = 0.1;       // 注文のロットサイズ
 input int inpMagicnumber = 20231006; // マジックナンバー
 input double inpStopLoss = 100; // ストップロスのpips
 input double inpTakeProfit = 700; // 利確のpips
 
 input int inpShortSmaPeriod = 3; // 移動平均の短い期間
 input int inpLongSmaPeriod = 5; // 移動平均の長い期間
 
 
 // ポジションについての情報
 struct Posi {
    datetime openTime; // 二重登録防止用
    double price; // 注文価格
    double stopLoss; // ストップロス
    double takeProfit; // 利確
    bool needRetry; // 取引失敗時のリトライ管理
    int sign; // 計算用 1 or -1
    ENUM_POSITION_TYPE posi_type;
    ENUM_SYMBOL_INFO_DOUBLE symbol_type;
    ENUM_ORDER_TYPE order_type;
 };
 Posi posiBuy = {0, 0, 0, 0, false, 1, POSITION_TYPE_BUY, SYMBOL_ASK, ORDER_TYPE_BUY}; // 買いポジション管理
 Posi posiSell = {0, 0, 0, 0, false, -1, POSITION_TYPE_SELL, SYMBOL_BID, ORDER_TYPE_SELL}; // 売りポジション管理
 
 // 移動平均の構造体
 struct Sma {
    int period; // 期間
    int handle; // ハンドル
    double prices[]; // 直近とその前の値
 };
 Sma smaShort; // 短い期間の移動平均
 Sma smaLong; // 長いほうの期間の移動平均
 
 CTrade trade; // 取引実行インスタンス
 
 int OnInit() {
    // ユーザ入力チェック
    if (inpLotSize <= 0 || inpLotSize >= 1) {
       Alert("inpLotSize <=0 || inpLotSize >= 1 ");
       return INIT_PARAMETERS_INCORRECT;
    }
    
    if (inpStopLoss <= 0 || inpStopLoss >= 1000) {
       Alert("inpStopLoss <= 0 || inpStopLoss >= 1000");
       return INIT_PARAMETERS_INCORRECT;
    }
    
    if (inpTakeProfit <= 0) {
       Alert("inpTakeProfit <= 0");
       return INIT_PARAMETERS_INCORRECT;
    }
    
    if (inpShortSmaPeriod <= 0) {
       Alert("inpShortSmaPeriod <= 0");
       return INIT_PARAMETERS_INCORRECT;
    }
    
    if (inpLongSmaPeriod <= 0) {
       Alert("inpLongSmaPeriod <= 0");
       return INIT_PARAMETERS_INCORRECT;
    }  
    
    if (inpLongSmaPeriod <= inpShortSmaPeriod) {
       Alert("inpLongSmaPeriod <= inpShortSmaPeriod");
       return INIT_PARAMETERS_INCORRECT;
    }         
    
    // Sma設定
    setSma(smaShort,inpShortSmaPeriod);
    setSma(smaLong,inpLongSmaPeriod);
     
    return(INIT_SUCCEEDED);
 }
 
 void OnDeinit(const int reason){
    // メモリ解放
    releaseSma(smaShort);
    releaseSma(smaLong);
 }
 
 void OnTick() {
    // 価格取得
    if (!fetchPrice(smaShort)) return;
    if (!fetchPrice(smaLong)) return;
    
    // 買いポジションを取る
    if (posiBuy.needRetry) {
       openPosi(posiBuy);
    }
    if (isCrossOver(smaShort.prices, smaLong.prices) && !hasPosition(posiBuy)) {
       Print("ゴールデンクロス");
       posiBuy.needRetry = true;
       openPosi(posiBuy);
       dump(smaShort);
       dump(smaLong);
    }
 
    // 売りポジションを取る
    if (posiSell.needRetry) {
       openPosi(posiSell);
    }   
    if (isCrossOver(smaLong.prices, smaShort.prices) && !hasPosition(posiSell)) {
       Print("デッドクロス");
       posiSell.needRetry = true;
       openPosi(posiSell);
       dump(smaShort);
       dump(smaLong);
    }  
 }
 
 
 //+------------------------------------------------------------------+
 //| Utility                                                          |
 //+------------------------------------------------------------------+
 // 移動平均の初期化
 void setSma(Sma &sma, int period) {
    sma.period = period;
    sma.handle = iMA(_Symbol, PERIOD_CURRENT, period, 0, MODE_SMA, PRICE_CLOSE);
    ArraySetAsSeries(sma.prices, true);
 }
 
 // インジケータをメモリから解放
 void releaseSma(Sma &sma) {
    if (sma.handle != INVALID_HANDLE) {IndicatorRelease(sma.handle);} 
 }
 
 // 移動平均の現在値とひとつ前の値取得
 bool fetchPrice(Sma &sma) {
    int arraySize= CopyBuffer(sma.handle, 0, 0, 2, sma.prices);
    if (arraySize != 2) {
       Print("移動平均のデータが十分ではない。");
       return false;
    }
    return true;
 }
 
 // 交わっているか判定
 bool isCrossOver(double &prices1[], double &prices2[]) {
    return ((prices1[1] <= prices2[1]) && (prices1[0] > prices2[0]));
 }
 
 // Tickの現時間取得
 datetime now() {
    return iTime(_Symbol,PERIOD_CURRENT,0);
 }
 
 // ポジション持っているか
 bool hasPosition(Posi &posi) {
    return (posi.openTime == now());
 }
 
 // ポジションを持つ
 void openPosi(Posi &posi) {
    double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    posi.price = SymbolInfoDouble(_Symbol, posi.symbol_type);
    posi.stopLoss = posi.price - (posi.sign * inpStopLoss * symbolPoint );
    posi.takeProfit = posi.price + (posi.sign + inpTakeProfit * symbolPoint ); 
    
    Print("symbolPoint: ", symbolPoint, ", price: ", posi.price, ", st: ", posi.stopLoss, " tp: ", posi.takeProfit);
    
    // ポジションをもてなければリトライフラグを取り下げない
    if (trade.PositionOpen(_Symbol, posi.order_type,inpLotSize,posi.price, posi.stopLoss, posi.takeProfit,"cross EA")){
       posi.needRetry = false;
    }
    posi.openTime = now();
    
 }
 
 // 確認用
 void dump(Sma &sma){
    Print("[0]: ", sma.prices[0], ", [1]: ", sma.prices[1]," :Sma" , sma.period);
 }

* クラスも作成できる [#m97c955f]
 class CSomethingClass{
   public:
     int number;
 };

インスタンスの生成例
 CSomethingClass somethingClass;

クラスの配列の作成例
 CSomethingClass somethingClass[];

要素を追加するには
 ArrayResize(somethingClass, ArraySize(somethingClass) + 1);


* Scriptの作成 [#y8ce17d0]
ちょっとしたチャート上でよくやる操作は、Sciptとして作成し、ショートカットで呼び出すと便利です。

** 取引履歴のトグル表示 [#h9ef0b2e]
まだ、確認画面がでる点がスマートではないですが、チャートの表示状態の取得と変更のサンプルにはなるでしょう。
 //+------------------------------------------------------------------+
 //|                                       ToggleShowOrderHistory.mq5 |
 //|                                 Copyright 2023, Hayashi Kuniyuki |
 //+------------------------------------------------------------------+
 #property copyright "Copyright 2023, Hayashi Kuniyuki"
 //+------------------------------------------------------------------+
 //| Script program start function                                    |
 //+------------------------------------------------------------------+
 #property script_show_inputs
 #property strict
 //+------------------------------------------------------------------+
 //| Script program start function                                    |
 //+------------------------------------------------------------------+
 void OnStart() {
    // Get the current chart ID
    long chartID = ChartID();
 
    // Check the current state of 'Show trade history' property
    bool showTradeHistory = ChartGetInteger(chartID, CHART_SHOW_TRADE_HISTORY);
 
    // Toggle the 'Show trade history' property
    showTradeHistory = !showTradeHistory;
    ChartSetInteger(chartID, CHART_SHOW_TRADE_HISTORY, showTradeHistory);
 
    // Notify the user of the change
    if(showTradeHistory)
       Print("Trade history is now displayed.");
    else
       Print("Trade history is now hidden.");
 }

** チャートテンプレートを適用するコード [#j36d75d8]
チャートのテンプレートをショートカットで切り替えれるようになると便利です。
 //+------------------------------------------------------------------+
 //|                                 Copyright 2023, Hayashi Kuniyuki |
 //+------------------------------------------------------------------+
 #property copyright "Copyright 2023, Hayashi Kuniyuki"
 input string templateName = "xxx"; // 使用したいテンプレート名
 
 //+------------------------------------------------------------------+
 //| Script program start function                                    |
 //+------------------------------------------------------------------+
 void OnStart()
 {
    // インジケータのテンプレートを読み込む
    ChartApplyTemplate(0, templateName + ".tpl");
 }

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS