パーフェクトオーダーでサインが出るコードを紹介

// 使用するバッファ数とプロット数
#property indicator_buffers 9 // 使用するバッファの合計数を9に設定
#property indicator_plots 9 // 描画するプロットの合計数を9に設定

// —- サイン(ゴールデンクロス/デッドクロス)
#property indicator_label1 “MA_Cross_Sign_UP” // 1本目のバッファの表示名
#property indicator_type1 DRAW_ARROW // 1本目を矢印として描画
#property indicator_color1 clrTomato // 1本目の矢印の色をトマト色に設定
#property indicator_width1 2 // 1本目の矢印の太さを2に設定

#property indicator_label9 “MA_Cross_Sign_DN” // 9本目のバッファの表示名
#property indicator_type9 DRAW_ARROW // 9本目を矢印として描画
#property indicator_color9 clrAqua // 9本目の矢印の色を水色に設定
#property indicator_width9 2 // 9本目の矢印の太さを2に設定

// —- MAライン(MA描画用)
#property indicator_label2 “MA_Line” // 2本目のバッファの表示名
#property indicator_type2 DRAW_LINE // 2本目を線として描画
#property indicator_color2 clrRed // 2本目の線の色を赤色に設定
#property indicator_style2 STYLE_SOLID // 2本目を実線に設定
#property indicator_width2 2 // 2本目の線の太さを2に設定

// —- MA2ライン(MA2描画用)
#property indicator_label3 “MA2_Line” // 3本目のバッファの表示名
#property indicator_type3 DRAW_LINE // 3本目を線として描画
#property indicator_color3 clrDodgerBlue // 3本目の線の色を青色に設定
#property indicator_style3 STYLE_SOLID // 3本目を実線に設定
#property indicator_width3 2 // 3本目の線の太さを2に設定

// —- MA3ライン(MA3描画用)
#property indicator_label4 “MA3_Line” // 4本目のバッファの表示名
#property indicator_type4 DRAW_LINE // 4本目を線として描画
#property indicator_color4 clrLimeGreen // 4本目の線の色を緑色に設定
#property indicator_style4 STYLE_SOLID // 4本目を実線に設定
#property indicator_width4 2 // 4本目の線の太さを2に設定

// —- MA4ライン(MA4描画用)
#property indicator_label5 “MA4_Line” // 5本目のバッファの表示名
#property indicator_type5 DRAW_LINE // 5本目を線として描画
#property indicator_color5 clrGold // 5本目の線の色を金色に設定
#property indicator_style5 STYLE_SOLID // 5本目を実線に設定
#property indicator_width5 2 // 5本目の線の太さを2に設定

// —- MA5ライン(MA5描画用)
#property indicator_label6 “MA5_Line” // 6本目のバッファの表示名
#property indicator_type6 DRAW_LINE // 6本目を線として描画
#property indicator_color6 clrDarkOrange // 6本目の線の色を濃いオレンジ色に設定
#property indicator_style6 STYLE_SOLID // 6本目を実線に設定
#property indicator_width6 2 // 6本目の線の太さを2に設定

// —- MA6ライン(MA6描画用)
#property indicator_label7 “MA6_Line” // 7本目のバッファの表示名
#property indicator_type7 DRAW_LINE // 7本目を線として描画
#property indicator_color7 clrMagenta // 7本目の線の色をマゼンタに設定
#property indicator_style7 STYLE_SOLID // 7本目を実線に設定
#property indicator_width7 2 // 7本目の線の太さを2に設定

// —- MA7ライン(MA7描画用)
#property indicator_label8 “MA7_Line” // 8本目のバッファの表示名
#property indicator_type8 DRAW_LINE // 8本目を線として描画
#property indicator_color8 clrAqua // 8本目の線の色を水色に設定
#property indicator_style8 STYLE_SOLID // 8本目を実線に設定
#property indicator_width8 2 // 8本目の線の太さを2に設定

// — デザイン用カラー定義(変数名を分かりやすく:IRO_…) —
#define IRO_UI_HAIKEI_OFF clrWhite // UIオフ時の背景色(白)
#define IRO_UI_HAIKEI_ON clrLime // UIオン時の背景色(ライム)
#define IRO_UI_MOJI clrBlack // UIの基本文字色(黒)
#define IRO_UI_MOJI2 clrWhite // UIの反転文字色(白)
#define IRO_UI_WAKU C’50,50,50′ // UIの枠線色(ダークグレー)
#define IRO_SLIDER_HAIKEI clrSilver // スライダーの溝の背景色(銀色)
#define IRO_TSUMAMI clrOrangeRed // スライダーのつまみの色(オレンジレッド)
#define IRO_LABEL_HAIKEI C’30,30,30′ // 値ラベルの背景色(ほぼ黒)

// ボタン用オブジェクト名(枠と文字ラベル)
string alert_waku = “【c-t-a】AlertButtonFrame”; // Alertボタンの枠オブジェクト名
string alert_moji = “【c-t-a】AlertButtonText”; // Alertボタンの文字オブジェクト名
string push_waku = “【c-t-a】PushButtonFrame”; // Push通知ボタンの枠オブジェクト名
string push_moji = “【c-t-a】PushButtonText”; // Push通知ボタンの文字オブジェクト名
string open_waku = “【c-t-a】OpenButtonFrame”; // UI開閉ボタンの枠オブジェクト名
string open_moji = “【c-t-a】OpenButtonText”; // UI開閉ボタンの文字オブジェクト名
// 追加:KAKUTEIボタン
string kakutei_waku = “【c-t-a】KakuteiButtonFrame”; // KAKUTEIボタンの枠オブジェクト名
string kakutei_moji = “【c-t-a】KakuteiButtonText”; // KAKUTEIボタンの文字オブジェクト名
// 追加:MI-KAKUTEIボタン
string mikakutei_waku = “【c-t-a】MiKakuteiButtonFrame”; // MI-KAKUTEIボタンの枠オブジェクト名
string mikakutei_moji = “【c-t-a】MiKakuteiButtonText”; // MI-KAKUTEIボタンの文字オブジェクト名

// 追加:SMA/EMA切り替えボタン
string sma_waku = “【c-t-a】SMAButtonFrame”; // SMAボタンの枠オブジェクト名
string sma_moji = “【c-t-a】SMAButtonText”; // SMAボタンの文字オブジェクト名
string ema_waku = “【c-t-a】EMAButtonFrame”; // EMAボタンの枠オブジェクト名
string ema_moji = “【c-t-a】EMAButtonText”; // EMAボタンの文字オブジェクト名

// 追加:ボタンの配置位置
enum ENUM_BUTTON_POS
{
POS_LEFT_UPPER = 0, // 左上配置
POS_RIGHT_UPPER = 1, // 右上配置
POS_LEFT_LOWER = 2, // 左下配置
POS_RIGHT_LOWER = 3 // 右下配置
};
input ENUM_BUTTON_POS Button_Position = POS_LEFT_UPPER; // ユーザーが選択可能なUI配置位置

// 入力パラメータ(ATR、土日対策)
input bool donichi = false; // 土日の描画処理を行うかどうかの設定

input int heikin_honsuu = 1440; // 矢印の上下幅を計算するための平均本数
input double haba = 0.3; // 矢印をローソク足から離す係数

// 追加:表示期間の選択用
enum ENUM_DISPLAY_RANGE {
RANGE_DAYS_180 = 180, // 表示期間180日
RANGE_YEAR_1 = 365, // 表示期間1年
RANGE_YEAR_2 = 730, // 表示期間2年
RANGE_YEAR_3 = 1095, // 表示期間3年
RANGE_YEAR_4 = 1460, // 表示期間4年
RANGE_YEAR_5 = 1825 // 表示期間5年
};
input ENUM_DISPLAY_RANGE Inp_Display_Period = RANGE_YEAR_1; // ユーザーが選択可能な表示期間

// 追加:MAの表示本数選択用
enum ENUM_MA_COUNT {
MA_COUNT_2 = 2, // MA2本表示
MA_COUNT_3 = 3, // MA3本表示
MA_COUNT_4 = 4, // MA4本表示
MA_COUNT_5 = 5, // MA5本表示
MA_COUNT_6 = 6, // MA6本表示
MA_COUNT_7 = 7 // MA7本表示
};
input ENUM_MA_COUNT InpMACount = MA_COUNT_3; // ユーザーが選択可能なMA表示本数

// 追加:MAの線の太さ選択用
enum ENUM_MA_WIDTH {
MA_WIDTH_1 = 1, // 線の太さ1
MA_WIDTH_2 = 2, // 線の太さ2
MA_WIDTH_3 = 3, // 線の太さ3
MA_WIDTH_4 = 4, // 線の太さ4
MA_WIDTH_5 = 5 // 線の太さ5
};
input ENUM_MA_WIDTH InpMAWidth = MA_WIDTH_1; // ユーザーが選択可能なMAの線の太さ

double heikin_nagasa = 0.0; // 計算されたローソク足の平均サイズを保持
bool heikin_keisan_zumi = false; // 平均サイズの計算が完了したかどうかのフラグ

// バッファ
double sign_buffer[]; // 上向きサイン表示用のデータ配列
double sign_dn_buffer[]; // 下向きサイン表示用のデータ配列
double ma_buffer[]; // MA1の値を保持するデータ配列
double ma2_buffer[]; // MA2の値を保持するデータ配列
double ma3_buffer[]; // MA3の値を保持するデータ配列
double ma4_buffer[]; // MA4の値を保持するデータ配列
double ma5_buffer[]; // MA5の値を保持するデータ配列
double ma6_buffer[]; // MA6の値を保持するデータ配列
double ma7_buffer[]; // MA7の値を保持するデータ配列

// 真偽値(スイッチ)
bool alert_switch = false; // アラート機能のオンオフ状態
bool push_switch = false; // プッシュ通知のオンオフ状態
bool open_switch = true; // UIパネルの開閉状態
bool kakutei_switch = false; // 確定足サインのオンオフ状態
bool mikakutei_switch = true; // 未確定足サインのオンオフ状態
bool zenbu_keisan = false; // 全バー再計算を要求するフラグ

// 追加:MA種別スイッチ
bool sma_switch = true; // SMAモードのオンオフ状態
bool ema_switch = false; // EMAモードのオンオフ状態

// 多重通知防止
datetime last_alert_time = 0; // 最後に通知を行ったバーの時刻

// ——————————————————————
// MA Period Slider (期間スライダー)
// ——————————————————————
string kikan_slider_namae_ = “【c-t-a】SMASlider_”; // MA1スライダーのベース名
string kikan_slider_haikei = kikan_slider_namae_ + “BG”; // MA1スライダーの背景オブジェクト名
string kikan_slider_tsumami = kikan_slider_namae_ + “Knob”; // MA1スライダーのつまみオブジェクト名
string kikan_slider_atai_label = kikan_slider_namae_ + “Value”; // MA1スライダーの値ラベルオブジェクト名

// + / – 追加
string kikan_slider_minus = kikan_slider_namae_ + “Minus”; // MA1スライダーのマイナスボタン名
string kikan_slider_plus = kikan_slider_namae_ + “Plus”; // MA1スライダーのプラスボタン名

int kikan_slider_x = 25; // MA1スライダーのベースX座標
int kikan_slider_y = 92; // MA1スライダーのベースY座標
int kikan_slider_haba = 200; // MA1スライダーの横幅ピクセル数
int kikan_slider_takasa = 4; // MA1スライダーの高さピクセル数
int kikan_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int kikan_slider_atai = 20; // MA1スライダーの現在の表示値
bool kikan_slider_drag_chu = false; // MA1スライダーがドラッグ中かどうかのフラグ
int kikan_slider_kotei_atai = 20; // MA1スライダーの確定(適用)値
int sma_kikan = 20; // 実際の計算に使用されるMA1の期間

bool mouse_scroll_mae = true; // ドラッグ操作前のチャートスクロール設定状態

int handle_ma = INVALID_HANDLE; // MA1のインジケーターハンドル
int mae_no_kikan = -1; // 前回処理時のチャート時間足

// 追加:カラー変更用
string color_waku = “【c-t-a】ColorButtonFrame”; // MA1カラーボタンの枠オブジェクト名
string color_moji = “【c-t-a】ColorButtonText”; // MA1カラーボタンの文字オブジェクト名
int ma_color_index = 0; // 現在選択されているMA1のカラーインデックス
color ma_color_list[7] = {clrRed, clrDodgerBlue, clrLimeGreen, clrGold, clrDarkOrange, clrMagenta, clrAqua}; // 選択可能なカラー配列

// ——————————————————————
// MA2 Period Slider (MA2スライダー)
// ——————————————————————
string ma2_slider_namae_ = “【c-t-a】MA2Slider_”; // MA2スライダーのベース名
string ma2_slider_haikei = ma2_slider_namae_ + “BG”; // MA2スライダーの背景オブジェクト名
string ma2_slider_tsumami = ma2_slider_namae_ + “Knob”; // MA2スライダーのつまみオブジェクト名
string ma2_slider_atai_label = ma2_slider_namae_ + “Value”; // MA2スライダーの値ラベルオブジェクト名
string ma2_slider_minus = ma2_slider_namae_ + “Minus”; // MA2スライダーのマイナスボタン名
string ma2_slider_plus = ma2_slider_namae_ + “Plus”; // MA2スライダーのプラスボタン名

int ma2_slider_x = 25; // MA2スライダーのベースX座標
int ma2_slider_y = 122; // MA2スライダーのベースY座標
int ma2_slider_haba = 200; // MA2スライダーの横幅ピクセル数
int ma2_slider_takasa = 4; // MA2スライダーの高さピクセル数
int ma2_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma2_slider_atai = 50; // MA2スライダーの現在の表示値
bool ma2_slider_drag_chu = false; // MA2スライダーがドラッグ中かどうかのフラグ
int ma2_slider_kotei_atai = 50; // MA2スライダーの確定(適用)値
int ma2_kikan = 50; // 実際の計算に使用されるMA2の期間

int handle_ma2 = INVALID_HANDLE; // MA2のインジケーターハンドル

// ★追加:カラー変更用(MA2)
string color2_waku = “【c-t-a】Color2ButtonFrame”; // MA2カラーボタンの枠オブジェクト名
string color2_moji = “【c-t-a】Color2ButtonText”; // MA2カラーボタンの文字オブジェクト名
int ma2_color_index = 1; // 現在選択されているMA2のカラーインデックス

// ——————————————————————
// MA3 Period Slider (MA3スライダー)
// ——————————————————————
string ma3_slider_namae_ = “【c-t-a】MA3Slider_”; // MA3スライダーのベース名
string ma3_slider_haikei = ma3_slider_namae_ + “BG”; // MA3スライダーの背景オブジェクト名
string ma3_slider_tsumami = ma3_slider_namae_ + “Knob”; // MA3スライダーのつまみオブジェクト名
string ma3_slider_atai_label = ma3_slider_namae_ + “Value”; // MA3スライダーの値ラベルオブジェクト名
string ma3_slider_minus = ma3_slider_namae_ + “Minus”; // MA3スライダーのマイナスボタン名
string ma3_slider_plus = ma3_slider_namae_ + “Plus”; // MA3スライダーのプラスボタン名

int ma3_slider_x = 25; // MA3スライダーのベースX座標
int ma3_slider_y = 152; // MA3スライダーのベースY座標
int ma3_slider_haba = 200; // MA3スライダーの横幅ピクセル数
int ma3_slider_takasa = 4; // MA3スライダーの高さピクセル数
int ma3_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma3_slider_atai = 75; // MA3スライダーの現在の表示値
bool ma3_slider_drag_chu = false; // MA3スライダーがドラッグ中かどうかのフラグ
int ma3_slider_kotei_atai = 75; // MA3スライダーの確定(適用)値
int ma3_kikan = 75; // 実際の計算に使用されるMA3の期間

int handle_ma3 = INVALID_HANDLE; // MA3のインジケーターハンドル

string color3_waku = “【c-t-a】Color3ButtonFrame”; // MA3カラーボタンの枠オブジェクト名
string color3_moji = “【c-t-a】Color3ButtonText”; // MA3カラーボタンの文字オブジェクト名
int ma3_color_index = 2; // 現在選択されているMA3のカラーインデックス

// ——————————————————————
// MA4 Period Slider (MA4スライダー)
// ——————————————————————
string ma4_slider_namae_ = “【c-t-a】MA4Slider_”; // MA4スライダーのベース名
string ma4_slider_haikei = ma4_slider_namae_ + “BG”; // MA4スライダーの背景オブジェクト名
string ma4_slider_tsumami = ma4_slider_namae_ + “Knob”; // MA4スライダーのつまみオブジェクト名
string ma4_slider_atai_label = ma4_slider_namae_ + “Value”; // MA4スライダーの値ラベルオブジェクト名
string ma4_slider_minus = ma4_slider_namae_ + “Minus”; // MA4スライダーのマイナスボタン名
string ma4_slider_plus = ma4_slider_namae_ + “Plus”; // MA4スライダーのプラスボタン名

int ma4_slider_x = 25; // MA4スライダーのベースX座標
int ma4_slider_y = 182; // MA4スライダーのベースY座標
int ma4_slider_haba = 200; // MA4スライダーの横幅ピクセル数
int ma4_slider_takasa = 4; // MA4スライダーの高さピクセル数
int ma4_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma4_slider_atai = 100; // MA4スライダーの現在の表示値
bool ma4_slider_drag_chu = false; // MA4スライダーがドラッグ中かどうかのフラグ
int ma4_slider_kotei_atai = 100; // MA4スライダーの確定(適用)値
int ma4_kikan = 100; // 実際の計算に使用されるMA4の期間

int handle_ma4 = INVALID_HANDLE; // MA4のインジケーターハンドル

string color4_waku = “【c-t-a】Color4ButtonFrame”; // MA4カラーボタンの枠オブジェクト名
string color4_moji = “【c-t-a】Color4ButtonText”; // MA4カラーボタンの文字オブジェクト名
int ma4_color_index = 3; // 現在選択されているMA4のカラーインデックス

// ——————————————————————
// MA5 Period Slider (MA5スライダー)
// ——————————————————————
string ma5_slider_namae_ = “【c-t-a】MA5Slider_”; // MA5スライダーのベース名
string ma5_slider_haikei = ma5_slider_namae_ + “BG”; // MA5スライダーの背景オブジェクト名
string ma5_slider_tsumami = ma5_slider_namae_ + “Knob”; // MA5スライダーのつまみオブジェクト名
string ma5_slider_atai_label = ma5_slider_namae_ + “Value”; // MA5スライダーの値ラベルオブジェクト名
string ma5_slider_minus = ma5_slider_namae_ + “Minus”; // MA5スライダーのマイナスボタン名
string ma5_slider_plus = ma5_slider_namae_ + “Plus”; // MA5スライダーのプラスボタン名

int ma5_slider_x = 25; // MA5スライダーのベースX座標
int ma5_slider_y = 212; // MA5スライダーのベースY座標
int ma5_slider_haba = 200; // MA5スライダーの横幅ピクセル数
int ma5_slider_takasa = 4; // MA5スライダーの高さピクセル数
int ma5_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma5_slider_atai = 125; // MA5スライダーの現在の表示値
bool ma5_slider_drag_chu = false; // MA5スライダーがドラッグ中かどうかのフラグ
int ma5_slider_kotei_atai = 125; // MA5スライダーの確定(適用)値
int ma5_kikan = 125; // 実際の計算に使用されるMA5の期間

int handle_ma5 = INVALID_HANDLE; // MA5のインジケーターハンドル

string color5_waku = “【c-t-a】Color5ButtonFrame”; // MA5カラーボタンの枠オブジェクト名
string color5_moji = “【c-t-a】Color5ButtonText”; // MA5カラーボタンの文字オブジェクト名
int ma5_color_index = 4; // 現在選択されているMA5のカラーインデックス

// ——————————————————————
// MA6 Period Slider (MA6スライダー)
// ——————————————————————
string ma6_slider_namae_ = “【c-t-a】MA6Slider_”; // MA6スライダーのベース名
string ma6_slider_haikei = ma6_slider_namae_ + “BG”; // MA6スライダーの背景オブジェクト名
string ma6_slider_tsumami = ma6_slider_namae_ + “Knob”; // MA6スライダーのつまみオブジェクト名
string ma6_slider_atai_label = ma6_slider_namae_ + “Value”; // MA6スライダーの値ラベルオブジェクト名
string ma6_slider_minus = ma6_slider_namae_ + “Minus”; // MA6スライダーのマイナスボタン名
string ma6_slider_plus = ma6_slider_namae_ + “Plus”; // MA6スライダーのプラスボタン名

int ma6_slider_x = 25; // MA6スライダーのベースX座標
int ma6_slider_y = 242; // MA6スライダーのベースY座標
int ma6_slider_haba = 200; // MA6スライダーの横幅ピクセル数
int ma6_slider_takasa = 4; // MA6スライダーの高さピクセル数
int ma6_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma6_slider_atai = 150; // MA6スライダーの現在の表示値
bool ma6_slider_drag_chu = false; // MA6スライダーがドラッグ中かどうかのフラグ
int ma6_slider_kotei_atai = 150; // MA6スライダーの確定(適用)値
int ma6_kikan = 150; // 実際の計算に使用されるMA6の期間

