#property copyright "Copyright 2024, Your Name" #property link "https://www.yourwebsite.com" #property version "1.00" #property script_show_inputs input int StartBars = 1000; // 開始バー(現在から何本前か) input int EndBars = 0; // 終了バー(0は現在のバー) input double minDistance = 0; // 最小間隔,デフォ0.0002 double MinDistance = 0; input int MinCount = 3; // 最小本数 input int MaxLines = 50; // 最大ライン数 input int MinWidth = 2; // 最小線幅 input int MaxWidth = 5; // 最大線幅 struct ResistanceLevel { double price; int count; int importance; }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { // 古い線を削除 ObjectsDeleteAll(0, "ResistanceLine_"); //シンボルごとに最小数値を変える if (minDistance==0.0){ MinDistance=0.0002; if(_Symbol=="USDJPY") { if (Period()==5)MinDistance=0.0002; if (Period()==15)MinDistance=0.001; if (Period()==30)MinDistance=0.002; if (Period()==16385)MinDistance=0.003;//H1 if (Period()==16388)MinDistance=0.003;//H4 if (Period()==16408)MinDistance=0.006;//D1 if (Period()==32769)MinDistance=0.006;//W1 if (Period()==49153)MinDistance=0.04;//M1 } if(_Symbol=="EURJPY")MinDistance=0.0002; if(_Symbol=="GBPJPY")MinDistance=0.0002; if(_Symbol=="AUDJPY")MinDistance=0.0002; if(_Symbol=="NZDJPY")MinDistance=0.0002; if(_Symbol=="CHFJPY")MinDistance=0.0002; if(_Symbol=="CADJPY")MinDistance=0.0002; if(_Symbol=="CHFJPY")MinDistance=0.0002; if(_Symbol=="EURUSD")MinDistance=0.0002; if(_Symbol=="GBPUSD")MinDistance=0.0002; if(_Symbol=="AUDUSD")MinDistance=0.0002; if(_Symbol=="GBPUSD")MinDistance=0.0002; if(_Symbol=="USDCAD")MinDistance=0.0002; if(_Symbol=="USDCHF")MinDistance=0.0002; if(_Symbol=="GBPAUD")MinDistance=0.0002; if(_Symbol=="USDCAD")MinDistance=0.0002; if(_Symbol=="GBPAUD")MinDistance=0.0002; if(_Symbol=="EURAUD")MinDistance=0.0002; if(_Symbol=="EURGBP")MinDistance=0.0002; } else MinDistance=minDistance; //Alert (Symbol()+"_"+ Period() + "_" +MinDistance) // バーデータを取得 MqlRates rates[]; ArraySetAsSeries(rates, true); int copied = CopyRates(_Symbol, PERIOD_CURRENT, EndBars, StartBars - EndBars + 1, rates); if(copied <= 0) { Print("データのコピーに失敗しました"); return; } // レジスタンス/サポートレベルを抽出 ResistanceLevel levels[]; for(int i = 0; i < copied; i++) { AddLevel(levels, rates[i].high); AddLevel(levels, rates[i].low); } // 重要度を計算 CalculateImportance(levels); // 重要度の高いレベルのみを選択 ResistanceLevel importantLevels[]; for(int i = 0; i < ArraySize(levels); i++) { if(levels[i].importance > 1) { ArrayResize(importantLevels, ArraySize(importantLevels) + 1); importantLevels[ArraySize(importantLevels) - 1] = levels[i]; } } // 重要なレベルの重要度を再計算 CalculateImportance(importantLevels); // 水平線を描画 DrawHorizontalLines(importantLevels); ChartRedraw(); Print(Symbol()+"_"+ Period() + "_" +MinDistance); } //+------------------------------------------------------------------+ //| レベルを追加または更新 | //+------------------------------------------------------------------+ void AddLevel(ResistanceLevel &levels[], double price) { for(int i = 0; i < ArraySize(levels); i++) { if(MathAbs(levels[i].price - price) < MinDistance) { levels[i].count++; return; } } int size = ArraySize(levels); ArrayResize(levels, size + 1); levels[size].price = price; levels[size].count = 1; levels[size].importance = 1; } //+------------------------------------------------------------------+ //| 重要度を計算 | //+------------------------------------------------------------------+ void CalculateImportance(ResistanceLevel &levels[]) { for(int i = 0; i < ArraySize(levels); i++) { if(levels[i].count >= MinCount) { int nearCount = 0; for(int j = 0; j < ArraySize(levels); j++) { if(i != j && MathAbs(levels[i].price - levels[j].price) < MinDistance * 5) { nearCount += levels[j].count; } } levels[i].importance = 1 + MathMin(nearCount / MinCount, 4); } } } //+------------------------------------------------------------------+ //| 水平線を描画 | //+------------------------------------------------------------------+ void DrawHorizontalLines(const ResistanceLevel &levels[]) { int maxImportance = 0; for(int i = 0; i < ArraySize(levels); i++) { if(levels[i].importance > maxImportance) maxImportance = levels[i].importance; } int drawnLines = 0; for(int i = 0; i < ArraySize(levels) && drawnLines < MaxLines; i++) { if(levels[i].importance > 1) { string name = "ResistanceLine_" + IntegerToString(i); ObjectCreate(0, name, OBJ_HLINE, 0, 0, levels[i].price); ObjectSetInteger(0, name, OBJPROP_COLOR, clrYellow); // 重要度に応じて線の太さを調整 int width = MinWidth + (MaxWidth - MinWidth) * (levels[i].importance - 1) / (maxImportance - 1); ObjectSetInteger(0, name, OBJPROP_WIDTH, width-1); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID); drawnLines++; } } }