//|====================================================================+
//|  Indicator is a Stochastics strategy; it attempts to indicate when the price is leaving a range.
//|
//|====================================================================+
#property  copyright "ramzam"
#property  link      "http://www.forexfactory.com/ramzam"
#property version    "1.00"
//
#property strict
#property indicator_chart_window
//
#property indicator_buffers 2
#property indicator_color1 clrLime
#property indicator_color2 clrRed
#include <stdlib.mqh>
//
const int I_TWENTY_FIVE = 25;
const int dotChar       = 159;
const int CHARTWINDOW   = 0;
const int NOWIDTH       = 0;
const int NOSHIFT       = 0;
const int ONESHIFT      = 1;
//
int    displayChar = dotChar;
double PIPpoint;
//
enum ENUM_ON_OFF { ON, OFF };
extern long        UniqueID          = 153;
extern uint        ChangeRange       = 17;   // Range change test bars (17)
extern string      Alert_Setting     = "---------- Alert Setting";
extern bool        EnableAlert       = false;
extern ENUM_ON_OFF SignalSound       = OFF;  
extern string      SoundFilename     = "alert.wav";
extern int         DisplayYOffset    = 100;
extern ENUM_ON_OFF MakeBackground    = ON;
extern ENUM_ON_OFF DisplayMarketInfo = ON;
//
double redDots[];
double limeDots[];
//
enum  ENUM_BKGRND_BOX           {HEADER_BOX,          BODY_BOX,     endBkBoxs};
      string bkgrndNames   [] = {"HEADER",            "BKGRND",     };
const color  bkgrndClrs    [] = {clrWhiteSmoke,       clrGray       };
const bool   bkGrndState   [] = {true,                true,         };
const int    bkgrndXSize   [] = {280,                 280           };  // Width o the boxes
const int    bkgrndYSize   [] = {25,                  130           };  // Hight of the boxes
const int    bkgrndXpos    [] = {5,                   5             };  // Distance from the side of the chart
      int    bkgrndYpos    [] = {20,                  44            };  // Distance from the corner of the chart
//
enum  ENUM_MSG_LINES           {TITLE,      MRKT_RANGE,   STOCH_VAL,   MRKT_CONDITION,   LAST_SIGNAL,   BROKER_TIME,   ACT_CURR,   SPREAD_MSG,   LEVERAG_MSG, endMsgs};
      string labelNames   [] = {"TITLE",    "MRKT_RANGE", "STOCH_VAL", "MRKT_CONDITION", "LAST_SIGNAL", "BROKER_TIME", "ACT_CURR", "SPREAD_MSG", "LEVERAG_MSG"};
      color  labelClrs    [] = {clrBlack,   clrWhite,     clrWhite,    clrWhite,         clrWhite,      clrWhite,      clrWhite,   clrWhite,     clrWhite};
      string labelStr     [] = {"",         "",           "",          "",               "",            "",            "",         "",           ""};
const string labelFont    [] = {"Courier",  "Courier",    "Courier",   "Courier",        "Courier",     "Courier",     "Courier",  "Courier",    "Courier"};
const bool   labelState   [] = {false,      false,        false,       false,            false,         false,         false,      false,        false};
const int    labelFontSize[] = {10,         10,           10,          10,               10,            10,            10,         10,           10};
const int    labelXpos    [] = {10,         10,           10,          10,               10,            10,            10,         10,           10};
      int    labelYpos    [] = {NULL,       NULL,         NULL,        NULL,             NULL,          NULL,          NULL,       NULL,         NULL};