int handle_ma6 = INVALID_HANDLE; // MA6のインジケーターハンドル

string color6_waku = “【c-t-a】Color6ButtonFrame”; // MA6カラーボタンの枠オブジェクト名
string color6_moji = “【c-t-a】Color6ButtonText”; // MA6カラーボタンの文字オブジェクト名
int ma6_color_index = 5; // 現在選択されているMA6のカラーインデックス

// ——————————————————————
// MA7 Period Slider (MA7スライダー)
// ——————————————————————
string ma7_slider_namae_ = “【c-t-a】MA7Slider_”; // MA7スライダーのベース名
string ma7_slider_haikei = ma7_slider_namae_ + “BG”; // MA7スライダーの背景オブジェクト名
string ma7_slider_tsumami = ma7_slider_namae_ + “Knob”; // MA7スライダーのつまみオブジェクト名
string ma7_slider_atai_label = ma7_slider_namae_ + “Value”; // MA7スライダーの値ラベルオブジェクト名
string ma7_slider_minus = ma7_slider_namae_ + “Minus”; // MA7スライダーのマイナスボタン名
string ma7_slider_plus = ma7_slider_namae_ + “Plus”; // MA7スライダーのプラスボタン名

int ma7_slider_x = 25; // MA7スライダーのベースX座標
int ma7_slider_y = 272; // MA7スライダーのベースY座標
int ma7_slider_haba = 200; // MA7スライダーの横幅ピクセル数
int ma7_slider_takasa = 4; // MA7スライダーの高さピクセル数
int ma7_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int ma7_slider_atai = 200; // MA7スライダーの現在の表示値
bool ma7_slider_drag_chu = false; // MA7スライダーがドラッグ中かどうかのフラグ
int ma7_slider_kotei_atai = 200; // MA7スライダーの確定(適用)値
int ma7_kikan = 200; // 実際の計算に使用されるMA7の期間

int handle_ma7 = INVALID_HANDLE; // MA7のインジケーターハンドル

string color7_waku = “【c-t-a】Color7ButtonFrame”; // MA7カラーボタンの枠オブジェクト名
string color7_moji = “【c-t-a】Color7ButtonText”; // MA7カラーボタンの文字オブジェクト名
int ma7_color_index = 6; // 現在選択されているMA7のカラーインデックス

// ——————————————————————
// Repeat Slider (リピートスライダー)
// ——————————————————————
string repeat_slider_namae_ = “【c-t-a】RepeatSlider_”; // リピートスライダーのベース名
string repeat_slider_haikei = repeat_slider_namae_ + “BG”; // リピートスライダーの背景オブジェクト名
string repeat_slider_tsumami = repeat_slider_namae_ + “Knob”; // リピートスライダーのつまみオブジェクト名
string repeat_slider_atai_label = repeat_slider_namae_ + “Value”; // リピートスライダーの値ラベルオブジェクト名
string repeat_slider_minus = repeat_slider_namae_ + “Minus”; // リピートスライダーのマイナスボタン名
string repeat_slider_plus = repeat_slider_namae_ + “Plus”; // リピートスライダーのプラスボタン名

int repeat_slider_x = 25; // リピートスライダーのベースX座標
int repeat_slider_y = 302; // リピートスライダーのベースY座標
int repeat_slider_haba = 200; // リピートスライダーの横幅ピクセル数
int repeat_slider_takasa = 4; // リピートスライダーの高さピクセル数
int repeat_slider_tsumami_size = 14; // つまみの縦横ピクセルサイズ

int repeat_slider_atai = 0; // リピートスライダーの現在の表示値
bool repeat_slider_drag_chu = false; // リピートスライダーがドラッグ中かどうかのフラグ
int repeat_slider_kotei_atai = 0; // リピートスライダーの確定(適用)値

// ==================================================================
// オフセット計算用変数と関数
// ==================================================================
int g_offsetX = 0; // UI全体をX軸方向にずらすためのオフセット値
int g_offsetY = 0; // UI全体をY軸方向にずらすためのオフセット値

void CalcOffset() // チャートサイズからUI配置のオフセットを計算する関数
{
long chartWidth = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); // チャートのピクセル幅を取得
long chartHeight = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); // チャートのピクセル高さを取得

int panelWidth = 450; // UIパネル全体の想定最大幅
int panelHeight = open_switch ? (repeat_slider_y + 40) : 54; // UI開閉状態に応じた高さを設定

g_offsetX = 0; // Xオフセットを初期化
g_offsetY = 0; // Yオフセットを初期化

if(Button_Position == POS_RIGHT_UPPER || Button_Position == POS_RIGHT_LOWER) { // 右側配置の場合
g_offsetX = (int)chartWidth – panelWidth; // 右端に合うようにXオフセットを計算
if(g_offsetX < 0) g_offsetX = 0; // マイナスにならないよう補正 } if(Button_Position == POS_LEFT_LOWER || Button_Position == POS_RIGHT_LOWER) { // 下側配置の場合 g_offsetY = (int)chartHeight - panelHeight; // 下端に合うようにYオフセットを計算 if(g_offsetY < 0) g_offsetY = 0; // マイナスにならないよう補正 } } //+------------------------------------------------------------------+ //| ★追加:UI状態を時間足変更でも保持する(Global Variable保存/復元) | //+------------------------------------------------------------------+ string gv_key(const string name) // 固有のグローバル変数キーを生成する関数 { return("btn+ma_cross:" + (string)ChartID() + ":" + _Symbol + ":" + name); // チャートIDと銘柄名を結合して一意なキーを作成 } void gv_set_bool(const string name, const bool v) // 真偽値をグローバル変数に保存する関数 { GlobalVariableSet(gv_key(name), v ? 1.0 : 0.0); // boolを数値(1.0/0.0)に変換して保存 } bool gv_get_bool(const string name, const bool def) // 真偽値をグローバル変数から読み込む関数 { string k = gv_key(name); // キー名を取得 if(GlobalVariableCheck(k)) // 変数が存在するか確認 { return(GlobalVariableGet(k) > 0.5); // 0.5より大きければtrueとして扱う
}
return(def); // 変数がなければデフォルト値を返す
}
void gv_set_int(const string name, const int v) // 整数値をグローバル変数に保存する関数
{
GlobalVariableSet(gv_key(name), (double)v); // intをdoubleに変換して保存
}
int gv_get_int(const string name, const int def) // 整数値をグローバル変数から読み込む関数
{
string k = gv_key(name); // キー名を取得
if(GlobalVariableCheck(k)) // 変数が存在するか確認
{
return((int)MathRound(GlobalVariableGet(k))); // 値を取得し四捨五入してintに変換
}
return(def); // 変数がなければデフォルト値を返す
}
void ui_state_save() // UIの全状態を保存する関数
{
// 各スイッチの状態を保存
gv_set_bool(“alert_switch”, alert_switch); // アラート設定を保存
gv_set_bool(“push_switch”, push_switch); // プッシュ通知設定を保存
gv_set_bool(“open_switch”, open_switch); // パネル開閉設定を保存
gv_set_bool(“kakutei_switch”, kakutei_switch); // 確定足モードを保存
gv_set_bool(“mikakutei_switch”, mikakutei_switch); // 未確定足モードを保存
gv_set_bool(“sma_switch”, sma_switch); // SMAモードを保存
gv_set_bool(“ema_switch”, ema_switch); // EMAモードを保存

// SMA関連の値を保存
gv_set_int(“kikan_slider_atai”, kikan_slider_atai); // MA1スライダーの表示値を保存
gv_set_int(“kikan_slider_kotei_atai”, kikan_slider_kotei_atai); // MA1スライダーの適用値を保存
gv_set_int(“sma_kikan”, sma_kikan); // MA1の計算期間を保存
gv_set_int(“ma_color_index”, ma_color_index); // MA1のカラーインデックスを保存

// MA2関連の値を保存
gv_set_int(“ma2_slider_atai”, ma2_slider_atai); // MA2スライダーの表示値を保存
gv_set_int(“ma2_slider_kotei_atai”, ma2_slider_kotei_atai); // MA2スライダーの適用値を保存
gv_set_int(“ma2_kikan”, ma2_kikan); // MA2の計算期間を保存
gv_set_int(“ma2_color_index”, ma2_color_index); // MA2のカラーインデックスを保存

// MA3~7の値を保存
gv_set_int(“ma3_slider_atai”, ma3_slider_atai); // MA3スライダーの表示値を保存
gv_set_int(“ma3_slider_kotei_atai”, ma3_slider_kotei_atai); // MA3スライダーの適用値を保存
gv_set_int(“ma3_kikan”, ma3_kikan); // MA3の計算期間を保存
gv_set_int(“ma3_color_index”, ma3_color_index); // MA3のカラーインデックスを保存

gv_set_int(“ma4_slider_atai”, ma4_slider_atai); // MA4スライダーの表示値を保存
gv_set_int(“ma4_slider_kotei_atai”, ma4_slider_kotei_atai); // MA4スライダーの適用値を保存
gv_set_int(“ma4_kikan”, ma4_kikan); // MA4の計算期間を保存
gv_set_int(“ma4_color_index”, ma4_color_index); // MA4のカラーインデックスを保存

gv_set_int(“ma5_slider_atai”, ma5_slider_atai); // MA5スライダーの表示値を保存
gv_set_int(“ma5_slider_kotei_atai”, ma5_slider_kotei_atai); // MA5スライダーの適用値を保存
gv_set_int(“ma5_kikan”, ma5_kikan); // MA5の計算期間を保存
gv_set_int(“ma5_color_index”, ma5_color_index); // MA5のカラーインデックスを保存

gv_set_int(“ma6_slider_atai”, ma6_slider_atai); // MA6スライダーの表示値を保存
gv_set_int(“ma6_slider_kotei_atai”, ma6_slider_kotei_atai); // MA6スライダーの適用値を保存
gv_set_int(“ma6_kikan”, ma6_kikan); // MA6の計算期間を保存
gv_set_int(“ma6_color_index”, ma6_color_index); // MA6のカラーインデックスを保存

gv_set_int(“ma7_slider_atai”, ma7_slider_atai); // MA7スライダーの表示値を保存
gv_set_int(“ma7_slider_kotei_atai”, ma7_slider_kotei_atai); // MA7スライダーの適用値を保存
gv_set_int(“ma7_kikan”, ma7_kikan); // MA7の計算期間を保存
gv_set_int(“ma7_color_index”, ma7_color_index); // MA7のカラーインデックスを保存

// リピート関連の値を保存
gv_set_int(“repeat_slider_atai”, repeat_slider_atai); // リピートスライダーの表示値を保存
gv_set_int(“repeat_slider_kotei_atai”, repeat_slider_kotei_atai); // リピートスライダーの適用値を保存
}
bool ui_state_load() // 保存されたUI状態を復元する関数
{
// 保存データの存在チェック(どれか一つでもあれば復元処理へ)
if(!GlobalVariableCheck(gv_key(“open_switch”)) &&
!GlobalVariableCheck(gv_key(“kikan_slider_atai”)) &&
!GlobalVariableCheck(gv_key(“ma2_slider_atai”)) &&
!GlobalVariableCheck(gv_key(“repeat_slider_atai”)))
{
return(false); // 保存データがなければfalseを返す
}

// 各スイッチの状態を読み込み
alert_switch = gv_get_bool(“alert_switch”, alert_switch); // アラート設定を復元
push_switch = gv_get_bool(“push_switch”, push_switch); // プッシュ通知設定を復元
open_switch = gv_get_bool(“open_switch”, open_switch); // パネル開閉設定を復元
kakutei_switch = gv_get_bool(“kakutei_switch”, kakutei_switch); // 確定足モードを復元
mikakutei_switch = gv_get_bool(“mikakutei_switch”, mikakutei_switch); // 未確定足モードを復元
sma_switch = gv_get_bool(“sma_switch”, sma_switch); // SMAモードを復元
ema_switch = gv_get_bool(“ema_switch”, ema_switch); // EMAモードを復元

// スライダーの値を読み込み
kikan_slider_atai = gv_get_int(“kikan_slider_atai”, kikan_slider_atai); // MA1スライダーの表示値を復元
kikan_slider_kotei_atai = gv_get_int(“kikan_slider_kotei_atai”, kikan_slider_kotei_atai); // MA1スライダーの適用値を復元
sma_kikan = gv_get_int(“sma_kikan”, sma_kikan); // MA1の計算期間を復元
ma_color_index = gv_get_int(“ma_color_index”, ma_color_index); // MA1のカラーインデックスを復元
if(ma_color_index < 0 || ma_color_index > 6) ma_color_index = 0; // カラーインデックスが範囲外なら補正

ma2_slider_atai = gv_get_int(“ma2_slider_atai”, ma2_slider_atai); // MA2スライダーの表示値を復元
ma2_slider_kotei_atai = gv_get_int(“ma2_slider_kotei_atai”, ma2_slider_kotei_atai); // MA2スライダーの適用値を復元
ma2_kikan = gv_get_int(“ma2_kikan”, ma2_kikan); // MA2の計算期間を復元
ma2_color_index = gv_get_int(“ma2_color_index”, ma2_color_index); // MA2のカラーインデックスを復元
if(ma2_color_index < 0 || ma2_color_index > 6) ma2_color_index = 1; // カラーインデックスが範囲外なら補正

ma3_slider_atai = gv_get_int(“ma3_slider_atai”, ma3_slider_atai); // MA3スライダーの表示値を復元
ma3_slider_kotei_atai = gv_get_int(“ma3_slider_kotei_atai”, ma3_slider_kotei_atai); // MA3スライダーの適用値を復元
ma3_kikan = gv_get_int(“ma3_kikan”, ma3_kikan); // MA3の計算期間を復元
ma3_color_index = gv_get_int(“ma3_color_index”, ma3_color_index); // MA3のカラーインデックスを復元
if(ma3_color_index < 0 || ma3_color_index > 6) ma3_color_index = 2; // カラーインデックスが範囲外なら補正

ma4_slider_atai = gv_get_int(“ma4_slider_atai”, ma4_slider_atai); // MA4スライダーの表示値を復元
ma4_slider_kotei_atai = gv_get_int(“ma4_slider_kotei_atai”, ma4_slider_kotei_atai); // MA4スライダーの適用値を復元
ma4_kikan = gv_get_int(“ma4_kikan”, ma4_kikan); // MA4の計算期間を復元
ma4_color_index = gv_get_int(“ma4_color_index”, ma4_color_index); // MA4のカラーインデックスを復元
if(ma4_color_index < 0 || ma4_color_index > 6) ma4_color_index = 3; // カラーインデックスが範囲外なら補正

ma5_slider_atai = gv_get_int(“ma5_slider_atai”, ma5_slider_atai); // MA5スライダーの表示値を復元
ma5_slider_kotei_atai = gv_get_int(“ma5_slider_kotei_atai”, ma5_slider_kotei_atai); // MA5スライダーの適用値を復元
ma5_kikan = gv_get_int(“ma5_kikan”, ma5_kikan); // MA5の計算期間を復元
ma5_color_index = gv_get_int(“ma5_color_index”, ma5_color_index); // MA5のカラーインデックスを復元
if(ma5_color_index < 0 || ma5_color_index > 6) ma5_color_index = 4; // カラーインデックスが範囲外なら補正

ma6_slider_atai = gv_get_int(“ma6_slider_atai”, ma6_slider_atai); // MA6スライダーの表示値を復元
ma6_slider_kotei_atai = gv_get_int(“ma6_slider_kotei_atai”, ma6_slider_kotei_atai); // MA6スライダーの適用値を復元
ma6_kikan = gv_get_int(“ma6_kikan”, ma6_kikan); // MA6の計算期間を復元
ma6_color_index = gv_get_int(“ma6_color_index”, ma6_color_index); // MA6のカラーインデックスを復元
if(ma6_color_index < 0 || ma6_color_index > 6) ma6_color_index = 5; // カラーインデックスが範囲外なら補正

ma7_slider_atai = gv_get_int(“ma7_slider_atai”, ma7_slider_atai); // MA7スライダーの表示値を復元
ma7_slider_kotei_atai = gv_get_int(“ma7_slider_kotei_atai”, ma7_slider_kotei_atai); // MA7スライダーの適用値を復元
ma7_kikan = gv_get_int(“ma7_kikan”, ma7_kikan); // MA7の計算期間を復元
ma7_color_index = gv_get_int(“ma7_color_index”, ma7_color_index); // MA7のカラーインデックスを復元
if(ma7_color_index < 0 || ma7_color_index > 6) ma7_color_index = 6; // カラーインデックスが範囲外なら補正

repeat_slider_atai = gv_get_int(“repeat_slider_atai”, repeat_slider_atai); // リピートスライダーの表示値を復元
repeat_slider_kotei_atai = gv_get_int(“repeat_slider_kotei_atai”, repeat_slider_kotei_atai); // リピートスライダーの適用値を復元

// 値の安全化(異常値の場合に正常な範囲へ丸める)
if(kikan_slider_atai < 1) kikan_slider_atai = 1; // MA1表示値の下限補正 if(kikan_slider_atai > 200) kikan_slider_atai = 200; // MA1表示値の上限補正
if(kikan_slider_kotei_atai < 1) kikan_slider_kotei_atai = 1; // MA1適用値の下限補正 if(kikan_slider_kotei_atai > 200) kikan_slider_kotei_atai = 200; // MA1適用値の上限補正

if(ma2_slider_atai < 1) ma2_slider_atai = 1; // MA2表示値の下限補正 if(ma2_slider_atai > 200) ma2_slider_atai = 200; // MA2表示値の上限補正
if(ma2_slider_kotei_atai < 1) ma2_slider_kotei_atai = 1; // MA2適用値の下限補正 if(ma2_slider_kotei_atai > 200) ma2_slider_kotei_atai = 200; // MA2適用値の上限補正

if(ma3_slider_atai < 1) ma3_slider_atai = 1; // MA3表示値の下限補正 if(ma3_slider_atai > 200) ma3_slider_atai = 200; // MA3表示値の上限補正
if(ma3_slider_kotei_atai < 1) ma3_slider_kotei_atai = 1; // MA3適用値の下限補正 if(ma3_slider_kotei_atai > 200) ma3_slider_kotei_atai = 200; // MA3適用値の上限補正

if(ma4_slider_atai < 1) ma4_slider_atai = 1; // MA4表示値の下限補正 if(ma4_slider_atai > 200) ma4_slider_atai = 200; // MA4表示値の上限補正
if(ma4_slider_kotei_atai < 1) ma4_slider_kotei_atai = 1; // MA4適用値の下限補正 if(ma4_slider_kotei_atai > 200) ma4_slider_kotei_atai = 200; // MA4適用値の上限補正

if(ma5_slider_atai < 1) ma5_slider_atai = 1; // MA5表示値の下限補正 if(ma5_slider_atai > 200) ma5_slider_atai = 200; // MA5表示値の上限補正
if(ma5_slider_kotei_atai < 1) ma5_slider_kotei_atai = 1; // MA5適用値の下限補正 if(ma5_slider_kotei_atai > 200) ma5_slider_kotei_atai = 200; // MA5適用値の上限補正

if(ma6_slider_atai < 1) ma6_slider_atai = 1; // MA6表示値の下限補正 if(ma6_slider_atai > 200) ma6_slider_atai = 200; // MA6表示値の上限補正
if(ma6_slider_kotei_atai < 1) ma6_slider_kotei_atai = 1; // MA6適用値の下限補正 if(ma6_slider_kotei_atai > 200) ma6_slider_kotei_atai = 200; // MA6適用値の上限補正

if(ma7_slider_atai < 1) ma7_slider_atai = 1; // MA7表示値の下限補正 if(ma7_slider_atai > 200) ma7_slider_atai = 200; // MA7表示値の上限補正
if(ma7_slider_kotei_atai < 1) ma7_slider_kotei_atai = 1; // MA7適用値の下限補正 if(ma7_slider_kotei_atai > 200) ma7_slider_kotei_atai = 200; // MA7適用値の上限補正

if(repeat_slider_atai < 0) repeat_slider_atai = 0; // リピート表示値の下限補正 if(repeat_slider_atai > 50) repeat_slider_atai = 50; // リピート表示値の上限補正
if(repeat_slider_kotei_atai < 0) repeat_slider_kotei_atai = 0; // リピート適用値の下限補正 if(repeat_slider_kotei_atai > 50) repeat_slider_kotei_atai = 50; // リピート適用値の上限補正

// 同期(確定値を実際の計算パラメータへ反映)
sma_kikan = kikan_slider_kotei_atai; // MA1の計算期間を更新
ma2_kikan = ma2_slider_kotei_atai; // MA2の計算期間を更新
ma3_kikan = ma3_slider_kotei_atai; // MA3の計算期間を更新
ma4_kikan = ma4_slider_kotei_atai; // MA4の計算期間を更新
ma5_kikan = ma5_slider_kotei_atai; // MA5の計算期間を更新
ma6_kikan = ma6_slider_kotei_atai; // MA6の計算期間を更新
ma7_kikan = ma7_slider_kotei_atai; // MA7の計算期間を更新

// SMA/EMAスイッチの整合性確保(片方のみONにする処理)
if(sma_switch && ema_switch) // 両方ONになっていた場合
{
ema_switch = false; // EMAをOFFにする
}
if(!sma_switch && !ema_switch) // 両方OFFになっていた場合
{
sma_switch = true; // SMAを強制的にONにする
ema_switch = false; // EMAはOFF
}

return(true); // 読み込み成功を返す
}

