//+------------------------------------------------------------------+ //| MSZ-006.mq4 | //| Copyright 2021, TNK.Co.,Ltd.| //| https://note.com/tnk_system | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, TNK" #property link "https://note.com/tnk_system" #property version "3.1" //複利機能残高追加、チャートコメント変更 #property strict #include //ユーザー入力用パラメーター //基本設定 string Basic_setting = "基本設定"; // ■■■ 基本設定 ■■■ input double Lots = 0.2; // ロット(単利運用時) enum MM_Select{ Fixed, // 0:単利/固定 FreeMargin, // 1:複利/余剰証拠金 Balance, // 2:複利/残高 }; input MM_Select MM_ON = Fixed; // 複利機能(0:単利/1:余剰証拠金/2:残高) input double MM_Risk = 1.0; // リスク%(余剰証拠金/残高の何%か) input double MaxSpread_pips = 5.5; // 許容スプレッド(Pips) input int Slippage = 10; // 許容スリッページ(Point) input int TakeProfit_pips = 20; // 利確指値(Pips) input int StopLoss_pips = 50; // 損切逆指値(Pips) input bool WR_MODE = true; // トレンド耐性強化モード enum Week_Select{ Nomal, // 0:通常(月~木) Wednesday, // 1:水曜日無 Thursday, // 2:木曜日無 Wednesday_Thursday, // 3:水,木曜日無 }; input Week_Select WS_MODE = Nomal; // 23時台曜日制御(0:月~木/1:水無/2:木無/3:水木無) input bool NG0_MODE = false; // 0時台トレード無しモード //input bool WS_MODE = true; // 0時台・木曜日トレード無しモード input int MagicNumber = 1980617; // マジックナンバー(他EAと重複不可) input int GMT = 2; // GMT(冬時間) input int Summertime = 1; // サマータイム(1:米/2:英/0:無し) input string _Comment = "MSZ-006"; // 通知用コメント //内部設定 int Maxposition = 1; // 最大ポジション int CandleMargin_Pips = 1; // 1本前ローソク足終値と現在価格の差pips int CandleCloseHour = 9; // 強制決済するポジション保有時間 bool Buy_Entry = true; // 買いエントリー bool Sell_Entry = true; // 売りエントリー bool WeekendClose = true; // 週末クローズ bool YearendClose = true; // 12/25~1/3クローズ //ローソク足始値のみで稼働:「true」 bool CandleStartStartingEntry = false; // エントリー bool CandleStartStartingTrailing = true; // トレイリング bool CandleStartStartingExit = false; // 決済 //バーカウント・桁合わせ・時間制御用 int xBarsEntry = 0, xBarsExit = 0, xBarsTrailing = 0; int xBars=0, xxBars=0; double xpoint; int xTime, xxTime, yTime; //エントリー・決済ベースルールの各変数 int WilliamsPR_Gyakubari_period = 42; // EnEx_ウィリアムズ%Rの計算期間 int WilliamsPR_Line1 = -95; // 逆張りエントリーの基準となるライン(買い) int WilliamsPR_Line2 = -5; // 逆張りエントリーの基準となるライン(売り) int WilliamsPR_BuyExit_Line = -10; // 逆張り決済の基準となるライン(買い) int WilliamsPR_SellExit_Line = -90; // 逆張り決済の基準となるライン(売り) int RSI_period = 9; // EnEx_RSIの計算期間 int RSI_Gyakubari_Line1 = 30; // 逆張りエントリーの基準となるライン(買い) / 25~35 / 1 int RSI_Gyakubari_Line2 = 70; // 逆張りエントリーの基準となるライン(売り) / 65~75 / 1 int RSI_BuyExit_Line = 70; // RSI決済ライン(買い) int RSI_SellExit_Line = 30; // RSI決済ライン(売り) //エントリーフィルター double BBMargin = 8.0; // F7_BB幅pips int CandleCheckCount = 48; // F8_HLマージンチェック/ローソク足何本前まで? int HL_Margin_pips = 100; // F8_高値安値の差pips int RSI_JUNBARI_TF = 2; int RSI_Junbari_Filter_Line = 30; // F10_RSI順張りエントリーの基準となるライン int MACD_TF = 5; int ADX_TF = 7; // ADXタイムフレーム int ADX_value = 50; // ADXライン //決済ルールの各変数 //成行決済 int Rikaku_pips1 = 4; // Ex_成行利確シグナルPips //int Songiri_pips = 1000; // 成行損切シグナルPips / 50~300 / 10 //トレーリング //bool Modify = false; //int TrailingTakeProfitStart_pips = -40; // トレール開始損益Pips / -80~-10 / 10 //int TrailingTakeProfit_pips = -10; // トレール時の短期MAからの値幅Pips / -10~20 / 5 //週末決済(日本時間) bool GMT_Kadou_NG = false; // 週末稼働 bool PositionClose = false; // 週末決済 int EntryNG_StartTime1 = 1; // エントリー中止時間(開始) / 0~4(= 25) || (MON >= 4 && MON <= 9) || (MON == 10 && SUN_day <= 24)) //3月で、その週の日曜日が25日以上/4月~9月/10月で、その週の日曜日が23日以下 { summertime_shift = 1; } else { summertime_shift = 0; } } else if (Summertime == 1) // 米国式の場合 { if ((MON == 3 && SUN_day >= 8) || (MON >= 4 && MON <= 10) || (MON == 11 && SUN_day <= 0)) //3月で、その週の日曜日が8日以上/4月~10月/11月で、その週の日曜日が存在しない { summertime_shift = 1; } else { summertime_shift = 0; } } else // サマータイム無しの場合 { summertime_shift = 0; } xGMT = GMT - 9 + summertime_shift;//GMT+9を基準に //GMT+9基準でどれだけずれているかを算出する(ココマデ)-------------------- //+------------------------------------------------------------------+ //| 時間制御 | //+------------------------------------------------------------------+ //---- トレード許可時間の判定 ---- xTime = TimeHour(TimeCurrent()) - xGMT; // 日本時間 xxTime = TimeHour(TimeCurrent()) - (GMT - 2); // サーバー時間(サマータイム計算なし) yTime = TimeMinute(TimeCurrent()); // サーバーの分 gmtadjusted = TimeCurrent() - 60 * 60 * xGMT; if (xTime < 0) { xTime = xTime + 24; } else if (xTime > 23) { xTime = xTime - 24; } if (xxTime < 0) { xxTime = xxTime + 24; } else if (xxTime > 23) { xxTime = xxTime - 24; } // 週末ポジションクローズ if ((xTime == PositionClose_Time_W && TimeDayOfWeek(gmtadjusted) == PositionClose_DayOfWeek1 && WeekendClose == true) ) { PositionClose = true; } else { PositionClose = false; } // エントリーNG時間 if ( // 週末決済(日本時間) (xTime >= EntryNG_StartTime1 && xTime <= EntryNG_EndTime1 // 週末決済用(日本時間) && TimeDayOfWeek(gmtadjusted) >= EntryNG_DayOfWeek1 // 週末決済曜日(日本時間) && WeekendClose == true) ) { GMT_Kadou_NG = true; } else { GMT_Kadou_NG = false; } // ロールオーバー・メンテナンス時間 if (((xxTime == 23 && yTime >= 55 && TimeDayOfWeek(TimeCurrent()) != 5) || (xxTime == 23 && yTime >= 50 && TimeDayOfWeek(TimeCurrent()) == 5) || (xxTime == 0 && yTime <= 9)) && BacktestMode == true) { ROTime = true; } else { ROTime = false; } // エントリーOK時間 if ( (xxTime >= EntryOK_StartTime1 && xxTime <= EntryOK_EndTime1) // エントリー可能時間1(サーバー時間) || (xxTime >= EntryOK_StartTime2 && xxTime <= EntryOK_EndTime2)) // エントリー可能時間2(サーバー時間) { Logic1_Time = true; } else { Logic1_Time = false; } // ここまで、エグジットとトレーリングは、取引時間に関係なく実施する //---- トレード許可時間の判定(ココマデ) ---- } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ポジションのクローズ | //+------------------------------------------------------------------+ void PositionClose() { int i; double profit; bool res; int OrderOpenCandleCount; //ローソク足始値のみ稼働(選択式)の場合、ココカラ if(Bars != xBars || CandleStartStartingExit == false) { xBars = Bars; // 所有しているポジションをクローズする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; OrderOpenCandleCount = iBarShift(NULL, 0, OrderOpenTime()); // エントリーからのローソク足本数 if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する // オーダーを成り行き決済する if (ROTime == false && (profit >= Rikaku_pips1 * xpoint || (Exit2(false) == 2 && Ask - Bid <= MaxSpread_pips * xpoint) || (Exit2(false) == 2 && Ask - Bid > MaxSpread_pips * xpoint && profit > 0) || PositionClose == true || OrderOpenCandleCount >= CandleCloseHour * 12) ) { double CSpread = Ask - Bid;// スプレッド計測 uint OrderCloseTimestamp = GetTickCount();// レイテンシー計測 double Close_Price = Bid;// 決済売り注文を入れる価格 res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green); if (res == true && Measurement == true) { CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測 if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) //履歴を選択 { Print("Access to history failed with error (",GetLastError(),")"); return; } //オーダー確認(通貨ペアが一致した場合は、次の処理へ進む if (OrderSymbol() == Symbol()) { //マジックナンバー確認(マジックナンバーが一致した場合は、次の処理へ進む if (OrderMagicNumber() == MagicNumber) { Close_Price = NormalizeDouble(Close_Price, Digits); // 売り注文価格を正規化 Yakujyou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格 Close_Slippage = NormalizeDouble(Yakujyou_Price - Close_Price, Digits) / xpoint; // スリッページ、桁合わせ Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ profitpips = NormalizeDouble((OrderClosePrice() - OrderOpenPrice()) / xpoint, 1); /*Print("Slippage = ", DoubleToString(Close_Slippage, Digits), " Latency = ", CloseLatency, " OOT = ", OrderOpenTime(), " OCT = ", OrderCloseTime(), " OOP = ", OrderOpenPrice(), " YJP = ", Yakujyou_Price, " OSp = ", Open_Spread, " OSl = ", Open_Slippage, " CSp = ", Close_Spread, " CSl = ", Close_Slippage); */ fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv) if (fp != INVALID_HANDLE) { FileSeek(fp, 0, SEEK_END); FileWrite(fp, OrderOpenTime(), OrderCloseTime(), OrderOpenPrice(), Yakujyou_Price, "buy", profitpips, Open_Spread, Open_Slippage, OpenLatency, Close_Spread, Close_Slippage, CloseLatency, Symbol(), WindowExpertName()); FileClose(fp); } } } } } } if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する // オーダーを成り行き決済する if (ROTime == false && (profit >= Rikaku_pips1 * xpoint || (Exit1(true) == 1 && Ask - Bid <= MaxSpread_pips * xpoint) || (Exit1(true) == 1 && Ask - Bid > MaxSpread_pips * xpoint && profit > 0) || PositionClose == true || OrderOpenCandleCount >= CandleCloseHour * 12) ) { double CSpread = Ask - Bid;// スプレッド計測 uint OrderCloseTimestamp = GetTickCount();// レイテンシー計測 double Close_Price = Ask;// 決済買い注文を入れる価格 res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green); if (res == true && Measurement == true) { CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測 if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) //履歴を選択 { Print("Access to history failed with error (",GetLastError(),")"); return; } //オーダー確認(通貨ペアが一致した場合は、次の処理へ進む if (OrderSymbol() == Symbol()) { //マジックナンバー確認(マジックナンバーが一致した場合は、次の処理へ進む if (OrderMagicNumber() == MagicNumber) { Close_Price = NormalizeDouble(Close_Price , Digits); // 買い注文価格を正規化 Yakujyou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格 Close_Slippage = NormalizeDouble(Close_Price - Yakujyou_Price, Digits) / xpoint; // スリッページ、桁合わせ Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ profitpips = NormalizeDouble((OrderOpenPrice() - OrderClosePrice()) / xpoint, 1); /*Print("Slippage = ", DoubleToString(Close_Slippage, Digits), " Latency = ", CloseLatency, " OOT = ", OrderOpenTime(), " OCT = ", OrderCloseTime(), " OOP = ", OrderOpenPrice(), " YJP = ", Yakujyou_Price, " OSp = ", Open_Spread, " OSl = ", Open_Slippage, " CSp = ", Close_Spread, " CSl = ", Close_Slippage); */ fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv) if (fp != INVALID_HANDLE) { FileSeek(fp, 0, SEEK_END); FileWrite(fp, OrderOpenTime(), OrderCloseTime(), OrderOpenPrice(), OrderClosePrice(), "sell", profitpips, Open_Spread, Open_Slippage, OpenLatency, Close_Spread, Close_Slippage, CloseLatency, Symbol(), WindowExpertName()); FileClose(fp); } } } } } } } // 所有しているポジションをクローズする(ココマデ) } //ローソク足始値のみ稼働(ココマデ) } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| トレーリング | //+------------------------------------------------------------------+ /*void Trailing() { int i; double profit; bool res; double MA_fast1 = iMA(NULL, MA_TF, MA_period_fast, 0, MODE_EMA, PRICE_CLOSE, 1); // 1本前の短期MA // トレーリングのローソク足始値のみ稼働(選択式) if(Bars != xBarsTrailing || CandleStartStartingTrailing == false) { xBarsTrailing = Bars; // 所有しているポジションのストップをトレールする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の含み損益を計算する // トレイルON、OFF if (Modify == true) { // 含み損が一定以上かつ短期MAを割り込んだ場合、TPを引き下げる if (profit <= TrailingTakeProfitStart_pips * xpoint && OrderTakeProfit() > NormalizeDouble(MA_fast1 + TrailingTakeProfit_pips * xpoint, Digits()) && Close[1] < MA_fast1) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), MA_fast1 + TrailingTakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の含み損益を計算する // トレイルON、OFF if (Modify == true) { // 含み損が一定以上かつ短期MAを上抜けた場合、TPを引き下げる if (profit <= TrailingTakeProfitStart_pips * xpoint && OrderTakeProfit() < NormalizeDouble(MA_fast1 - TrailingTakeProfit_pips * xpoint, Digits()) && Close[1] > MA_fast1) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), MA_fast1 - TrailingTakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } } // 所有しているポジションのストップをトレールする(ココマデ) } // トレーリングのローソク足始値のみ稼働(ココマデ) }*/ //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ポジションのオープン | //+------------------------------------------------------------------+ void PositionOpen() { int i; int ticket; int CountBuy = 0,CountSell = 0; bool res; // エントリー判断のローソク足始値のみ稼働(選択式) if(Bars != xBarsEntry || CandleStartStartingEntry == false) { xBarsEntry = Bars; // ポジションの数をカウントする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) { CountBuy = CountBuy + 1; } if (OrderType() == OP_SELL) { CountSell = CountSell + 1; } } // ポジションの数をカウントする(ココマデ) // エントリー条件を確認し、成立していればエントリーを行う if (Entry(true) == 1 // 買いエントリー && CountSell == 0 && CountBuy < Maxposition && xxBars != Bars && GMT_Kadou_NG == false && Logic1_Time == true && Buy_Entry == true) { double OSpread = Ask - Bid;// スプレッド計測 uint StartOrderTimestamp = GetTickCount();// レイテンシー計測 double Order_Price = Ask;// 買い注文を入れる価格 ticket = OrderSend(Symbol(), OP_BUY, CalculateLots(MM_Risk, StopLoss_pips), Ask, Slippage, 0, 0, _Comment, MagicNumber, 0, Blue); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測 Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化 Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化 Open_Slippage = NormalizeDouble(Order_Price - Yakujyou_Price, Digits) / xpoint; // スリッページ、桁合わせ Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - StopLoss_pips * xpoint, OrderOpenPrice() + TakeProfit_pips * xpoint, 0, MediumSeaGreen); //Print("Slippage = ", DoubleToString(Open_Slippage,Digits), // " Latency= ", OpenLatency); } } xxBars = Bars; } else if (Entry(false) == 2 // 売りエントリー && CountBuy == 0 && CountSell < Maxposition && xxBars != Bars && GMT_Kadou_NG == false && Logic1_Time == true && Sell_Entry == true) { double OSpread = Ask - Bid;// スプレッド計測 uint StartOrderTimestamp = GetTickCount();// レイテンシー計測 double Order_Price = Bid;// 売り注文を入れる価格 ticket = OrderSend(Symbol(), OP_SELL, CalculateLots(MM_Risk, StopLoss_pips), Bid, Slippage, 0, 0, _Comment, MagicNumber, 0, Red); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測 Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化 Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化 Open_Slippage = NormalizeDouble(Yakujyou_Price - Order_Price, Digits) / xpoint; // スリッページ、桁合わせ Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + StopLoss_pips * xpoint, OrderOpenPrice() - TakeProfit_pips * xpoint, 0, MediumSeaGreen); //Print("Slippage = ", DoubleToString(Open_Slippage,Digits), // " Latency= ", OpenLatency); } } xxBars = Bars; } } // エントリー判断のローソク足始値のみ稼働(ココマデ) } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| TakeProfit, StopLoss | //+------------------------------------------------------------------+ void SetTPSL() { int i; double profit; bool res; // ポジションにTP, SLをセットする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; // 買いポジションの場合 if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - StopLoss_pips * xpoint, OrderOpenPrice() + TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } // 売りポジションの場合 if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + StopLoss_pips * xpoint, OrderOpenPrice() - TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 複利機能 | //+------------------------------------------------------------------+ // 複利機能のロット数を計算する double CalculateLots(double risk, // 許容するリスク int sl_pips) // ストップロス { // バックテスト時は、バックテスト用の複利機能を使用する if (IsTesting()) return(CalculateLots_forTest(risk, sl_pips)); else return(CalculateLots_forReal(risk, sl_pips)); } // 複利機能のロット数を計算する(実トレード用) double CalculateLots_forReal(double risk, // 許容するリスク int sl_pips) // ストップロス { double freemargin; // アカウントの余剰証拠金 double balance; // アカウントの口座残高 double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額 double lotstep; // サーバのロット数の最小刻み制限 double maxlots; // サーバの最大ロット数制限 double minlots; // サーバの最小ロット数制限 double lotsize = Lots; // ロットサイズ // 複利機能を使わない場合、Lotsを返す if (MM_ON == Fixed) return(Lots); freemargin = AccountFreeMargin(); balance = AccountBalance(); tickvalue = MarketInfo(NULL, MODE_TICKVALUE); lotstep = MarketInfo(NULL, MODE_LOTSTEP); maxlots = MarketInfo(NULL, MODE_MAXLOT); minlots = MarketInfo(NULL, MODE_MINLOT); // tickvalueはpipsではなくpointなので、小数点以下の桁数に応じて補正する if (Digits() == 3 || Digits() == 5) tickvalue = tickvalue * 10; // 許容するリスクとSLの幅から、ロットサイズを計算する。 if (MM_ON == FreeMargin) // 余剰証拠金方式 { lotsize = (freemargin * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%) / (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額 } else if (MM_ON == Balance) // 残高方式 { lotsize = (balance * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%) / (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額 } // サーバのロット数の刻みに合わせてロット数を修正 lotsize = MathFloor(lotsize / lotstep) * lotstep; // サーバの最小ロット数・最大ロット数で補正をかける lotsize = MathMax(lotsize, minlots); lotsize = MathMin(lotsize, maxlots); return(lotsize); } // 複利機能のロット数を計算する(バックテスト用) double CalculateLots_forTest(double risk, // 許容するリスク int sl_pips) // ストップロス { double freemargin; // アカウントの余剰証拠金 double balance; // アカウントの口座残高 double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額 double lotstep; // サーバのロット数の最小刻み制限 double maxlots; // サーバの最大ロット数制限 double minlots; // サーバの最小ロット数制限 double lotamount; // 1ロットの通貨数 double lotsize = Lots; // ロットサイズ double conv; // 口座通貨種類による補正係数 // 複利機能を使わない場合、Lotsを返す if (MM_ON == Fixed) return(Lots); freemargin = AccountFreeMargin(); balance = AccountBalance(); tickvalue = MarketInfo(NULL, MODE_TICKVALUE); lotstep = MarketInfo(NULL, MODE_LOTSTEP); maxlots = MarketInfo(NULL, MODE_MAXLOT); minlots = MarketInfo(NULL, MODE_MINLOT); lotamount = MarketInfo(NULL, MODE_LOTSIZE); // 1万通貨*1pips = $1 = 100円と仮定し、1ロット1pipの変動が口座通貨でいくらに相当するか計算 // 1 lot = 10万通貨 // 口座通貨 = JPY : tickvalue = 1000円/(lot・pip) // 口座通貨 = USD : tickvalue = $10/(lot・pip) conv = 1; if (AccountCurrency() == "JPY") conv = 100; tickvalue = lotamount / 10000 * conv; // 許容するリスクとSLの幅から、ロットサイズを計算する。 if (MM_ON == FreeMargin) // 余剰証拠金方式 { lotsize = (freemargin * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%) / (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額 } else if (MM_ON == Balance) // 残高方式 { lotsize = (balance * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%) / (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額 } // サーバのロット数の刻みに合わせてロット数を修正 lotsize = MathFloor(lotsize / lotstep) * lotstep; // サーバの最小ロット数・最大ロット数で補正をかける lotsize = MathMax(lotsize, minlots); lotsize = MathMin(lotsize, maxlots); return(lotsize); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリー総括 | //+------------------------------------------------------------------+ int Entry(bool isbuy) { if (Entry_Rule1(isbuy) == 1 && (Entry_Filter1(isbuy) == 1 || Entry_Filter1(isbuy) == 3) && (Entry_Filter2(isbuy) == 1 || Entry_Filter2(isbuy) == 3) && (Entry_Filter3(isbuy) == 1 || Entry_Filter3(isbuy) == 3) && (Entry_Filter4(isbuy) == 1 || Entry_Filter4(isbuy) == 3) && (Entry_Filter5(isbuy) == 1 || Entry_Filter5(isbuy) == 3) && (Entry_Filter6(isbuy) == 1 || Entry_Filter6(isbuy) == 3) && (Entry_Filter7(isbuy) == 1 || Entry_Filter7(isbuy) == 3) && (Entry_Filter8(isbuy) == 1 || Entry_Filter8(isbuy) == 3) ) { return(1); } else if (Entry_Rule1(isbuy) == 2 && (Entry_Filter1(isbuy) == 2 || Entry_Filter1(isbuy) == 3) && (Entry_Filter2(isbuy) == 2 || Entry_Filter2(isbuy) == 3) && (Entry_Filter3(isbuy) == 2 || Entry_Filter3(isbuy) == 3) && (Entry_Filter4(isbuy) == 2 || Entry_Filter4(isbuy) == 3) && (Entry_Filter5(isbuy) == 2 || Entry_Filter5(isbuy) == 3) && (Entry_Filter6(isbuy) == 2 || Entry_Filter6(isbuy) == 3) && (Entry_Filter7(isbuy) == 2 || Entry_Filter7(isbuy) == 3) && (Entry_Filter8(isbuy) == 2 || Entry_Filter8(isbuy) == 3) ) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 売りポジションの決済総括 | //+------------------------------------------------------------------+ int Exit1(bool isbuy) { if (Exit_Rule1(isbuy) == 3 && Exit_Rule2(isbuy) == 3 && Exit_Rule3(isbuy) == 3 && Exit_Rule4(isbuy) == 3 && Exit_Rule5(isbuy) == 3) { return(0); } else if (Exit_Rule1(isbuy) == 1) { return(1); } else if (Exit_Rule2(isbuy) == 1) { return(1); } else if (Exit_Rule3(isbuy) == 1) { return(1); } else if (Exit_Rule4(isbuy) == 1) { return(1); } else if (Exit_Rule5(isbuy) == 1) { return(1); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 買いポジションの決済総括 | //+------------------------------------------------------------------+ int Exit2(bool isbuy) { if (Exit_Rule1(isbuy) == 3 && Exit_Rule2(isbuy) == 3 && Exit_Rule3(isbuy) == 3 && Exit_Rule4(isbuy) == 3 && Exit_Rule5(isbuy) == 3) { return(0); } else if (Exit_Rule1(isbuy) == 2) { return(2); } else if (Exit_Rule2(isbuy) == 2) { return(2); } else if (Exit_Rule3(isbuy) == 2) { return(2); } else if (Exit_Rule4(isbuy) == 2) { return(2); } else if (Exit_Rule5(isbuy) == 2) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリールール1 | //+------------------------------------------------------------------+ int Entry_Rule1(bool isbuy) { //エントリールール1 //RSIが指定値以下になったら「買い」、指定値以上になったら「売り」 //かつ、1本前と2本前のRSI値差が指定範囲以内ならエントリー可(価格変動の速度制御) double RSI1 = iRSI(NULL, PERIOD_M5, RSI_period, PRICE_CLOSE, 1); double RSI2 = iRSI(NULL, PERIOD_M5, RSI_period, PRICE_CLOSE, 2); //ウィリアムズ%Rが指定値以下にいる間は「買い」、指定値以上にいる間は「売り」 double WPR1 = iWPR(NULL, PERIOD_M5, WilliamsPR_Gyakubari_period, 1); double WPR2 = iWPR(NULL, PERIOD_M5, WilliamsPR_Gyakubari_period, 2); if (isbuy == true && Logic1_Time == true) // ポジション0のときは、テクニカルが指定範囲内でエントリー { if ((RSI1 <= RSI_Gyakubari_Line1 && WPR1 < WilliamsPR_BuyExit_Line) || (WPR1 <= WilliamsPR_Line1 && RSI1 < RSI_BuyExit_Line)) { return(1); } // 買い } if (isbuy == false && Logic1_Time == true) // ポジション0のときは、テクニカルが指定範囲内でエントリー { if ((RSI1 >= RSI_Gyakubari_Line2 && WPR1 > WilliamsPR_SellExit_Line) || (WPR1 >= WilliamsPR_Line2 && RSI1 > RSI_SellExit_Line)) { return(2); } // 売り } return(0); // エントリー出来ない //エントリールール1ココマデ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター1 | //+------------------------------------------------------------------+ int Entry_Filter1(bool isbuy) { //エントリーフィルター1 //スプレッド&マージンフィルター double spread = MarketInfo(NULL, MODE_SPREAD); if(Digits == 3 || Digits == 5) spread /= 10.0; double Close0 = iClose(NULL, PERIOD_M5, 0); double Close1 = iClose(NULL, PERIOD_M5, 1); if(spread > MaxSpread_pips) return(0); // スプレッドが指定pips以上でトレード不許可 if(isbuy == true && Close0 - Close1 >= CandleMargin_Pips * xpoint) return(0); // (現在価格-1本足終値)が、指定pips以上だったら買い禁止 if(isbuy == false && Close1 - Close0 >= CandleMargin_Pips * xpoint) return(0); // (1本足終値-現在価格)が、指定pips以上だったら売り禁止 else return(3); // トレード許可 //エントリーフィルター1ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター2 | //+------------------------------------------------------------------+ int Entry_Filter2(bool isbuy) { //エントリーフィルター2 //12/24~1/3まではエントリーしない int NGMonth = Month(); int NGDay = Day(); if (YearendClose == true && ((NGMonth == 12 && NGDay >= 24) || (NGMonth == 1 && NGDay <= 3)) ) { return(0); } // エントリー出来ない //エントリーフィルター2ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター3 | //+------------------------------------------------------------------+ int Entry_Filter3(bool isbuy) { //エントリーフィルター3 // バンド幅が、指定pips以上ならエントリー可 double UpperBB2 = iBands(NULL, PERIOD_M5, 20, 2, 0, PRICE_CLOSE, MODE_UPPER, 1); double LowerBB2 = iBands(NULL, PERIOD_M5, 20, 2, 0, PRICE_CLOSE, MODE_LOWER, 1); if (UpperBB2 - LowerBB2 >= BBMargin * xpoint) { return(3); } // トレード許可 else { return(0); } // トレード不許可 //エントリーフィルター3ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター4 | //+------------------------------------------------------------------+ int Entry_Filter4(bool isbuy) { //エントリーフィルター4 // 過去◯本の高値安値の値を取得 double MostHigh; double MostLow; int HighestIndex = iHighest(NULL, PERIOD_M5, MODE_HIGH, CandleCheckCount, 1); int LowestIndex = iLowest(NULL, PERIOD_M5, MODE_LOW , CandleCheckCount, 1); MostHigh = iHigh(NULL, PERIOD_M5, HighestIndex); MostLow = iLow(NULL, PERIOD_M5, LowestIndex); // 過去〇本に〇〇pips以上値動きがあったらエントリー禁止 if (MostHigh - MostLow > HL_Margin_pips * xpoint) { return(0); } // エントリー出来ない //エントリーフィルター4ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター5 | //+------------------------------------------------------------------+ int Entry_Filter5(bool isbuy) { //エントリーフィルター5 int F5_PERIOD = PERIOD_M5; if (RSI_JUNBARI_TF == 1) F5_PERIOD = PERIOD_M1; if (RSI_JUNBARI_TF == 2) F5_PERIOD = PERIOD_M5; if (RSI_JUNBARI_TF == 3) F5_PERIOD = PERIOD_M15; if (RSI_JUNBARI_TF == 4) F5_PERIOD = PERIOD_M30; if (RSI_JUNBARI_TF == 5) F5_PERIOD = PERIOD_H1; if (RSI_JUNBARI_TF == 6) F5_PERIOD = PERIOD_H4; if (RSI_JUNBARI_TF == 7) F5_PERIOD = PERIOD_D1; if (RSI_JUNBARI_TF == 8) F5_PERIOD = PERIOD_W1; if (RSI_JUNBARI_TF == 9) F5_PERIOD = PERIOD_MN1; // RSIが指定値以上にいる間は「買い」、指定値以下にいる間は「売り」 double RSI0 = iRSI(NULL, F5_PERIOD, 14, PRICE_CLOSE, 1); // RSIが指定値以上にいる間は「買い」 if (isbuy == true && RSI0 >= RSI_Junbari_Filter_Line) { return(1); } // 買い // RSIが指定値以下にいる間は「売り」 if (isbuy == false && RSI0 <= 100 - RSI_Junbari_Filter_Line) { return(2); } // 売り else { return(0); } // エントリー不可 //エントリーフィルター5ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター6 | //+------------------------------------------------------------------+ int Entry_Filter6(bool isbuy) { //エントリーフィルター6 int F6_PERIOD = PERIOD_H1; if (MACD_TF == 1) F6_PERIOD = PERIOD_M1; if (MACD_TF == 2) F6_PERIOD = PERIOD_M5; if (MACD_TF == 3) F6_PERIOD = PERIOD_M15; if (MACD_TF == 4) F6_PERIOD = PERIOD_M30; if (MACD_TF == 5) F6_PERIOD = PERIOD_H1; if (MACD_TF == 6) F6_PERIOD = PERIOD_H4; if (MACD_TF == 7) F6_PERIOD = PERIOD_D1; if (MACD_TF == 8) F6_PERIOD = PERIOD_W1; if (MACD_TF == 9) F6_PERIOD = PERIOD_MN1; // MACD線がゼロ0より上の間は「買い」/ゼロより下の間は「売り」 double MACD_MAIN1 = iMACD(NULL, F6_PERIOD, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1); // 1本前のMACD線 // MACD線がゼロ0より上の間は「買い」 if (isbuy == true && MACD_MAIN1 > 0) { return(1); } // 買い // MACD線がゼロ0より下の間は「売り」 if (isbuy == false && MACD_MAIN1 < 0) { return(2); } // 売り else { return(0); } //エントリーフィルター6ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター7 | //+------------------------------------------------------------------+ int Entry_Filter7(bool isbuy) { if (WR_MODE == true) { //エントリーフィルター7 int ADX_PERIOD = 240; if (ADX_TF == 1) ADX_PERIOD = PERIOD_M1; if (ADX_TF == 2) ADX_PERIOD = PERIOD_M5; if (ADX_TF == 3) ADX_PERIOD = PERIOD_M15; if (ADX_TF == 4) ADX_PERIOD = PERIOD_M30; if (ADX_TF == 5) ADX_PERIOD = PERIOD_H1; if (ADX_TF == 6) ADX_PERIOD = PERIOD_H4; if (ADX_TF == 7) ADX_PERIOD = PERIOD_D1; if (ADX_TF == 8) ADX_PERIOD = PERIOD_W1; if (ADX_TF == 9) ADX_PERIOD = PERIOD_MN1; // ADXが指定値以上の時のみエントリー出来る double ADX1 = iADX(NULL, ADX_PERIOD, 14, PRICE_CLOSE, MODE_MAIN, 1); double ADX2 = iADX(NULL, ADX_PERIOD, 14, PRICE_CLOSE, MODE_MAIN, 2); if (ADX1 > ADX_value)// && ADX1 > ADX2 ) { return(0); } // エントリー不可 else { return(3); } // エントリー可 } //エントリーフィルター7ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター8 | //+------------------------------------------------------------------+ int Entry_Filter8(bool isbuy) { //エントリーフィルター8 // 各種モード切替 int Week = TimeDayOfWeek(TimeCurrent()); if (WS_MODE == Wednesday && Week == 3 && xxTime == 23) { return(0); } if (WS_MODE == Thursday && Week == 4 && xxTime == 23) { return(0); } if (WS_MODE == Wednesday_Thursday && (Week == 3 || Week == 4) && xxTime == 23) { return(0); } if (NG0_MODE == true && xxTime == 0) { return(0); } else { return(3); } //エントリーフィルター8ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール1 | //+------------------------------------------------------------------+ int Exit_Rule1(bool isbuy) { // 決済ルール1 //RSIが指定値以上になったら「買いポジション決済」、指定値以下になったら「売りポジション決済」 double WPR1 = iWPR(NULL, PERIOD_M5, WilliamsPR_Gyakubari_period, 1); // RSIが指定以上になったら買いポジション決済 if (WPR1 >= WilliamsPR_BuyExit_Line) { return(2); } else if (WPR1 <= WilliamsPR_SellExit_Line) { return(1); } else { return(0); } // 決済ルール1ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール2 | //+------------------------------------------------------------------+ int Exit_Rule2(bool isbuy) { // 決済ルール2 //RSIが指定値以上になったら「買いポジション決済」、指定値以下になったら「売りポジション決済」 double RSI1 = iRSI(NULL, PERIOD_M5, RSI_period, PRICE_CLOSE, 1); // RSIが指定以上になったら買いポジション決済 if (RSI1 >= RSI_BuyExit_Line) { return(2); } else if (RSI1 <= RSI_SellExit_Line) { return(1); } else { return(0); } // 決済ルール2ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール3 | //+------------------------------------------------------------------+ int Exit_Rule3(bool isbuy) { // 決済ルール3 // 決済ルール3ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール4 | //+------------------------------------------------------------------+ int Exit_Rule4(bool isbuy) { // 決済ルール4 // 決済ルール4ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール5 | //+------------------------------------------------------------------+ int Exit_Rule5(bool isbuy) { // 決済ルール5 // 決済ルール5ココマデ return(3); } //+------------------------------------------------------------------+