//
class C_MarketChangeInfo  // A Singleton pattern class
 {
   private:
      static C_MarketChangeInfo *marketRangeInfo;           // Static pointer to the only instance of this class
      datetime lastBarTime;
      double   stochVal;
      double   rangeVal;
      int averagingRange, kPeriod, dPeriod, slowing;
      enum ENUM_PRICE_FIELD { LOW_HIGH=0, CLOSE_CLOSE=1 };
      struct signal
       {
         double takeProfit, entry, stopLoss;
         datetime entryTime;
         int operation;
       } lastSignal;
      string priceMarkNames[];
      ENUM_ON_OFF PRICE_MARKS_ON_OFF;
      void C_MarketChangeInfo(void);                            // Private constructor as partr of the Singleton pattern
      string getPriceMarkName(void);                            // Make the object names that will go in priceMarkNames[]
      C_MarketChangeInfo(C_MarketChangeInfo const&){};          // Private Copy Constructor prevents copy of the object as part of Singleton pattern
      C_MarketChangeInfo operator=(C_MarketChangeInfo const&);  // Private Assignment Operator, prevents assignment as part of Singleton pattern
   protected:
      void newBarUpdates(void);                                 // Update the object values when there is a new bar
      void deletePriceMarks(void);                              // Delete all the price marks from the display
      void makePriceMark(void);                                 // Make a new price mark on the diplsay
   public:
      static C_MarketChangeInfo *GetInstance(void);             // A Static Function that will provide a pointer to 'this'
      void ~C_MarketChangeInfo(void);                           // Public Destructor
      string getRiskText(void);                                 // Make text for Display based on Stochastic value
      string getStochStrVal(void);                              // Return Stochastic value as string
      string getMrktRange(void);                                // Return Market Range calculated value as string
      void setLastSignal(int tradeType, double entryPrice, datetime signalTime); // Record values of the last indicator signal
      string getLastSignalStr(void);                            // Provide the last signal information as a string
      void setPriceMarksState(ENUM_ON_OFF onOff);               // Set the state for displaying price marks
      ENUM_ON_OFF getPriceMarksState(void);                     // Provide the state for displaying price marks 
 }