//+——————————————————————+
//| 指定された表示期間の有効バー数を求める(series=0が最新前提) |
//+——————————————————————+
int kako_5nen_check(const datetime &time[], const int rates_total) // 指定期間内のバー数を計算する関数
{
datetime latest = time[0]; // 最新バーの時間を取得
datetime kijun_jikan = latest – (datetime)(86400 * (int)Inp_Display_Period); // 指定された期間分さかのぼった基準時刻を算出

int idx = iBarShift(_Symbol, _Period, kijun_jikan, false); // 基準時刻に近いバーのインデックスを取得

if(idx < 0) // ヒストリデータが足りずバーが見つからない場合 { idx = 200; // 最低保証として200本をインデックスとする } if(idx > rates_total – 1) // 取得したインデックスがチャート上の最大バー数を超えている場合
{
idx = rates_total – 1; // 存在する最大のインデックスに制限する
}

return(idx + 1); // 0始まりのインデックスに1を足して要素数(バーの総本数)として返す
}

//+——————————————————————+
//| MAハンドルを更新する関数 |
//+——————————————————————+
void ma_handle_koushin(int kikan) // MA1ハンドルの再作成・更新処理
{
// MA/MA2 は常に「ペア」として作り直す(共有状態での解放エラーを避けるため)
ENUM_MA_METHOD method = MODE_SMA; // 移動平均線の種類をSMAに初期設定
if(ema_switch) // EMAスイッチがONの場合
{
method = MODE_EMA; // 種類をEMAに変更
}

// 共有している場合は release を1回だけにする安全な解放処理
if(handle_ma != INVALID_HANDLE && handle_ma == handle_ma2) // MA1とMA2が同じハンドルを共有している場合
{
IndicatorRelease(handle_ma); // 共有ハンドルを解放
handle_ma = INVALID_HANDLE; // MA1ハンドルを無効化
handle_ma2 = INVALID_HANDLE; // MA2ハンドルも無効化
}
else // ハンドルが別々の場合
{
if(handle_ma != INVALID_HANDLE) // MA1ハンドルが有効な場合
{
IndicatorRelease(handle_ma); // MA1ハンドルを解放
handle_ma = INVALID_HANDLE; // MA1ハンドルを無効化
}
if(handle_ma2 != INVALID_HANDLE) // MA2ハンドルが有効な場合
{
IndicatorRelease(handle_ma2); // MA2ハンドルを解放
handle_ma2 = INVALID_HANDLE; // MA2ハンドルを無効化
}
}

// 新規作成(ここで新しくインジケーターハンドルを取得)
handle_ma = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA1のハンドルを取得
handle_ma2 = iMA(_Symbol, _Period, ma2_kikan, 0, method, PRICE_CLOSE); // MA2のハンドルを取得
}

//+——————————————————————+
//| MA2ハンドルを更新する関数 |
//+——————————————————————+
void ma2_handle_koushin(int kikan) // MA2ハンドルの再作成・更新処理
{
// MA/MA2 は常に「ペア」として作り直す(共有状態での解放エラーを避けるため)
ENUM_MA_METHOD method = MODE_SMA; // 移動平均線の種類をSMAに初期設定
if(ema_switch) // EMAスイッチがONの場合
{
method = MODE_EMA; // 種類をEMAに変更
}

// 共有している場合は release を1回だけにする安全な解放処理
if(handle_ma2 != INVALID_HANDLE && handle_ma2 == handle_ma) // MA1とMA2が同じハンドルを共有している場合
{
IndicatorRelease(handle_ma2); // 共有ハンドルを解放
handle_ma = INVALID_HANDLE; // MA1ハンドルを無効化
handle_ma2 = INVALID_HANDLE; // MA2ハンドルも無効化
}
else // ハンドルが別々の場合
{
if(handle_ma2 != INVALID_HANDLE) // MA2ハンドルが有効な場合
{
IndicatorRelease(handle_ma2); // MA2ハンドルを解放
handle_ma2 = INVALID_HANDLE; // MA2ハンドルを無効化
}
if(handle_ma != INVALID_HANDLE) // MA1ハンドルが有効な場合
{
IndicatorRelease(handle_ma); // MA1ハンドルを解放
handle_ma = INVALID_HANDLE; // MA1ハンドルを無効化
}
}

// 新規作成
handle_ma2 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA2のハンドルを新規取得
handle_ma = iMA(_Symbol, _Period, sma_kikan, 0, method, PRICE_CLOSE); // MA1のハンドルを新規取得
}

void ma3_handle_koushin(int kikan) // MA3ハンドルの再作成・更新処理
{
ENUM_MA_METHOD method = MODE_SMA; // 移動平均の種類をSMAに初期化
if(ema_switch) method = MODE_EMA; // EMAモードならEMAに変更
if(handle_ma3 != INVALID_HANDLE) // 既存ハンドルが有効なら
{
IndicatorRelease(handle_ma3); // ハンドルを解放
handle_ma3 = INVALID_HANDLE; // 無効化
}
handle_ma3 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA3の新規ハンドル取得
}

void ma4_handle_koushin(int kikan) // MA4ハンドルの再作成・更新処理
{
ENUM_MA_METHOD method = MODE_SMA; // 移動平均の種類をSMAに初期化
if(ema_switch) method = MODE_EMA; // EMAモードならEMAに変更
if(handle_ma4 != INVALID_HANDLE) // 既存ハンドルが有効なら
{
IndicatorRelease(handle_ma4); // ハンドルを解放
handle_ma4 = INVALID_HANDLE; // 無効化
}
handle_ma4 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA4の新規ハンドル取得
}

void ma5_handle_koushin(int kikan) // MA5ハンドルの再作成・更新処理
{
ENUM_MA_METHOD method = MODE_SMA; // 移動平均の種類をSMAに初期化
if(ema_switch) method = MODE_EMA; // EMAモードならEMAに変更
if(handle_ma5 != INVALID_HANDLE) // 既存ハンドルが有効なら
{
IndicatorRelease(handle_ma5); // ハンドルを解放
handle_ma5 = INVALID_HANDLE; // 無効化
}
handle_ma5 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA5の新規ハンドル取得
}

void ma6_handle_koushin(int kikan) // MA6ハンドルの再作成・更新処理
{
ENUM_MA_METHOD method = MODE_SMA; // 移動平均の種類をSMAに初期化
if(ema_switch) method = MODE_EMA; // EMAモードならEMAに変更
if(handle_ma6 != INVALID_HANDLE) // 既存ハンドルが有効なら
{
IndicatorRelease(handle_ma6); // ハンドルを解放
handle_ma6 = INVALID_HANDLE; // 無効化
}
handle_ma6 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA6の新規ハンドル取得
}

void ma7_handle_koushin(int kikan) // MA7ハンドルの再作成・更新処理
{
ENUM_MA_METHOD method = MODE_SMA; // 移動平均の種類をSMAに初期化
if(ema_switch) method = MODE_EMA; // EMAモードならEMAに変更
if(handle_ma7 != INVALID_HANDLE) // 既存ハンドルが有効なら
{
IndicatorRelease(handle_ma7); // ハンドルを解放
handle_ma7 = INVALID_HANDLE; // 無効化
}
handle_ma7 = iMA(_Symbol, _Period, kikan, 0, method, PRICE_CLOSE); // MA7の新規ハンドル取得
}

//+——————————————————————+
//| Alertボタン作成 |
//+——————————————————————+
void alert_button_tsukuru() // Alert切り替えボタンを作成する関数
{
ObjectDelete(0, alert_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, alert_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, alert_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, alert_waku, OBJPROP_XDISTANCE, 85 + g_offsetX); // X座標をオフセット込みで設定
ObjectSetInteger(0, alert_waku, OBJPROP_YDISTANCE, 20 + g_offsetY); // Y座標をオフセット込みで設定
ObjectSetInteger(0, alert_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, alert_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, alert_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, alert_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, alert_waku, OBJPROP_BGCOLOR, alert_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, alert_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, alert_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, alert_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, alert_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, alert_moji, OBJPROP_XDISTANCE, 125 + g_offsetX); // 文字のX座標をオフセット込みで設定
ObjectSetInteger(0, alert_moji, OBJPROP_YDISTANCE, 32 + g_offsetY); // 文字のY座標をオフセット込みで設定
ObjectSetInteger(0, alert_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, alert_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, alert_moji, OBJPROP_TEXT, alert_switch ? “Alert” : “Alert”); // 表示するテキストを設定
}

