//+------------------------------------------------------------------+ //| MA-EA-Mark11.mq4 | //| Copyright(c) 2010 Masaru Sasaki | //| | //+------------------------------------------------------------------+ // // < MetaTrader4 FX(外国為替証拠金取引)自動売買システムEA > // 「ソースコード公開理由」 // *一般的な個人トレーダーの一人として、プログラムに不慣れな方への // 参考として公開する事にしました。 // 自分は幸いにもプログラミングを趣味として来たサンデープログラマー // である事から、システムプログラミング(EA)ができました。 // プログラミングは習うより、慣れろだと思います。 // // 「禁止事項」 // *このプログラムソースコードをそのまま流用したソフトの販売等を // 一切禁止致します。 // // 「免責事項」 // *このプログラムに基づく行為の結果発生した障害、損失などについて // 著作者は一切の責任を負いません。 // // 「説明」 // *モメンタム指標とPivot指標を組合わせた // システムです。 // // 参考書籍:FXメタトレーダー入門 (PanRolling) // FXメタトレーダー実践プログラミング (PanRolling) // 売買システム入門 (PanRolling) // 勝利の売買システム with TradeStation (PanRolling) // ちゃんと儲けたい人の株価チャート分析大全 (自由国民社) // ここまで使えるローソク足チャート (日本経済新聞社) // #property copyright "Copyright(c) 2010 Masaru Sasaki" #property link "youtarou.blogzine.jp" #include // マジックナンバー #define MAGIC 20100913 // ストップロスタイプ #define STOPLOSPIPS 1 #define STOPLOSRATE 2 // ストップロスをpips幅にするか価格に対するパーセンテージするかを選択 extern int STOPLosType = STOPLOSPIPS; // 0=pips幅 1=レート幅 extern int STOPpips = 50; // ストップロスpips幅 extern double STOPrate = 0.01; // ストップロスレート幅 0.01=1% // 利食い値 (Pips) extern int TAKEProfit = 200; // 利食い値のオンオフ設定 標準オン extern bool TAKEProfitFlag = true; // トレード時間帯設定 extern string STime = "22:00"; // 開始時刻 extern string ETime = "5:00"; // 終了時刻 extern bool TradeTime = false; // トレード時間帯のオンオフ 標準はオフ // レバレッジの選択 extern double Leverage = 1.0; // 1.0 -> 1倍 // メールアラート通知の on/off extern bool mail_flag = false; // 標準設定はオフ // 最小ロット数 証券会社により異なる。 extern double minlot = 0.01; // 1000通貨 FOREX.COM Japan // モメンタム期間 extern int Mom_period = 20; // スリップベージ extern int Slippage = 3; // デバッグ on/off フラグ bool debug = false; // ポジション決済関数 startにて呼出して使用 void ClosePositions() { for( int i=0; i < OrdersTotal(); i++ ){ if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false ) break; if( OrderMagicNumber() != MAGIC || OrderSymbol() != Symbol() ) continue; // オーダータイプのチェック if( OrderType() == OP_BUY ) // 買い { OrderClose( OrderTicket(), OrderLots(), Bid, Slippage, White); break; } if( OrderType() == OP_SELL ) // 売り { OrderClose( OrderTicket(), OrderLots(), Ask, Slippage, White); break; } } } // オーダー有無の判定関数 startにて呼出して使用 int OrderPosition() { int r_type = 0; for( int i=0; i < OrdersTotal(); i++ ){ if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false ) break; if( OrderMagicNumber() != MAGIC || OrderSymbol() != Symbol() ) continue; // オーダータイプのチェック if( OrderType() == OP_BUY || OrderType() == OP_SELL ) { r_type = OrderType(); break; } } return(r_type); } // トレード時間帯フィルター関数 startにて呼出して使用 bool SignalFilter() { string Sdata = TimeToStr(TimeCurrent(), TIME_DATE); datetime s_time = StrToTime(Sdata + " " + STime); datetime e_time = StrToTime(Sdata + " " + ETime); bool r = false; if( s_time < e_time ) { if( TimeCurrent() >= s_time && TimeCurrent() < e_time ) r = true; else r = false; } else { if( TimeCurrent() >= e_time && TimeCurrent() < s_time ) r = false; else r = true; } // トレード時間帯オフの場合、常に真 if( TradeTime == false ) r = true; return(r); } //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { // バーの始値でトレード可能かチェック if( Volume[0] > 1 || IsTradeAllowed() == false ) return(0); // Pivotの計算とブレイクアウト判定 (時間枠は日足を使用) int s = iBarShift(NULL, PERIOD_D1, Time[1]) + 1; double LH = iHigh(NULL, PERIOD_D1, s); double LL = iLow(NULL, PERIOD_D1, s); double LC = iClose(NULL, PERIOD_D1, s); double P = (LH + LL + LC)/3; double R1 = P + (P - LL); double S1 = P - (LH - P); double R2 = P + (LH - LL); double S2 = P - (LH - LL); double HBOP = LH + 2*(P - LL); double LBOP = LL - 2*(LH - P); if( Close[2] <= HBOP && Close[1] > HBOP ) bool Pivot_Up = true; if( Close[2] >= LBOP && Close[1] < LBOP ) bool Pivot_Down = true; // モメンタムの計算 double Mom1 = iMomentum(NULL, 0, Mom_period, PRICE_CLOSE, 1); // ストップロス計算用 double StopType = 0.0; // 利食い値計算用 double TakeProfit = 0.0; // ロット数の計算 double Lots = NormalizeDouble(AccountFreeMargin()*Leverage/100000,1); if( Lots < minlot ) Lots = minlot; // オーダータイムアウト時間 12秒間 int OrderWaitTime = 12; int startTime; // 買いシグナル // 条件:モメンタム値が100より上かつPivot指標で上抜け // if( SignalFilter() == true ) if( Mom1 > 100 ) if( Pivot_Up == true ) { if( OrderPosition() == OP_BUY ) // 買いオーダーがすでに有る場合はキャンセルする。ナンピンしない。 return(0); ClosePositions(); if( STOPLosType == STOPLOSPIPS ) StopType = Ask-STOPpips*Point; else StopType = Ask*(1-STOPrate); if( TAKEProfitFlag == true ) TakeProfit = Ask+TAKEProfit*Point; else TakeProfit = 0; // 通信エラーがあった場合、オーダーを繰り返す。 startTime = GetTickCount(); while( true ) { if( GetTickCount() - startTime > OrderWaitTime*1000) { Alert("OrderSend Time Out ERROR!! Check Experts Log!!"); // メール送信可であれば、エラーを送信。 if( mail_flag == true ) SendMail("MetaTrader 4 MAIL アラート:", "OrderSend 買いタイムアウトエラー!!"+Symbol()); return(false); } if( IsTradeAllowed() == true ) { RefreshRates(); if(OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, StopType, TakeProfit, "", MAGIC, 0, Red) != -1) return(true); int buyerror = GetLastError(); Print("OrderSend Error : ", buyerror); } Sleep(100); } // メールアラート通知 if( mail_flag == true ) SendMail("MetaTrader4 MAIL アラート:", "買い" + Symbol() + "at" + DoubleToStr(Ask, Digits)); return(0); } // 売りシグナル // 条件:モメンタム値が100より下かつPivot指標で下抜け // if( SignalFilter() == true ) if( Mom1 < 100 ) if( Pivot_Down == true ) { if( OrderPosition() == OP_SELL ) // 売りオーダーがすでに有る場合はキャンセルする。ナンピンしない。 return(0); ClosePositions(); if( STOPLosType == STOPLOSPIPS ) StopType = Bid+STOPpips*Point; else StopType = Bid*(1+STOPrate); if( TAKEProfitFlag == true ) TakeProfit = Bid-TAKEProfit*Point; else TakeProfit = 0; // 通信エラーがあった場合、オーダーを繰り返す。 startTime = GetTickCount(); while( true ) { if( GetTickCount() - startTime > OrderWaitTime*1000) { Alert("OrderSend Time Out ERROR!! Check Experts Log!!"); // メール送信可であれば、エラーを送信。 if( mail_flag == true ) SendMail("MetaTrader 4 MAIL アラート:", "OrderSend 売りタイムアウトエラー!!"+Symbol()); return(false); } if( IsTradeAllowed() == true ) { RefreshRates(); if(OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, StopType, TakeProfit, "", MAGIC, 0, Blue) != -1) return(true); int sellerror = GetLastError(); Print("OrderSend Error : ", sellerror); } Sleep(100); } // メールアラート通知 if( mail_flag == true ) SendMail("MetaTrader4 MAIL アラート:", "売り" + Symbol() + "at" + DoubleToStr(Bid, Digits)); return(0); } // 設定時間帯でポジションが有る場合の手仕舞い処理 if( OrderPosition() == OP_BUY ) { if( SignalFilter() == false ) ClosePositions(); } else if( OrderPosition() == OP_SELL ) { if( SignalFilter() == false ) ClosePositions(); } // デバッグ表示 if( debug == true ) { Print("終値 :", Close[1]); Print("モメンタム :", Mom1); Print("バンド下抜け:", Pivot_Down); Print("バンド上抜け:", Pivot_Up); } return(0); } //+------------------------------------------------------------------+