MQL5で作成したパーツを書き溜める
//+------------------------------------------------------------------+ //| PriceData クラス | //+------------------------------------------------------------------+ class PriceData { public: MqlRates rates[]; // レートデータ配列 int ratesTotal; // レートデータ配列の総数 // コンストラクタ: シンボル名、時間枠、開始日時、終了日時を指定してレートデータを初期化 // symbol: 取引シンボル(例:"EURUSD") // timeframe: チャートの時間枠(例:PERIOD_D1は日足) // startDate: データコピーの開始日時 // endDate: データコピーの終了日時 PriceData(string symbol, ENUM_TIMEFRAMES timeframe, datetime startDate, datetime endDate) { this.ratesTotal = CopyRates(symbol, timeframe, startDate, endDate, this.rates); } // コンストラクタ: 既存のレートデータ配列とその総数を指定して初期化 // inputRates: MqlRates型のレートデータ配列 // total: レートデータ配列の総数 PriceData(const MqlRates &inputRates[], int total) { ArrayResize(rates, total); for(int i = 0; i < total; i++) { rates[i] = inputRates[i]; } ratesTotal = total; } // 指定された日付のインデックスを返すメソッド // targetDate: 検索対象の日付 // 戻り値: 指定された日付のインデックス(見つからない場合は-1) int GetIndexByDate(const datetime &targetDate) { for(int i = 0; i < ratesTotal; i++) { if(rates[i].time == targetDate) { return ratesTotal - 1 - i; } } return -1; } // 指定されたインデックスでの特定の価格タイプの価格を返すメソッド // index: レートデータ配列内のインデックス // priceType: 取得したい価格のタイプ(開始、終了、高値、安値) // 戻り値: 指定されたインデックスと価格タイプに対応する価格 double GetPriceByType(int index, ENUM_APPLIED_PRICE priceType) { if(index < 0 || index >= ratesTotal) { Print("インデックスが範囲外です。"); return -1; // 無効値を返す } switch(priceType) { case PRICE_CLOSE: return rates[index].close; case PRICE_OPEN: return rates[index].open; case PRICE_HIGH: return rates[index].high; case PRICE_LOW: return rates[index].low; default: Print("無効な価格タイプが指定されました。"); return -1; // 無効値を返す } } // 指定された日付で特定の価格タイプの価格を返すメソッド // targetDate: 検索対象の日付 // priceType: 取得したい価格のタイプ // 戻り値: 指定された日付と価格タイプに対応する価格(データが見つからない場合は-1) double GetPriceByDate(const datetime &targetDate, ENUM_APPLIED_PRICE priceType) { if(targetDate <= TimeCurrent()) { int targetIndex = GetIndexByDate(targetDate); // 自身のメソッドを呼び出す if(targetIndex != -1) { double actualPrice = GetPriceByType(targetIndex, priceType); // 自身のメソッドを呼び出す Print("実際の価格: ", actualPrice); return actualPrice; } else { Print("指定された日付でのデータが見つかりません。"); return -1; } } else { Print("targetDateが未来の日付です。"); return -1; } } // トレンドラインを延長して特定日の価格を計算するメソッド // date1, date2: トレンドラインを形成する2つの日付 // targetDate: 価格を計算したい日付 // priceType: 使用する価格のタイプ(開始、終了、高値、安値) // 戻り値: トレンドラインに基づいて計算された特定日の価格 double CalculateExtendedTrendLinePrice(datetime date1, datetime date2, datetime targetDate, ENUM_APPLIED_PRICE priceType) { int index1 = GetIndexByDate(date1); int index2 = GetIndexByDate(date2); if (index1 == -1 || index2 == -1) return 0; double y1 = GetPriceByType(index1, priceType); double y2 = GetPriceByType(index2, priceType); // トレンドラインの傾き(m)と切片(b)の計算 double x1 = index1; double x2 = index2; double m = (y2 - y1) / (x2 - x1); double b = y1 - m * x1; // targetDateのインデックスを計算 int targetIndex = GetIndexByDate(targetDate); if (targetIndex == -1) return 0; // targetDateにおけるトレンドライン上の予想価格を計算 double extendedPrice = m * (targetIndex - x1) + y1; // 直線方程式を使用 return extendedPrice; } };