MetaQuotes社のMoving AverageのサンプルEAをコメント解説しています。
//+------------------------------------------------------------------+ //| Moving Average.mq4 | //| Copyright 2005-2014, MetaQuotes Software Corp. | //| http://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2005-2014, MetaQuotes Software Corp." #property link "http://www.mql4.com" #property description "移動平均線EA" #property description "日本語翻訳-最大ポジション保有数は1つ" //--- 定数のマジックナンバー #define MAGICMA 20131111 //--- 入力変数(外部変数) //--- ロット数 input double Lots =0.1; //--- リスクロット調整(%) input double MaximumRisk =0.02; //--- ロット減少調整数値 input double DecreaseFactor=3; //--- 移動平均線の期間 input int MovingPeriod =12; //--- 移動平均線のシフト input int MovingShift =6; //+------------------------------------------------------------------+ //| 保有中のポジションの計算 | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol){ //--- ポジションの数を0で初期化(買、売) int buys=0,sells=0; //--- 全ての保有中&待機中のポジションを検索 for(int i=0;i< OrdersTotal();i++){ //--- ポジションを選択出来なければループを抜ける if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; //--- 注文時の通貨ペアとマジックナンバーを検証 if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA){ //--- ポジションが買ポジションならばbuysに+1 if(OrderType()==OP_BUY) buys++; //--- ポジションが売りポジションならばsellsに+1 if(OrderType()==OP_SELL) sells++; } }//ループ終了 //--- ポジションの数を返す if(buys>0) return(buys); //--- 買いポジションの数 else return(-sells); //--- 売りポジションの数(-をつけて返す) } //+------------------------------------------------------------------+ //| ロットの計算 | //+------------------------------------------------------------------+ double LotsOptimized(){ double lot=Lots; int orders=HistoryTotal(); // 全ポジション履歴 int losses=0; // 負数を入れる変数(0で初期化) //--- 余剰証拠金×リスク%÷1000の答えを少数点第1位に丸める lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); //--- ロットの減少調整数値がが0以上ならば if(DecreaseFactor>0){ for(int i=orders-1;i>=0;i--){ //--- ポジションの履歴がない場合ループを抜ける if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false){ Print("Error in history!"); break; } //--- 注文時の通貨ペアと開いて選択している通貨ペアが違う //--- 又は //--- 保留中の注文の削除履歴の場合。次へ if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; //--- 利益が出ていたらループを抜ける if(OrderProfit()>0) break; //--- 損失ならlossesに+1 if(OrderProfit()<0) losses++; }//ループ終了 //--- 連敗が1より多ければ if(losses>1){ //--- ロットの数を再調整 lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } } //--- ロット数が0.1未満なら0.1をロットにする if(lot<0.1) lot=0.1; //--- ロット数を返す return(lot); } //+------------------------------------------------------------------+ //| エントリー関数 | //+------------------------------------------------------------------+ void CheckForOpen(){ //--- 移動平均線の値を格納する変数を宣言 double ma; //--- 注文の返り値を入れる変数を宣言 int res; //--- 現在の出来高が1より大きければ処理終了 if(Volume[0]>1) return; //--- 移動平均線の値を取得 ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0); //--- 売りのエントリー条件 if(Open[1]>ma && Close[1]< ma){ //--- エントリー res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); return; } //--- 買いのエントリー条件 if(Open[1]< ma && Close[1]>ma){ //--- エントリー res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue); return; } } //+------------------------------------------------------------------+ //| クローズ関数 | //+------------------------------------------------------------------+ void CheckForClose(){ //移動平均線の値を入れる変数を宣言 double ma; //--- 現在の出来高が1より大き場合は処理終了 if(Volume[0]>1) return; //--- 移動平均線の値を取得 ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0); //--- 全ての保有中&待機中のポジションを検索 for(int i=0;i< OrdersTotal();i++){ //--- ポジションを選択できない場合ループを抜ける if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; //--- 注文時の通貨ペアとマジックナンバーが一致していない場合次へ if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue; //--- 買ポジションなら if(OrderType()==OP_BUY){ //--- 決済条件 if(Open[1]>ma && Close[1]< ma){ //--- 決済処理 if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White)){ //--- 決済に失敗した場合にエラーを吐く Print("OrderClose error ",GetLastError()); } } break; } //--- 売ポジションなら if(OrderType()==OP_SELL){ //--- 決済条件 if(Open[1]< ma && Close[1]>ma){ //--- 決済処理 if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White)){ //--- 決済に失敗ならエラーを吐く Print("OrderClose error ",GetLastError()); } } break; } }//ループ終了 } //+------------------------------------------------------------------+ //| OnTick function | //+------------------------------------------------------------------+ void OnTick(){ //--- バーの数が100未満又は、自動売買が許可されていない場合処理終了 if(Bars< 100 || IsTradeAllowed()==false) return; //--- ポジションを保有していない場合はエントリー関数を呼ぶ if(CalculateCurrentOrders(Symbol())==0){ CheckForOpen(); //--- ポジションを保有してたらクローズ関数を呼ぶ }else{ CheckForClose(); } } //+------------------------------------------------------------------+