* C_MarketChangeInfo::marketRangeInfo=NULL;   // Initialize the static pointer to the class.
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
 {
   IndicatorShortName("RAMZAM_RANGE_CHANGE"+IntegerToString(UniqueID));
   if ( (Digits == 3) || (Digits == 5) )
      PIPpoint = Point*10;
   else
      PIPpoint = Point;
   for(ENUM_BKGRND_BOX i = 0; i<endBkBoxs ; i++)
    {
      bkgrndYpos[i]  = bkgrndYpos[i] + DisplayYOffset;
      bkgrndNames[i] = IntegerToString(UniqueID)+bkgrndNames[i];
    }
   for(ENUM_MSG_LINES i = 0; i<endMsgs; i++)
    {
      if(i==TITLE)
       {
         labelYpos[i]  = bkgrndYpos[HEADER_BOX] + 5;
       }
      else
       {
         labelYpos[i]  = bkgrndYpos[BODY_BOX] -10 + (15*i);
       }
      labelNames[i] = IntegerToString(UniqueID)+labelNames[i];
    }
   IndicatorBuffers(2);
   enum ENUM_BUFFER_NUMS {LIME_DOTS = 0, RED_DOTS = 1 };
   //
   SetIndexBuffer(LIME_DOTS, limeDots);
   SetIndexBuffer(RED_DOTS,  redDots);
   //
   int drawWeight = 3;
   SetIndexStyle(LIME_DOTS, DRAW_ARROW, STYLE_SOLID, drawWeight);
   SetIndexStyle(RED_DOTS,  DRAW_ARROW, STYLE_SOLID, drawWeight);
   //
   SetIndexArrow(LIME_DOTS, displayChar);
   SetIndexArrow(RED_DOTS,  displayChar);
   //
   int drawBegin = 0;
   SetIndexDrawBegin(LIME_DOTS, drawBegin);
   SetIndexDrawBegin(RED_DOTS,  drawBegin);
   // --- Set the default value
   SetIndexEmptyValue(LIME_DOTS, EMPTY_VALUE);
   SetIndexEmptyValue(RED_DOTS,  EMPTY_VALUE);
   //
   C_MarketChangeInfo::GetInstance().setPriceMarksState( getPriceMarksGlobalValue() );
   //
   return (INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
   for(ENUM_BKGRND_BOX i = 0; i<endBkBoxs ; i++)
    {
      ObjectDelete(bkgrndNames[i]);
    }
   for(ENUM_MSG_LINES i = 0; i<endMsgs; i++)
    {
      ObjectDelete(labelNames[i]);
    }
   if( C_MarketChangeInfo::GetInstance() != NULL )
    {
      delete C_MarketChangeInfo::GetInstance();
    }
   Comment("");
 }
//+------------------------------------------------------------------+
//| Expert Chart Event Function                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,  const long &lparam, const double &dparam,  const string &sparam)
 {
   if(id==CHARTEVENT_OBJECT_CLICK)
    {
      if ( sparam==labelNames[LAST_SIGNAL] )    // Get the Next Oscillator
       {
         C_MarketChangeInfo::GetInstance().setPriceMarksState( (C_MarketChangeInfo::GetInstance().getPriceMarksState()==ON)?OFF:ON);
         GlobalVariableSet(getPriceMarksGlobalName(),(double) C_MarketChangeInfo::GetInstance().getPriceMarksState() );
       }
    }
 }
//+------------------------------------------------------------------+
//| Custom indicator Iteration Function                              |
//+------------------------------------------------------------------+
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[] )
 {
   static int alertSelector, highAlertSent=0, lowAlertSent=0;
   int oldestBar;
   if(prev_calculated < 1)  // First time
    {
      oldestBar = rates_total-(I_TWENTY_FIVE+1);
      oldestBar = (oldestBar<0)?0:oldestBar;
    }
   else
    {
      oldestBar = rates_total-prev_calculated;
    }
   calculateSignal(oldestBar, alertSelector, highAlertSent, lowAlertSent);
   //
   performAlerting(alertSelector, highAlertSent, lowAlertSent);
   //
   if (DisplayMarketInfo == ON)
      buildDisplay();
   //
   return (rates_total);
}
//
void calculateSignal(const int& oldestBar, int& alertSelector, int& highAlertSent, int& lowAlertSent )
 {
   for (int barShift = oldestBar; barShift > 0; barShift--)  // try working from the past (oldestBar) to the newest bar (1)
    {
      double dotSpacer = 0;
      for (int workingBar =barShift; workingBar <barShift + 10; workingBar++) // calculate how far from the bar to place to dot
       {
         dotSpacer += (barShift + 10 - workingBar) * (High[workingBar] - Low[workingBar]);
       }
      dotSpacer /= 55.0;
      double barShiftHigh = High[iHighest(NULL, 0, MODE_HIGH, I_TWENTY_FIVE, barShift)];
      double barShiftLow = Low[iLowest(NULL, 0, MODE_LOW, I_TWENTY_FIVE, barShift)];
      if (Close[barShift] > barShiftHigh - (barShiftHigh -barShiftLow) * ChangeRange / 100.0 && alertSelector != 1)
       {
         redDots[barShift] = High[barShift] + dotSpacer / 2.0;
         C_MarketChangeInfo::GetInstance().setLastSignal(OP_SELL,Close[barShift],Time[barShift]);
         alertSelector = 1;
         lowAlertSent = 0;
       } 
      else if (Close[barShift] <barShiftLow + (barShiftHigh -barShiftLow) * ChangeRange / 100.0 && alertSelector != -1)
       {
            limeDots[barShift] = Low[barShift] - dotSpacer / 2.0;
            C_MarketChangeInfo::GetInstance().setLastSignal(OP_BUY,Close[barShift]+(Ask-Bid),Time[barShift]);
            alertSelector = -1;
            highAlertSent = 0;
       }
    }
 }
