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();
}
}
//+------------------------------------------------------------------+
