//+------------------------------------------------------------------+
//|                                                RevealWormhole_01 |
//+------------------------------------------------------------------+
/*
Attach to any chart, any timeframe.

Timeframes H1 and M30 will be compared unless the source code is
changed.

The price level where the most recent stochastic difference between
the two timeframes was detected will be shown as a horizontal line
on the chart.
*/

//+------------------------------------------------------------------+
//|              External Variables                                  |
//+------------------------------------------------------------------+

extern int    MiniSize    =   10000;
extern int    StdSize     =  100000;

extern int    MagicNumber =  960117;


//+------------------------------------------------------------------+
//|              Internal Variables                                  |
//+------------------------------------------------------------------+

int AccountTypeVal;

bool AccountIsMini;
bool BidsHaveChanged = false;

string AccountTypeString;

string StoDeltaRateMark;      double valStoDeltaRateMark;

string SubCommentString, CommentString;

double Spread, prevBid, PipsFromMark;
double HourStochastic, Min30Stochastic;



//+------------------------------------------------------------------+
//|   Expert Advisor Initialization, executes only when the EA is    |
//|   first attached to a chart or on platform  restart.             |
//+------------------------------------------------------------------+

int init()
{
  SetGlobalVariableNames();
  InitGlobalVars();

  return (0);
}

//+------------------------------------------------------------------+
//|    Expert Advisor start function, executes on each tick of the   |
//|    currecy pair it's attached to.                                |
//+------------------------------------------------------------------+

int start()
{
  Spread = Ask - Bid;

  RefreshGlobalVars();
  GetAccountInfo();  
  GetStochasticValues();
  SetAccountType();

  BidsHaveChanged = prevBid != 0.0 && prevBid != Bid;

  prevBid = Bid;

  PrintChartComments();
    
  return(0);
}

//+------------------------------------------------------------------+
//|          Assign values to global variable namestrings.           |
//+------------------------------------------------------------------+

void SetGlobalVariableNames()
{
  StoDeltaRateMark = MagicNumber+"_"+Symbol()+"_StoDeltaRateMark";

  return;
}

//+------------------------------------------------------------------+
//|            Assign initial values to global variables.            |
//+------------------------------------------------------------------+

void InitGlobalVars()
{
  if (!GlobalVariableCheck(StoDeltaRateMark)) GlobalVariableSet(StoDeltaRateMark, 0.0);

  return;
}

//+------------------------------------------------------------------+
//|   Get global variable values via their namestring and assign the |
//|   stored values to the variables used in the EA's logic.         |
//+------------------------------------------------------------------+

void RefreshGlobalVars()
{
  valStoDeltaRateMark = GlobalVariableGet(StoDeltaRateMark);

  return;
}

//+------------------------------------------------------------------+
//|  Get important account parameters that affect how the lot size   |
//|  will be set.                                                    |
//+------------------------------------------------------------------+

void GetAccountInfo()
{
  // Get account type.

  AccountTypeVal = MarketInfo(Symbol(), MODE_LOTSIZE);

  return;
}

//+------------------------------------------------------------------+
//|                      Get Stochastic Values.                      |
//+------------------------------------------------------------------+

void GetStochasticValues()
{
  HourStochastic  = iStochastic (NULL, PERIOD_H1,  300, 1, 1, MODE_SMA, 0, MODE_MAIN, 0);
  Min30Stochastic = iStochastic (NULL, PERIOD_M30, 600, 1, 1, MODE_SMA, 0, MODE_MAIN, 0);

  return;
}


//+------------------------------------------------------------------+
//|             Set the account type and minimum equity.             |
//+------------------------------------------------------------------+

void SetAccountType()
{
  if (AccountTypeVal == MiniSize || StringLen(Symbol()) == 7)
  {
    AccountIsMini     = true;
    AccountTypeString = "MINI";
  }
  else if (AccountTypeVal == StdSize || StringLen(Symbol()) == 6)
  {
    AccountIsMini     = false;
    AccountTypeString = "STANDARD";
  }
  
  return;
}


//+------------------------------------------------------------------+
//|                      Print Info to Chart                         |
//+------------------------------------------------------------------+

void PrintChartComments()
{
  if (BidsHaveChanged)
  {
    if (valStoDeltaRateMark != 0.0)
    {
      ObjectDelete("Price of Last Stochastic Mismatch");
      ObjectCreate("Price of Last Stochastic Mismatch", OBJ_HLINE, 0, Time[0], valStoDeltaRateMark, 0, 0); 
    }

    if (HourStochastic == Min30Stochastic)
    {
      SubCommentString = "Insignificant";
    
      if (valStoDeltaRateMark != 0.0)
      {
        if (Bid > valStoDeltaRateMark + Spread + _Point)
        {
          PipsFromMark = (Bid - (valStoDeltaRateMark + Spread))/_Point;
          SubCommentString = DoubleToStr(PipsFromMark, 2) + " Above";
        }
        else
        if (Ask < valStoDeltaRateMark - _Point)
        {
          PipsFromMark = (valStoDeltaRateMark - Ask)/_Point;
          SubCommentString = DoubleToStr(PipsFromMark, 2) + " Below";
        }
      }

      CommentString = 
          "\nPURPOSE: Show the level on the chart where different-timeframe stochastics disagree." +
          "\n\nHour   Stochastic: " + DoubleToStr(HourStochastic,5) + 
          "\n30-Min Stochastic: " + DoubleToStr(Min30Stochastic,5) +
          "\n\nSto Delta Rate Mark: " + DoubleToStr(valStoDeltaRateMark,5) + 
          "\n\nPoint Value: " + DoubleToStr(_Point,5) +
          "\nPoint distance from Stochastic Delta Mark: " + SubCommentString +
          "\n\nAccount Type: " + AccountTypeString + " Account";
    }
    else
    {
      SubCommentString = "\n*** DISTORTION EXISTS!!!! ***" +
          "  Distortion Delta: " + MathAbs(DoubleToStr(HourStochastic - Min30Stochastic,5)) +
          " at Price Level " + Bid;
      CommentString =
          SubCommentString +
          "\n\nPURPOSE: Show the level on the chart where different-timeframe stochastics disagree." +
          "\n\nHour   Stochastic: " + DoubleToStr(HourStochastic,5) + 
          "\n30-Min Stochastic: " + DoubleToStr(Min30Stochastic,5) +
          "\n\nSto Delta Rate Mark: " + DoubleToStr(valStoDeltaRateMark,5) + 
          "\n\nAccount Type: " + AccountTypeString + " Account";

      valStoDeltaRateMark = Bid;
      GlobalVariableSet(StoDeltaRateMark, valStoDeltaRateMark);

      Print(SubCommentString);

    }      
  }
  Comment(CommentString);

  return;
}