//
void setLabelString(ENUM_MSG_LINES MSG)
 {
   switch (MSG)
    {
      case TITLE:
         labelStr[TITLE] = "RAMZAN Range Change";
         break;
      case MRKT_RANGE:
         labelStr[MRKT_RANGE] = "Market Range: "+C_MarketChangeInfo::GetInstance().getMrktRange()+" Pips";
         break;
      case STOCH_VAL:
         labelStr[STOCH_VAL] = "Stochastic: "+C_MarketChangeInfo::GetInstance().getStochStrVal();
         break;
      case MRKT_CONDITION:
         labelStr[MRKT_CONDITION] = "Market Condition: " + C_MarketChangeInfo::GetInstance().getRiskText(); 
         break;
      case LAST_SIGNAL:
         labelStr[LAST_SIGNAL] = "Last Signal: " + C_MarketChangeInfo::GetInstance().getLastSignalStr(); 
         break;
      case BROKER_TIME:
         labelStr[BROKER_TIME] = "Broker Time Is " + TimeToStr(TimeCurrent());
         break;
      case ACT_CURR:
         labelStr[ACT_CURR] = "Account Curency:" + AccountCurrency();
         break;
      case SPREAD_MSG:
         labelStr[SPREAD_MSG] = "Spread = " + DoubleToStr((Ask - Bid) / PIPpoint, 1) + " pips";
         break;
      case LEVERAG_MSG:
         labelStr[LEVERAG_MSG] = "Leverage 1:" + IntegerToString(AccountLeverage());
         break;
      default:
         Print(__FUNCTION__,", called with invalid value: ",IntegerToString(MSG));
         break;
    }
 }
//
void buildDisplay()
 {
   if( MakeBackground == ON )
    {
      makeBackgroundBox();
    }
   makeMarketDisplay();
 }
void makeMarketDisplay(void)
 {
   long chartID = ChartID();
   for(ENUM_MSG_LINES i = 0; i<endMsgs; i++)
    {
      setLabelString(i);
      string objName = labelNames[i];
      if ( ObjectFind(chartID,objName) < 0 )
       {
         ObjectCreate(chartID,objName,OBJ_LABEL,CHARTWINDOW,  0, 0);
         ObjectSetInteger(chartID,objName,OBJPROP_FONTSIZE,  labelFontSize[i]);
         ObjectSetString (chartID,objName,OBJPROP_FONT,      labelFont[i]);
         ObjectSetInteger(chartID,objName,OBJPROP_COLOR,     labelClrs[i]);
         ObjectSetInteger(chartID,objName,OBJPROP_CORNER,    CORNER_LEFT_UPPER);
         ObjectSetInteger(chartID,objName,OBJPROP_ANCHOR,    ANCHOR_LEFT_UPPER);
         ObjectSetInteger(chartID,objName,OBJPROP_BACK,      labelState[i]); 
         ObjectSetInteger(chartID,objName,OBJPROP_SELECTABLE,false); 
         ObjectSetInteger(chartID,objName,OBJPROP_SELECTED,  false); 
         ObjectSetInteger(chartID,objName,OBJPROP_HIDDEN,    true);
       }
      ObjectSetInteger(chartID,objName,OBJPROP_XDISTANCE,    labelXpos[i] );
      ObjectSetInteger(chartID,objName,OBJPROP_YDISTANCE,    labelYpos[i] );
      ObjectSetString (chartID,objName,OBJPROP_TEXT,         labelStr[i] );
    }
 }
void makeBackgroundBox(void)
 {
   long chart_ID = ChartID();
   for(ENUM_BKGRND_BOX i = 0; i<endBkBoxs ; i++)
    {
      if (ObjectFind(bkgrndNames[i]) < 0)
       {
         ObjectCreate(    chart_ID,bkgrndNames[i],OBJ_RECTANGLE_LABEL,CHARTWINDOW,0,0);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_XSIZE,      bkgrndXSize[i]);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_YSIZE,      bkgrndYSize[i]);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_BGCOLOR,    bkgrndClrs[i]);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_BORDER_TYPE,BORDER_SUNKEN);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_CORNER,     CORNER_LEFT_UPPER);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_BACK,       bkGrndState[i]);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_HIDDEN,     true);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_SELECTABLE, false);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_SELECTED,   false);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_COLOR,      clrNONE);              // We set a not flat border, so it should have no color
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_STYLE,      STYLE_SOLID);
         ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_WIDTH,      NOWIDTH); 
       }
      ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_XDISTANCE,     bkgrndXpos[i]);
      ObjectSetInteger(chart_ID,bkgrndNames[i],OBJPROP_YDISTANCE,     bkgrndYpos[i]);
    }
 }
//
string getPriceMarksGlobalName(void)
 {
   return( IntegerToString(UniqueID)+"PriceMarksGolbalName" );
 }
