﻿//+------------------------------------------------------------------+
//|                                         ParameterDefinitions.mqh |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                          https://www.mql5.com/en/users/lynnchris |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com/en/users/lynnchris"
#property version   "3.0"

#ifndef _PARAMETER_DEFINITIONS_MQH
#define _PARAMETER_DEFINITIONS_MQH

#include <Indicators\Indicators.mqh>

//--- Parameter type enumeration
enum ENUM_PARAM_TYPE
  {
   PARAM_INTEGER,   // integer (whole number) value
   PARAM_DOUBLE,    // floating‑point value
   PARAM_ENUM       // enumeration (e.g., MA method, applied price)
  };

//--- Structure describing a single parameter
struct SParameterDef
  {
   string            name;           // displayed name (e.g., "Period")
   ENUM_PARAM_TYPE   type;           // PARAM_INTEGER, PARAM_DOUBLE, or PARAM_ENUM
   int               default_int;    // default integer value
   double            default_double; // default double value
   int               default_enum;   // default enumeration code
   int               min_value;      // minimum allowed integer (for validation)
   int               max_value;      // maximum allowed integer (for validation)
   string            enum_values[];  // display names for enums (e.g., "SMA", "EMA")
   int               enum_codes[];   // corresponding MT5 enum codes (e.g., MODE_SMA)
   string            description;    // optional tooltip
  };

//+------------------------------------------------------------------+
//| Helper to fill an SParameterDef with applied price enum values   |
//+------------------------------------------------------------------+
void AddPriceEnums(SParameterDef &def)
  {
//--- 6 possible applied price options
   ArrayResize(def.enum_values, 6);
   ArrayResize(def.enum_codes, 6);
   def.enum_values[0] = "Close";
   def.enum_codes[0] = PRICE_CLOSE;
   def.enum_values[1] = "Open";
   def.enum_codes[1] = PRICE_OPEN;
   def.enum_values[2] = "High";
   def.enum_codes[2] = PRICE_HIGH;
   def.enum_values[3] = "Low";
   def.enum_codes[3] = PRICE_LOW;
   def.enum_values[4] = "Median";
   def.enum_codes[4] = PRICE_MEDIAN;
   def.enum_values[5] = "Typical";
   def.enum_codes[5] = PRICE_TYPICAL;
  }

//+------------------------------------------------------------------+
//| Helper to fill an SParameterDef with MA method enum values       |
//+------------------------------------------------------------------+
void AddMAMethodEnums(SParameterDef &def)
  {
//--- 4 standard moving average methods
   ArrayResize(def.enum_values, 4);
   ArrayResize(def.enum_codes, 4);
   def.enum_values[0] = "SMA";
   def.enum_codes[0] = MODE_SMA;
   def.enum_values[1] = "EMA";
   def.enum_codes[1] = MODE_EMA;
   def.enum_values[2] = "SMMA";
   def.enum_codes[2] = MODE_SMMA;
   def.enum_values[3] = "LWMA";
   def.enum_codes[3] = MODE_LWMA;
  }

//+------------------------------------------------------------------+
//| Parameter definitions for built‑in indicators                    |
//+------------------------------------------------------------------+
class CParameterDefinitions
  {
public:
   //--- Returns an array of parameter definitions for the given indicator type
   static int        GetDefinitions(const ENUM_INDICATOR type, SParameterDef &defs[]);
  };