//+——————————————————————+
//| Pushボタン作成(Alertの横) |
//+——————————————————————+
void push_button_tsukuru() // Push通知切り替えボタンを作成する関数
{
ObjectDelete(0, push_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, push_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, push_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定

// Alertボタンの右側に配置
ObjectSetInteger(0, push_waku, OBJPROP_XDISTANCE, 170 + g_offsetX); // X座標を設定
ObjectSetInteger(0, push_waku, OBJPROP_YDISTANCE, 20 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, push_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, push_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, push_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, push_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, push_waku, OBJPROP_BGCOLOR, push_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, push_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, push_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, push_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, push_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, push_moji, OBJPROP_XDISTANCE, 210 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, push_moji, OBJPROP_YDISTANCE, 32 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, push_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, push_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, push_moji, OBJPROP_TEXT, “Push”); // 表示するテキストを設定
}

// 追加:SMAボタン作成(Pushの横)
void sma_button_tsukuru() // SMA切り替えボタンを作成する関数
{
ObjectDelete(0, sma_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, sma_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, sma_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定

ObjectSetInteger(0, sma_waku, OBJPROP_XDISTANCE, 170 + g_offsetX); // X座標を設定
ObjectSetInteger(0, sma_waku, OBJPROP_YDISTANCE, 50 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, sma_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, sma_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, sma_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, sma_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, sma_waku, OBJPROP_BGCOLOR, sma_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, sma_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, sma_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, sma_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, sma_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, sma_moji, OBJPROP_XDISTANCE, 210 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, sma_moji, OBJPROP_YDISTANCE, 62 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, sma_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, sma_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, sma_moji, OBJPROP_TEXT, “SMA”); // 表示するテキストを設定
}

// 追加:EMAボタン作成(SMAの横)
void ema_button_tsukuru() // EMA切り替えボタンを作成する関数
{
ObjectDelete(0, ema_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, ema_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, ema_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定

ObjectSetInteger(0, ema_waku, OBJPROP_XDISTANCE, 255 + g_offsetX); // X座標を設定
ObjectSetInteger(0, ema_waku, OBJPROP_YDISTANCE, 50 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, ema_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, ema_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, ema_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, ema_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, ema_waku, OBJPROP_BGCOLOR, ema_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, ema_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, ema_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, ema_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, ema_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, ema_moji, OBJPROP_XDISTANCE, 295 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, ema_moji, OBJPROP_YDISTANCE, 62 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, ema_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, ema_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, ema_moji, OBJPROP_TEXT, “EMA”); // 表示するテキストを設定
}

void open_button_tsukuru() // Open/Closeパネル切り替えボタンを作成する関数
{
ObjectDelete(0, open_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, open_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, open_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, open_waku, OBJPROP_XDISTANCE, 0 + g_offsetX); // X座標を設定
ObjectSetInteger(0, open_waku, OBJPROP_YDISTANCE, 20 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, open_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, open_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, open_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, open_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, open_waku, OBJPROP_BGCOLOR, open_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, open_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, open_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, open_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, open_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, open_moji, OBJPROP_XDISTANCE, 40 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, open_moji, OBJPROP_YDISTANCE, 32 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, open_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, open_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, open_moji, OBJPROP_TEXT, open_switch ? “Close” : “Open”); // 状態に応じてテキストをOpen/Closeで切り替え
}

// 追加:KAKUTEIボタン作成(Openの横)
void kakutei_button_tsukuru() // KAKUTEI(確定足)ボタンを作成する関数
{
ObjectDelete(0, kakutei_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, kakutei_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, kakutei_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_XDISTANCE, 0 + g_offsetX); // X座標を設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_YDISTANCE, 50 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, kakutei_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, kakutei_waku, OBJPROP_BGCOLOR, kakutei_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, kakutei_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, kakutei_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, kakutei_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, kakutei_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, kakutei_moji, OBJPROP_XDISTANCE, 40 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, kakutei_moji, OBJPROP_YDISTANCE, 62 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, kakutei_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, kakutei_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, kakutei_moji, OBJPROP_TEXT, “KAKUTEI”); // 表示するテキストを設定
}

// 追加:MI-KAKUTEIボタン作成(KAKUTEIの横)
void mikakutei_button_tsukuru() // MI-KAKUTEI(未確定足)ボタンを作成する関数
{
ObjectDelete(0, mikakutei_waku); // 既存の枠オブジェクトを削除
ObjectCreate(0, mikakutei_waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, mikakutei_waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_XDISTANCE, 85 + g_offsetX); // X座標を設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_YDISTANCE, 50 + g_offsetY); // Y座標を設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_XSIZE, 80); // 横幅を設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_YSIZE, 24); // 高さを設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, mikakutei_waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, mikakutei_waku, OBJPROP_BGCOLOR, mikakutei_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に応じた背景色を設定

ObjectDelete(0, mikakutei_moji); // 既存の文字オブジェクトを削除
ObjectCreate(0, mikakutei_moji, OBJ_LABEL, 0, 0, 0); // 新しい文字ラベルオブジェクトを作成
ObjectSetInteger(0, mikakutei_moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー基準を左上に設定
ObjectSetInteger(0, mikakutei_moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // アンカーを中心位置に設定
ObjectSetInteger(0, mikakutei_moji, OBJPROP_XDISTANCE, 125 + g_offsetX); // 文字のX座標を設定
ObjectSetInteger(0, mikakutei_moji, OBJPROP_YDISTANCE, 62 + g_offsetY); // 文字のY座標を設定
ObjectSetInteger(0, mikakutei_moji, OBJPROP_FONTSIZE, 9); // 文字サイズを設定
ObjectSetInteger(0, mikakutei_moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, mikakutei_moji, OBJPROP_TEXT, “MI-KAKUTEI”); // 表示するテキストを設定
}

// — スライダー・カラーボタン共通関数 —
void common_slider_tsukuru(string haikei, string tsumami, string atai_label, string minus_btn, string plus_btn, int x, int y, int haba, int takasa, int tsumami_size, int &atai, int min_val, int max_val) // UIスライダーを生成する汎用関数
{
ObjectDelete(0, haikei); // 既存の背景オブジェクトを削除
ObjectDelete(0, tsumami); // 既存のつまみオブジェクトを削除
ObjectDelete(0, atai_label); // 既存の値ラベルオブジェクトを削除
ObjectDelete(0, minus_btn); // 既存のマイナスボタンを削除
ObjectDelete(0, plus_btn); // 既存のプラスボタンを削除

int draw_x = x + g_offsetX; // 実際の描画X座標を計算
int draw_y = y + g_offsetY; // 実際の描画Y座標を計算

ObjectCreate(0, haikei, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 背景となる枠を作成
ObjectSetInteger(0, haikei, OBJPROP_XDISTANCE, draw_x); // 背景のX座標を設定
ObjectSetInteger(0, haikei, OBJPROP_YDISTANCE, draw_y); // 背景のY座標を設定
ObjectSetInteger(0, haikei, OBJPROP_XSIZE, haba + tsumami_size); // 背景の横幅を設定
ObjectSetInteger(0, haikei, OBJPROP_YSIZE, takasa); // 背景の高さを設定
ObjectSetInteger(0, haikei, OBJPROP_BGCOLOR, IRO_SLIDER_HAIKEI); // 背景の色を設定
ObjectSetInteger(0, haikei, OBJPROP_BORDER_TYPE, BORDER_FLAT); // 背景をフラットデザインに設定
ObjectSetInteger(0, haikei, OBJPROP_CORNER, CORNER_LEFT_UPPER); // 背景の基準位置を左上に設定
ObjectSetInteger(0, haikei, OBJPROP_SELECTABLE, false); // 背景を選択不可に設定

ObjectCreate(0, tsumami, OBJ_BUTTON, 0, 0, 0); // つまみ用ボタンを作成
ObjectSetInteger(0, tsumami, OBJPROP_BORDER_COLOR, IRO_TSUMAMI); // つまみの枠線色を設定
int knobY = draw_y – (tsumami_size / 2) + (takasa / 2); // つまみのY座標を計算(中央揃え)
ObjectSetInteger(0, tsumami, OBJPROP_YDISTANCE, knobY); // つまみのY座標を設定
ObjectSetInteger(0, tsumami, OBJPROP_XSIZE, tsumami_size); // つまみの幅を設定
ObjectSetInteger(0, tsumami, OBJPROP_YSIZE, tsumami_size); // つまみの高さを設定
ObjectSetInteger(0, tsumami, OBJPROP_BGCOLOR, IRO_TSUMAMI); // つまみの背景色を設定
ObjectSetInteger(0, tsumami, OBJPROP_CORNER, CORNER_LEFT_UPPER); // つまみの基準位置を左上に設定
ObjectSetInteger(0, tsumami, OBJPROP_SELECTABLE, false); // つまみを選択不可に設定
ObjectSetInteger(0, tsumami, OBJPROP_ZORDER, 10); // つまみを前面に表示するようZオーダーを設定

ObjectCreate(0, atai_label, OBJ_BUTTON, 0, 0, 0); // 値表示用のラベルボタンを作成
ObjectSetInteger(0, atai_label, OBJPROP_XDISTANCE, draw_x + haba + tsumami_size + 30); // ラベルのX座標を設定
ObjectSetInteger(0, atai_label, OBJPROP_YDISTANCE, draw_y – 8); // ラベルのY座標を設定
ObjectSetInteger(0, atai_label, OBJPROP_XSIZE, 90); // ラベルの横幅を設定
ObjectSetInteger(0, atai_label, OBJPROP_YSIZE, 20); // ラベルの高さを設定
ObjectSetInteger(0, atai_label, OBJPROP_CORNER, CORNER_LEFT_UPPER); // ラベルの基準位置を左上に設定
ObjectSetInteger(0, atai_label, OBJPROP_BGCOLOR, IRO_LABEL_HAIKEI); // ラベルの背景色を設定
ObjectSetInteger(0, atai_label, OBJPROP_COLOR, IRO_UI_MOJI2); // ラベルの文字色を設定
ObjectSetInteger(0, atai_label, OBJPROP_BORDER_COLOR, clrWhite); // ラベルの枠線色を設定
ObjectSetInteger(0, atai_label, OBJPROP_FONTSIZE, 9); // ラベルの文字サイズを設定
ObjectSetInteger(0, atai_label, OBJPROP_SELECTABLE, false); // ラベルを選択不可に設定

ObjectCreate(0, minus_btn, OBJ_BUTTON, 0, 0, 0); // マイナスボタンを作成
ObjectSetInteger(0, minus_btn, OBJPROP_XDISTANCE, draw_x – 25); // マイナスボタンのX座標を設定
ObjectSetInteger(0, minus_btn, OBJPROP_YDISTANCE, draw_y – 8); // マイナスボタンのY座標を設定
ObjectSetInteger(0, minus_btn, OBJPROP_XSIZE, 20); // マイナスボタンの幅を設定
ObjectSetInteger(0, minus_btn, OBJPROP_YSIZE, 20); // マイナスボタンの高さを設定
ObjectSetInteger(0, minus_btn, OBJPROP_CORNER, CORNER_LEFT_UPPER); // マイナスボタンの基準位置を設定
ObjectSetInteger(0, minus_btn, OBJPROP_BGCOLOR, IRO_LABEL_HAIKEI); // マイナスボタンの背景色を設定
ObjectSetInteger(0, minus_btn, OBJPROP_COLOR, IRO_UI_MOJI2); // マイナスボタンの文字色を設定
ObjectSetInteger(0, minus_btn, OBJPROP_BORDER_COLOR, clrWhite); // マイナスボタンの枠線色を設定
ObjectSetInteger(0, minus_btn, OBJPROP_FONTSIZE, 11); // マイナスボタンのフォントサイズを設定
ObjectSetInteger(0, minus_btn, OBJPROP_SELECTABLE, false); // マイナスボタンを選択不可に設定
ObjectSetString (0, minus_btn, OBJPROP_TEXT, “-“); // マイナスボタンのテキストを「-」に設定

ObjectCreate(0, plus_btn, OBJ_BUTTON, 0, 0, 0); // プラスボタンを作成
ObjectSetInteger(0, plus_btn, OBJPROP_XDISTANCE, draw_x + haba + tsumami_size + 5); // プラスボタンのX座標を設定
ObjectSetInteger(0, plus_btn, OBJPROP_YDISTANCE, draw_y – 8); // プラスボタンのY座標を設定
ObjectSetInteger(0, plus_btn, OBJPROP_XSIZE, 20); // プラスボタンの幅を設定
ObjectSetInteger(0, plus_btn, OBJPROP_YSIZE, 20); // プラスボタンの高さを設定
ObjectSetInteger(0, plus_btn, OBJPROP_CORNER, CORNER_LEFT_UPPER); // プラスボタンの基準位置を設定
ObjectSetInteger(0, plus_btn, OBJPROP_BGCOLOR, IRO_LABEL_HAIKEI); // プラスボタンの背景色を設定
ObjectSetInteger(0, plus_btn, OBJPROP_COLOR, IRO_UI_MOJI2); // プラスボタンの文字色を設定
ObjectSetInteger(0, plus_btn, OBJPROP_BORDER_COLOR, clrWhite); // プラスボタンの枠線色を設定
ObjectSetInteger(0, plus_btn, OBJPROP_FONTSIZE, 11); // プラスボタンのフォントサイズを設定
ObjectSetInteger(0, plus_btn, OBJPROP_SELECTABLE, false); // プラスボタンを選択不可に設定
ObjectSetString (0, plus_btn, OBJPROP_TEXT, “+”); // プラスボタンのテキストを「+」に設定

if(atai < min_val) atai = min_val; // 初期値が最小値を下回る場合は最小値に補正 if(atai > max_val) atai = max_val; // 初期値が最大値を上回る場合は最大値に補正

int knobX = draw_x + (int)((double)haba * ((double)(atai – min_val) / (double)(max_val – min_val)) + 0.5); // 値からつまみのX座標を計算
ObjectSetInteger(0, tsumami, OBJPROP_XDISTANCE, knobX); // 計算した位置につまみを配置
}

void common_color_button_tsukuru(string waku, string moji, int x, int y, int haba, int tsumami_size, color bg_color) // ラインの色変更用ボタンを生成する汎用関数
{
ObjectDelete(0, waku); // 既存のカラー枠オブジェクトを削除

int draw_x = x + g_offsetX; // 描画X座標をオフセット込みで計算
int draw_y = y + g_offsetY; // 描画Y座標をオフセット込みで計算

ObjectCreate(0, waku, OBJ_RECTANGLE_LABEL, 0, 0, 0); // 新しい枠オブジェクトを作成
ObjectSetInteger(0, waku, OBJPROP_CORNER, CORNER_LEFT_UPPER); // 枠の基準位置を左上に設定
ObjectSetInteger(0, waku, OBJPROP_XDISTANCE, draw_x + haba + tsumami_size + 130); // 枠のX座標を設定
ObjectSetInteger(0, waku, OBJPROP_YDISTANCE, draw_y – 10); // 枠のY座標を設定
ObjectSetInteger(0, waku, OBJPROP_XSIZE, 40); // 枠の横幅を設定
ObjectSetInteger(0, waku, OBJPROP_YSIZE, 24); // 枠の高さを設定
ObjectSetInteger(0, waku, OBJPROP_COLOR, IRO_UI_WAKU); // 枠線の色を設定
ObjectSetInteger(0, waku, OBJPROP_BORDER_TYPE, BORDER_FLAT); // フラットデザインを適用
ObjectSetInteger(0, waku, OBJPROP_BGCOLOR, bg_color); // 渡された色を背景色として設定

ObjectDelete(0, moji); // 既存のカラー文字オブジェクトを削除
ObjectCreate(0, moji, OBJ_LABEL, 0, 0, 0); // 新しい文字オブジェクトを作成
ObjectSetInteger(0, moji, OBJPROP_CORNER, CORNER_LEFT_UPPER); // 文字の基準位置を左上に設定
ObjectSetInteger(0, moji, OBJPROP_ANCHOR, ANCHOR_CENTER); // 文字のアンカーを中心位置に設定
ObjectSetInteger(0, moji, OBJPROP_XDISTANCE, draw_x + haba + tsumami_size + 150); // 文字のX座標を設定
ObjectSetInteger(0, moji, OBJPROP_YDISTANCE, draw_y + 2); // 文字のY座標を設定
ObjectSetInteger(0, moji, OBJPROP_FONTSIZE, 9); // 文字のフォントサイズを設定
ObjectSetInteger(0, moji, OBJPROP_COLOR, IRO_UI_MOJI); // 文字色を設定
ObjectSetString (0, moji, OBJPROP_TEXT, “color”); // テキストを「color」に設定
}

void common_slider_koushin(string atai_label, string prefix, int &atai, int min_val, int max_val) // スライダーの値をUIラベルに反映する関数
{
if(atai < min_val) atai = min_val; // 値が下限未満の場合は下限に補正 if(atai > max_val) atai = max_val; // 値が上限を超過した場合は上限に補正
ObjectSetString(0, atai_label, OBJPROP_TEXT, prefix + (string)atai); // プレフィックスと値を結合してラベル文字列を更新
}

// — 各種スライダー・カラーボタン作成(共通関数呼び出し) —
void kikan_slider_tsukuru() { common_slider_tsukuru(kikan_slider_haikei, kikan_slider_tsumami, kikan_slider_atai_label, kikan_slider_minus, kikan_slider_plus, kikan_slider_x, kikan_slider_y, kikan_slider_haba, kikan_slider_takasa, kikan_slider_tsumami_size, kikan_slider_atai, 1, 200); } // MA1用スライダー作成のラッパー関数
void color_button_tsukuru() { common_color_button_tsukuru(color_waku, color_moji, kikan_slider_x, kikan_slider_y, kikan_slider_haba, kikan_slider_tsumami_size, ma_color_list[ma_color_index]); } // MA1用カラーボタン作成のラッパー関数
void kikan_slider_koushin() { common_slider_koushin(kikan_slider_atai_label, “MA: “, kikan_slider_atai, 1, 200); } // MA1スライダーの表示更新関数

void ma2_slider_tsukuru() { common_slider_tsukuru(ma2_slider_haikei, ma2_slider_tsumami, ma2_slider_atai_label, ma2_slider_minus, ma2_slider_plus, ma2_slider_x, ma2_slider_y, ma2_slider_haba, ma2_slider_takasa, ma2_slider_tsumami_size, ma2_slider_atai, 1, 200); } // MA2用スライダー作成のラッパー関数
void color2_button_tsukuru() { common_color_button_tsukuru(color2_waku, color2_moji, ma2_slider_x, ma2_slider_y, ma2_slider_haba, ma2_slider_tsumami_size, ma_color_list[ma2_color_index]); } // MA2用カラーボタン作成のラッパー関数
void ma2_slider_koushin() { common_slider_koushin(ma2_slider_atai_label, “MA2: “, ma2_slider_atai, 1, 200); } // MA2スライダーの表示更新関数

void ma3_slider_tsukuru() { common_slider_tsukuru(ma3_slider_haikei, ma3_slider_tsumami, ma3_slider_atai_label, ma3_slider_minus, ma3_slider_plus, ma3_slider_x, ma3_slider_y, ma3_slider_haba, ma3_slider_takasa, ma3_slider_tsumami_size, ma3_slider_atai, 1, 200); } // MA3用スライダー作成のラッパー関数
void color3_button_tsukuru() { common_color_button_tsukuru(color3_waku, color3_moji, ma3_slider_x, ma3_slider_y, ma3_slider_haba, ma3_slider_tsumami_size, ma_color_list[ma3_color_index]); } // MA3用カラーボタン作成のラッパー関数
void ma3_slider_koushin() { common_slider_koushin(ma3_slider_atai_label, “MA3: “, ma3_slider_atai, 1, 200); } // MA3スライダーの表示更新関数

void ma4_slider_tsukuru() { common_slider_tsukuru(ma4_slider_haikei, ma4_slider_tsumami, ma4_slider_atai_label, ma4_slider_minus, ma4_slider_plus, ma4_slider_x, ma4_slider_y, ma4_slider_haba, ma4_slider_takasa, ma4_slider_tsumami_size, ma4_slider_atai, 1, 200); } // MA4用スライダー作成のラッパー関数
void color4_button_tsukuru() { common_color_button_tsukuru(color4_waku, color4_moji, ma4_slider_x, ma4_slider_y, ma4_slider_haba, ma4_slider_tsumami_size, ma_color_list[ma4_color_index]); } // MA4用カラーボタン作成のラッパー関数
void ma4_slider_koushin() { common_slider_koushin(ma4_slider_atai_label, “MA4: “, ma4_slider_atai, 1, 200); } // MA4スライダーの表示更新関数

void ma5_slider_tsukuru() { common_slider_tsukuru(ma5_slider_haikei, ma5_slider_tsumami, ma5_slider_atai_label, ma5_slider_minus, ma5_slider_plus, ma5_slider_x, ma5_slider_y, ma5_slider_haba, ma5_slider_takasa, ma5_slider_tsumami_size, ma5_slider_atai, 1, 200); } // MA5用スライダー作成のラッパー関数
void color5_button_tsukuru() { common_color_button_tsukuru(color5_waku, color5_moji, ma5_slider_x, ma5_slider_y, ma5_slider_haba, ma5_slider_tsumami_size, ma_color_list[ma5_color_index]); } // MA5用カラーボタン作成のラッパー関数
void ma5_slider_koushin() { common_slider_koushin(ma5_slider_atai_label, “MA5: “, ma5_slider_atai, 1, 200); } // MA5スライダーの表示更新関数

void ma6_slider_tsukuru() { common_slider_tsukuru(ma6_slider_haikei, ma6_slider_tsumami, ma6_slider_atai_label, ma6_slider_minus, ma6_slider_plus, ma6_slider_x, ma6_slider_y, ma6_slider_haba, ma6_slider_takasa, ma6_slider_tsumami_size, ma6_slider_atai, 1, 200); } // MA6用スライダー作成のラッパー関数
void color6_button_tsukuru() { common_color_button_tsukuru(color6_waku, color6_moji, ma6_slider_x, ma6_slider_y, ma6_slider_haba, ma6_slider_tsumami_size, ma_color_list[ma6_color_index]); } // MA6用カラーボタン作成のラッパー関数
void ma6_slider_koushin() { common_slider_koushin(ma6_slider_atai_label, “MA6: “, ma6_slider_atai, 1, 200); } // MA6スライダーの表示更新関数

void ma7_slider_tsukuru() { common_slider_tsukuru(ma7_slider_haikei, ma7_slider_tsumami, ma7_slider_atai_label, ma7_slider_minus, ma7_slider_plus, ma7_slider_x, ma7_slider_y, ma7_slider_haba, ma7_slider_takasa, ma7_slider_tsumami_size, ma7_slider_atai, 1, 200); } // MA7用スライダー作成のラッパー関数
void color7_button_tsukuru() { common_color_button_tsukuru(color7_waku, color7_moji, ma7_slider_x, ma7_slider_y, ma7_slider_haba, ma7_slider_tsumami_size, ma_color_list[ma7_color_index]); } // MA7用カラーボタン作成のラッパー関数
void ma7_slider_koushin() { common_slider_koushin(ma7_slider_atai_label, “MA7: “, ma7_slider_atai, 1, 200); } // MA7スライダーの表示更新関数

void repeat_slider_tsukuru() { common_slider_tsukuru(repeat_slider_haikei, repeat_slider_tsumami, repeat_slider_atai_label, repeat_slider_minus, repeat_slider_plus, repeat_slider_x, repeat_slider_y, repeat_slider_haba, repeat_slider_takasa, repeat_slider_tsumami_size, repeat_slider_atai, 0, 50); } // リピート用スライダー作成のラッパー関数
void repeat_slider_koushin() { common_slider_koushin(repeat_slider_atai_label, “Repeat: “, repeat_slider_atai, 0, 50); } // リピートスライダーの表示更新関数

void open_igai_kesu() // パネルがCloseの時にOpenボタン以外のUIを非表示にする関数
{
ObjectDelete(0, alert_waku); // Alert枠を削除
ObjectDelete(0, alert_moji); // Alert文字を削除
ObjectDelete(0, push_waku); // Push枠を削除
ObjectDelete(0, push_moji); // Push文字を削除
ObjectDelete(0, kakutei_waku); // KAKUTEI枠を削除
ObjectDelete(0, kakutei_moji); // KAKUTEI文字を削除
ObjectDelete(0, mikakutei_waku); // MI-KAKUTEI枠を削除
ObjectDelete(0, mikakutei_moji); // MI-KAKUTEI文字を削除

// 追加:SMA/EMAボタン削除
ObjectDelete(0, sma_waku); // SMAボタン枠を削除
ObjectDelete(0, sma_moji); // SMAボタン文字を削除
ObjectDelete(0, ema_waku); // EMAボタン枠を削除
ObjectDelete(0, ema_moji); // EMAボタン文字を削除

ObjectDelete(0, kikan_slider_haikei); // MA1スライダーの背景を削除
ObjectDelete(0, kikan_slider_tsumami); // MA1スライダーのつまみを削除
ObjectDelete(0, kikan_slider_atai_label); // MA1スライダーの値ラベルを削除
ObjectDelete(0, kikan_slider_minus); // MA1スライダーのマイナスボタンを削除
ObjectDelete(0, kikan_slider_plus); // MA1スライダーのプラスボタンを削除
ObjectDelete(0, color_waku); // MA1カラーボタンの枠を削除
ObjectDelete(0, color_moji); // MA1カラーボタンの文字を削除

// ★追加:MA2スライダー削除
ObjectDelete(0, ma2_slider_haikei); // MA2スライダーの背景を削除
ObjectDelete(0, ma2_slider_tsumami); // MA2スライダーのつまみを削除
ObjectDelete(0, ma2_slider_atai_label); // MA2スライダーの値ラベルを削除
ObjectDelete(0, ma2_slider_minus); // MA2スライダーのマイナスボタンを削除
ObjectDelete(0, ma2_slider_plus); // MA2スライダーのプラスボタンを削除
ObjectDelete(0, color2_waku); // MA2カラーボタンの枠を削除
ObjectDelete(0, color2_moji); // MA2カラーボタンの文字を削除

// MA3~7スライダー削除
ObjectDelete(0, ma3_slider_haikei); ObjectDelete(0, ma3_slider_tsumami); ObjectDelete(0, ma3_slider_atai_label); ObjectDelete(0, ma3_slider_minus); ObjectDelete(0, ma3_slider_plus); ObjectDelete(0, color3_waku); ObjectDelete(0, color3_moji); // MA3コンポーネントを削除
ObjectDelete(0, ma4_slider_haikei); ObjectDelete(0, ma4_slider_tsumami); ObjectDelete(0, ma4_slider_atai_label); ObjectDelete(0, ma4_slider_minus); ObjectDelete(0, ma4_slider_plus); ObjectDelete(0, color4_waku); ObjectDelete(0, color4_moji); // MA4コンポーネントを削除
ObjectDelete(0, ma5_slider_haikei); ObjectDelete(0, ma5_slider_tsumami); ObjectDelete(0, ma5_slider_atai_label); ObjectDelete(0, ma5_slider_minus); ObjectDelete(0, ma5_slider_plus); ObjectDelete(0, color5_waku); ObjectDelete(0, color5_moji); // MA5コンポーネントを削除
ObjectDelete(0, ma6_slider_haikei); ObjectDelete(0, ma6_slider_tsumami); ObjectDelete(0, ma6_slider_atai_label); ObjectDelete(0, ma6_slider_minus); ObjectDelete(0, ma6_slider_plus); ObjectDelete(0, color6_waku); ObjectDelete(0, color6_moji); // MA6コンポーネントを削除
ObjectDelete(0, ma7_slider_haikei); ObjectDelete(0, ma7_slider_tsumami); ObjectDelete(0, ma7_slider_atai_label); ObjectDelete(0, ma7_slider_minus); ObjectDelete(0, ma7_slider_plus); ObjectDelete(0, color7_waku); ObjectDelete(0, color7_moji); // MA7コンポーネントを削除

ObjectDelete(0, repeat_slider_haikei); // リピートスライダー背景を削除
ObjectDelete(0, repeat_slider_tsumami); // リピートスライダーつまみを削除
ObjectDelete(0, repeat_slider_atai_label); // リピートスライダー値ラベルを削除
ObjectDelete(0, repeat_slider_minus); // リピートスライダーマイナスボタンを削除
ObjectDelete(0, repeat_slider_plus); // リピートスライダープラスボタンを削除

ChartSetInteger(0, CHART_MOUSE_SCROLL, true); // パネルを閉じたらマウススクロールを有効に戻す
ChartRedraw(); // チャート画面を再描画して変更を反映
}

void zenbu_hyouji() // パネルがOpenの時にすべてのUIコンポーネントを表示する関数
{
open_button_tsukuru(); // Open/Closeボタンを描画
kakutei_button_tsukuru(); // 確定足ボタンを描画
mikakutei_button_tsukuru(); // 未確定足ボタンを描画
alert_button_tsukuru(); // アラートボタンを描画
push_button_tsukuru(); // プッシュ通知ボタンを描画

// 追加:SMA/EMAボタンを作る
sma_button_tsukuru(); // SMAボタンを描画
ema_button_tsukuru(); // EMAボタンを描画

kikan_slider_tsukuru(); // MA1スライダーの構成要素を描画
kikan_slider_koushin(); // MA1スライダーの表示値を更新
color_button_tsukuru(); // MA1カラーボタンを描画

// ユーザーが選択したMAの表示本数に応じてスライダーとボタンを描画
if(InpMACount >= 2) { ma2_slider_tsukuru(); ma2_slider_koushin(); color2_button_tsukuru(); } // 2本以上ならMA2UIを描画
if(InpMACount >= 3) { ma3_slider_tsukuru(); ma3_slider_koushin(); color3_button_tsukuru(); } // 3本以上ならMA3UIを描画
if(InpMACount >= 4) { ma4_slider_tsukuru(); ma4_slider_koushin(); color4_button_tsukuru(); } // 4本以上ならMA4UIを描画
if(InpMACount >= 5) { ma5_slider_tsukuru(); ma5_slider_koushin(); color5_button_tsukuru(); } // 5本以上ならMA5UIを描画
if(InpMACount >= 6) { ma6_slider_tsukuru(); ma6_slider_koushin(); color6_button_tsukuru(); } // 6本以上ならMA6UIを描画
if(InpMACount >= 7) { ma7_slider_tsukuru(); ma7_slider_koushin(); color7_button_tsukuru(); } // 7本ならMA7UIを描画

repeat_slider_tsukuru(); // リピートスライダーを描画
repeat_slider_koushin(); // リピートスライダーの表示値を更新

ChartRedraw(); // チャート画面を再描画して変更を反映
}
//+——————————————————————+
//| 初期化 |
//+——————————————————————+
int OnInit() // インジケーター起動時の初期化処理
{
// Y座標の動的再計算(Repeatスライダーを詰める)
repeat_slider_y = kikan_slider_y + (InpMACount * 30); // 表示するMA本数に応じてリピートスライダーのY座標を動的に調整

// ★オフセットの初回計算
CalcOffset(); // チャートサイズに基づきUIの基準座標を計算

// ★追加:保存済みのUI状態を復元(無ければ従来の初期値を使う)
bool has_saved = ui_state_load(); // グローバル変数から状態の読み込みを試行

if(!has_saved) // 保存されたデータが存在しなかった場合(初回起動など)
{
kikan_slider_atai = 20; // MA1スライダーの表示初期値を20に設定
kikan_slider_kotei_atai = 20; // MA1の適用初期値を20に設定
sma_kikan = 20; // MA1の計算期間を20に設定

ma2_slider_atai = 50; // MA2スライダーの表示初期値を50に設定
ma2_slider_kotei_atai = 50; // MA2の適用初期値を50に設定
ma2_kikan = 50; // MA2の計算期間を50に設定

ma3_slider_atai = 75; ma3_slider_kotei_atai = 75; ma3_kikan = 75; // MA3の初期値をそれぞれ75に設定
ma4_slider_atai = 100; ma4_slider_kotei_atai = 100; ma4_kikan = 100; // MA4の初期値をそれぞれ100に設定
ma5_slider_atai = 125; ma5_slider_kotei_atai = 125; ma5_kikan = 125; // MA5の初期値をそれぞれ125に設定
ma6_slider_atai = 150; ma6_slider_kotei_atai = 150; ma6_kikan = 150; // MA6の初期値をそれぞれ150に設定
ma7_slider_atai = 200; ma7_slider_kotei_atai = 200; ma7_kikan = 200; // MA7の初期値をそれぞれ200に設定

repeat_slider_atai = 0; // リピートスライダーの表示初期値を0に設定
repeat_slider_kotei_atai = 0; // リピートスライダーの適用初期値を0に設定
}

ma_handle_koushin(sma_kikan); // MA1のインジケーターハンドルを取得
ma2_handle_koushin(ma2_kikan); // MA2のインジケーターハンドルを取得
ma3_handle_koushin(ma3_kikan); // MA3のインジケーターハンドルを取得
ma4_handle_koushin(ma4_kikan); // MA4のインジケーターハンドルを取得
ma5_handle_koushin(ma5_kikan); // MA5のインジケーターハンドルを取得
ma6_handle_koushin(ma6_kikan); // MA6のインジケーターハンドルを取得
ma7_handle_koushin(ma7_kikan); // MA7のインジケーターハンドルを取得

if(handle_ma == INVALID_HANDLE || handle_ma2 == INVALID_HANDLE || handle_ma3 == INVALID_HANDLE || handle_ma4 == INVALID_HANDLE || handle_ma5 == INVALID_HANDLE || handle_ma6 == INVALID_HANDLE || handle_ma7 == INVALID_HANDLE) // いずれかのハンドル取得に失敗した場合
{
return(INIT_FAILED); // 初期化エラーを返してインジケーターを終了
}

ArraySetAsSeries(sign_buffer, true); // 上向きサインバッファを時系列(最新がインデックス0)に設定
ArraySetAsSeries(sign_dn_buffer, true); // 下向きサインバッファを時系列(最新がインデックス0)に設定
ArraySetAsSeries(ma_buffer, true); // MA1バッファを時系列に設定
ArraySetAsSeries(ma2_buffer, true); // MA2バッファを時系列に設定
ArraySetAsSeries(ma3_buffer, true); // MA3バッファを時系列に設定
ArraySetAsSeries(ma4_buffer, true); // MA4バッファを時系列に設定
ArraySetAsSeries(ma5_buffer, true); // MA5バッファを時系列に設定
ArraySetAsSeries(ma6_buffer, true); // MA6バッファを時系列に設定
ArraySetAsSeries(ma7_buffer, true); // MA7バッファを時系列に設定

SetIndexBuffer(0, sign_buffer, INDICATOR_DATA); // バッファ番号0に上向きサイン配列を割り当て
SetIndexBuffer(8, sign_dn_buffer, INDICATOR_DATA); // バッファ番号8に下向きサイン配列を割り当て
SetIndexBuffer(1, ma_buffer, INDICATOR_DATA); // バッファ番号1にMA1配列を割り当て
SetIndexBuffer(2, ma2_buffer, INDICATOR_DATA); // バッファ番号2にMA2配列を割り当て
SetIndexBuffer(3, ma3_buffer, INDICATOR_DATA); // バッファ番号3にMA3配列を割り当て
SetIndexBuffer(4, ma4_buffer, INDICATOR_DATA); // バッファ番号4にMA4配列を割り当て
SetIndexBuffer(5, ma5_buffer, INDICATOR_DATA); // バッファ番号5にMA5配列を割り当て
SetIndexBuffer(6, ma6_buffer, INDICATOR_DATA); // バッファ番号6にMA6配列を割り当て
SetIndexBuffer(7, ma7_buffer, INDICATOR_DATA); // バッファ番号7にMA7配列を割り当て

ArrayInitialize(sign_buffer, EMPTY_VALUE); // 上向きサインバッファを空値で初期化
ArrayInitialize(sign_dn_buffer, EMPTY_VALUE); // 下向きサインバッファを空値で初期化
// ma_bufferは自動描画されるのでInitialize不要(CopyBufferで上書きされるため)

PlotIndexSetInteger(0, PLOT_ARROW, 233); // 上向きサインの矢印コード(233)を設定
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); // バッファ0の空値を定義
PlotIndexSetInteger(8, PLOT_ARROW, 234); // 下向きサインの矢印コード(234)を設定
PlotIndexSetDouble(8, PLOT_EMPTY_VALUE, EMPTY_VALUE); // バッファ8の空値を定義
PlotIndexSetInteger(1, PLOT_LINE_COLOR, ma_color_list[ma_color_index]); // MA1の初期描画色を反映
PlotIndexSetInteger(2, PLOT_LINE_COLOR, ma_color_list[ma2_color_index]); // MA2の初期描画色を反映
PlotIndexSetInteger(3, PLOT_LINE_COLOR, ma_color_list[ma3_color_index]); // MA3の初期描画色を反映
PlotIndexSetInteger(4, PLOT_LINE_COLOR, ma_color_list[ma4_color_index]); // MA4の初期描画色を反映
PlotIndexSetInteger(5, PLOT_LINE_COLOR, ma_color_list[ma5_color_index]); // MA5の初期描画色を反映
PlotIndexSetInteger(6, PLOT_LINE_COLOR, ma_color_list[ma6_color_index]); // MA6の初期描画色を反映
PlotIndexSetInteger(7, PLOT_LINE_COLOR, ma_color_list[ma7_color_index]); // MA7の初期描画色を反映

// ★追加:起動時にMAの線の太さを反映
PlotIndexSetInteger(1, PLOT_LINE_WIDTH, InpMAWidth); // MA1の描画の太さを反映
PlotIndexSetInteger(2, PLOT_LINE_WIDTH, InpMAWidth); // MA2の描画の太さを反映
PlotIndexSetInteger(3, PLOT_LINE_WIDTH, InpMAWidth); // MA3の描画の太さを反映
PlotIndexSetInteger(4, PLOT_LINE_WIDTH, InpMAWidth); // MA4の描画の太さを反映
PlotIndexSetInteger(5, PLOT_LINE_WIDTH, InpMAWidth); // MA5の描画の太さを反映
PlotIndexSetInteger(6, PLOT_LINE_WIDTH, InpMAWidth); // MA6の描画の太さを反映
PlotIndexSetInteger(7, PLOT_LINE_WIDTH, InpMAWidth); // MA7の描画の太さを反映

// 表示本数に満たないMAはチャートに描画しない
PlotIndexSetInteger(7, PLOT_DRAW_TYPE, InpMACount >= 7 ? DRAW_LINE : DRAW_NONE); // 表示本数が7未満ならMA7を非表示
PlotIndexSetInteger(6, PLOT_DRAW_TYPE, InpMACount >= 6 ? DRAW_LINE : DRAW_NONE); // 表示本数が6未満ならMA6を非表示
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, InpMACount >= 5 ? DRAW_LINE : DRAW_NONE); // 表示本数が5未満ならMA5を非表示
PlotIndexSetInteger(4, PLOT_DRAW_TYPE, InpMACount >= 4 ? DRAW_LINE : DRAW_NONE); // 表示本数が4未満ならMA4を非表示
PlotIndexSetInteger(3, PLOT_DRAW_TYPE, InpMACount >= 3 ? DRAW_LINE : DRAW_NONE); // 表示本数が3未満ならMA3を非表示
PlotIndexSetInteger(2, PLOT_DRAW_TYPE, InpMACount >= 2 ? DRAW_LINE : DRAW_NONE); // 表示本数が2未満ならMA2を非表示

open_button_tsukuru(); // UIパネル開閉用ボタンを構築
if(open_switch) // 初期状態でパネルがOpenになっている場合
{
zenbu_hyouji(); // すべてのUI要素を画面に描画
}
else // 初期状態でパネルがCloseになっている場合
{
open_igai_kesu(); // Openボタン以外の不要なUI要素を隠す
}

ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); // チャート上でのマウス移動イベントの検知を有効化

datetime Kidoku_Time = iTime(_Symbol, _Period, 1); // 現在のチャートにおける1つ前のローソク足の確定時間を取得
last_alert_time = Kidoku_Time; // アラート多重発報を防ぐための最終通知時刻にセット

// ★追加:起動時点の状態を保存(初回でも以後維持されるように)
ui_state_save(); // 初期化完了時点でのUI設定値をグローバル変数へ保存
mae_no_kikan = (int)_Period; // 時間足変更検知用として現在の時間足を記録

return(INIT_SUCCEEDED); // 初期化が正常に完了したことを返す
}

//+——————————————————————+
//| クリックイベント |
//+——————————————————————+
void OnChartEvent(const int id, const long &l, const double &d, const string &s) // ユーザーの各種操作イベントを受け取る関数
{
// ★追加:チャートサイズの変更を検知してレイアウトを更新
if(id == CHARTEVENT_CHART_CHANGE) // ウィンドウサイズが変更された場合
{
CalcOffset(); // UI配置のためのオフセットを再計算
if(open_switch) zenbu_hyouji(); // パネルが開いていればすべてのUIを再描画
else // パネルが閉じていれば
{
open_button_tsukuru(); // 開閉ボタンのみ再作成
open_igai_kesu(); // その他のUI要素を非表示に
}
ChartRedraw(); // チャートを再描画して反映
return; // 処理を終了
}

// Open OFF中は、Openボタン以外のイベントは無視
if(!open_switch) // パネルが閉じている場合
{
if(id == CHARTEVENT_OBJECT_CLICK && (s == open_waku || s == open_moji)) // ユーザーが開閉ボタンをクリックした場合
{
open_switch = true; // 開閉状態を「開」に変更
CalcOffset(); // パネル展開時の高さでオフセットを再計算
ObjectSetInteger(0, open_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_ON); // ボタンの背景色をアクティブ色に変更
ObjectSetString (0, open_moji, OBJPROP_TEXT, “Close”); // ボタンの文字を「Close」に変更
zenbu_hyouji(); // パネル内の全UIコンポーネントを描画
ui_state_save(); // 変更された状態をグローバル変数に保存
}
return; // 以降の操作判定は不要なため終了
}

// —- スライダー(ドラッグ) —-
if(id == CHARTEVENT_MOUSE_MOVE) // マウスのポインターが移動した場合
{
int x = (int)l; // マウスの現在のX座標を取得
int y = (int)d; // マウスの現在のY座標を取得
int mouseState = (int)StringToInteger(s); // マウスのボタン状態(左クリック押下など)を取得

int margin = 10; // 当たり判定に余裕を持たせるための余白ピクセル数

int draw_kikan_x = kikan_slider_x + g_offsetX; // MA1スライダーの実際のX座標
int draw_kikan_y = kikan_slider_y + g_offsetY; // MA1スライダーの実際のY座標
int draw_ma2_x = ma2_slider_x + g_offsetX; // MA2スライダーの実際のX座標
int draw_ma2_y = ma2_slider_y + g_offsetY; // MA2スライダーの実際のY座標
int draw_ma3_x = ma3_slider_x + g_offsetX; // MA3スライダーの実際のX座標
int draw_ma3_y = ma3_slider_y + g_offsetY; // MA3スライダーの実際のY座標
int draw_ma4_x = ma4_slider_x + g_offsetX; // MA4スライダーの実際のX座標
int draw_ma4_y = ma4_slider_y + g_offsetY; // MA4スライダーの実際のY座標
int draw_ma5_x = ma5_slider_x + g_offsetX; // MA5スライダーの実際のX座標
int draw_ma5_y = ma5_slider_y + g_offsetY; // MA5スライダーの実際のY座標
int draw_ma6_x = ma6_slider_x + g_offsetX; // MA6スライダーの実際のX座標
int draw_ma6_y = ma6_slider_y + g_offsetY; // MA6スライダーの実際のY座標
int draw_ma7_x = ma7_slider_x + g_offsetX; // MA7スライダーの実際のX座標
int draw_ma7_y = ma7_slider_y + g_offsetY; // MA7スライダーの実際のY座標
int draw_repeat_x = repeat_slider_x + g_offsetX; // リピートスライダーの実際のX座標
int draw_repeat_y = repeat_slider_y + g_offsetY; // リピートスライダーの実際のY座標

bool hover3 = (x >= draw_kikan_x – margin && x <= draw_kikan_x + kikan_slider_haba + kikan_slider_tsumami_size + margin && y >= draw_kikan_y – margin && y <= draw_kikan_y + kikan_slider_takasa + margin); // MA1スライダー上にマウスがあるか判定 bool hover_ma2 = (InpMACount >= 2 && x >= draw_ma2_x – margin && x <= draw_ma2_x + ma2_slider_haba + ma2_slider_tsumami_size + margin && y >= draw_ma2_y – margin && y <= draw_ma2_y + ma2_slider_takasa + margin); // MA2スライダー上にマウスがあるか判定 bool hover_ma3 = (InpMACount >= 3 && x >= draw_ma3_x – margin && x <= draw_ma3_x + ma3_slider_haba + ma3_slider_tsumami_size + margin && y >= draw_ma3_y – margin && y <= draw_ma3_y + ma3_slider_takasa + margin); // MA3スライダー上にマウスがあるか判定 bool hover_ma4 = (InpMACount >= 4 && x >= draw_ma4_x – margin && x <= draw_ma4_x + ma4_slider_haba + ma4_slider_tsumami_size + margin && y >= draw_ma4_y – margin && y <= draw_ma4_y + ma4_slider_takasa + margin); // MA4スライダー上にマウスがあるか判定 bool hover_ma5 = (InpMACount >= 5 && x >= draw_ma5_x – margin && x <= draw_ma5_x + ma5_slider_haba + ma5_slider_tsumami_size + margin && y >= draw_ma5_y – margin && y <= draw_ma5_y + ma5_slider_takasa + margin); // MA5スライダー上にマウスがあるか判定 bool hover_ma6 = (InpMACount >= 6 && x >= draw_ma6_x – margin && x <= draw_ma6_x + ma6_slider_haba + ma6_slider_tsumami_size + margin && y >= draw_ma6_y – margin && y <= draw_ma6_y + ma6_slider_takasa + margin); // MA6スライダー上にマウスがあるか判定 bool hover_ma7 = (InpMACount >= 7 && x >= draw_ma7_x – margin && x <= draw_ma7_x + ma7_slider_haba + ma7_slider_tsumami_size + margin && y >= draw_ma7_y – margin && y <= draw_ma7_y + ma7_slider_takasa + margin); // MA7スライダー上にマウスがあるか判定 bool hover4 = (x >= draw_repeat_x – margin && x <= draw_repeat_x + repeat_slider_haba + repeat_slider_tsumami_size + margin && y >= draw_repeat_y – margin && y <= draw_repeat_y + repeat_slider_takasa + margin); // リピートスライダー上にマウスがあるか判定 bool isAnyHover = (hover3 || hover_ma2 || hover_ma3 || hover_ma4 || hover_ma5 || hover_ma6 || hover_ma7 || hover4); // いずれかのスライダー領域にマウスが乗っているか bool isAnyDragging = (kikan_slider_drag_chu || ma2_slider_drag_chu || ma3_slider_drag_chu || ma4_slider_drag_chu || ma5_slider_drag_chu || ma6_slider_drag_chu || ma7_slider_drag_chu || repeat_slider_drag_chu); // いずれかのスライダーを現在ドラッグ中か if(isAnyHover || isAnyDragging) // スライダー領域にいる、またはドラッグ中の場合 { ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // 誤操作を防ぐためチャートのスクロールを無効化 } else // スライダー操作範囲外の場合 { ChartSetInteger(0, CHART_MOUSE_SCROLL, true); // チャートのスクロールを有効に戻す } if((mouseState & 1) == 1) // 左クリックが押されている状態の場合 { if(!kikan_slider_drag_chu && !ma2_slider_drag_chu && !ma3_slider_drag_chu && !ma4_slider_drag_chu && !ma5_slider_drag_chu && !ma6_slider_drag_chu && !ma7_slider_drag_chu && !repeat_slider_drag_chu) // まだどのスライダーもドラッグ開始判定されていない場合 { long knobX2 = ObjectGetInteger(0, kikan_slider_tsumami, OBJPROP_XDISTANCE); // MA1のつまみの現在のX座標を取得 long knobY2 = ObjectGetInteger(0, kikan_slider_tsumami, OBJPROP_YDISTANCE); // MA1のつまみの現在のY座標を取得 long knobX_ma2 = ObjectGetInteger(0, ma2_slider_tsumami, OBJPROP_XDISTANCE); // MA2のつまみの現在のX座標を取得 long knobY_ma2 = ObjectGetInteger(0, ma2_slider_tsumami, OBJPROP_YDISTANCE); // MA2のつまみの現在のY座標を取得 long knobX_ma3 = ObjectGetInteger(0, ma3_slider_tsumami, OBJPROP_XDISTANCE); // MA3のつまみの現在のX座標を取得 long knobY_ma3 = ObjectGetInteger(0, ma3_slider_tsumami, OBJPROP_YDISTANCE); // MA3のつまみの現在のY座標を取得 long knobX_ma4 = ObjectGetInteger(0, ma4_slider_tsumami, OBJPROP_XDISTANCE); // MA4のつまみの現在のX座標を取得 long knobY_ma4 = ObjectGetInteger(0, ma4_slider_tsumami, OBJPROP_YDISTANCE); // MA4のつまみの現在のY座標を取得 long knobX_ma5 = ObjectGetInteger(0, ma5_slider_tsumami, OBJPROP_XDISTANCE); // MA5のつまみの現在のX座標を取得 long knobY_ma5 = ObjectGetInteger(0, ma5_slider_tsumami, OBJPROP_YDISTANCE); // MA5のつまみの現在のY座標を取得 long knobX_ma6 = ObjectGetInteger(0, ma6_slider_tsumami, OBJPROP_XDISTANCE); // MA6のつまみの現在のX座標を取得 long knobY_ma6 = ObjectGetInteger(0, ma6_slider_tsumami, OBJPROP_YDISTANCE); // MA6のつまみの現在のY座標を取得 long knobX_ma7 = ObjectGetInteger(0, ma7_slider_tsumami, OBJPROP_XDISTANCE); // MA7のつまみの現在のX座標を取得 long knobY_ma7 = ObjectGetInteger(0, ma7_slider_tsumami, OBJPROP_YDISTANCE); // MA7のつまみの現在のY座標を取得 long knobX3 = ObjectGetInteger(0, repeat_slider_tsumami, OBJPROP_XDISTANCE); // リピートのつまみの現在のX座標を取得 long knobY3 = ObjectGetInteger(0, repeat_slider_tsumami, OBJPROP_YDISTANCE); // リピートのつまみの現在のY座標を取得 if(x >= knobX2 && x <= knobX2 + kikan_slider_tsumami_size && y >= knobY2 && y <= knobY2 + kikan_slider_tsumami_size) // マウス座標がMA1のつまみ内にあるか判定 { kikan_slider_drag_chu = true; // MA1のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // 操作前のチャートスクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 2 && x >= knobX_ma2 && x <= knobX_ma2 + ma2_slider_tsumami_size && y >= knobY_ma2 && y <= knobY_ma2 + ma2_slider_tsumami_size) // MA2のつまみがクリックされたか判定 { ma2_slider_drag_chu = true; // MA2のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 3 && x >= knobX_ma3 && x <= knobX_ma3 + ma3_slider_tsumami_size && y >= knobY_ma3 && y <= knobY_ma3 + ma3_slider_tsumami_size) // MA3のつまみがクリックされたか判定 { ma3_slider_drag_chu = true; // MA3のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 4 && x >= knobX_ma4 && x <= knobX_ma4 + ma4_slider_tsumami_size && y >= knobY_ma4 && y <= knobY_ma4 + ma4_slider_tsumami_size) // MA4のつまみがクリックされたか判定 { ma4_slider_drag_chu = true; // MA4のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 5 && x >= knobX_ma5 && x <= knobX_ma5 + ma5_slider_tsumami_size && y >= knobY_ma5 && y <= knobY_ma5 + ma5_slider_tsumami_size) // MA5のつまみがクリックされたか判定 { ma5_slider_drag_chu = true; // MA5のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 6 && x >= knobX_ma6 && x <= knobX_ma6 + ma6_slider_tsumami_size && y >= knobY_ma6 && y <= knobY_ma6 + ma6_slider_tsumami_size) // MA6のつまみがクリックされたか判定 { ma6_slider_drag_chu = true; // MA6のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(InpMACount >= 7 && x >= knobX_ma7 && x <= knobX_ma7 + ma7_slider_tsumami_size && y >= knobY_ma7 && y <= knobY_ma7 + ma7_slider_tsumami_size) // MA7のつまみがクリックされたか判定 { ma7_slider_drag_chu = true; // MA7のドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } else if(x >= knobX3 && x <= knobX3 + repeat_slider_tsumami_size && y >= knobY3 && y <= knobY3 + repeat_slider_tsumami_size) // リピートのつまみがクリックされたか判定 { repeat_slider_drag_chu = true; // リピートのドラッグフラグをオン mouse_scroll_mae = (bool)ChartGetInteger(0, CHART_MOUSE_SCROLL); // スクロール状態を記録 ChartSetInteger(0, CHART_MOUSE_SCROLL, false); // チャートスクロールを無効化 } } if(kikan_slider_drag_chu) // MA1のスライダーをドラッグして動かしている場合 { int draw_x = kikan_slider_x + g_offsetX; // スライダー背景の左端のX座標 int newX = x - (kikan_slider_tsumami_size / 2); // マウス位置が中心になるように新しいつまみのX座標を計算 if(newX < draw_x) newX = draw_x; // つまみがスライダーの左端を越えないように固定 if(newX > draw_x + kikan_slider_haba) newX = draw_x + kikan_slider_haba; // つまみがスライダーの右端を越えないように固定

ObjectSetInteger(0, kikan_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみのオブジェクトを新しい位置へ移動

double percent = (double)(newX – draw_x) / (double)kikan_slider_haba; // 現在のつまみ位置が全体の何パーセントか算出
// 1~200に変換
int newVal = 1 + (int)(percent * 199.0 + 0.5); // パーセント値から設定値(1〜200)を逆算

if(newVal < 1) newVal = 1; // 計算結果が1未満なら1に制限 if(newVal > 200) newVal = 200; // 計算結果が200超過なら200に制限

if(kikan_slider_atai != newVal) // ドラッグによって値に変化があった場合
{
kikan_slider_atai = newVal; // スライダーの表示値を更新
kikan_slider_koushin(); // 表示ラベルのテキストを更新
ChartRedraw(); // オブジェクト移動を画面に反映
ui_state_save(); // 変更されたUI状態を保存
}
}
else if(ma2_slider_drag_chu) // MA2スライダーをドラッグ中なら
{
int draw_x = ma2_slider_x + g_offsetX; // MA2スライダーの左端X座標
int newX = x – (ma2_slider_tsumami_size / 2); // マウスに合わせたつまみ中心のX座標

if(newX < draw_x) newX = draw_x; // 左端超過を防止 if(newX > draw_x + ma2_slider_haba) newX = draw_x + ma2_slider_haba; // 右端超過を防止

ObjectSetInteger(0, ma2_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみの表示位置を更新

double percent = (double)(newX – draw_x) / (double)ma2_slider_haba; // 移動割合を計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 1~200の範囲で値を算出

if(newVal < 1) newVal = 1; // 最小値ガード if(newVal > 200) newVal = 200; // 最大値ガード

if(ma2_slider_atai != newVal) // 値が変化した場合
{
ma2_slider_atai = newVal; // 値を更新
ma2_slider_koushin(); // ラベルを更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態を保存
}
}
else if(ma3_slider_drag_chu) // MA3スライダーをドラッグ中の場合
{
int draw_x = ma3_slider_x + g_offsetX; // MA3スライダー左端
int newX = x – (ma3_slider_tsumami_size / 2); // 新しいX座標計算
if(newX < draw_x) newX = draw_x; // 下限ガード if(newX > draw_x + ma3_slider_haba) newX = draw_x + ma3_slider_haba; // 上限ガード
ObjectSetInteger(0, ma3_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみ移動
double percent = (double)(newX – draw_x) / (double)ma3_slider_haba; // 割合計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 値計算
if(newVal < 1) newVal = 1; // 最小値補正 if(newVal > 200) newVal = 200; // 最大値補正
if(ma3_slider_atai != newVal) // 変化があれば
{
ma3_slider_atai = newVal; // 値更新
ma3_slider_koushin(); // 表示更新
ChartRedraw(); // 画面更新
ui_state_save(); // 状態保存
}
}
else if(ma4_slider_drag_chu) // MA4スライダーをドラッグ中の場合
{
int draw_x = ma4_slider_x + g_offsetX; // MA4スライダー左端
int newX = x – (ma4_slider_tsumami_size / 2); // 新しいX座標計算
if(newX < draw_x) newX = draw_x; // 下限ガード if(newX > draw_x + ma4_slider_haba) newX = draw_x + ma4_slider_haba; // 上限ガード
ObjectSetInteger(0, ma4_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみ移動
double percent = (double)(newX – draw_x) / (double)ma4_slider_haba; // 割合計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 値計算
if(newVal < 1) newVal = 1; // 最小値補正 if(newVal > 200) newVal = 200; // 最大値補正
if(ma4_slider_atai != newVal) // 変化があれば
{
ma4_slider_atai = newVal; // 値更新
ma4_slider_koushin(); // 表示更新
ChartRedraw(); // 画面更新
ui_state_save(); // 状態保存
}
}
else if(ma5_slider_drag_chu) // MA5スライダーをドラッグ中の場合
{
int draw_x = ma5_slider_x + g_offsetX; // MA5スライダー左端
int newX = x – (ma5_slider_tsumami_size / 2); // 新しいX座標計算
if(newX < draw_x) newX = draw_x; // 下限ガード if(newX > draw_x + ma5_slider_haba) newX = draw_x + ma5_slider_haba; // 上限ガード
ObjectSetInteger(0, ma5_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみ移動
double percent = (double)(newX – draw_x) / (double)ma5_slider_haba; // 割合計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 値計算
if(newVal < 1) newVal = 1; // 最小値補正 if(newVal > 200) newVal = 200; // 最大値補正
if(ma5_slider_atai != newVal) // 変化があれば
{
ma5_slider_atai = newVal; // 値更新
ma5_slider_koushin(); // 表示更新
ChartRedraw(); // 画面更新
ui_state_save(); // 状態保存
}
}
else if(ma6_slider_drag_chu) // MA6スライダーをドラッグ中の場合
{
int draw_x = ma6_slider_x + g_offsetX; // MA6スライダー左端
int newX = x – (ma6_slider_tsumami_size / 2); // 新しいX座標計算
if(newX < draw_x) newX = draw_x; // 下限ガード if(newX > draw_x + ma6_slider_haba) newX = draw_x + ma6_slider_haba; // 上限ガード
ObjectSetInteger(0, ma6_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみ移動
double percent = (double)(newX – draw_x) / (double)ma6_slider_haba; // 割合計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 値計算
if(newVal < 1) newVal = 1; // 最小値補正 if(newVal > 200) newVal = 200; // 最大値補正
if(ma6_slider_atai != newVal) // 変化があれば
{
ma6_slider_atai = newVal; // 値更新
ma6_slider_koushin(); // 表示更新
ChartRedraw(); // 画面更新
ui_state_save(); // 状態保存
}
}
else if(ma7_slider_drag_chu) // MA7スライダーをドラッグ中の場合
{
int draw_x = ma7_slider_x + g_offsetX; // MA7スライダー左端
int newX = x – (ma7_slider_tsumami_size / 2); // 新しいX座標計算
if(newX < draw_x) newX = draw_x; // 下限ガード if(newX > draw_x + ma7_slider_haba) newX = draw_x + ma7_slider_haba; // 上限ガード
ObjectSetInteger(0, ma7_slider_tsumami, OBJPROP_XDISTANCE, newX); // つまみ移動
double percent = (double)(newX – draw_x) / (double)ma7_slider_haba; // 割合計算
int newVal = 1 + (int)(percent * 199.0 + 0.5); // 値計算
if(newVal < 1) newVal = 1; // 最小値補正 if(newVal > 200) newVal = 200; // 最大値補正
if(ma7_slider_atai != newVal) // 変化があれば
{
ma7_slider_atai = newVal; // 値更新
ma7_slider_koushin(); // 表示更新
ChartRedraw(); // 画面更新
ui_state_save(); // 状態保存
}
}
else if(repeat_slider_drag_chu) // リピートスライダーをドラッグ中なら
{
int draw_x = repeat_slider_x + g_offsetX; // リピートスライダー左端
int newX = x – (repeat_slider_tsumami_size / 2); // つまみ中心座標

if(newX < draw_x) newX = draw_x; // 左側ガード if(newX > draw_x + repeat_slider_haba) newX = draw_x + repeat_slider_haba; // 右側ガード

ObjectSetInteger(0, repeat_slider_tsumami, OBJPROP_XDISTANCE, newX); // オブジェクト移動

double percent = (double)(newX – draw_x) / (double)repeat_slider_haba; // 進捗パーセントを計算
int newVal = (int)(percent * 50.0 + 0.5); // 0~50にスケール変換

if(newVal < 0) newVal = 0; // 下限ガード if(newVal > 50) newVal = 50; // 上限ガード

if(repeat_slider_atai != newVal) // 表示値が変わった場合
{
repeat_slider_atai = newVal; // 変数更新
repeat_slider_koushin(); // 表示更新
ChartRedraw(); // 描画
ui_state_save(); // 状態を保存
}
}
}
else // 左クリックを離した状態(ドラッグ終了)
{
if(kikan_slider_drag_chu) // MA1スライダーのドラッグが終了した瞬間
{
kikan_slider_drag_chu = false; // ドラッグフラグをオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // 無効化していたスクロールを元に戻す

if(kikan_slider_kotei_atai != kikan_slider_atai) // ドラッグ前と値が異なる場合(本当に変更された場合)
{
kikan_slider_kotei_atai = kikan_slider_atai; // 確定値を更新
sma_kikan = kikan_slider_kotei_atai; // 実際の計算用変数を更新

ma_handle_koushin(sma_kikan); // 新しい期間でMA1のハンドルを再作成

zenbu_keisan = true; // MAが変わったので過去のサインをすべて再計算するフラグを立てる
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日設定がオンならチャート更新をトリガー
}

ChartRedraw(); // 変更を画面に反映
ui_state_save(); // 確定した状態を保存
}
else if(ma2_slider_drag_chu) // MA2スライダーのドラッグが終了した瞬間
{
ma2_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復元

if(ma2_slider_kotei_atai != ma2_slider_atai) // 確定値と表示値が異なる場合
{
ma2_slider_kotei_atai = ma2_slider_atai; // 確定値更新
ma2_kikan = ma2_slider_kotei_atai; // 計算用変数更新

ma2_handle_koushin(ma2_kikan); // ハンドル再作成(MA2)

zenbu_keisan = true; // 全計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理トリガー
}

ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(ma3_slider_drag_chu) // MA3スライダーのドラッグが終了した場合
{
ma3_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰
if(ma3_slider_kotei_atai != ma3_slider_atai) // 変更があった場合
{
ma3_slider_kotei_atai = ma3_slider_atai; // 確定値更新
ma3_kikan = ma3_slider_kotei_atai; // 計算値更新
ma3_handle_koushin(ma3_kikan); // ハンドル再取得
zenbu_keisan = true; // 再計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
}
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(ma4_slider_drag_chu) // MA4スライダーのドラッグが終了した場合
{
ma4_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰
if(ma4_slider_kotei_atai != ma4_slider_atai) // 変更があった場合
{
ma4_slider_kotei_atai = ma4_slider_atai; // 確定値更新
ma4_kikan = ma4_slider_kotei_atai; // 計算値更新
ma4_handle_koushin(ma4_kikan); // ハンドル再取得
zenbu_keisan = true; // 再計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
}
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(ma5_slider_drag_chu) // MA5スライダーのドラッグが終了した場合
{
ma5_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰
if(ma5_slider_kotei_atai != ma5_slider_atai) // 変更があった場合
{
ma5_slider_kotei_atai = ma5_slider_atai; // 確定値更新
ma5_kikan = ma5_slider_kotei_atai; // 計算値更新
ma5_handle_koushin(ma5_kikan); // ハンドル再取得
zenbu_keisan = true; // 再計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
}
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(ma6_slider_drag_chu) // MA6スライダーのドラッグが終了した場合
{
ma6_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰
if(ma6_slider_kotei_atai != ma6_slider_atai) // 変更があった場合
{
ma6_slider_kotei_atai = ma6_slider_atai; // 確定値更新
ma6_kikan = ma6_slider_kotei_atai; // 計算値更新
ma6_handle_koushin(ma6_kikan); // ハンドル再取得
zenbu_keisan = true; // 再計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
}
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(ma7_slider_drag_chu) // MA7スライダーのドラッグが終了した場合
{
ma7_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰
if(ma7_slider_kotei_atai != ma7_slider_atai) // 変更があった場合
{
ma7_slider_kotei_atai = ma7_slider_atai; // 確定値更新
ma7_kikan = ma7_slider_kotei_atai; // 計算値更新
ma7_handle_koushin(ma7_kikan); // ハンドル再取得
zenbu_keisan = true; // 再計算フラグオン
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
}
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
else if(repeat_slider_drag_chu) // リピートスライダーのドラッグが終了した瞬間
{
repeat_slider_drag_chu = false; // フラグオフ
ChartSetInteger(0, CHART_MOUSE_SCROLL, mouse_scroll_mae); // スクロール復帰

if(repeat_slider_kotei_atai != repeat_slider_atai) // 変更があった場合
{
repeat_slider_kotei_atai = repeat_slider_atai; // 確定値更新
zenbu_keisan = true; // リピート処理のため全計算要求
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理トリガー
}

ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
}
}
return; // マウス移動イベントの処理はここまで
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == kikan_slider_minus || s == kikan_slider_plus)) // MA1スライダーのプラス・マイナスボタンがクリックされた場合
{
if(s == kikan_slider_minus) kikan_slider_atai–; // マイナスボタンなら値を1減らす
if(s == kikan_slider_plus) kikan_slider_atai++; // プラスボタンなら値を1増やす

if(kikan_slider_atai < 1) kikan_slider_atai = 1; // 最小値ガード if(kikan_slider_atai > 200) kikan_slider_atai = 200; // 最大値ガード

int draw_x = kikan_slider_x + g_offsetX; // つまみの起点X座標
int knobX = draw_x + (int)((double)kikan_slider_haba * ((double)(kikan_slider_atai – 1) / 199.0) + 0.5); // 値に合わせた新しいつまみ位置を計算
ObjectSetInteger(0, kikan_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみを移動
kikan_slider_koushin(); // ラベル文字を更新

kikan_slider_kotei_atai = kikan_slider_atai; // 確定値を直ちに更新
sma_kikan = kikan_slider_kotei_atai; // 計算用変数を更新

ma_handle_koushin(sma_kikan); // 新しい期間でMA1ハンドルを更新

zenbu_keisan = true; // 期間変更に伴い全再計算を要求
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理トリガー
ChartRedraw(); // 画面を更新
ui_state_save(); // 状態を保存
return; // クリック処理終了
}

if(InpMACount >= 2 && id == CHARTEVENT_OBJECT_CLICK && (s == ma2_slider_minus || s == ma2_slider_plus)) // MA2スライダーの増減ボタンがクリックされた場合
{
if(s == ma2_slider_minus) ma2_slider_atai–; // 減算
if(s == ma2_slider_plus) ma2_slider_atai++; // 加算

if(ma2_slider_atai < 1) ma2_slider_atai = 1; // 下限 if(ma2_slider_atai > 200) ma2_slider_atai = 200; // 上限

int draw_x = ma2_slider_x + g_offsetX; // 描画基点
int knobX = draw_x + (int)((double)ma2_slider_haba * ((double)(ma2_slider_atai – 1) / 199.0) + 0.5); // 座標計算
ObjectSetInteger(0, ma2_slider_tsumami, OBJPROP_XDISTANCE, knobX); // 移動
ma2_slider_koushin(); // 文字更新

ma2_slider_kotei_atai = ma2_slider_atai; // 確定値同期
ma2_kikan = ma2_slider_kotei_atai; // 計算値同期

ma2_handle_koushin(ma2_kikan); // MA2ハンドル更新

zenbu_keisan = true; // 再計算
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日処理
ChartRedraw(); // 描画
ui_state_save(); // 保存
return; // 処理終了
}

if(InpMACount >= 3 && id == CHARTEVENT_OBJECT_CLICK && (s == ma3_slider_minus || s == ma3_slider_plus)) // MA3スライダーの増減ボタンクリック時処理
{
if(s == ma3_slider_minus) ma3_slider_atai–; // 減算
if(s == ma3_slider_plus) ma3_slider_atai++; // 加算
if(ma3_slider_atai < 1) ma3_slider_atai = 1; // 下限チェック if(ma3_slider_atai > 200) ma3_slider_atai = 200; // 上限チェック
int draw_x = ma3_slider_x + g_offsetX; // X座標基準
int knobX = draw_x + (int)((double)ma3_slider_haba * ((double)(ma3_slider_atai – 1) / 199.0) + 0.5); // つまみX座標
ObjectSetInteger(0, ma3_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみ移動
ma3_slider_koushin(); // ラベル更新
ma3_slider_kotei_atai = ma3_slider_atai; // 確定値反映
ma3_kikan = ma3_slider_kotei_atai; // 計算値反映
ma3_handle_koushin(ma3_kikan); // ハンドル更新
zenbu_keisan = true; // 再計算フラグ
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 再描画
ui_state_save(); // 保存
return; // 終了
}

if(InpMACount >= 4 && id == CHARTEVENT_OBJECT_CLICK && (s == ma4_slider_minus || s == ma4_slider_plus)) // MA4スライダーの増減ボタンクリック時処理
{
if(s == ma4_slider_minus) ma4_slider_atai–; // 減算
if(s == ma4_slider_plus) ma4_slider_atai++; // 加算
if(ma4_slider_atai < 1) ma4_slider_atai = 1; // 下限チェック if(ma4_slider_atai > 200) ma4_slider_atai = 200; // 上限チェック
int draw_x = ma4_slider_x + g_offsetX; // X座標基準
int knobX = draw_x + (int)((double)ma4_slider_haba * ((double)(ma4_slider_atai – 1) / 199.0) + 0.5); // つまみX座標
ObjectSetInteger(0, ma4_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみ移動
ma4_slider_koushin(); // ラベル更新
ma4_slider_kotei_atai = ma4_slider_atai; // 確定値反映
ma4_kikan = ma4_slider_kotei_atai; // 計算値反映
ma4_handle_koushin(ma4_kikan); // ハンドル更新
zenbu_keisan = true; // 再計算フラグ
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 再描画
ui_state_save(); // 保存
return; // 終了
}

if(InpMACount >= 5 && id == CHARTEVENT_OBJECT_CLICK && (s == ma5_slider_minus || s == ma5_slider_plus)) // MA5スライダーの増減ボタンクリック時処理
{
if(s == ma5_slider_minus) ma5_slider_atai–; // 減算
if(s == ma5_slider_plus) ma5_slider_atai++; // 加算
if(ma5_slider_atai < 1) ma5_slider_atai = 1; // 下限チェック if(ma5_slider_atai > 200) ma5_slider_atai = 200; // 上限チェック
int draw_x = ma5_slider_x + g_offsetX; // X座標基準
int knobX = draw_x + (int)((double)ma5_slider_haba * ((double)(ma5_slider_atai – 1) / 199.0) + 0.5); // つまみX座標
ObjectSetInteger(0, ma5_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみ移動
ma5_slider_koushin(); // ラベル更新
ma5_slider_kotei_atai = ma5_slider_atai; // 確定値反映
ma5_kikan = ma5_slider_kotei_atai; // 計算値反映
ma5_handle_koushin(ma5_kikan); // ハンドル更新
zenbu_keisan = true; // 再計算フラグ
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 再描画
ui_state_save(); // 保存
return; // 終了
}

if(InpMACount >= 6 && id == CHARTEVENT_OBJECT_CLICK && (s == ma6_slider_minus || s == ma6_slider_plus)) // MA6スライダーの増減ボタンクリック時処理
{
if(s == ma6_slider_minus) ma6_slider_atai–; // 減算
if(s == ma6_slider_plus) ma6_slider_atai++; // 加算
if(ma6_slider_atai < 1) ma6_slider_atai = 1; // 下限チェック if(ma6_slider_atai > 200) ma6_slider_atai = 200; // 上限チェック
int draw_x = ma6_slider_x + g_offsetX; // X座標基準
int knobX = draw_x + (int)((double)ma6_slider_haba * ((double)(ma6_slider_atai – 1) / 199.0) + 0.5); // つまみX座標
ObjectSetInteger(0, ma6_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみ移動
ma6_slider_koushin(); // ラベル更新
ma6_slider_kotei_atai = ma6_slider_atai; // 確定値反映
ma6_kikan = ma6_slider_kotei_atai; // 計算値反映
ma6_handle_koushin(ma6_kikan); // ハンドル更新
zenbu_keisan = true; // 再計算フラグ
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 再描画
ui_state_save(); // 保存
return; // 終了
}

if(InpMACount >= 7 && id == CHARTEVENT_OBJECT_CLICK && (s == ma7_slider_minus || s == ma7_slider_plus)) // MA7スライダーの増減ボタンクリック時処理
{
if(s == ma7_slider_minus) ma7_slider_atai–; // 減算
if(s == ma7_slider_plus) ma7_slider_atai++; // 加算
if(ma7_slider_atai < 1) ma7_slider_atai = 1; // 下限チェック if(ma7_slider_atai > 200) ma7_slider_atai = 200; // 上限チェック
int draw_x = ma7_slider_x + g_offsetX; // X座標基準
int knobX = draw_x + (int)((double)ma7_slider_haba * ((double)(ma7_slider_atai – 1) / 199.0) + 0.5); // つまみX座標
ObjectSetInteger(0, ma7_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみ移動
ma7_slider_koushin(); // ラベル更新
ma7_slider_kotei_atai = ma7_slider_atai; // 確定値反映
ma7_kikan = ma7_slider_kotei_atai; // 計算値反映
ma7_handle_koushin(ma7_kikan); // ハンドル更新
zenbu_keisan = true; // 再計算フラグ
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 再描画
ui_state_save(); // 保存
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == repeat_slider_minus || s == repeat_slider_plus)) // リピートスライダーの増減ボタンがクリックされた場合
{
if(s == repeat_slider_minus) repeat_slider_atai–; // 減算
if(s == repeat_slider_plus) repeat_slider_atai++; // 加算

if(repeat_slider_atai < 0) repeat_slider_atai = 0; // 下限0 if(repeat_slider_atai > 50) repeat_slider_atai = 50; // 上限50

int draw_x = repeat_slider_x + g_offsetX; // つまみX基点
int knobX = draw_x + (int)((double)repeat_slider_haba * ((double)(repeat_slider_atai) / 50.0) + 0.5); // 座表計算
ObjectSetInteger(0, repeat_slider_tsumami, OBJPROP_XDISTANCE, knobX); // つまみを移動
repeat_slider_koushin(); // 表示ラベル更新

repeat_slider_kotei_atai = repeat_slider_atai; // 確定値に同期

zenbu_keisan = true; // サイン間引き計算のため全計算要求
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 土日更新
ChartRedraw(); // 描画
ui_state_save(); // 状態を保存
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == open_waku || s == open_moji)) // Openボタン(現在はCloseと表示)がクリックされた場合
{
open_switch = false; // 開閉状態を「閉」に設定
CalcOffset(); // 閉じた状態の高さでオフセット再計算
open_button_tsukuru(); // オフセットに基づき開閉ボタンのみ作り直し
ObjectSetString (0, open_moji, OBJPROP_TEXT, “Open”); // ボタン文字を「Open」に戻す
open_igai_kesu(); // その他のUI要素を削除(非表示)
ui_state_save(); // パネル閉鎖状態を保存
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == alert_waku || s == alert_moji)) // Alertボタンがクリックされた場合
{
alert_switch = !alert_switch; // アラートのオンオフ状態を反転

ObjectSetString (0, alert_moji, OBJPROP_TEXT, alert_switch ? “Alert” : “Alert”); // テキストはそのまま
ObjectSetInteger(0, alert_waku, OBJPROP_BGCOLOR, alert_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 状態に合わせて背景色を変更

datetime Last_Close_Time = iTime(_Symbol, _Period, 1); // 直前の確定足の時刻を取得
if(Last_Close_Time > 0) // 時刻が正常に取得できた場合
{
last_alert_time = Last_Close_Time; // ボタン操作時点で過去のサインとして既読扱いにする
}

if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // チャート更新トリガー
ChartRedraw(); // 色変更を反映
ui_state_save(); // アラート設定状態を保存
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == kakutei_waku || s == kakutei_moji)) // KAKUTEI(確定足)ボタンがクリックされた場合
{
if(!kakutei_switch) // 現在が未確定足モードだった場合
{
kakutei_switch = true; // 確定足モードをオンに
mikakutei_switch = false; // 未確定足モードをオフに(排他制御)

ObjectSetInteger(0, kakutei_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_ON); // KAKUTEIボタンをアクティブ色に
ObjectSetInteger(0, mikakutei_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_OFF); // MI-KAKUTEIボタンを非アクティブ色に

zenbu_keisan = true; // サイン表示位置が変わるため全再計算を要求
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 更新トリガー
ChartRedraw(); // 色・サイン変更を反映
ui_state_save(); // モード状態を保存
}
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == mikakutei_waku || s == mikakutei_moji)) // MI-KAKUTEI(未確定足)ボタンがクリックされた場合
{
if(!mikakutei_switch) // 現在が確定足モードだった場合
{
mikakutei_switch = true; // 未確定足モードをオンに
kakutei_switch = false; // 確定足モードをオフに(排他制御)

ObjectSetInteger(0, mikakutei_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_ON); // MI-KAKUTEIボタンをアクティブ色に
ObjectSetInteger(0, kakutei_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_OFF); // KAKUTEIボタンを非アクティブ色に

zenbu_keisan = true; // サイン表示位置が変わるため全再計算を要求
if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 更新トリガー
ChartRedraw(); // 反映
ui_state_save(); // 状態を保存
}
return; // 終了
}

if(id == CHARTEVENT_OBJECT_CLICK && (s == push_waku || s == push_moji)) // Pushボタンがクリックされた場合
{
push_switch = !push_switch; // Push通知のオンオフを反転

ObjectSetString (0, push_moji, OBJPROP_TEXT, “Push”); // テキストはそのまま
ObjectSetInteger(0, push_waku, OBJPROP_BGCOLOR, push_switch ? IRO_UI_HAIKEI_ON : IRO_UI_HAIKEI_OFF); // 背景色を反転

datetime Last_Close_Time = iTime(_Symbol, _Period, 1); // 既読処理用時刻取得
if(Last_Close_Time > 0) // 正常取得確認
{
last_alert_time = Last_Close_Time; // 過去の通知を発報しないよう既読処理
}

if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 更新トリガー
ChartRedraw(); // 反映
ui_state_save(); // 状態保存
return; // 終了
}

// ★追加:Colorボタンクリック処理
if(id == CHARTEVENT_OBJECT_CLICK && (s == color_waku || s == color_moji)) // MA1のカラーボタンがクリックされた場合
{
ma_color_index++; // カラー配列のインデックスを1進める
if(ma_color_index > 6) ma_color_index = 0; // 配列外(7以上)になったら0(最初の色)に戻す

ObjectSetInteger(0, color_waku, OBJPROP_BGCOLOR, ma_color_list[ma_color_index]); // UIボタンの背景色を選択色に変更
PlotIndexSetInteger(1, PLOT_LINE_COLOR, ma_color_list[ma_color_index]); // 実際のインジケーターMA1の描画色を変更

ChartRedraw(); // チャートに新しい色を反映
ui_state_save(); // カラー状態を保存
return; // 終了
}

// ★追加:Color2ボタン(MA2用)クリック処理
if(InpMACount >= 2 && id == CHARTEVENT_OBJECT_CLICK && (s == color2_waku || s == color2_moji)) // MA2のカラーボタンがクリックされた場合
{
ma2_color_index++; // MA2用のカラーインデックスを進める
if(ma2_color_index > 6) ma2_color_index = 0; // ループ処理

ObjectSetInteger(0, color2_waku, OBJPROP_BGCOLOR, ma_color_list[ma2_color_index]); // ボタンの色を更新
PlotIndexSetInteger(2, PLOT_LINE_COLOR, ma_color_list[ma2_color_index]); // MA2の描画色を更新

ChartRedraw(); // 描画反映
ui_state_save(); // カラー状態保存
return; // 終了
}

if(InpMACount >= 3 && id == CHARTEVENT_OBJECT_CLICK && (s == color3_waku || s == color3_moji)) // MA3のカラーボタンがクリックされた場合
{
ma3_color_index++; // カラーインデックス進行
if(ma3_color_index > 6) ma3_color_index = 0; // ループ処理
ObjectSetInteger(0, color3_waku, OBJPROP_BGCOLOR, ma_color_list[ma3_color_index]); // ボタン色更新
PlotIndexSetInteger(3, PLOT_LINE_COLOR, ma_color_list[ma3_color_index]); // ライン色更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
return; // 終了
}

if(InpMACount >= 4 && id == CHARTEVENT_OBJECT_CLICK && (s == color4_waku || s == color4_moji)) // MA4のカラーボタンクリック時処理
{
ma4_color_index++; // カラーインデックス進行
if(ma4_color_index > 6) ma4_color_index = 0; // ループ処理
ObjectSetInteger(0, color4_waku, OBJPROP_BGCOLOR, ma_color_list[ma4_color_index]); // ボタン色更新
PlotIndexSetInteger(4, PLOT_LINE_COLOR, ma_color_list[ma4_color_index]); // ライン色更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
return; // 終了
}

if(InpMACount >= 5 && id == CHARTEVENT_OBJECT_CLICK && (s == color5_waku || s == color5_moji)) // MA5のカラーボタンクリック時処理
{
ma5_color_index++; // カラーインデックス進行
if(ma5_color_index > 6) ma5_color_index = 0; // ループ処理
ObjectSetInteger(0, color5_waku, OBJPROP_BGCOLOR, ma_color_list[ma5_color_index]); // ボタン色更新
PlotIndexSetInteger(5, PLOT_LINE_COLOR, ma_color_list[ma5_color_index]); // ライン色更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
return; // 終了
}

if(InpMACount >= 6 && id == CHARTEVENT_OBJECT_CLICK && (s == color6_waku || s == color6_moji)) // MA6のカラーボタンクリック時処理
{
ma6_color_index++; // カラーインデックス進行
if(ma6_color_index > 6) ma6_color_index = 0; // ループ処理
ObjectSetInteger(0, color6_waku, OBJPROP_BGCOLOR, ma_color_list[ma6_color_index]); // ボタン色更新
PlotIndexSetInteger(6, PLOT_LINE_COLOR, ma_color_list[ma6_color_index]); // ライン色更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
return; // 終了
}

if(InpMACount >= 7 && id == CHARTEVENT_OBJECT_CLICK && (s == color7_waku || s == color7_moji)) // MA7のカラーボタンクリック時処理
{
ma7_color_index++; // カラーインデックス進行
if(ma7_color_index > 6) ma7_color_index = 0; // ループ処理
ObjectSetInteger(0, color7_waku, OBJPROP_BGCOLOR, ma_color_list[ma7_color_index]); // ボタン色更新
PlotIndexSetInteger(7, PLOT_LINE_COLOR, ma_color_list[ma7_color_index]); // ライン色更新
ChartRedraw(); // 再描画
ui_state_save(); // 状態保存
return; // 終了
}

// SMAボタンクリック処理(MA~MA7同時切替)
if(id == CHARTEVENT_OBJECT_CLICK && (s == sma_waku || s == sma_moji)) // SMA切り替えボタンがクリックされた場合
{
if(!sma_switch) // 現在がEMAモードだった場合
{
sma_switch = true; // SMAモードをオンに
ema_switch = false; // EMAモードをオフに(排他制御)

ObjectSetInteger(0, sma_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_ON); // SMAボタンをアクティブ色に
ObjectSetInteger(0, ema_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_OFF); // EMAボタンを非アクティブ色に

ma_handle_koushin(sma_kikan); // MA1ハンドルをSMAで再作成
ma2_handle_koushin(ma2_kikan); // MA2ハンドルをSMAで再作成
ma3_handle_koushin(ma3_kikan); // MA3ハンドルをSMAで再作成
ma4_handle_koushin(ma4_kikan); // MA4ハンドルをSMAで再作成
ma5_handle_koushin(ma5_kikan); // MA5ハンドルをSMAで再作成
ma6_handle_koushin(ma6_kikan); // MA6ハンドルをSMAで再作成
ma7_handle_koushin(ma7_kikan); // MA7ハンドルをSMAで再作成
zenbu_keisan = true; // 計算種別が変わるため全再計算フラグを立てる

if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 更新トリガー
ChartRedraw(); // 描画反映
ui_state_save(); // 状態保存
}
return; // 終了
}

// EMAボタンクリック処理(MA~MA7同時切替)
if(id == CHARTEVENT_OBJECT_CLICK && (s == ema_waku || s == ema_moji)) // EMA切り替えボタンがクリックされた場合
{
if(!ema_switch) // 現在がSMAモードだった場合
{
ema_switch = true; // EMAモードをオンに
sma_switch = false; // SMAモードをオフに(排他制御)

ObjectSetInteger(0, ema_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_ON); // EMAボタンをアクティブ色に
ObjectSetInteger(0, sma_waku, OBJPROP_BGCOLOR, IRO_UI_HAIKEI_OFF); // SMAボタンを非アクティブ色に

ma_handle_koushin(sma_kikan); // MA1ハンドルをEMAで再作成
ma2_handle_koushin(ma2_kikan); // MA2ハンドルをEMAで再作成
ma3_handle_koushin(ma3_kikan); // MA3ハンドルをEMAで再作成
ma4_handle_koushin(ma4_kikan); // MA4ハンドルをEMAで再作成
ma5_handle_koushin(ma5_kikan); // MA5ハンドルをEMAで再作成
ma6_handle_koushin(ma6_kikan); // MA6ハンドルをEMAで再作成
ma7_handle_koushin(ma7_kikan); // MA7ハンドルをEMAで再作成
zenbu_keisan = true; // 計算種別が変わるため全再計算フラグを立てる

if(donichi) ChartSetSymbolPeriod(0, _Symbol, Period()); // 更新トリガー
ChartRedraw(); // 描画反映
ui_state_save(); // 状態保存
}
return; // 終了
}
}

//+——————————————————————+
//| メイン処理 |
//+——————————————————————+
int OnCalculate(const int rates_total, // チャート上の全ローソク足の本数
const int prev_calculated, // 前回までに計算が完了したバーの本数
const datetime &time[], // 各バーの開始時刻を保持する配列
const double &open[], // 各バーの始値を保持する配列
const double &high[], // 各バーの高値を保持する配列
const double &low[], // 各バーの安値を保持する配列
const double &close[], // 各バーの終値を保持する配列
const long &tick_volume[], // 各バーのティックボリューム
const long &volume[], // 各バーのリアルボリューム
const int &spread[]) // 各バーのスプレッド
{

if(mae_no_kikan != (int)_Period) // 時間足が変更されたことを検知した場合
{
mae_no_kikan = (int)_Period; // 現在の時間足を新しい前回の時間足として記憶

// ★保存されている確定値で作り直す
ma_handle_koushin(sma_kikan); // MA1ハンドルを現在のパラメータで再作成
ma2_handle_koushin(ma2_kikan); // MA2ハンドルを現在のパラメータで再作成
ma3_handle_koushin(ma3_kikan); // MA3ハンドルを現在のパラメータで再作成
ma4_handle_koushin(ma4_kikan); // MA4ハンドルを現在のパラメータで再作成
ma5_handle_koushin(ma5_kikan); // MA5ハンドルを現在のパラメータで再作成
ma6_handle_koushin(ma6_kikan); // MA6ハンドルを現在のパラメータで再作成
ma7_handle_koushin(ma7_kikan); // MA7ハンドルを現在のパラメータで再作成

heikin_keisan_zumi = false; // 時間足が変わったためローソク足の平均サイズ計算をやり直すフラグを立てる
zenbu_keisan = true; // 時間足が変わったため全ローソク足の再計算を要求

datetime t = iTime(_Symbol, _Period, 1); // 変更後時間足の1本前の確定時刻を取得
if(t > 0) last_alert_time = t; // 多重通知防止のため最終通知時刻を更新
}

// 1. サーバーとの同期が完了していない(読み込み中)なら計算しない(ヒストリ対策:起動時の安全性確保)
if(SeriesInfoInteger(_Symbol, _Period, SERIES_SYNCHRONIZED) == false) // データ同期が未完了の場合
{
return(0); // 計算を行わずに0を返し、次回ティックで再試行させる
}

// 2. データがあまりにも少ない(ダウンロード直後の初期段階)なら計算しない(ヒストリ対策:配列範囲外エラー防止)
if(rates_total < MathMax(MathMax(MathMax(sma_kikan, ma2_kikan), MathMax(ma3_kikan, ma4_kikan)), MathMax(MathMax(ma5_kikan, ma6_kikan), ma7_kikan)) + 10) // 存在するバーが指定された最大MA期間+10本より少ない場合 { return(0); // インジケーターの計算に必要なデータが揃うまで待機 } if(handle_ma == INVALID_HANDLE || handle_ma2 == INVALID_HANDLE || handle_ma3 == INVALID_HANDLE || handle_ma4 == INVALID_HANDLE || handle_ma5 == INVALID_HANDLE || handle_ma6 == INVALID_HANDLE || handle_ma7 == INVALID_HANDLE) // いずれかのMAハンドルが無効な場合 { return(prev_calculated); // 計算をスキップして前回計算済み本数をそのまま返す } // 3. MAの内部計算が追いつくまで待機する(ヒストリ対策:CopyBuffer失敗や不完全な状態での計算を防止) int bc1 = BarsCalculated(handle_ma); // MA1の計算済み本数を取得 int bc2 = BarsCalculated(handle_ma2); // MA2の計算済み本数を取得 int bc3 = BarsCalculated(handle_ma3); // MA3の計算済み本数を取得 int bc4 = BarsCalculated(handle_ma4); // MA4の計算済み本数を取得 int bc5 = BarsCalculated(handle_ma5); // MA5の計算済み本数を取得 int bc6 = BarsCalculated(handle_ma6); // MA6の計算済み本数を取得 int bc7 = BarsCalculated(handle_ma7); // MA7の計算済み本数を取得 if(bc1 < rates_total || bc2 < rates_total || bc3 < rates_total || bc4 < rates_total || bc5 < rates_total || bc6 < rates_total || bc7 < rates_total) // いずれかのMAの計算がチャート全体のバー数に追いついていない場合 { return(prev_calculated); // MAの準備が整うまで自身の計算を待機する } if(!ArrayGetAsSeries(time)) ArraySetAsSeries(time, true); // time配列が時系列でない場合は時系列にする if(!ArrayGetAsSeries(open)) ArraySetAsSeries(open, true); // open配列を時系列にする if(!ArrayGetAsSeries(high)) ArraySetAsSeries(high, true); // high配列を時系列にする if(!ArrayGetAsSeries(low)) ArraySetAsSeries(low, true); // low配列を時系列にする if(!ArrayGetAsSeries(close)) ArraySetAsSeries(close, true); // close配列を時系列にする // この後の処理で「現在の足だけでなく1本前の足も参照する」ため、安全に参照できる余白として2本分を足しています。(ヒストリ対策) if(rates_total < MathMax(MathMax(MathMax(sma_kikan, ma2_kikan), MathMax(ma3_kikan, ma4_kikan)), MathMax(MathMax(ma5_kikan, ma6_kikan), ma7_kikan)) + 2) // バッファアクセス違反を防ぐための安全マージン確認 { return(0); // マージンが確保できなければ計算をスキップ } // ヒストリ対策:ユーザーが指定した表示期間分のバー数を取得 int get_5bars_count = kako_5nen_check(time, rates_total); // 設定された期間(例:1年間)が何バーに相当するか計算 int bars5_or_total = (get_5bars_count > 0 ? MathMin(get_5bars_count, rates_total) : rates_total); // 実際の総バー数を超えないように制限をかける

int begin = MathMax(0, rates_total – bars5_or_total); // チャート左側から数えた描画開始インデックスを決定
for(int p = 0; p < 9; ++p) // すべてのプロット(バッファ0~8)に対してループ { PlotIndexSetInteger(p, PLOT_DRAW_BEGIN, begin); // インジケーターの描画開始位置を指定期間に合わせる } static int zenkai_taishougai = -1; // 前回計算時の対象外バー数を保持する静的変数 bool left_kakudai = (zenkai_taishougai >= 0 && begin < zenkai_taishougai); // チャートが左にスクロールされて描画範囲が拡大されたか判定 if(left_kakudai) // 描画範囲が拡大された場合 { int s_from = rates_total - zenkai_taishougai; // 新たに描画対象となった範囲の開始インデックス int s_to = rates_total - 1 - begin; // 新たに描画対象となった範囲の終了インデックス if(s_from <= s_to) // インデックスが正常な関係である場合 { for(int i = s_from; i <= s_to; ++i) // 新しい範囲をループ処理 { if(!(i == 0 && !kakutei_switch)) // 未確定足でサインを出す設定でない限り { sign_buffer[i] = EMPTY_VALUE; // 上向きサインバッファを一旦空にする sign_dn_buffer[i] = EMPTY_VALUE; // 下向きサインバッファを一旦空にする } } } zenbu_keisan = true; // 新たな範囲を含めて全体の再計算を要求する } zenkai_taishougai = begin; // 今回の描画開始位置を次回の比較用に保存 bool shokai_or_all_keisan = (prev_calculated == 0) || zenbu_keisan; // 初回起動または全再計算フラグが立っているか判定 int inc = (prev_calculated == 0) ? 0 : MathMax(0, rates_total - prev_calculated); // 新しく生成されたバーの本数を算出 int need = shokai_or_all_keisan ? bars5_or_total : MathMax(2, MathMin(bars5_or_total, inc + 2)); // 今回計算する必要があるバーの本数を決定 int min_end = need - 2; // ループの終了インデックス(配列アクセスエラーを防ぐため-2) if(min_end < 0) // ループがマイナスになる場合は { return(rates_total); // 処理不要として現在のバー数を返す } int min_end_or_zouka = (prev_calculated == 0) ? min_end : MathMax(0, rates_total - prev_calculated); // 初回か追加バー分かによる必要計算本数を算出 int yobi = 1; // 過去の足とクロス判定するための予備の1本 int main_loop_start = 0; // ループの開始位置(0 = 最新の足) int main_loop_end = shokai_or_all_keisan ? min_end : MathMin(main_loop_start + MathMax(1, min_end_or_zouka + yobi) - 1, min_end); // ループの終了位置を安全な範囲で決定 // ------------------------------------------------------- // ★ 追加修正:計算対象外(指定期間より昔)のゴミデータを確実に消去する // ------------------------------------------------------- if(shokai_or_all_keisan) // 全再計算のタイミングの場合 { for(int i = main_loop_end + 1; i < rates_total; i++) // 指定期間より古い過去のバーに対してループ { sign_buffer[i] = EMPTY_VALUE; // 対象外領域の上向きサインを消去 sign_dn_buffer[i] = EMPTY_VALUE; // 対象外領域の下向きサインを消去 } } if(main_loop_end < main_loop_start) // ループの終了位置が開始位置より小さい(異常または計算不要)場合 { return(rates_total); // 何もせず終了 } zenbu_keisan = false; // 全計算フラグの役目が終わったのでオフにする int needMACount1 = main_loop_end + sma_kikan + 10; // MA1の値をバッファからコピーするために必要な本数を算出 if(needMACount1 > rates_total) needMACount1 = rates_total; // コピー本数が総バー数を超えないように制限
int needMACount2 = main_loop_end + ma2_kikan + 10; // MA2のコピー必要本数を算出
if(needMACount2 > rates_total) needMACount2 = rates_total; // コピー本数制限
int needMACount3 = main_loop_end + ma3_kikan + 10; // MA3のコピー必要本数を算出
if(needMACount3 > rates_total) needMACount3 = rates_total; // コピー本数制限
int needMACount4 = main_loop_end + ma4_kikan + 10; // MA4のコピー必要本数を算出
if(needMACount4 > rates_total) needMACount4 = rates_total; // コピー本数制限
int needMACount5 = main_loop_end + ma5_kikan + 10; // MA5のコピー必要本数を算出
if(needMACount5 > rates_total) needMACount5 = rates_total; // コピー本数制限
int needMACount6 = main_loop_end + ma6_kikan + 10; // MA6のコピー必要本数を算出
if(needMACount6 > rates_total) needMACount6 = rates_total; // コピー本数制限
int needMACount7 = main_loop_end + ma7_kikan + 10; // MA7のコピー必要本数を算出
if(needMACount7 > rates_total) needMACount7 = rates_total; // コピー本数制限

ArraySetAsSeries(ma_buffer, true); // コピー先MA1配列を時系列にする
ArraySetAsSeries(ma2_buffer, true); // コピー先MA2配列を時系列にする
ArraySetAsSeries(ma3_buffer, true); // コピー先MA3配列を時系列にする
ArraySetAsSeries(ma4_buffer, true); // コピー先MA4配列を時系列にする
ArraySetAsSeries(ma5_buffer, true); // コピー先MA5配列を時系列にする
ArraySetAsSeries(ma6_buffer, true); // コピー先MA6配列を時系列にする
ArraySetAsSeries(ma7_buffer, true); // コピー先MA7配列を時系列にする

int copied1 = CopyBuffer(handle_ma, 0, 0, needMACount1, ma_buffer); // MA1インジケーターから配列へ値をコピー
int copied2 = CopyBuffer(handle_ma2, 0, 0, needMACount2, ma2_buffer); // MA2インジケーターから配列へ値をコピー
int copied3 = CopyBuffer(handle_ma3, 0, 0, needMACount3, ma3_buffer); // MA3インジケーターから配列へ値をコピー
int copied4 = CopyBuffer(handle_ma4, 0, 0, needMACount4, ma4_buffer); // MA4インジケーターから配列へ値をコピー
int copied5 = CopyBuffer(handle_ma5, 0, 0, needMACount5, ma5_buffer); // MA5インジケーターから配列へ値をコピー
int copied6 = CopyBuffer(handle_ma6, 0, 0, needMACount6, ma6_buffer); // MA6インジケーターから配列へ値をコピー
int copied7 = CopyBuffer(handle_ma7, 0, 0, needMACount7, ma7_buffer); // MA7インジケーターから配列へ値をコピー

if(!heikin_keisan_zumi) // まだローソク足の平均長さを計算していない場合
{
int n = MathMin(heikin_honsuu, rates_total – 1); // ユーザー指定本数と実在するバー数の小さい方を採用
double s = 0.0; // 長さの合計を保持する変数を初期化
for(int k = 1; k <= n; ++k) // 直近の確定足(1)から指定本数分過去へループ { s += (high[k] - low[k]); // 各バーの高値から安値を引いた長さを合計に加算 } heikin_nagasa = (n > 0) ? (s / n) : 0.0; // 合計を本数で割り、1本あたりの平均の長さを算出
heikin_keisan_zumi = true; // 計算完了フラグを立てて以後はスキップさせる
}

if(copied1 <= 0 || copied2 <= 0 || copied3 <= 0 || copied4 <= 0 || copied5 <= 0 || copied6 <= 0 || copied7 <= 0) // いずれかのCopyBufferに失敗した場合 { return(0); // 値が取得できなかったため計算を中断し、再試行させる } for(int i = main_loop_start; i <= main_loop_end; i++) // 最新のバー(または追加バー)から必要な過去のバーまでループ { // ★ここから判定ロジック(MAクロス) double ma1_now = ma_buffer[i]; // 現在判定しているバーのMA1の値 double ma2_now = ma2_buffer[i]; // 現在判定しているバーのMA2の値 double ma3_now = ma3_buffer[i]; // 現在判定しているバーのMA3の値 double ma4_now = ma4_buffer[i]; // 現在判定しているバーのMA4の値 double ma5_now = ma5_buffer[i]; // 現在判定しているバーのMA5の値 double ma6_now = ma6_buffer[i]; // 現在判定しているバーのMA6の値 double ma7_now = ma7_buffer[i]; // 現在判定しているバーのMA7の値 double ma1_prev = ma_buffer[i + 1]; // 1つ過去のバーのMA1の値 double ma2_prev = ma2_buffer[i + 1]; // 1つ過去のバーのMA2の値 double ma3_prev = ma3_buffer[i + 1]; // 1つ過去のバーのMA3の値 double ma4_prev = ma4_buffer[i + 1]; // 1つ過去のバーのMA4の値 double ma5_prev = ma5_buffer[i + 1]; // 1つ過去のバーのMA5の値 double ma6_prev = ma6_buffer[i + 1]; // 1つ過去のバーのMA6の値 double ma7_prev = ma7_buffer[i + 1]; // 1つ過去のバーのMA7の値 bool po_up_now = true; // 現在の上昇パーフェクトオーダー(PO)条件の初期値 bool po_up_prev = true; // 過去の上昇PO条件の初期値 bool po_dn_now = true; // 現在の下降PO条件の初期値 bool po_dn_prev = true; // 過去の下降PO条件の初期値 if(InpMACount >= 2) // MAが2本以上表示されている設定の場合
{
po_up_now = po_up_now && (ma1_now > ma2_now); // 現在MA1がMA2より上なら上昇PO条件維持
po_dn_now = po_dn_now && (ma1_now < ma2_now); // 現在MA1がMA2より下なら下降PO条件維持 po_up_prev = po_up_prev && (ma1_prev > ma2_prev); // 過去MA1がMA2より上なら過去の上昇PO条件維持
po_dn_prev = po_dn_prev && (ma1_prev < ma2_prev); // 過去MA1がMA2より下なら過去の下降PO条件維持 } if(InpMACount >= 3) // MAが3本以上の場合
{
po_up_now = po_up_now && (ma2_now > ma3_now); // MA2がMA3より上なら上昇PO条件維持
po_dn_now = po_dn_now && (ma2_now < ma3_now); // MA2がMA3より下なら下降PO条件維持 po_up_prev = po_up_prev && (ma2_prev > ma3_prev); // 過去MA2がMA3より上か判定
po_dn_prev = po_dn_prev && (ma2_prev < ma3_prev); // 過去MA2がMA3より下か判定 } if(InpMACount >= 4) // MAが4本以上の場合
{
po_up_now = po_up_now && (ma3_now > ma4_now); // MA3がMA4より上か判定
po_dn_now = po_dn_now && (ma3_now < ma4_now); // MA3がMA4より下か判定 po_up_prev = po_up_prev && (ma3_prev > ma4_prev); // 過去MA3がMA4より上か判定
po_dn_prev = po_dn_prev && (ma3_prev < ma4_prev); // 過去MA3がMA4より下か判定 } if(InpMACount >= 5) // MAが5本以上の場合
{
po_up_now = po_up_now && (ma4_now > ma5_now); // MA4がMA5より上か判定
po_dn_now = po_dn_now && (ma4_now < ma5_now); // MA4がMA5より下か判定 po_up_prev = po_up_prev && (ma4_prev > ma5_prev); // 過去MA4がMA5より上か判定
po_dn_prev = po_dn_prev && (ma4_prev < ma5_prev); // 過去MA4がMA5より下か判定 } if(InpMACount >= 6) // MAが6本以上の場合
{
po_up_now = po_up_now && (ma5_now > ma6_now); // MA5がMA6より上か判定
po_dn_now = po_dn_now && (ma5_now < ma6_now); // MA5がMA6より下か判定 po_up_prev = po_up_prev && (ma5_prev > ma6_prev); // 過去MA5がMA6より上か判定
po_dn_prev = po_dn_prev && (ma5_prev < ma6_prev); // 過去MA5がMA6より下か判定 } if(InpMACount >= 7) // MAが7本表示の場合
{
po_up_now = po_up_now && (ma6_now > ma7_now); // MA6がMA7より上か判定
po_dn_now = po_dn_now && (ma6_now < ma7_now); // MA6がMA7より下か判定 po_up_prev = po_up_prev && (ma6_prev > ma7_prev); // 過去MA6がMA7より上か判定
po_dn_prev = po_dn_prev && (ma6_prev < ma7_prev); // 過去MA6がMA7より下か判定 } bool golden = (!po_up_prev && po_up_now); // 1つ前は上昇POでなく、現在上昇POになった瞬間をゴールデンクロスと定義 bool dead = (!po_dn_prev && po_dn_now); // 1つ前は下降POでなく、現在下降POになった瞬間をデッドクロスと定義 // KAKUTEIスイッチがONの場合、未確定足(0本目)ではサインを出さない if(kakutei_switch && i == 0) // 確定足モードかつ、現在処理しているのが最新の未確定バー(0)の場合 { golden = false; // ゴールデンクロスの判定を取り消し dead = false; // デッドクロスの判定を取り消し } sign_buffer[i] = EMPTY_VALUE; // 配列を空値にしてサインをリセット sign_dn_buffer[i] = EMPTY_VALUE; // 下向き配列も空値にリセット if(golden) // 上昇PO成立(ゴールデンクロス)の場合 { sign_buffer[i] = low[i] - (heikin_nagasa * haba); // ローソク足の安値から、計算した平均距離を引いた位置に上向き矢印をセット } else if(dead) // 下降PO成立(デッドクロス)の場合 { sign_dn_buffer[i] = high[i] + (heikin_nagasa * haba); // ローソク足の高値に、計算した平均距離を足した位置に下向き矢印をセット } } if(repeat_slider_kotei_atai > 0) // リピート(サイン間引き)設定が0より大きい場合
{
int cool_time = repeat_slider_kotei_atai; // 設定された間引きバー数をクールタイムとして取得
int nokori = 0; // クールタイムの残機カウンターを初期化
for(int i = MathMin(rates_total – 1, main_loop_end + cool_time); i >= main_loop_start; i–) // 古いバーから新しいバーへ向かって再走査
{
bool sign_aru = (sign_buffer[i] != EMPTY_VALUE || sign_dn_buffer[i] != EMPTY_VALUE); // そのバーに何らかのサインが存在するか判定

if(nokori > 0) // クールタイム中(残機がある)の場合
{
if(sign_aru) // クールタイム中にもかかわらずサインが発生していたら
{
if(i <= main_loop_end) // そのサインが描画対象範囲内であれば { sign_buffer[i] = EMPTY_VALUE; // 上向きサインを強制的に消去(間引き) sign_dn_buffer[i] = EMPTY_VALUE; // 下向きサインを強制的に消去(間引き) } } nokori--; // バーを一つ進めるごとにクールタイム残機を減らす } else // クールタイムが終了している場合 { if(sign_aru) // サインが正常に発生していれば { nokori = cool_time; // そのサインを採用し、新たにクールタイムを設定して以降の連続サインを防止する } } } } // KAKUTEIモードなら1本前(確定足)、通常なら0本目(未確定足)を見る int alert_taisyou_bar = 0; // アラートの判定基準となるバーのインデックス初期値(0 = 未確定足) if(kakutei_switch) // 確定足モードがオンの場合 { alert_taisyou_bar = 1; // 判定基準を1本前(確定足)に変更 } if(alert_switch || push_switch) // アラートまたはプッシュ通知のいずれかがオンの場合 { if((sign_buffer[alert_taisyou_bar] != EMPTY_VALUE || sign_dn_buffer[alert_taisyou_bar] != EMPTY_VALUE) && (last_alert_time != time[alert_taisyou_bar])) // 判定対象バーにサインが存在し、かつそのバーでまだ通知を行っていない場合 { bool is_dead = (sign_dn_buffer[alert_taisyou_bar] != EMPTY_VALUE); // 下向きサインがあるか(デッドクロスか)を判定 string cross_type = is_dead ? "DOWN" : "UP"; // 判定に応じてテキストをセット if(alert_switch) // アラート設定がオンの場合 { Alert(StringFormat("[%s] Perfect Order %s %s", // アラートダイアログに表示する文字列をフォーマット _Symbol, // 通貨ペア名 cross_type, // UPまたはDOWN TimeToString(time[alert_taisyou_bar], TIME_DATE | TIME_MINUTES))); // 発生時刻 } if(push_switch) // プッシュ通知設定がオンの場合 { SendNotification(StringFormat("[%s] Perfect Order %s %s", // スマホへ送る文字列をフォーマット _Symbol, // 通貨ペア名 cross_type, // UPまたはDOWN TimeToString(time[alert_taisyou_bar], TIME_DATE | TIME_MINUTES))); // 発生時刻 } last_alert_time = time[alert_taisyou_bar]; // 処理したバーの時刻を記録し、同一バーでの連続発報を防止 } } return(rates_total); // 今回の処理で計算済みのバー数として、総バー数を返す } //+------------------------------------------------------------------+ //| 削除処理 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) // インジケーター終了時やパラメーター変更時に呼ばれる関数 { // ★追加:終了時に状態を保存(時間足変更でも確実に保持) ui_state_save(); // インジケーターを閉じる直前のUI状態を保存 if(handle_ma != INVALID_HANDLE) IndicatorRelease(handle_ma); // MA1ハンドルが有効なら解放してメモリリークを防ぐ handle_ma = INVALID_HANDLE; // MA1ハンドルを無効状態に戻す if(handle_ma2 != INVALID_HANDLE) IndicatorRelease(handle_ma2); // MA2ハンドルが有効なら解放 handle_ma2 = INVALID_HANDLE; // MA2ハンドルを無効化 if(handle_ma3 != INVALID_HANDLE) IndicatorRelease(handle_ma3); // MA3ハンドルを解放 handle_ma3 = INVALID_HANDLE; // MA3ハンドル無効化 if(handle_ma4 != INVALID_HANDLE) IndicatorRelease(handle_ma4); // MA4ハンドルを解放 handle_ma4 = INVALID_HANDLE; // MA4ハンドル無効化 if(handle_ma5 != INVALID_HANDLE) IndicatorRelease(handle_ma5); // MA5ハンドルを解放 handle_ma5 = INVALID_HANDLE; // MA5ハンドル無効化 if(handle_ma6 != INVALID_HANDLE) IndicatorRelease(handle_ma6); // MA6ハンドルを解放 handle_ma6 = INVALID_HANDLE; // MA6ハンドル無効化 if(handle_ma7 != INVALID_HANDLE) IndicatorRelease(handle_ma7); // MA7ハンドルを解放 handle_ma7 = INVALID_HANDLE; // MA7ハンドル無効化 ObjectDelete(0, alert_waku); // Alertボタン枠をチャートから削除 ObjectDelete(0, alert_moji); // Alertボタン文字をチャートから削除 ObjectDelete(0, push_waku); // Pushボタン枠を削除 ObjectDelete(0, push_moji); // Pushボタン文字を削除 ObjectDelete(0, open_waku); // Openボタン枠を削除 ObjectDelete(0, open_moji); // Openボタン文字を削除 ObjectDelete(0, kakutei_waku); // 確定足ボタン枠を削除 ObjectDelete(0, kakutei_moji); // 確定足ボタン文字を削除 ObjectDelete(0, mikakutei_waku); // 未確定足ボタン枠を削除 ObjectDelete(0, mikakutei_moji); // 未確定足ボタン文字を削除 ObjectDelete(0, sma_waku); // SMAボタン枠を削除 ObjectDelete(0, sma_moji); // SMAボタン文字を削除 ObjectDelete(0, ema_waku); // EMAボタン枠を削除 ObjectDelete(0, ema_moji); // EMAボタン文字を削除 ObjectDelete(0, kikan_slider_haikei); // MA1スライダーの背景を削除 ObjectDelete(0, kikan_slider_tsumami); // MA1スライダーのつまみを削除 ObjectDelete(0, kikan_slider_atai_label); // MA1スライダーの値ラベルを削除 ObjectDelete(0, kikan_slider_minus); // MA1スライダーのマイナスボタンを削除 ObjectDelete(0, kikan_slider_plus); // MA1スライダーのプラスボタンを削除 ObjectDelete(0, color_waku); // MA1カラーボタンの枠を削除 ObjectDelete(0, color_moji); // MA1カラーボタンの文字を削除 // ★追加:MA2スライダー削除 ObjectDelete(0, ma2_slider_haikei); // MA2スライダー関連UIを削除 ObjectDelete(0, ma2_slider_tsumami); // MA2スライダー関連UIを削除 ObjectDelete(0, ma2_slider_atai_label); // MA2スライダー関連UIを削除 ObjectDelete(0, ma2_slider_minus); // MA2スライダー関連UIを削除 ObjectDelete(0, ma2_slider_plus); // MA2スライダー関連UIを削除 ObjectDelete(0, color2_waku); // MA2カラーボタンの枠を削除 ObjectDelete(0, color2_moji); // MA2カラーボタンの文字を削除 ObjectDelete(0, ma3_slider_haikei); ObjectDelete(0, ma3_slider_tsumami); ObjectDelete(0, ma3_slider_atai_label); ObjectDelete(0, ma3_slider_minus); ObjectDelete(0, ma3_slider_plus); ObjectDelete(0, color3_waku); ObjectDelete(0, color3_moji); // MA3スライダーUI群を削除 ObjectDelete(0, ma4_slider_haikei); ObjectDelete(0, ma4_slider_tsumami); ObjectDelete(0, ma4_slider_atai_label); ObjectDelete(0, ma4_slider_minus); ObjectDelete(0, ma4_slider_plus); ObjectDelete(0, color4_waku); ObjectDelete(0, color4_moji); // MA4スライダーUI群を削除 ObjectDelete(0, ma5_slider_haikei); ObjectDelete(0, ma5_slider_tsumami); ObjectDelete(0, ma5_slider_atai_label); ObjectDelete(0, ma5_slider_minus); ObjectDelete(0, ma5_slider_plus); ObjectDelete(0, color5_waku); ObjectDelete(0, color5_moji); // MA5スライダーUI群を削除 ObjectDelete(0, ma6_slider_haikei); ObjectDelete(0, ma6_slider_tsumami); ObjectDelete(0, ma6_slider_atai_label); ObjectDelete(0, ma6_slider_minus); ObjectDelete(0, ma6_slider_plus); ObjectDelete(0, color6_waku); ObjectDelete(0, color6_moji); // MA6スライダーUI群を削除 ObjectDelete(0, ma7_slider_haikei); ObjectDelete(0, ma7_slider_tsumami); ObjectDelete(0, ma7_slider_atai_label); ObjectDelete(0, ma7_slider_minus); ObjectDelete(0, ma7_slider_plus); ObjectDelete(0, color7_waku); ObjectDelete(0, color7_moji); // MA7スライダーUI群を削除 ObjectDelete(0, repeat_slider_haikei); // リピートスライダー関連UIを削除 ObjectDelete(0, repeat_slider_tsumami); // リピートスライダー関連UIを削除 ObjectDelete(0, repeat_slider_atai_label); // リピートスライダー関連UIを削除 ObjectDelete(0, repeat_slider_minus); // リピートスライダー関連UIを削除 ObjectDelete(0, repeat_slider_plus); // リピートスライダー関連UIを削除 ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false); // マウス移動イベントの取得を停止(リソース節約) ChartSetInteger(0, CHART_MOUSE_SCROLL, true); // もし無効化されていれば、チャートスクロールを有効に戻す ArrayInitialize(sign_buffer, EMPTY_VALUE); // 終了時にチャート上の矢印サイン(上)を消去 ArrayInitialize(sign_dn_buffer, EMPTY_VALUE); // 終了時にチャート上の矢印サイン(下)を消去 ChartRedraw(); // オブジェクト削除結果を画面に反映させるため再描画 } //+------------------------------------------------------------------+ // ファイル終わり