ENUM_ON_OFF getPriceMarksGlobalValue(void)
 {
   double onOffDouble;
   if( !GlobalVariableGet(getPriceMarksGlobalName(),onOffDouble) )
    {
      onOffDouble = ON;
    }
   return( (ENUM_ON_OFF) onOffDouble );
 }
//
void performAlerting(int& selector, int& highSent, int& lowSent)
 {
   if (EnableAlert)
    {
      if (selector == 1 && highSent == 0)
       {
         Alert(Symbol(), " - ", "BUY - UP DIRECTION !");
         if(SignalSound == ON )
          {
            PlaySound(SoundFilename);
          }
         highSent++;
       }
      if (selector == -1 && lowSent == 0)
       {
         Alert(Symbol(), " - ", "SELL - DOWN DIRECTION !");
         if(SignalSound == ON )
          {
            PlaySound(SoundFilename);
          }
         lowSent++;
       }
    }
 }
//
//+------------------------------------------------------------------+
//| Begin C_MarketChangeInfo Class Method definitions                |
//+------------------------------------------------------------------+
void C_MarketChangeInfo::C_MarketChangeInfo(void)
 {
   lastBarTime = NULL;
   averagingRange = 5; kPeriod = 20; dPeriod = 12; slowing = 12;
   newBarUpdates();
   PRICE_MARKS_ON_OFF = OFF;
 }
string C_MarketChangeInfo::getPriceMarkName(void)
 {
   string nameString;
   int arraySize = ArraySize(priceMarkNames);
   if(ArrayResize(priceMarkNames,arraySize+1)>0)  // success if >0
    {
      nameString = IntegerToString(UniqueID)+"Price_Mark"+IntegerToString(ArraySize(priceMarkNames));
      priceMarkNames[arraySize]= nameString;
    }
   else
    {
      nameString = "";
      Print(__FUNCTION__,", Array Resize error: ",IntegerToString(GetLastError()),", ",ErrorDescription(GetLastError()));
    }
   return(nameString);
 }
void C_MarketChangeInfo::newBarUpdates(void)
 {
   if(Time[0]>lastBarTime)
    {
      stochVal = iStochastic(Symbol(), PERIOD_CURRENT, kPeriod, dPeriod, slowing, MODE_EMA, (int)CLOSE_CLOSE, MODE_MAIN, NOSHIFT);
      double barsAverageRange=0;
      for(int i= ONESHIFT; i<=averagingRange; i++)
       {
         barsAverageRange += High[i]-Low[i];
       }
      barsAverageRange /= averagingRange;
      rangeVal = (1.45 * MathRound(barsAverageRange * MathPow(7, Digits)))*2.0;
    }
 }
void C_MarketChangeInfo::deletePriceMarks(void)
 {
   for(int i = 0; i<ArraySize(priceMarkNames); i++)
    {
      ObjectDelete(priceMarkNames[i]);
    }
   ArrayResize(priceMarkNames,0);
 }
void C_MarketChangeInfo::makePriceMark(void)
 {
   if( PRICE_MARKS_ON_OFF == ON )
    {
      string objNameStr = getPriceMarkName();
      if(objNameStr != "" )  // Go a valid name
       {
         long chartID = ChartID();
         ENUM_OBJECT leftOrRight = ((lastSignal.operation==OP_BUY)?OBJ_ARROW_RIGHT_PRICE:OBJ_ARROW_LEFT_PRICE);
         color priceClr = ((lastSignal.operation==OP_BUY)?clrLimeGreen:clrMediumVioletRed);
         int windowIndex = ObjectFind(objNameStr);
         if( windowIndex < 0 )                      // Not found, create - This should be the case every time in this implementation
          {
            ObjectCreate    ( chartID, objNameStr, leftOrRight,        CHARTWINDOW, lastSignal.entryTime, lastSignal.entry );
            ObjectSetInteger( chartID, objNameStr, OBJPROP_COLOR,      priceClr);
            ObjectSetInteger( chartID, objNameStr, OBJPROP_STYLE,      STYLE_SOLID);
            ObjectSetInteger( chartID, objNameStr, OBJPROP_WIDTH,      3 );
            ObjectSetInteger( chartID, objNameStr, OBJPROP_BACK,       false);
            ObjectSetInteger( chartID, objNameStr, OBJPROP_SELECTABLE, false);
            ObjectSetInteger( chartID, objNameStr, OBJPROP_SELECTED,   false);
            ObjectSetInteger( chartID, objNameStr, OBJPROP_HIDDEN,     true);
          }
         ObjectSetInteger(chartID, objNameStr, OBJPROP_COLOR,      priceClr);
         ObjectSetDouble( chartID, objNameStr, OBJPROP_PRICE,      lastSignal.entry);
         ObjectSetInteger(chartID, objNameStr, OBJPROP_TIME,       lastSignal.entryTime);
       }
    }
 }