//+------------------------------------------------------------------+
//| Returns the parameter definition array for the indicator type   |
//+------------------------------------------------------------------+
int CParameterDefinitions::GetDefinitions(const ENUM_INDICATOR type, SParameterDef &defs[])
  {
   ArrayResize(defs, 0);   // start with empty array
   int count = 0;

//--- Each indicator has its own set of parameters.
//--- If an indicator is not listed here, it has no configurable parameters.
   switch(type)
     {
      //--- Moving Average – 4 parameters
      case IND_MA:
         ArrayResize(defs, 4);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 10;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Shift";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 0;
         defs[1].min_value = -100;
         defs[1].max_value = 100;
         defs[2].name = "MA Method";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[2]);
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         count = 4;
         break;

      //--- RSI – 2 parameters
      case IND_RSI:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Applied Price";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[1]);
         count = 2;
         break;

      //--- MACD – 4 parameters
      case IND_MACD:
         ArrayResize(defs, 4);
         defs[0].name = "Fast EMA";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 12;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Slow EMA";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 26;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Signal Period";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 9;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         count = 4;
         break;

      //--- Bollinger Bands – 4 parameters
      case IND_BANDS:
         ArrayResize(defs, 4);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 20;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Deviation";
         defs[1].type = PARAM_DOUBLE;
         defs[1].default_double = 2.0;
         defs[2].name = "Shift";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 0;
         defs[2].min_value = -100;
         defs[2].max_value = 100;
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         count = 4;
         break;

      //--- Stochastic – 5 parameters
      case IND_STOCHASTIC:
         ArrayResize(defs, 5);
         defs[0].name = "%K Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 5;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "%D Period";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 3;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Slowing";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 3;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "MA Method";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[3]);
         defs[4].name = "Applied Price";
         defs[4].type = PARAM_ENUM;
         defs[4].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[4]);
         count = 5;
         break;

      //--- ADX, ADXW, ATR – 1 parameter each (Period)
      case IND_ADX:
      case IND_ADXW:
      case IND_ATR:
         ArrayResize(defs, 1);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         count = 1;
         break;

      //--- CCI – 2 parameters
      case IND_CCI:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Applied Price";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[1]);
         count = 2;
         break;

      //--- Momentum / TRIX – 2 parameters
      case IND_MOMENTUM:
      case IND_TRIX:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Applied Price";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[1]);
         count = 2;
         break;

      //--- WPR, DeMarker – 1 parameter each
      case IND_WPR:
      case IND_DEMARKER:
         ArrayResize(defs, 1);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         count = 1;
         break;

      //--- Envelopes – 5 parameters
      case IND_ENVELOPES:
         ArrayResize(defs, 5);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 10;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Shift";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 0;
         defs[1].min_value = -100;
         defs[1].max_value = 100;
         defs[2].name = "MA Method";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[2]);
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         defs[4].name = "Deviation";
         defs[4].type = PARAM_DOUBLE;
         defs[4].default_double = 0.1;
         count = 5;
         break;

      //--- Ichimoku – 5 parameters
      case IND_ICHIMOKU:
         ArrayResize(defs, 5);
         defs[0].name = "Tenkan-sen";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 9;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Kijun-sen";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 26;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Senkou Span B";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 52;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "Chikou Span";
         defs[3].type = PARAM_INTEGER;
         defs[3].default_int = 26;
         defs[3].min_value = 1;
         defs[3].max_value = 1000;
         defs[4].name = "Offset";
         defs[4].type = PARAM_INTEGER;
         defs[4].default_int = 26;
         defs[4].min_value = -100;
         defs[4].max_value = 100;
         count = 5;
         break;

      //--- SAR – 2 double parameters
      case IND_SAR:
         ArrayResize(defs, 2);
         defs[0].name = "Step";
         defs[0].type = PARAM_DOUBLE;
         defs[0].default_double = 0.02;
         defs[1].name = "Max Step";
         defs[1].type = PARAM_DOUBLE;
         defs[1].default_double = 0.2;
         count = 2;
         break;

      //--- Alligator – 6 parameters
      case IND_ALLIGATOR:
         ArrayResize(defs, 6);
         defs[0].name = "Jaw Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 13;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Teeth Period";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 8;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Lips Period";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 5;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "Jaw Shift";
         defs[3].type = PARAM_INTEGER;
         defs[3].default_int = 8;
         defs[3].min_value = -100;
         defs[3].max_value = 100;
         defs[4].name = "Teeth Shift";
         defs[4].type = PARAM_INTEGER;
         defs[4].default_int = 5;
         defs[4].min_value = -100;
         defs[4].max_value = 100;
         defs[5].name = "Lips Shift";
         defs[5].type = PARAM_INTEGER;
         defs[5].default_int = 3;
         defs[5].min_value = -100;
         defs[5].max_value = 100;
         count = 6;
         break;

      //--- DEMA / TEMA – 4 parameters
      case IND_DEMA:
      case IND_TEMA:
         ArrayResize(defs, 4);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Shift";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 0;
         defs[1].min_value = -100;
         defs[1].max_value = 100;
         defs[2].name = "MA Method";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[2]);
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         count = 4;
         break;

      //--- VIDYA – 3 parameters
      case IND_VIDYA:
         ArrayResize(defs, 3);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Volatility";
         defs[1].type = PARAM_DOUBLE;
         defs[1].default_double = 0.2;
         defs[2].name = "Applied Price";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[2]);
         count = 3;
         break;

      //--- AMA – 5 parameters
      case IND_AMA:
         ArrayResize(defs, 5);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 9;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Fast MA Period";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 30;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Slow MA Period";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 2;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "Efficiency Ratio";
         defs[3].type = PARAM_INTEGER;
         defs[3].default_int = 30;
         defs[3].min_value = 1;
         defs[3].max_value = 1000;
         defs[4].name = "Applied Price";
         defs[4].type = PARAM_ENUM;
         defs[4].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[4]);
         count = 5;
         break;

      //--- Force Index – 3 parameters
      case IND_FORCE:
         ArrayResize(defs, 3);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 13;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "MA Method";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[1]);
         defs[2].name = "Volume";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = VOLUME_TICK;
         ArrayResize(defs[2].enum_values, 1);
         ArrayResize(defs[2].enum_codes, 1);
         defs[2].enum_values[0] = "Tick";
         defs[2].enum_codes[0] = VOLUME_TICK;
         count = 3;
         break;

      //--- RVI – 2 parameters
      case IND_RVI:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 10;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "MA Method";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[1]);
         count = 2;
         break;

      //--- OSMA – 4 parameters
      case IND_OSMA:
         ArrayResize(defs, 4);
         defs[0].name = "Fast EMA";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 12;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Slow EMA";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 26;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "Signal Period";
         defs[2].type = PARAM_INTEGER;
         defs[2].default_int = 9;
         defs[2].min_value = 1;
         defs[2].max_value = 1000;
         defs[3].name = "Applied Price";
         defs[3].type = PARAM_ENUM;
         defs[3].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[3]);
         count = 4;
         break;

      //--- Chaikin – 4 parameters
      case IND_CHAIKIN:
         ArrayResize(defs, 4);
         defs[0].name = "Fast Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 3;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Slow Period";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 10;
         defs[1].min_value = 1;
         defs[1].max_value = 1000;
         defs[2].name = "MA Method";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = MODE_SMA;
         AddMAMethodEnums(defs[2]);
         defs[3].name = "Volume";
         defs[3].type = PARAM_DOUBLE;
         defs[3].default_double = 0.0;
         count = 4;
         break;

      //--- Bears / Bulls Power – 2 parameters
      case IND_BEARS:
      case IND_BULLS:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 13;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Applied Price";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[1]);
         count = 2;
         break;

      //--- Standard Deviation – 3 parameters
      case IND_STDDEV:
         ArrayResize(defs, 3);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 10;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Shift";
         defs[1].type = PARAM_INTEGER;
         defs[1].default_int = 0;
         defs[1].min_value = -100;
         defs[1].max_value = 100;
         defs[2].name = "Applied Price";
         defs[2].type = PARAM_ENUM;
         defs[2].default_enum = PRICE_CLOSE;
         AddPriceEnums(defs[2]);
         count = 3;
         break;

      //--- MFI – 2 parameters
      case IND_MFI:
         ArrayResize(defs, 2);
         defs[0].name = "Period";
         defs[0].type = PARAM_INTEGER;
         defs[0].default_int = 14;
         defs[0].min_value = 1;
         defs[0].max_value = 1000;
         defs[1].name = "Volume";
         defs[1].type = PARAM_ENUM;
         defs[1].default_enum = VOLUME_TICK;
         ArrayResize(defs[1].enum_values, 1);
         ArrayResize(defs[1].enum_codes, 1);
         defs[1].enum_values[0] = "Tick";
         defs[1].enum_codes[0] = VOLUME_TICK;
         count = 2;
         break;

      //--- Zero‑parameter indicators – no configurable parameters
      case IND_AO:
      case IND_AC:
      case IND_AD:
      case IND_OBV:
      case IND_BWMFI:
      case IND_GATOR:
      case IND_VOLUMES:
      case IND_FRACTALS:
         count = 0;
         break;

      default:
         count = 0;
         break;
     }

   return(count);
  }

#endif // _PARAMETER_DEFINITIONS_MQH
//+------------------------------------------------------------------+
