//+------------------------------------------------------------------+ //| MAN-010.mq4 | //| Copyright 2025, TNK/TNK_SYSTEM | //| https://note.com/tnk_system | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, TNK/TNK_SYSTEM" #property link "https://note.com/tnk_system" #property version "6.5" //ロジック調整 #property icon "TNKIcon.ico" // アイコン取り込み #property strict #include //#define ROSOKU_Check //#define MQLDebug_OPCL //#define MQLDebug_SLTP //#include #property description "[通貨ペア] USDJPY [時間足] M5 [スタイル] デイトレ [ポジション数] 1" #property description "[両建て] 無し [トレール] 有り [週末持ち越し] 無し [翌日持ち越し] 無し" #property description "[TP/SL] 買1:140/140 買2:80/80 売1:400/200 pips(変更可)" #property description "[年末年始停止] 12/21~1/3(新規エントリー無し・決済のみ実行)" #property description "[GMT] 冬+2/夏+3(日足5本)専用 [バー数] 1000以上" //string limitDate = "2025.3.31 23:59"; //int validAccount1 = 81154073; // 口座縛り1 //int validAccount2 = 230087286; // 口座縛り2 //+------------------------------------------------------------------+ //|ユーザー入力用パラメーター | //+------------------------------------------------------------------+ input int MagicNumber = 8691307; // マジックナンバー(他EAと重複不可) input double Lots = 0.25; // ロット(単利運用時) input double MM_Risk = 3.0; // リスク%(複利選択項目の何%か) enum MM_Select{ Fixed, // 0:単利/固定 FreeMargin, // 1:複利/余剰証拠金 Balance, // 2:複利/残高 }; input MM_Select MM_ON = Fixed; // 複利機能(0:固定/1:余剰証拠金/2:残高) double MaxSpread_pips = 4.0; // 許容スプレッド(Pips) input double AllowSpread = 10.0; // 許容スプレッドPips(0:自動) input bool Recording = false; // トレード情報記録(スプレッド・スリッページ等) input bool VisualHistory = false; // 取引履歴データ等をチャートに表示 input string _Comment = "32854:AMX-USDJPY_M5"; // 通知用コメント //+------------------------------------------------------------------+ //|内部設定・グローバル関数 | //+------------------------------------------------------------------+ //内部設定 int Maxposition = 1; // 最大ポジション int Slippage = 100; // 許容スリッページ(Point) int TakeProfit_pips = 1000; // 利確指値(Pips) int StopLoss_pips = 1000; // 損切逆指値(Pips) int MaxTakeprofit_pips = 1000; int MaxStopLoss_pips = 1000; bool YearendClose = true; // 12/21~1/3クローズ int GMT = 2; // GMT(冬時間) int Summertime = 1; // サマータイム(0:無し/1:米/2:英) ENUM_TIMEFRAMES SD_TF_TP_buy; int SD_Period_TP_buy; double SD_mul_TP_buy, SD_mul_SL_buy; int TakeProfit_pips_buy, StopLoss_pips_buy; double TrailStartMul_buy; int BarCountSL_buy; //桁合わせ・時間制御用 double xpoint; int xxTime, xxxTime, yTime; int xBars = 0, xxBars = 0, yyBars = 0; // 証拠金チェック int aCmd = 0; //エントリー時間(サーバー時間) bool GMT_Kadou_OK_buy1 = false; // エントリー時間 bool GMT_Kadou_OK_buy2 = false; // エントリー時間 bool GMT_Kadou_OK_sell1 = false; // エントリー時間 //ポジション決済(サーバー時間) bool ExitTimeClose_buy1 = false; // 時間決済(buy1) bool ExitTimeClose_buy2 = false; // 時間決済(buy2) bool ExitTimeClose_sell1 = false; // 時間決済(sell1) bool ExitPosition_buy1 = false; // ポジション決済(buy) bool ExitPosition_buy2 = false; // ポジション決済(buy2) bool ExitPosition_sell1 = false; // ポジション決済(sell1) //バックテスト用モード切替 bool Development = false; // 開発モードON/OFF(OnTester欄にRF表示、インジケータ表示) bool Modify = true; // トレール //+------------------------------------------------------------------+ //|便利機能系 | //+------------------------------------------------------------------+ //チャートセット固定用 string SYMBOL1 = "USDJPY"; // シンボル名(頭6文字) //string SYMBOL2 = "GOLD"; // シンボル名(頭4文字) ENUM_TIMEFRAMES Chart_TimeFrame = PERIOD_M5; // タイムフレーム // EAの状態変化用 bool ChartWarning; // マジックナンバー重複セットアラート static bool check_duplicate = true; static const string kEA_NAME = (string)MagicNumber; // スプレッド計測用 double MeasureSpread, SpreadAve = 0, SpreadAve1 = 0; // オートスプレッド用 double Adjustspread = 5.0; // 平均スプレッド加算用宣言 double AllowMaxSpread = 8.0; // 自動最大許容スプレッド double Adjustspread_Margin = 2.0; // 自動スプレッド調整幅 double Adjustspread_Margin1 = 1.0; // 自動スプレッド調整幅(1:00) // DPI換算 double DPIAdjust; // バックテスト時間計測 uint StartingTimestampBT; // 各計測用パラメータ int err, fp; string filename; double OSpread, CSpread; uint StartOrderTimestamp, OrderCloseTimestamp, StartingTimestamp; double Order_Price, Close_Price; uint OpenLatency, CloseLatency; string Timeframe = (Period() == PERIOD_M1? "M1": Period() == PERIOD_M5? "M5": Period() == PERIOD_M15? "M15": Period() == PERIOD_M30? "M30": Period() == PERIOD_H1? "H1": Period() == PERIOD_H4? "H4": Period() == PERIOD_D1? "D1": Period() == PERIOD_W1? "W1": "MN1"); string Open_Type, Close_Type; bool WritingTPSL = false; datetime OrderCloseTime_bak = 0; // チャートにトレード履歴表示用 double totalpips = 0, ProfitFactor = 0; double plus_profit = 0, minus_profit = 0; double minus_count = 0, plus_count = 0; double RRR, WinPer; double TradeCounts; //+------------------------------------------------------------------+ //|ロジック用パラメータ | //+------------------------------------------------------------------+ string Logic_Parameters = ""; // ■■■■■ロジック別パラメータ■■■■■ //エントリーフィルター double Gap_Pips = 7; // 【共通】1本前ローソク足終値と現在価格の差pips //+------------------------------------------------------------------+ string Logic_Buy1_Parameters = ""; // ■■■■■ロジック1パラメータ■■■■■ input bool Logic_Buy1 = true; // ▼Buy1稼働スイッチ string Entry_Parameters_buy1 = ""; // ■■■■■【buy1】エントリー■■■■■ int StartDay_buy1 = 25; // 【トリガー】開始日 int EndDay_buy1 = 30; // 【トリガー】終了日 int TimeOpen_buy1 = 9; // 【トリガー】時刻 int MinuteOpen_buy1 = 0; // 【トリガー】分 int MinuteOpen_buy1_2 = 0; // 【トリガー】分2 int MA_S_period_buy1 = 30; // 【環境認識】短期MA期間 int MA_L_period_buy1 = 58; // 【環境認識】長期MA期間 double Kairi_Judge_percent1_buy1 = 1.5; // 【環境認識】順張り:MA乖離% double Kairi_Judge_percent2_buy1 = 0.1; // 【環境認識】逆張り:MA乖離% string Exit_Parameters_buy1 = ""; // ■■■■■【buy1】決済■■■■■ int TimeClose_buy1 = 17; // 【トリガー】時刻 int MinuteClose_buy1 = 55; // 【トリガー】分 ENUM_TIMEFRAMES SD_TF_TP_buy1 = PERIOD_D1; // 【TPSL】SDタイムフレーム int SD_Period_TP_buy1 = 5; // 【TPSL】SD期間 double SD_mul_TP_buy1 = 3.5; // 【TP】SD倍数 input int TakeProfit_pips_buy1 = 140; // 【TP】Pips double SD_mul_SL_buy1 = 1.5; // 【SL】SD倍数 input int StopLoss_pips_buy1 = 140; // 【SL】Pips double TrailStartMul_buy1 = 0.1; // 【トレール】開始SD倍数 int BarCountSL_buy1 = 180; // 【トレール】安値を探すローソク足本数 //+------------------------------------------------------------------+ string Logic_Buy2_Parameters = ""; // ■■■■■ロジック2パラメータ■■■■■ input bool Logic_Buy2 = true; // ▼Buy2稼働スイッチ string Entry_Parameters_buy2 = ""; // ■■■■■【buy2】エントリー■■■■■ int TimeOpen_buy2 = 1; // 【トリガー】時刻 int MinuteOpen_buy2 = 0; // 【トリガー】分 int MinuteOpen_buy2_2 = 15; // 【トリガー】分2 //input int MA_S_period_buy2 = 30; // 【環境認識】短期MA期間 int MA_L_period_buy2 = 11; // 【環境認識】長期MA期間 double Kairi_Judge_percent1_buy2 = 2.2; // 【環境認識】順張り:MA乖離% double Kairi_Judge_percent2_buy2 = 0.2; // 【環境認識】逆張り:MA乖離% string Exit_Parameters_buy2 = ""; // ■■■■■【buy2】決済■■■■■ int TimeClose_xxx_buy2 = 2; // 【buy2|決済】時刻 int MinuteClose_xxx_buy2 = 55; // 【buy2|決済】分 int TimeClose_xx_buy2 = 2; // 【buy2|決済】時刻2 int MinuteClose_xx_buy2 = 55; // 【buy2|決済】分2 ENUM_TIMEFRAMES SD_TF_TP_buy2 = PERIOD_D1; // 【TPSL】SDタイムフレーム int SD_Period_TP_buy2 = 5; // 【TPSL】SD期間 double SD_mul_TP_buy2 = 0.4; // 【TP】SD倍数 input int TakeProfit_pips_buy2 = 80; // 【TP】Pips double SD_mul_SL_buy2 = 2.1; // 【SL】SD倍数 input int StopLoss_pips_buy2 = 80; // 【SL】Pips double TrailStartMul_buy2 = 0.1; // 【トレール】開始SD倍数 int BarCountSL_buy2 = 180; // 【トレール】安値を探すローソク足本数 //+------------------------------------------------------------------+ string Logic_Sell1_Parameters = ""; // ■■■■■ロジック2パラメータ■■■■■ input bool Logic_Sell1 = true; // ▼Sell1稼働スイッチ string Entry_Parameters_sell1 = ""; // ■■■■■【sell1】エントリー■■■■■ int StartDay_sell1 = 23; // 【トリガー】開始日 int EndDay_sell1 = 30; // 【トリガー】終了日 int TimeOpen_sell1 = 1; // 【トリガー】時刻 int MinuteOpen_sell1 = 0; // 【トリガー】分 int TimeOpen_sell1_2 = 3; // 【トリガー】時刻2 int MinuteOpen_sell1_2 = 0; // 【トリガー】分2 //input int MA_S_period_sell1 = 54; // 【環境認識】短期MA期間 int MA_L_period_sell1 = 62; // 【環境認識】長期MA期間 double Kairi_Judge_percent_sell1 = 4.2; // 【環境認識】順張り:MA乖離% double Kairi_Judge_percent_sell2 = 0; // 【環境認識】逆張り:MA乖離% string Exit_Parameters_sell1 = ""; // ■■■■■【sell1】決済■■■■■ int TimeClose_sell1 = 8; // 【トリガー】時刻 int MinuteClose_sell1 = 10; // 【トリガー】分 ENUM_TIMEFRAMES SD_TF_TP_sell1 = PERIOD_D1; // 【TPSL】SDタイムフレーム int SD_Period_TP_sell1 = 5; // 【TPSL】SD期間 double SD_mul_TP_sell1 = 4.2; // 【TP】SD倍数 input int TakeProfit_pips_sell1 = 400; // 【TP】Pips double SD_mul_SL_sell1 = 2.2; // 【SL】SD倍数 input int StopLoss_pips_sell1 = 200; // 【SL】Pips double TrailStartMul_sell1 = 2.0; // 【トレール】開始SD倍数 int BarCountSL_sell1 = 24; // 【トレール】高値を探すローソク足本数 //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| tester function | //+------------------------------------------------------------------+ double OnTester() { // OnTesterに表示【リカバリーファクター|勝率】 if (Development) { // リカバリーファクター return(NormalizeDouble(TesterStatistics(STAT_PROFIT) / TesterStatistics(STAT_EQUITY_DD), 2)); } return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //+------------------------------------------------------------------+ // バックテスト時間計測 StartingTimestampBT = GetTickCount(); //+------------------------------------------------------------------+ // 使用期限・デモ制御 /*int demosv = StringFind(AccountServer(), "demo", 0); // サーバー名に"demo"で稼働 int Demosv = StringFind(AccountServer(), "Demo", 0); // サーバー名に"Demo"で稼働 int trialsv = StringFind(AccountServer(), "trial", 0); // サーバー名に"trial"で稼働 int practicesv = StringFind(AccountServer(), "practice", 0); // サーバー名に"practice"で稼働 if (TimeCurrent() > StrToTime(limitDate) && //期限切れ (!IsDemo() && demosv == -1 && Demosv == -1 && trialsv == -1 && practicesv == -1) ) { Alert(WindowExpertName() + " has expired or is not a demo account." + "\n" + "使用期限が過ぎたか、デモ口座ではありません。"); return(INIT_FAILED); } if (!IsTesting()) {// コメントに使用期限を表示 Comment("使用期限は " + limitDate + " (サーバー時間) までです。以降はデモ口座のみで稼働可能です。"); }*/ //+------------------------------------------------------------------+ // 口座番号縛り /*if (IsTesting() == false) { if (!(AccountNumber() == validAccount1))// || AccountNumber() == validAccount2)) { Alert("Not allowed account!" +"\n"+ "許可されていない口座です。"); return(INIT_FAILED); // 初期化が失敗した事を返し、EAを終了させる } }*/ //+------------------------------------------------------------------+ // GMT0ブローカー禁止・サマータイム自動調整用宣言 string BrokerName0 = "Ava Trad"; // Ava "Ava Trade Ltd."; string BrokerName1 = "Exness T"; // Exness "Exness Technologies Ltd"; string BrokerName2 = "HF Marke"; // HFM "HF Markets (SV) Ltd.";"HF Markets(SV)Ltd."; string BrokerName3 = "Tradexfi"; // XM "Tradexfin Limited"; string BrokerName4 = "FinTrade"; // XM "FinTrade Limited"; string BrokerName5 = "NOTESCO "; // IronFX "NOTESCO Ltd"; //+------------------------------------------------------------------+ // GMT0ブローカー稼働禁止 if (StringSubstr(AccountCompany(), 0, 8) == BrokerName0 || StringSubstr(AccountCompany(), 0, 8) == BrokerName1 ) { Alert( WindowExpertName() + " cannot run on brokers at GMT0" + "\n" + "GMT0のブローカーは稼働できません" ); return(INIT_FAILED); } //+------------------------------------------------------------------+ // サマータイム自動調整 if (StringSubstr(AccountCompany(), 0, 8) == BrokerName1) { Summertime = 0; } else if (StringSubstr(AccountCompany(), 0, 8) == BrokerName2 || StringSubstr(AccountCompany(), 0, 8) == BrokerName3 || StringSubstr(AccountCompany(), 0, 8) == BrokerName4 || StringSubstr(AccountCompany(), 0, 8) == BrokerName5 ) { Summertime = 2; } else { Summertime = 1; } Print(Summertime == 0? "No summertime" : Summertime == 2? "European(UK) summertime" : "American summertime"); //+------------------------------------------------------------------+ // 小数点以下の桁数に応じてPipsの値を調整する xpoint = Point(); /*if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") // ゴールド用 { if (Digits() == 2) { xpoint = xpoint * 10; } else if (Digits() == 3) { xpoint = xpoint * 100; } } else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) // ゴールド以外用 {*/ if (Digits() == 3 || Digits() == 5) { xpoint = xpoint * 10; } //} //+-----------------------------------------------------------------+ // DPI換算 double USERdpi = TerminalInfoInteger(TERMINAL_SCREEN_DPI); double DevPCdpi = 144; DPIAdjust = USERdpi / DevPCdpi; //+------------------------------------------------------------------+ // 最大SL算出(コメント・複利の計算で使用) //TakeProfit_pips = MathMax(TakeProfit_pips_L1, TakeProfit_pips_L2); MaxStopLoss_pips = MathMax(Logic_Buy1? StopLoss_pips_buy1 : 0, MathMax(Logic_Buy2? StopLoss_pips_buy2 : 0, Logic_Sell1? StopLoss_pips_sell1 : 0)); //+------------------------------------------------------------------+ // 初期化スプレッド(バックテスト時または手動時、それ以外や自動) if (IsTesting() || AllowSpread != 0) MaxSpread_pips = AllowSpread; if (AllowSpread == 0) MaxSpread_pips = AllowMaxSpread; //+------------------------------------------------------------------+ // チャート自動変更・シンボル・チャートコメント・状態表示 if (!IsTesting()) { ChartSet(); // チャート自動変更 CenterSymbol(); // 中央のシンボル ChartComment(); // チャートコメント } //+------------------------------------------------------------------+ // トレード履歴をチャートに表示(ライン・pips) if (VisualHistory) { history(); PosHis(); } //+------------------------------------------------------------------+ // 開発モード(販売時はfalseに) if (Development) HideTestIndicators(false);// 使用しているインジケータを表示する else HideTestIndicators(true);// 使用しているインジケータを非表示にする //+------------------------------------------------------------------+ // マジックナンバー重複セットアラート if (check_duplicate) { double term_global_var; if (GlobalVariableGet(kEA_NAME, term_global_var)) { Alert( WindowExpertName() + " may have duplicate magic numbers. If all is well, press OK to continue with the setup" + "\n" + "マジックナンバー重複の可能性があります。問題が無ければ、OKを押して設定を継続してください。" ); } const datetime mutex_time = GlobalVariableSet(kEA_NAME, 1.0); if (mutex_time == 0) { const int errcode = GetLastError(); Print("GlobalVariableSet: ERRCODE[", errcode, "]:", ErrorDescription(errcode)); } } //+------------------------------------------------------------------+ // ファイル出力初期化処理 if (Recording) FileInit(); //+------------------------------------------------------------------+ // ビジュアルモードBT禁止 /*if (IsVisualMode()) { Alert("Cannot be tested in visual mode / ビジュアルモードのテストはできません"); return(INIT_FAILED); }*/ //+------------------------------------------------------------------+ return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| expert OnDeinit function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //+------------------------------------------------------------------+ // マジックナンバー重複用 if (check_duplicate) { if (!GlobalVariableDel(kEA_NAME)) { const int errcode = GetLastError(); Print("GlobalVariableDel: ERRCODE[", errcode, "]:", ErrorDescription(errcode)); } } //+------------------------------------------------------------------+ // オブジェクト削除関連 if (!IsTesting()) { ObjectsDeleteAll(); ChartSetInteger(0,CHART_COLOR_CHART_UP,clrLime); ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrLime); ChartSetInteger(0,CHART_COLOR_CHART_LINE,clrLime); Comment(""); } //+------------------------------------------------------------------+ // バックテスト時間計算・出力 if (IsTesting()) { uint EndingTimestamp = GetTickCount(); //始動時間 uint BT_Time = EndingTimestamp - StartingTimestampBT; uint msec_unit = BT_Time % 1000; datetime temp_date = BT_Time / 1000; Print( "バックテスト時間= ", TimeHour(temp_date), "hour ", TimeMinute(temp_date), "min ", TimeSeconds(temp_date), ".", msec_unit, "sec ", " 元データ= ", BT_Time ); } //+------------------------------------------------------------------+ // BT後にチャートにトレード線とpips表示 if (IsTesting() && VisualHistory) TradeLinePips(); //+------------------------------------------------------------------+ // BT後の解析防止 //if (IsTesting()) {ObjectsDeleteAll(0, "#");} //+------------------------------------------------------------------+ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //+------------------------------------------------------------------+ //始動時間 StartingTimestamp = GetTickCount(); //+------------------------------------------------------------------+ if (Volume[0] <= 10) { GetSummertimeShift(); // サマータイム調整・時間制御 PositionClose(); // ポジションをクローズ Trailing(); // トレーリング if (GMT_Kadou_OK_buy1 || GMT_Kadou_OK_buy2 || GMT_Kadou_OK_sell1) PositionOpen(); // ポジションのエントリー } if (Volume[0] == 11) {SetTPSL();} // TP, SLの再設定 //+------------------------------------------------------------------+ // チャート自動変更・シンボル・チャートコメント・状態表示 if (!IsTesting()) { CenterSymbol(); // センターにシンボル情報 ChartComment(); // チャートコメント } //+------------------------------------------------------------------+ // スプレッド値取得 if (!IsTesting() && AllowSpread == 0) { MeasureSpread = MarketInfo(Symbol(),MODE_SPREAD) / 10; MeasureSP(); } //+------------------------------------------------------------------+ // チャートにトレード線とpips表示 if (!IsTesting() && VisualHistory) TradeLinePips(); //+------------------------------------------------------------------+ // 決済がTP/SLなら情報取得 if (Recording && !WritingTPSL) ClosedTradeTPSL(); //+------------------------------------------------------------------+ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 補正関数 | //+------------------------------------------------------------------+ void GetSummertimeShift() { int MON, SUN_day; int summertime_shift = 0; // GMT+9を基準に、どれだけずれているかを算出する------------------------ MON = TimeMonth(TimeCurrent()); // 何月? SUN_day = TimeDay(TimeCurrent()) - TimeDayOfWeek(TimeCurrent()); // その週の日曜日は何日? if (Summertime == 2) // 英国式の場合 { if ((MON == 3 && SUN_day >= 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; } //GMT+9基準でどれだけずれているかを算出する(ココマデ)-------------------- //+------------------------------------------------------------------+ //| 時間制御 | //+------------------------------------------------------------------+ //---- トレード許可時間の判定 ---- xxTime = Hour() - (GMT - 2); // サーバー時間(サマータイム計算なし) xxxTime = Hour() - (GMT - 2 + summertime_shift); // サーバー時間(サマータイム計算あり) yTime = Minute(); // サーバーの分 // サーバー時間 if (xxTime < 0) { xxTime = xxTime + 24; } else if (xxTime > 23) { xxTime = xxTime - 24; } // サーバー時間(サマータイムあり) if (xxxTime < 0) { xxxTime = xxxTime + 24; } else if (xxxTime > 23) { xxxTime = xxxTime - 24; } //+------------------------------------------------------------------+ //| ロジック別時間制御 | //+------------------------------------------------------------------+ // ロジック買い1 if (Logic_Buy1) { // ポジションクローズ時間(サーバー時間) if ( ( (xxTime == TimeClose_buy1 && yTime == MinuteClose_buy1) || xxTime > TimeClose_buy1 ) && Day() >= StartDay_buy1 && Day() <= EndDay_buy1+1 ) { ExitTimeClose_buy1 = true; } else { ExitTimeClose_buy1 = false; } // ポジション保持中決済(サーバー時間) if (( (xxTime == TimeOpen_buy1 && yTime >= MinuteOpen_buy1) || (xxTime > TimeOpen_buy1 && xxTime < TimeClose_buy1) || (xxTime == TimeClose_buy1 && yTime < MinuteClose_buy1)) && Day() >= StartDay_buy1 && Day() <= EndDay_buy1+1 ) { ExitPosition_buy1 = true; } else { ExitPosition_buy1 = false; } // エントリー時間(サーバー時間) if (xxTime == TimeOpen_buy1 && yTime == MinuteOpen_buy1 //&& yTime <= MinuteOpen_buy1_2 && (Day() >= StartDay_buy1 && Day() <= EndDay_buy1) ) { SD_TF_TP_buy = SD_TF_TP_buy1; SD_Period_TP_buy = SD_Period_TP_buy1; SD_mul_TP_buy = SD_mul_TP_buy1; TakeProfit_pips_buy = TakeProfit_pips_buy1; SD_mul_SL_buy = SD_mul_SL_buy1; StopLoss_pips_buy = StopLoss_pips_buy1; TrailStartMul_buy = TrailStartMul_buy1; BarCountSL_buy = BarCountSL_buy1; Modify = true; GMT_Kadou_OK_buy1 = true; } else { GMT_Kadou_OK_buy1 = false; } } // ロジック買い2 if (Logic_Buy2) { // ポジションクローズ時間(サーバー時間) if ( (((xxxTime == TimeClose_xxx_buy2 && yTime >= MinuteClose_xxx_buy2) || (xxxTime > TimeClose_xxx_buy2 && xxxTime < TimeOpen_buy1-1)) && !(Day() >= StartDay_sell1 && Day() <= EndDay_sell1)) || (((xxTime == TimeClose_xx_buy2 && yTime >= MinuteClose_xx_buy2) || (xxTime > TimeClose_xx_buy2 && xxTime < TimeOpen_buy1)) && (Day() >= StartDay_sell1 && Day() <= EndDay_sell1)) ) { ExitTimeClose_buy2 = true; } else { ExitTimeClose_buy2 = false; } // ポジション保持中決済(サーバー時間) if ( (xxTime == TimeOpen_buy2 && yTime >= MinuteOpen_buy2) || xxTime > TimeOpen_buy2 || xxTime <= TimeClose_xxx_buy2 ) { ExitPosition_buy2 = true; } else { ExitPosition_buy2 = false; } // ゴトー日制御 bool Gotobi; /*if (Day() == 4 || Day() == 9 || Day() == 14 || Day() == 19 || Day() == 24 || Day() == 29 || (TimeDayOfWeek(TimeCurrent()) == 5 && ( Day() == 2 || Day() == 3 || Day() == 7 || Day() == 8 || Day() == 12 || Day() == 13 || Day() == 17 || Day() == 18 || Day() == 22 || Day() == 23 || Day() == 27 || Day() == 28 ) ))*/ if (Day() == 10 || Day() == 15 || Day() == 20 || Day() == 25) { Gotobi = true; } else { Gotobi = false; } // エントリー時間(サーバー時間) if (Gotobi && xxTime == TimeOpen_buy2 && yTime >= MinuteOpen_buy2 && yTime <= MinuteOpen_buy2_2) { SD_TF_TP_buy = SD_TF_TP_buy2; SD_Period_TP_buy = SD_Period_TP_buy2; SD_mul_TP_buy = SD_mul_TP_buy2; TakeProfit_pips_buy = TakeProfit_pips_buy2; SD_mul_SL_buy = SD_mul_SL_buy2; StopLoss_pips_buy = StopLoss_pips_buy2; TrailStartMul_buy = TrailStartMul_buy2; BarCountSL_buy = BarCountSL_buy2; Modify = false; GMT_Kadou_OK_buy2 = true; } else { GMT_Kadou_OK_buy2 = false; } } // ロジック売り1 if (Logic_Sell1) { // ポジションクローズ時間(サーバー時間) if ((xxTime == TimeClose_sell1 && yTime >= MinuteClose_sell1) || xxTime > TimeClose_sell1 || xxTime < TimeOpen_sell1 ) { ExitTimeClose_sell1 = true; } else { ExitTimeClose_sell1 = false; } // ポジション保持中決済(サーバー時間) if ( (xxTime == TimeOpen_sell1 && yTime >= MinuteOpen_sell1) || xxTime > TimeOpen_sell1 || xxTime <= TimeClose_sell1 ) { ExitPosition_sell1 = true; } else { ExitPosition_sell1 = false; } // エントリー時間(サーバー時間) /*if (xxxTime == TimeOpen_sell1 && yTime >= MinuteOpen_sell1 && (Day() >= StartDay_sell1 && Day() <= EndDay_sell1) )*/ if ( ( (xxxTime == TimeOpen_sell1 && yTime == MinuteOpen_sell1 && Day() != 25) || (xxxTime == TimeOpen_sell1_2 && yTime == MinuteOpen_sell1_2 && Day() == 25)) && yTime <= 3 && (Day() >= StartDay_sell1 && Day() <= EndDay_sell1) ) { TakeProfit_pips = TakeProfit_pips_sell1; StopLoss_pips = StopLoss_pips_sell1; Modify = true; GMT_Kadou_OK_sell1 = true; } else { GMT_Kadou_OK_sell1 = false; } } // ここまで、エグジットとトレーリングは、取引時間に関係なく実施する //---- トレード許可時間の判定(ココマデ) ---- } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ポジションのクローズ | //+------------------------------------------------------------------+ void PositionClose() { int i; double profit; bool res = false; // 所有しているポジションをクローズする 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; //エントリーからのローソク足本数が1本未満なら、for文の先頭に戻る) int OrderOpenCandleCount = iBarShift(NULL, PERIOD_M5, OrderOpenTime()); if (OrderOpenCandleCount == 0) continue; int spread = (int)MarketInfo(NULL, MODE_SPREAD); if (OrderType() == OP_BUY) { profit = NormalizeDouble(Bid - OrderOpenPrice(), Digits); // 買いポジションだった場合の、含み損益を計算する if ( (Exit2(false, profit) == 2 && spread <= (int)MaxSpread_pips*10) || (Exit2(false, profit) == 2 && spread > (int)MaxSpread_pips*10 && profit > 0) ) { CSpread = MarketInfo(NULL, MODE_SPREAD); // スプレッド取得 OrderCloseTimestamp = GetTickCount();// レイテンシー取得 Close_Price = Bid; // 決済売り注文を入れる価格 res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green); CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー取得 } } if (OrderType() == OP_SELL) { profit = NormalizeDouble(OrderOpenPrice() - Ask, Digits); // 売りポジションだった場合の、含み損益を計算する // オーダーを成り行き決済する if ( (Exit1(true, profit) == 1 && spread <= (int)MaxSpread_pips*10) || (Exit1(true, profit) == 1 && spread > (int)MaxSpread_pips*10 && profit > 0) ) { CSpread = MarketInfo(NULL, MODE_SPREAD); //スプレッド取得 OrderCloseTimestamp = GetTickCount(); // レイテンシー取得 Close_Price = Ask; // 決済買い注文を入れる価格 res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green); CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー取得 } } } // 所有しているポジションをクローズする(ココマデ) // ファイル書込 if (res && Recording) { for(int j=OrdersHistoryTotal()-1; j>=0; j--) { if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)==false) // 履歴を選択 { Print("Access to history failed with error (",GetLastError(),")"); break; } if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { CloseTradeInfo(); break; // 1ポジ分で書込終了の場合はfor文を抜ける } } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| トレーリング | //+------------------------------------------------------------------+ void Trailing() { if (!(Hour() == 0 && Minute() == 0)) { int i; double profit; bool res; double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * (xpoint / 10); if (Modify) // トレールON、OFF { // 所有しているポジションのストップをトレールする 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 && xBars != Bars && ((Minute() >= 0 && Minute() <= 4) || (Minute() >= 30 && Minute() <= 34)) ) { profit = NormalizeDouble(Bid - OrderOpenPrice(), Digits+2); // 買いポジションだった場合の、含み損益を計算する double SD_TPSL_buy = iStdDev(NULL, SD_TF_TP_buy, SD_Period_TP_buy, 0, MODE_SMA, PRICE_CLOSE, 1); double TrailingStart_buy = SD_TPSL_buy * TrailStartMul_buy; double LowSL = iLow(NULL, 0, (iLowest(NULL, 0, MODE_LOW, BarCountSL_buy, 1))); double SL_step_buy = MathMax(LowSL, OrderStopLoss()); TrailingStart_buy = NormalizeDouble(TrailingStart_buy, Digits+2); SL_step_buy = NormalizeDouble(SL_step_buy, Digits+2); if (profit > TrailingStart_buy && OrderStopLoss() < SL_step_buy && NormalizeDouble(Bid - StopLevel, Digits+2) >= SL_step_buy ) { res = OrderModify(OrderTicket(), OrderOpenPrice(), SL_step_buy, OrderTakeProfit(), 0, MediumSeaGreen); } if(res) xBars = Bars; } if (OrderType() == OP_SELL && xBars != Bars //&& ((Minute() >= 0 && Minute() <= 4) || (Minute() >= 30 && Minute() <= 34)) ) { profit = NormalizeDouble(OrderOpenPrice() - Ask, Digits+2); // 売りポジションだった場合の、含み損益を計算する double SD_TPSL_sell = iStdDev(NULL, SD_TF_TP_sell1, SD_Period_TP_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); double TrailingStart_sell = SD_TPSL_sell * TrailStartMul_sell1; double HighSL = iHigh(NULL, 0, (iHighest(NULL, 0, MODE_HIGH, BarCountSL_sell1, 1))); double SL_step_sell = MathMin(HighSL, OrderStopLoss()); TrailingStart_sell = NormalizeDouble(TrailingStart_sell, Digits+2); SL_step_sell = NormalizeDouble(SL_step_sell, Digits+2); if (profit > TrailingStart_sell && OrderStopLoss() > SL_step_sell && NormalizeDouble(Ask + StopLevel, Digits+2) <= SL_step_sell ) { res = OrderModify(OrderTicket(), OrderOpenPrice(), SL_step_sell, OrderTakeProfit(), 0, MediumSeaGreen); } if(res) xBars = Bars; } } // 所有しているポジションのストップをトレールする(ココマデ) } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ポジションのオープン | //+------------------------------------------------------------------+ void PositionOpen() { int i; int ticket = -2; // チケット初期値。-1は失敗時の番号のため、使われない-2で初期化 int CountBuy = 0,CountSell = 0; bool res; double profit = 0; // ポジションの数をカウントする 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; } aCmd = OrderType(); } // ポジションの数をカウントする(ココマデ) // 証拠金不足・トレード許可チェック if (EquityCheck()) { double SD_TPSL_buy = iStdDev(NULL, SD_TF_TP_buy, SD_Period_TP_buy, 0, MODE_SMA, PRICE_CLOSE, 1); double TP_buy = MathMin(SD_TPSL_buy * SD_mul_TP_buy, TakeProfit_pips_buy * xpoint); double SL_buy = MathMin(SD_TPSL_buy * SD_mul_SL_buy, StopLoss_pips_buy * xpoint); double SD_TPSL_sell = iStdDev(NULL, SD_TF_TP_sell1, SD_Period_TP_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); double TP_sell = MathMin(SD_TPSL_sell * SD_mul_TP_sell1, TakeProfit_pips_sell1 * xpoint); double SL_sell = MathMin(SD_TPSL_sell * SD_mul_SL_sell1, StopLoss_pips_sell1 * xpoint); // エントリー条件を確認し、成立していればエントリーを行う if (Entry(true) == 1 // 買いエントリー && CountSell == 0 && CountBuy < Maxposition && xxBars != Bars && Exit2(false, profit) != 2 // 買い決済シグナル無し ) { OSpread = MarketInfo(NULL, MODE_SPREAD);// スプレッド取得 StartOrderTimestamp = GetTickCount();// レイテンシー取得 Order_Price = Ask;// 買い注文を入れる価格 ticket = OrderSend(Symbol(), OP_BUY, CalculateLots(MM_Risk, MaxStopLoss_pips), Ask, Slippage, Ask - SL_buy,//StopLoss_pips * xpoint, Ask + TP_buy,//TakeProfit_pips * xpoint, _Comment, MagicNumber, 0, Blue); // エントリーが失敗であれば、TPSLを分割して注文する if (ticket == -1) { ticket = OrderSend(Symbol(), OP_BUY, CalculateLots(MM_Risk, MaxStopLoss_pips), Ask, Slippage, 0, 0, _Comment, MagicNumber, 0, Blue); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - SL_buy,//StopLoss_pips * xpoint, OrderOpenPrice() + TP_buy,//TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー取得 Open_Type = "Buy"; // ticket未成立時の出力用 if (ticket != -1) { xxBars = Bars; WritingTPSL = false; // TP/SL書込判定用 } } if (Entry(false) == 2 // 売りエントリー && CountBuy == 0 && CountSell < Maxposition && yyBars != Bars && Exit1(true, profit) != 1 // 売り決済シグナル無し ) { OSpread = MarketInfo(NULL, MODE_SPREAD);// スプレッド取得 StartOrderTimestamp = GetTickCount();// レイテンシー取得 Order_Price = Bid;// 売り注文を入れる価格 ticket = OrderSend(Symbol(), OP_SELL, CalculateLots(MM_Risk, MaxStopLoss_pips), Bid, Slippage, Bid + SL_sell,//StopLoss_pips * xpoint, Bid - TP_sell,//TakeProfit_pips * xpoint, _Comment, MagicNumber, 0, Red); // エントリーが失敗であれば、TPSLを分割して注文する if (ticket == -1) { ticket = OrderSend(Symbol(), OP_SELL, CalculateLots(MM_Risk, MaxStopLoss_pips), Bid, Slippage, 0, 0, _Comment, MagicNumber, 0, Red); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + SL_sell,//StopLoss_pips * xpoint, OrderOpenPrice() - TP_sell,//TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー取得 Open_Type = "Sell"; // ticket未成立時の出力用 if (ticket != -1) { yyBars = Bars; WritingTPSL = false; // TP/SL書込判定用 } } } // ファイル書込 if (ticket != -2 && Recording) { if (!OrderSelect(ticket, SELECT_BY_TICKET)) OpenTradeInfo_false(); // チケット未成立時の書込 if (OrderSelect(ticket, SELECT_BY_TICKET)) OpenTradeInfo(); // チケット成立時の書込 } } //+------------------------------------------------------------------+ bool EquityCheck() { // 証拠金不足・トレード許可チェック double usedMoney = AccountEquity() - AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, MaxStopLoss_pips)); if (!( (AccountStopoutMode() == 0 && usedMoney > 0.0 && (AccountEquity() / usedMoney) * 100 <= AccountStopoutLevel()) || (AccountStopoutMode() == 0 && usedMoney > 0.0 && AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, MaxStopLoss_pips)) <= 0) || (AccountStopoutMode() == 1 && AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, MaxStopLoss_pips)) <= AccountStopoutLevel()) ) && IsTradeAllowed()) // トレード許可判定 { return(true); } else return(false); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| TakeProfit, StopLoss | //+------------------------------------------------------------------+ void SetTPSL() { int i; 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) { double SD_TPSL_buy = iStdDev(NULL, SD_TF_TP_buy, SD_Period_TP_buy, 0, MODE_SMA, PRICE_CLOSE, 1); double TP_buy = MathMin(SD_TPSL_buy * SD_mul_TP_buy, TakeProfit_pips_buy * xpoint); double SL_buy = MathMin(SD_TPSL_buy * SD_mul_SL_buy, StopLoss_pips_buy * xpoint); // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - SL_buy, OrderOpenPrice() + TP_buy, 0, MediumSeaGreen); } } // 売りポジションの場合 if (OrderType() == OP_SELL) { double SD_TPSL_sell = iStdDev(NULL, SD_TF_TP_sell1, SD_Period_TP_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); double TP_sell = MathMin(SD_TPSL_sell * SD_mul_TP_sell1, TakeProfit_pips_sell1 * xpoint); double SL_sell = MathMin(SD_TPSL_sell * SD_mul_SL_sell1, StopLoss_pips_sell1 * xpoint); // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + SL_sell, OrderOpenPrice() - TP_sell, 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 credit; // アカウントのクレジット double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額 double lotstep; // サーバのロット数の最小刻み制限 double maxlots; // サーバの最大ロット数制限 double minlots; // サーバの最小ロット数制限 double lotsize = Lots; // ロットサイズ freemargin = AccountFreeMargin(); balance = AccountBalance(); credit = AccountCredit(); tickvalue = MarketInfo(NULL, MODE_TICKVALUE); lotstep = MarketInfo(NULL, MODE_LOTSTEP); maxlots = MarketInfo(NULL, MODE_MAXLOT); minlots = MarketInfo(NULL, MODE_MINLOT); // 複利機能を使わない場合、Lotsから修正されたlotsizeを返す int step = (int)MathAbs(MathLog10(MarketInfo(Symbol(), MODE_LOTSTEP))); lotsize = NormalizeDouble(Lots, (int)step); //ロットステップで四捨五入 lotsize = MathMax(minlots, MathMin(maxlots, lotsize)); //最小ロット以下なら最小ロットに、最大ロット以上なら最大ロットに修正 if (MM_ON == Fixed) return(lotsize); // tickvalueはpipsではなくpointなので、小数点以下の桁数に応じて補正する /*if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") { if (Digits() == 2) tickvalue = tickvalue * 10; else if (Digits() == 3) tickvalue = tickvalue * 100; } else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) {*/ 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 + credit) * 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 credit; // アカウントのクレジット double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額 double lotstep; // サーバのロット数の最小刻み制限 double maxlots; // サーバの最大ロット数制限 double minlots; // サーバの最小ロット数制限 double lotamount; // 1ロットの通貨数 double lotsize = Lots; // ロットサイズ double conv; // 口座通貨種類による補正係数 freemargin = AccountFreeMargin(); balance = AccountBalance(); credit = AccountCredit(); 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); // 複利機能を使わない場合、Lotsから修正されたlotsizeを返す int step = (int)MathAbs(MathLog10(MarketInfo(Symbol(), MODE_LOTSTEP))); lotsize = NormalizeDouble(Lots, step); //ロットステップで四捨五入 lotsize = MathMax(minlots, MathMin(maxlots, lotsize)); //最小ロット以下なら最小ロットに、最大ロット以上なら最大ロットに修正 if (MM_ON == Fixed) return(lotsize); // 1万通貨*1pips = $1 = 100円と仮定し、1ロット1pipの変動が口座通貨でいくらに相当するか計算 // 1 lot = 10万通貨 // 口座通貨 = JPY : tickvalue = 1000円/(lot・pip) // 口座通貨 = USD : tickvalue = $10/(lot・pip) /*if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") { conv = 1000; if (AccountCurrency() == "JPY") conv = 100000; tickvalue = lotamount / 10000 * conv; } else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) {*/ 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 + credit) * 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) ) { 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) ) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 売りポジションの決済総括 | //+------------------------------------------------------------------+ int Exit1(bool isbuy, double profit) { if (Exit_Rule1(isbuy, profit) == 3 && Exit_Rule2(isbuy, profit) == 3 ) { return(0); } else if (Exit_Rule1(isbuy, profit) == 1) { return(1); } else if (Exit_Rule2(isbuy, profit) == 1) { return(1); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 買いポジションの決済総括 | //+------------------------------------------------------------------+ int Exit2(bool isbuy, double profit) { if (Exit_Rule1(isbuy, profit) == 3 && Exit_Rule2(isbuy, profit) == 3 ) { return(0); } else if (Exit_Rule1(isbuy, profit) == 2) { return(2); } else if (Exit_Rule2(isbuy, profit) == 2) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリールール1 | //+------------------------------------------------------------------+ int Entry_Rule1(bool isbuy) { //エントリールール1 // 時間制御によるエントリー可能時間でエントリー判定 if (isbuy && (GMT_Kadou_OK_buy1 || GMT_Kadou_OK_buy2) ) { return(1); } // 買い if (!isbuy && (GMT_Kadou_OK_sell1) ) { return(2); } // 売り return(0); // エントリー出来ない //エントリールール1ココマデ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター1 | //+------------------------------------------------------------------+ int Entry_Filter1(bool isbuy) { //エントリーフィルター1 // 固定仕様系 // スプレッドフィルター double spread = MarketInfo(NULL, MODE_SPREAD); /*if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") // ゴールド桁合わせ { if (Digits() == 2) spread /= 10.0; else if (Digits() == 3) spread /= 100.0; } else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) // ゴールド以外桁合わせ {*/ if (Digits == 3 || Digits == 5) spread /= 10.0; //} if (spread > MaxSpread_pips) return(0); // ギャップフィルター if(isbuy && Close[0] - Close[1] >= Gap_Pips * xpoint) return(0); // (現在価格-1本足終値)が、指定pips以上だったら買い禁止 if(!isbuy && Close[1] - Close[0] >= Gap_Pips * xpoint) return(0); // (1本足終値-現在価格)が、指定pips以上だったら売り禁止 // 年末年始フィルター_12/23~1/3まではエントリーしない int NGMonth = Month(); int NGDay = Day(); if (YearendClose && ((NGMonth == 12 && NGDay >= 21) || (NGMonth == 1 && NGDay <= 3))) { return(0); } //エントリーフィルター1ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター2 | //+------------------------------------------------------------------+ int Entry_Filter2(bool isbuy) { //エントリーフィルター2 if (GMT_Kadou_OK_buy1) { if (!((Trend_Judge_buy1() >= 2 && Kairi_Judge_buy1() <= Kairi_Judge_percent1_buy1) || Kairi_Judge_buy1() <= -Kairi_Judge_percent2_buy1)) { return(0); } } //エントリーフィルター2ココマデ return(3); } //+------------------------------------------------------------------+ int Trend_Judge_buy1() { double MA_S_buy1 = iMA(NULL, PERIOD_D1, MA_S_period_buy1, 0, MODE_SMA, PRICE_CLOSE, 1); double MA_S_buy2 = iMA(NULL, PERIOD_D1, MA_S_period_buy1, 0, MODE_SMA, PRICE_CLOSE, 2); double MA_D1_buy1 = iMA(NULL, PERIOD_D1, MA_L_period_buy1, 0, MODE_SMA, PRICE_CLOSE, 1); double MA_D1_buy2 = iMA(NULL, PERIOD_D1, MA_L_period_buy1, 0, MODE_SMA, PRICE_CLOSE, 2); //bool UP_Trend = false; int UP_Trend = 0; //if (MA_D1_buy1 < MA_S_buy1) UP_Trend += 1; if (MA_S_buy2 < MA_S_buy1) UP_Trend += 1; if (MA_D1_buy2 < MA_D1_buy1) UP_Trend += 1; return(UP_Trend); } double Kairi_Judge_buy1() // 長期と終値の乖離 { // 長期移動平均線に対し短期移動平均線が、指定%以上、上に乖離したら「売り」、下に乖離したら「買い」。 double Close1 = iClose(NULL, PERIOD_D1, 1); double MA_D1 = iMA(NULL, PERIOD_D1, MA_L_period_buy1, 0, MODE_SMA, PRICE_CLOSE, 1); double Kairi_buy = 1; if (Close1 != 0) { Kairi_buy = (Close1 - MA_D1) / Close1 * 100; } return(Kairi_buy); } //+------------------------------------------------------------------+ //| エントリーフィルター3 | //+------------------------------------------------------------------+ int Entry_Filter3(bool isbuy) { //エントリーフィルター3 if (GMT_Kadou_OK_buy2) { if (!((Trend_Judge_buy2() >= 1 && Kairi_Judge_buy2() <= Kairi_Judge_percent1_buy2) || Kairi_Judge_buy2() <= -Kairi_Judge_percent2_buy2)) { return(0); } } //エントリーフィルター3ココマデ return(3); } //+------------------------------------------------------------------+ int Trend_Judge_buy2() { //double MA_S_buy1 = iMA(NULL, PERIOD_D1, MA_S_period_buy2, 0, MODE_SMA, PRICE_CLOSE, 1); //double MA_S_buy2 = iMA(NULL, PERIOD_D1, MA_S_period_buy2, 0, MODE_SMA, PRICE_CLOSE, 2); double MA_D1_buy1 = iMA(NULL, PERIOD_D1, MA_L_period_buy2, 0, MODE_SMA, PRICE_CLOSE, 1); double MA_D1_buy2 = iMA(NULL, PERIOD_D1, MA_L_period_buy2, 0, MODE_SMA, PRICE_CLOSE, 2); //bool UP_Trend = false; int UP_Trend = 0; //if (MA_D1_buy1 < MA_S_buy1) UP_Trend += 1; //if (MA_S_buy2 < MA_S_buy1) UP_Trend += 1; if (MA_D1_buy2 < MA_D1_buy1) UP_Trend += 1; return(UP_Trend); } double Kairi_Judge_buy2() // 長期と終値の乖離 { // 長期移動平均線に対し短期移動平均線が、指定%以上、上に乖離したら「売り」、下に乖離したら「買い」。 double Close1 = iClose(NULL, PERIOD_D1, 1); double MA_D1 = iMA(NULL, PERIOD_D1, MA_L_period_buy2, 0, MODE_SMA, PRICE_CLOSE, 1); double Kairi_buy = 1; if (Close1 != 0) { Kairi_buy = (Close1 - MA_D1) / Close1 * 100; } return(Kairi_buy); } //+------------------------------------------------------------------+ //| エントリーフィルター4 | //+------------------------------------------------------------------+ int Entry_Filter4(bool isbuy) { //エントリーフィルター4 if(GMT_Kadou_OK_sell1) { if (!((Trend_Judge_sell() >= 1 && Kairi_Judge_sell() <= Kairi_Judge_percent_sell1) || Kairi_Judge_sell() <= -Kairi_Judge_percent_sell2)) { return(0); } } //エントリーフィルター4ココマデ return(3); } //+------------------------------------------------------------------+ int Trend_Judge_sell() { //double MA_S_sell1 = iMA(NULL, PERIOD_D1, MA_S_period_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); //double MA_S_sell2 = iMA(NULL, PERIOD_D1, MA_S_period_sell1, 0, MODE_SMA, PRICE_CLOSE, 2); double MA_L_sell1 = iMA(NULL, PERIOD_D1, MA_L_period_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); double MA_L_sell2 = iMA(NULL, PERIOD_D1, MA_L_period_sell1, 0, MODE_SMA, PRICE_CLOSE, 2); //bool DOWN_Trend = false; int DOWN_Trend = 0; //if (MA_L_sell1 > MA_S_sell1) DOWN_Trend += 1; //if (MA_S_sell2 > MA_S_sell1) DOWN_Trend += 1; if (MA_L_sell2 > MA_L_sell1) DOWN_Trend += 1; return(DOWN_Trend); } double Kairi_Judge_sell() // 長期と終値の乖離 { // 長期移動平均線に対し短期移動平均線が、指定%以上、上に乖離したら「売り」、下に乖離したら「買い」。 double Close1 = iClose(NULL, PERIOD_D1, 1); double MA_D1 = iMA(NULL, PERIOD_D1, MA_L_period_sell1, 0, MODE_SMA, PRICE_CLOSE, 1); double Kairi_sell = 1; if (Close1 != 0) { Kairi_sell = (MA_D1 - Close1) / Close1 * 100; } return(Kairi_sell); } //+------------------------------------------------------------------+ //| 決済ルール1 | //+------------------------------------------------------------------+ int Exit_Rule1(bool isbuy, double profit) { // 決済ルール1 if (isbuy && ExitTimeClose_sell1) { return(1); } // 売りを決済 if (!isbuy && (ExitTimeClose_buy1 || ExitTimeClose_buy2)) { return(2); } // 買いを決済 // 決済ルール1ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール2 | //+------------------------------------------------------------------+ int Exit_Rule2(bool isbuy, double profit) { // 決済ルール2 // 決済ルール2ココマデ return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| チャート自動セット | //+------------------------------------------------------------------+ // チャートセット初期化 void ChartSet() { // 気配値強制表示&自動切替 int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); // チャート幅の計算 int textWidth = (int)NormalizeDouble(200 * DPIAdjust, 0); // 固定値pxまたはテキストの幅の計算 double ShiftPer = textWidth * 100 / chartWidth; if (!IsTesting()) { if (StringSubstr(Symbol(), 0, 6) != SYMBOL1 || Period() != Chart_TimeFrame) { SymbolSelect(SYMBOL1 + StringSubstr(Symbol(), 6, StringLen(Symbol())), true); ChartSetSymbolPeriod(0, SYMBOL1 + StringSubstr(Symbol(), 6, StringLen(Symbol())), Chart_TimeFrame); } // 現在のシンボルが4文字の場合。無しならコメントアウト /*else if ((StringSubstr(Symbol(), 0, 6) != SYMBOL1 && StringSubstr(Symbol(), 0, 4) != SYMBOL2) || Period() != Chart_TimeFrame) { SymbolSelect(SYMBOL2 + StringSubstr(Symbol(), StringSubstr(Symbol(), 0, 4) == SYMBOL2? 4 : 6, StringLen(Symbol())), true); ChartSetSymbolPeriod(0, SYMBOL2 + StringSubstr(Symbol(), StringSubstr(Symbol(), 0, 4) == SYMBOL2? 4 : 6, StringLen(Symbol())), Chart_TimeFrame); }*/ ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack); ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrWhite); ChartSetInteger(0, CHART_COLOR_GRID, clrLightSlateGray); ChartSetInteger(0, CHART_COLOR_CHART_UP, clrOlive); ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrOlive); ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrBlack); ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBeige); ChartSetInteger(0, CHART_COLOR_CHART_LINE, clrOlive); ChartSetInteger(0, CHART_COLOR_VOLUME, clrOlive); ChartSetInteger(0, CHART_COLOR_ASK, clrRed); ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, clrRed); ChartSetInteger(0, CHART_SHIFT, true); ChartSetDouble(0, CHART_SHIFT_SIZE, ShiftPer); ChartSetInteger(0, CHART_AUTOSCROLL, true); //ChartSetInteger(0, CHART_SHOW_DATE_SCALE, true); // これを入れるとなぜか表示範囲が狭くなる //ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true); // これを入れるとなぜか表示範囲が狭くなる ChartSetInteger(0, CHART_FOREGROUND, false); ChartSetInteger(0, CHART_SHOW_GRID, false); ChartSetInteger(0, CHART_SHOW_ONE_CLICK, false); ChartSetInteger(0, CHART_SHOW_OHLC, false); ChartSetInteger(0, CHART_SHOW_PERIOD_SEP, true); ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); ChartSetInteger(0, CHART_SCALE, 3); ChartSetInteger(0, CHART_MODE, CHART_CANDLES); } } // 状態によるチャート配色変更 void ChartSet2() { color ChartWar1 = ChartWarning? clrDarkGray : clrWhite; color ChartWar2 = ChartWarning? clrDimGray : clrOlive; color ChartWar3 = ChartWarning? clrSilver : clrBeige; if (!IsTesting()) { ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack); ChartSetInteger(0, CHART_COLOR_FOREGROUND, ChartWar1); ChartSetInteger(0, CHART_COLOR_GRID, clrLightSlateGray); ChartSetInteger(0, CHART_COLOR_CHART_UP, ChartWar2); ChartSetInteger(0, CHART_COLOR_CHART_DOWN, ChartWar2); ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrBlack); ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, ChartWar3); ChartSetInteger(0, CHART_COLOR_CHART_LINE, ChartWar2); ChartSetInteger(0, CHART_COLOR_VOLUME, ChartWar2); ChartSetInteger(0, CHART_COLOR_ASK, clrRed); ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, clrRed); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| チャートの中央にシンボルを描画する | //+------------------------------------------------------------------+ void CenterSymbol() { string TEXT1 = StringSubstr(Symbol(), 0, 6); string TEXT2 = (Period() == PERIOD_M1? "M1": Period() == PERIOD_M5? "M5": Period() == PERIOD_M15? "M15": Period() == PERIOD_M30? "M30": Period() == PERIOD_H1? "H1": Period() == PERIOD_H4? "H4": Period() == PERIOD_D1? "D1": Period() == PERIOD_W1? "W1": "MN1") + "/" + DoubleToStr(MarketInfo(Symbol(),MODE_SPREAD) / 10, 1); int FontSize = 36; int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); int chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); int textWidth = StringLen(TEXT1) * FontSize / 2; // テキストの幅の計算 int textHeight = FontSize; // テキストの高さ // テキストの中心からの座標を計算 int x = (chartWidth - textWidth) / 2 + textWidth / 2; int y = (chartHeight - textHeight) / 2 + textHeight / 2; DrawTextInCenter("Symbol1", TEXT1, x, y - FontSize, FontSize, C'60, 60, 60'); DrawTextInCenter("Symbol2", TEXT2, x, y + FontSize, FontSize, C'60, 60, 60'); } void DrawTextInCenter(string Symbolname, string label_text, int pos_x, int pos_y, int s, color clr= clrBlack) { ObjectCreate(Symbolname, OBJ_LABEL, 0, 0, 0); ObjectSetString(0, Symbolname, OBJPROP_TEXT, label_text); ObjectSetInteger(0, Symbolname, OBJPROP_FONTSIZE, s); ObjectSetString(0, Symbolname, OBJPROP_FONT, "Segoe UI"); ObjectSetInteger(0, Symbolname, OBJPROP_XDISTANCE, pos_x); ObjectSetInteger(0, Symbolname, OBJPROP_YDISTANCE, pos_y); ObjectSetInteger(0, Symbolname, OBJPROP_COLOR, clr); ObjectSetInteger(0, Symbolname, OBJPROP_BACK, true); ObjectSetInteger(0, Symbolname, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, Symbolname, OBJPROP_ANCHOR, ANCHOR_CENTER); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| チャートコメント表示 | //+------------------------------------------------------------------+ void ChartComment() { if (!IsTradeAllowed() || !IsConnected()) { ChartWarning = true; ChartSet2(); } else { ChartWarning = false; ChartSet2(); } color clrChartWar = ChartWarning? clrNONE : clrWhite; color clrChartWarCom = (_Comment == "" || StringLen(_Comment) > 31) ? clrOrangeRed : clrChartWar; color clrLogicL1 = ChartWarning? clrNONE : Logic_Buy1? clrWhite : clrGray; color clrLogicL2 = ChartWarning? clrNONE : Logic_Buy2? clrWhite : clrGray; color clrLogicL3 = ChartWarning? clrNONE : Logic_Sell1? clrWhite : clrGray; string LotsComment; if (MM_ON == Fixed) LotsComment = DoubleToStr(Lots,2); else LotsComment = DoubleToStr(CalculateLots(MM_Risk, MaxStopLoss_pips),2) + " (" + DoubleToStr(MM_Risk,1) +"%)"; string Comment0 = (string)MagicNumber + " [Magic]"; string Comment1 = LotsComment + " [Lots]"; string Comment2 = (MM_ON == 0 ? "Fixed" : MM_ON == 1 ? "FreeMargin" : "Balance") + " [MM]"; string Comment3 = DoubleToStr(MaxSpread_pips,1) + "/" + DoubleToStr(SpreadAve,1) + " [Spread Lim/Ave]"; string Comment4 = (string)Recording + " [Recording]"; string Comment5 = "[OrderComment]"; string Comment6 = _Comment; string Comment7 = (Summertime == 0 ? "none" : Summertime == 1 ? "American" : "European") + " [Summertime]"; string Comment8 = DoubleToStr(MarketInfo(Symbol(),MODE_SWAPLONG), 2) + "/" + DoubleToStr(MarketInfo(Symbol(),MODE_SWAPSHORT), 2) + " [Swap B/S]"; string Comment9 = "------------------------------"; string Comment10 = DoubleToStr(TakeProfit_pips_buy1, 0) + "/" + DoubleToStr(StopLoss_pips_buy1, 0) + " [Buy1 TP/SL]"; string Comment11 = DoubleToStr(TakeProfit_pips_buy2, 0) + "/" + DoubleToStr(StopLoss_pips_buy2, 0) + " [Buy2 TP/SL]"; string Comment12 = DoubleToStr(TakeProfit_pips_sell1, 0) + "/" + DoubleToStr(StopLoss_pips_sell1, 0) + " [Sell1 TP/SL]"; int xpix1 = 14, xpix2 = 20; CommentLabel("Comment0", Comment0, 4, 4+xpix2*1, 10, clrYellow); CommentLabel("Comment1", Comment1, 4, 8+xpix2*2, 10, clrYellow); CommentLabel("Comment2", Comment2, 4, xpix1+xpix2*3, 8, clrChartWar); CommentLabel("Comment3", Comment3, 4, xpix1+xpix2*4, 8, clrChartWar); CommentLabel("Comment4", Comment4, 4, xpix1+xpix2*5, 8, clrChartWar); CommentLabel("Comment5", Comment5, 4, xpix1+xpix2*6, 8, clrChartWarCom); CommentLabel("Comment6", Comment6, 4, xpix1+xpix2*7, 8, clrChartWarCom); CommentLabel("Comment7", Comment7, 4, xpix1+xpix2*8, 8, clrChartWar); CommentLabel("Comment8", Comment8, 4, xpix1+xpix2*9, 8, clrChartWar); CommentLabel("Comment9", Comment9, 4, xpix1+xpix2*10, 8, clrChartWar); CommentLabel("Comment10", Comment10, 4, xpix1+xpix2*11, 8, clrLogicL1); CommentLabel("Comment11", Comment11, 4, xpix1+xpix2*12, 8, clrLogicL2); CommentLabel("Comment12", Comment12, 4, xpix1+xpix2*13, 8, clrLogicL3); //+------------------------------------------------------------------+ // 履歴表示用 color clrVisualHistory = !VisualHistory? clrNONE : ChartWarning? clrNONE : clrWhite; color clrVisualHistoryPP = !VisualHistory? clrNONE : ChartWarning? clrNONE : totalpips < 0? clrOrangeRed : clrWhite; color clrVisualHistoryPF = !VisualHistory? clrNONE : ChartWarning? clrNONE : 0 < ProfitFactor && ProfitFactor < 1? clrOrangeRed : clrWhite; string Comment20 = "------------------------------"; string Comment21 = DoubleToStr(TradeCounts, 0) + " [TradeCounts]"; string Comment22 = DoubleToStr(totalpips, 1) + " [Profit (pips)]"; string Comment23 = (plus_profit == 0 || minus_profit == 0? "--- [Profit factor]" : DoubleToStr(ProfitFactor, 2) + " [Profit factor]"); string Comment24 = (plus_profit == 0 || minus_profit == 0? "---/--- [RRR/Win%]" : DoubleToStr(RRR, 2) + "/" + DoubleToStr(WinPer, 1) + " [RRR/Win%]"); CommentLabel("Comment20", Comment20, 4, xpix1+xpix2*14, 8, clrVisualHistory); CommentLabel("Comment21", Comment21, 4, xpix1+xpix2*15, 8, clrVisualHistory); CommentLabel("Comment22", Comment22, 4, xpix1+xpix2*16, 8, clrVisualHistoryPP); CommentLabel("Comment23", Comment23, 4, xpix1+xpix2*17, 8, clrVisualHistoryPF); CommentLabel("Comment24", Comment24, 4, xpix1+xpix2*18, 8, clrVisualHistory); } //+------------------------------------------------------------------+ void CommentLabel(string ComName, string ComText, int ComPos_x, int ComPos_y, int ComSize, color ComClr= clrBlack) { ComPos_x = (int)NormalizeDouble(ComPos_x * DPIAdjust, 0); // 別途DPI換算コードで調整 ComPos_y = (int)NormalizeDouble(ComPos_y * DPIAdjust, 0); // 別途DPI換算コードで調整 ObjectCreate(ComName, OBJ_LABEL, 0, 0, 0); ObjectSetString (0, ComName, OBJPROP_TEXT, ComText); ObjectSetInteger(0, ComName, OBJPROP_XDISTANCE, ComPos_x); ObjectSetInteger(0, ComName, OBJPROP_YDISTANCE, ComPos_y); ObjectSetInteger(0, ComName, OBJPROP_FONTSIZE, ComSize); ObjectSetInteger(0, ComName, OBJPROP_COLOR, ComClr); ObjectSetString (0, ComName, OBJPROP_FONT, "Segoe UI"); ObjectSetInteger(0, ComName, OBJPROP_BACK, true); ObjectSetInteger(0, ComName, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, ComName, OBJPROP_CORNER, CORNER_RIGHT_UPPER); ObjectSetInteger(0, ComName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| スプレッド計測 | //+------------------------------------------------------------------+ // 各スプレッド値計算 void MeasureSP() { double SpreadMin = 1000, SpreadMax = 0, SpreadSum = 0, SpreadMin1 = 1000, SpreadMax1 = 0, SpreadSum1 = 0; int TickCount = 0, TickCount1 = 0, lastBars = 0; TickCount++; SpreadSum += MeasureSpread; SpreadMin = SpreadMin == 0 ? SpreadMin = MeasureSpread : SpreadMin; if (TickCount > 0 && SpreadSum > 0) SpreadAve = SpreadSum / TickCount; if (SpreadMax < MeasureSpread) SpreadMax = MeasureSpread; if (SpreadMin > MeasureSpread) SpreadMin = MeasureSpread; // MT4時間1:00のスプレッド yTime = TimeMinute(TimeCurrent()); if (xxTime == 1 && yTime == 0) { TickCount1++; SpreadSum1 += MeasureSpread; SpreadMin1 = SpreadMin1 == 0 ? SpreadMin1 = MeasureSpread : SpreadMin1; if (TickCount1 > 0 && SpreadSum1 > 0) SpreadAve1 = SpreadSum1 / TickCount1; if (SpreadMax1 < MeasureSpread) SpreadMax1 = MeasureSpread; if (SpreadMin1 > MeasureSpread) SpreadMin1 = MeasureSpread; } // 月足のバー更新時に累積値リセット if (lastBars != iBars(NULL, PERIOD_MN1)) { lastBars = iBars(NULL, PERIOD_MN1); SpreadSum = 0; TickCount = 0; SpreadSum1 = 0; TickCount1 = 0; } // オートスプレッド設定機能 Adjustspread = SpreadAve + Adjustspread_Margin; // 平均にマージン加算 MaxSpread_pips = MathMin(Adjustspread, AllowMaxSpread); // 内部設定の最大値とマージン加算を比較し小さい方を採用 if (SpreadAve1 != 0) // 1:00エントリーEA用 { Adjustspread = SpreadMin1 + Adjustspread_Margin1; // 平均にマージン加算 MaxSpread_pips = MathMax(MathMin(Adjustspread, AllowMaxSpread), MaxSpread_pips); // 最大値とマージン加算、全体平均を比較 } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| チャートにトレード履歴表示 | //+------------------------------------------------------------------+ void TradeLinePips() { int sf = 0, tof = 0; datetime hf = 0; if (sf != Seconds() && OrdersTotal() > 0) { PosHis(); sf = Seconds(); } if ((hf != iTime((string)0, PERIOD_H1, 0) && Seconds() > 30) || tof != OrdersHistoryTotal()) { history(); hf = iTime((string)0, PERIOD_H1, 0); tof = OrdersHistoryTotal(); } } //+------------------------------------------------------------------+ void PosHis() { int res; double pips = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { res = OrderSelect(i, SELECT_BY_POS); if (res == false) continue; if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber) continue; pips += trend((string)OrderTicket(), OrderOpenTime(), OrderOpenPrice(), Time[0], OrderType() == 0 ? Bid : Ask, OrderType()); } } //+------------------------------------------------------------------+ void history() { int res; totalpips = 0; plus_profit = 0; minus_profit = 0;//, ProfitFactor = 0; minus_count = 0; plus_count = 0; TradeCounts = 0; // トレード履歴を検索 for (int i = OrdersHistoryTotal() - 1; i >= 0; i--) { res = OrderSelect(i, SELECT_BY_POS, MODE_HISTORY); if (res == false) continue; if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber) continue; // プロフィットファクター・RRR・勝率計算 if (OrderProfit() < 0) { minus_profit -= OrderProfit(); minus_count += 1; } else if (OrderProfit() >= 0) { plus_profit += OrderProfit(); plus_count += 1; } if (minus_profit != 0 && plus_count != 0 && minus_count != 0) { ProfitFactor = plus_profit / minus_profit; RRR = (plus_profit / plus_count) / (minus_profit / minus_count); WinPer = (plus_count * 100) / (plus_count + minus_count); } TradeCounts = minus_count + plus_count; // 合計pips計算 totalpips += trend((string)TradeCounts, OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice(), OrderType()); } } //+------------------------------------------------------------------+ double trend(string obj_name, datetime Time1, double Close1, datetime Time2, double Close2, int type) { double tes = 0.0; // 外付け手数料(PIPS換算) double pips = (double)DoubleToStr((type == 0 ? Close2 - Close1 : Close1 - Close2) / xpoint - tes, 1); int Shift2 = iBarShift(NULL, 0, Time2); datetime Timex = iTime(NULL, 0, Shift2 + 1); // トレード線 ObjectDelete("TradeLine" + obj_name); ObjectCreate(0, "TradeLine" + obj_name, OBJ_TREND, 0, Time1, Close1, Time2, Close2); ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_COLOR, type == 0 ? clrDodgerBlue : clrOrangeRed); ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_STYLE, 0); ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_WIDTH, 2); ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定 ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_RAY_RIGHT, false); // 右に線を延長 // pips表示 ObjectDelete("TradePips" + obj_name); ObjectCreate(0, "TradePips" + obj_name, OBJ_TEXT, 0, Timex, Close2); ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_COLOR, pips < 0 ? clrOrangeRed : !IsTesting()? clrLime : clrYellow);//type == 0 ? BuyColor : SellColor); ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定 ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_FONTSIZE, 12); // フォントサイズ ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_ANCHOR, ANCHOR_RIGHT); // 描画位置 ObjectSetString(0, "TradePips" + obj_name, OBJPROP_TEXT, DoubleToStr(pips, 1)); // 表示するテキスト ObjectSetString(0, "TradePips" + obj_name, OBJPROP_FONT, "Segoe UI Semibold"); // フォント return(pips); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 実行スプレッド・スリッページ・実行スプレッド計測・ファイル作成 | //+------------------------------------------------------------------+ // ファイル初期化 int FileInit() { filename = AccountCompany() + "_" + (string)AccountNumber() + "_TradeLog.csv";// ファイル名を決める fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv) if(fp==INVALID_HANDLE) { err = GetLastError(); printf("Error occured: [%d] %s", err, ErrorDescription(err)); return(0.0); } FileWrite(fp, "注文番号", "注文時間", "時刻", "分", "取引種別", "注文価格", "約定価格", "スプレッド(pips)", "スリッページ(pips)", "レイテンシー(ms)", "損益(pips)", "数量", "通貨ペア", "時間足", "EA名", "マジックナンバー", "開発1", "開発2"); // ファイルを閉じる FileClose(fp); return(0); } // トレード情報 void OpenTradeInfo_false() { Order_Price = (Open_Type == "Buy"? Ask : Bid); //NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化 double Open_Yakujyou_Price = GetLastError(); //NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化 double Open_Spread = OSpread / 10; // スプレッド、桁合わせ double Open_Slippage = (double)Volume[0]; //NormalizeDouble(MathAbs(Order_Price - Open_Yakujyou_Price), Digits) / xpoint; // スリッページ、桁合わせ uint Open_Runtime = StartOrderTimestamp - StartingTimestamp; // ランタイム時間 FileWriteingOpen_false(Open_Yakujyou_Price, Open_Spread, Open_Slippage, Open_Runtime); // 書き込み処理 } void OpenTradeInfo() { Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化 double Open_Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化 double Open_Spread = OSpread / 10; // スプレッド、桁合わせ double Open_Slippage = (OrderType() == OP_SELL? Open_Yakujyou_Price - Order_Price : Order_Price - Open_Yakujyou_Price) / xpoint; Open_Slippage = NormalizeDouble(Open_Slippage, Digits); // スリッページ、桁合わせ Open_Type = OrderType() == OP_BUY? "Buy" : "Sell"; uint Open_Runtime = StartOrderTimestamp - StartingTimestamp; // ランタイム時間 FileWriteingOpen(Open_Yakujyou_Price, Open_Spread, Open_Slippage, Open_Runtime); // 書き込み処理 } void CloseTradeInfo() { Close_Price = NormalizeDouble(Close_Price, Digits); // 売り注文価格を正規化 double Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格 double Close_Spread = CSpread / 10; // スプレッド、桁合わせ double Close_Slippage = (OrderType() == OP_BUY? Close_Yakujou_Price - Close_Price : Close_Price - Close_Yakujou_Price) / xpoint; Close_Slippage = NormalizeDouble(Close_Slippage, Digits); // スリッページ、桁合わせ double profitpips = NormalizeDouble(OrderType() == OP_BUY? (OrderClosePrice() - OrderOpenPrice()) / xpoint : (OrderOpenPrice() - OrderClosePrice()) / xpoint, 1); Close_Type = "Close"; uint Close_Runtime = OrderCloseTimestamp - StartingTimestamp; // ランタイム時間 FileWriteingClose(Close_Yakujou_Price, Close_Spread, Close_Slippage, profitpips, Close_Runtime); // 書き込み処理 } // ファイル書き込み void FileWriteingOpen_false(double OYP, double OSp, double OSl, uint OR) { for(int i = 0; i < 3000; i++) { FileClose(fp); // ファイルが開きっぱなしで開けないエラーを防ぐ fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1 if (fp != INVALID_HANDLE) { FileSeek(fp, 0, SEEK_END); FileWrite(fp, "false", TimeCurrent(), TimeHour(TimeCurrent()), TimeMinute(TimeCurrent()), Open_Type, Order_Price, "Err=" + (string)OYP, OSp, "tick=" + (string)OSl, OpenLatency, "---", CalculateLots(MM_Risk, StopLoss_pips), Symbol(), Timeframe, WindowExpertName(), OrderMagicNumber(), i, OR); FileClose(fp); break; } } if (fp == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました"); } void FileWriteingOpen(double OYP, double OSp, double OSl, uint OR) { for(int i = 0; i < 3000; i++) { FileClose(fp); // ファイルが開きっぱなしで開けないエラーを防ぐ fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1 if (fp != INVALID_HANDLE) { FileSeek(fp, 0, SEEK_END); FileWrite(fp, OrderTicket(), OrderOpenTime(), TimeHour(OrderOpenTime()), TimeMinute(OrderOpenTime()), Open_Type, Order_Price, OYP, OSp, OSl, OpenLatency, "---", CalculateLots(MM_Risk, StopLoss_pips), Symbol(), Timeframe, WindowExpertName(), OrderMagicNumber(), i, OR); FileClose(fp); break; } } if (fp == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました"); } void FileWriteingClose(double CYP, double CSp, double CSl, double pro, uint CR) { for(int i = 0; i < 3000; i++) { FileClose(fp); // ファイルが開きっぱなしで開けないエラーを防ぐ fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1 if (fp != INVALID_HANDLE) { FileSeek(fp, 0, SEEK_END); FileWrite(fp, OrderTicket(), OrderCloseTime(), TimeHour(OrderCloseTime()), TimeMinute(OrderCloseTime()), Close_Type, Close_Price, CYP, CSp, CSl, CloseLatency, pro, CalculateLots(MM_Risk, StopLoss_pips), Symbol(), Timeframe, WindowExpertName(), OrderMagicNumber(), i, CR); FileClose(fp); break; } } if (fp == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました"); } // TP/SL時の検出 void ClosedTradeTPSL() { for(int i=OrdersHistoryTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_HISTORY ) == false) { //Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; // 決済時間に更新がなければループ処理終了 if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderCloseTime() == OrderCloseTime_bak) break; if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderCloseTime() > OrderCloseTime_bak && !WritingTPSL) // 決済時間が最新であれば { OrderCloseTime_bak = OrderCloseTime(); int length = StringLen(OrderComment());//StringLenは文字数を返す if (length >= 4) { // TP/SL決済の確認 string tpsl = StringSubstr(OrderComment(), length-4, 4); if (tpsl == "[tp]" || tpsl == "[sl]") { Close_Price = NormalizeDouble((tpsl == "[tp]"? OrderTakeProfit() : OrderStopLoss()), Digits); // 売り注文価格を正規化 double Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格 double Close_Spread = MarketInfo(NULL,MODE_SPREAD) / 10; // スプレッド、桁合わせ double Close_Slippage = (OrderType() == OP_BUY? Close_Yakujou_Price - Close_Price : Close_Price - Close_Yakujou_Price) / xpoint; Close_Slippage = NormalizeDouble(Close_Slippage, Digits); // スリッページ、桁合わせ CloseLatency = 0; double profitpips = NormalizeDouble((OrderType() == OP_BUY? OrderClosePrice() - OrderOpenPrice() : OrderOpenPrice() - OrderClosePrice()) / xpoint, 1); Close_Type = tpsl == "[tp]"? "TP" : "SL"; uint Close_Runtime = 0; // ランタイム時間 FileWriteingClose(Close_Yakujou_Price, Close_Spread, Close_Slippage, profitpips, Close_Runtime); // 書き込み処理 WritingTPSL = true; break; } } } } } //+------------------------------------------------------------------+