static C_MarketChangeInfo* C_MarketChangeInfo::GetInstance(void) // A Static Function that will provide a pointer to 'this'
 {
   if(marketRangeInfo == NULL) // Does the private m_yoLinux pointer point or not?
   {
      marketRangeInfo=new C_MarketChangeInfo;     // Create Class Object on Demand, put the pointer in the pivate, static pointer
      if(marketRangeInfo == NULL)  // Object Creation Failed, this environment is toast
       {
         Print(__FUNCTION__,", Object Creation Failed: ",IntegerToString(GetLastError()),", ",ErrorDescription(GetLastError()));
       }
   }
   return(marketRangeInfo);               // Return a pointer to the one and only object of this class.
 }
void C_MarketChangeInfo::~C_MarketChangeInfo(void)
 {
   deletePriceMarks();
   C_MarketChangeInfo::marketRangeInfo=NULL;
 }
string C_MarketChangeInfo::getRiskText(void)
 {
   newBarUpdates();
   string marketText;
   if (stochVal <= 75.0 && stochVal >= 25.0) {
      marketText = "RANGING AREA";
    } else if (stochVal > 75.0 && stochVal <= 88.0) {
      marketText = "S/R AREA";
    } else if (stochVal < 25.0 && stochVal >= 12.0) {
      marketText = "S/R AREA";
    } else if (stochVal > 88.0) {
      marketText = "HIGH RISK!";
    } else if (stochVal < 12.0) {
      marketText = "HIGH RISK!";
    }
   return(marketText);
 }
string C_MarketChangeInfo::getStochStrVal(void)
 {
   newBarUpdates();
   return(DoubleToStr(stochVal,1));
 }
string C_MarketChangeInfo::getMrktRange(void)
 {
   newBarUpdates();
   return(DoubleToStr(rangeVal, 0));
 }
void C_MarketChangeInfo::setLastSignal(int tradeType, double entryPrice, datetime signalTime)
 {
   newBarUpdates();
   lastSignal.entry      = entryPrice;
   lastSignal.operation  = tradeType;
   lastSignal.entryTime  = signalTime;
   lastSignal.stopLoss   = (tradeType==OP_BUY)?(entryPrice-(rangeVal*PIPpoint)):(entryPrice+(rangeVal*PIPpoint));
   lastSignal.takeProfit = (tradeType==OP_BUY)?(entryPrice+(rangeVal*PIPpoint)):(entryPrice-(rangeVal*PIPpoint));
   makePriceMark();
 }
string C_MarketChangeInfo::getLastSignalStr(void)
 {
   string signalStr;
   if( lastSignal.entry > NULL )
    {
      signalStr = ((lastSignal.operation==OP_BUY)?"Buy, ":"Sell, ")+DoubleToStr(lastSignal.entry,Digits);
    }
   else
    {
      signalStr = "None";
    }
   return( signalStr );
 }
void C_MarketChangeInfo::setPriceMarksState(ENUM_ON_OFF onOff)
 {
   if( (PRICE_MARKS_ON_OFF == ON) && (onOff == OFF) )  // Being Turned Off
    {
      deletePriceMarks();
    }
   PRICE_MARKS_ON_OFF = onOff;
 }
ENUM_ON_OFF C_MarketChangeInfo::getPriceMarksState(void)
 {
   return(PRICE_MARKS_ON_OFF);
 }
//+------------------------------------------------------------------+
//| END C_MarketChangeInfo Class Method definitions                  |
//+------------------------------------------------------------------+
//