//+------------------------------------------------------------------+
//|                                      RevealWormhole_1min_5min_01 |
//+------------------------------------------------------------------+
/*
Attach to any chart, any timeframe.

Timeframes 1-minute and 5-minute 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     =  960111;
extern int    M1_K_PERIOD     =  500;
extern int    M5_K_PERIOD     =  100;
extern bool   ZeroMarkOnStart = true;


//+------------------------------------------------------------------+
//|              Internal Variables                                  |
//+------------------------------------------------------------------+

int AccountTypeVal;

bool AccountIsMini;
bool BidsHaveChanged = false;

string AccountTypeString;

string StoDeltaRateMark;      double valStoDeltaRateMark;

string SubCommentString, CommentString;

double Spread, prevBid, PipsFromMark;
double Min5Stochastic, Min1Stochastic;



//+------------------------------------------------------------------+
//|   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 (ZeroMarkOnStart)
  {
    GlobalVariableSet(StoDeltaRateMark, 0.0);
    ObjectDelete("Price of Last Stochastic Mismatch");
  }
  else
  {
    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()
{
  Min1Stochastic = iStochastic (NULL, PERIOD_M1, M1_K_PERIOD, 1, 1, MODE_SMA, 0, MODE_MAIN, 0);
  Min5Stochastic = iStochastic (NULL, PERIOD_M5, M5_K_PERIOD, 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); 
    }
    else
    {
      ObjectDelete("Price of Last Stochastic Mismatch");
    }

    if (Min1Stochastic == Min5Stochastic)
    {
      SubCommentString = "Insignificant";
    
      if (valStoDeltaRateMark != 0.0)
      {
        SubCommentString = "Insignificant";
      
        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";
        }
      }
      else
      {
        SubCommentString = "No Mismatch Yet";
      }

      CommentString = 
          "\nPURPOSE: Show the price on the chart where different-timeframe stochastics last disagreed." +
          "\n\n1-Min Stochastic: " + DoubleToStr(Min1Stochastic,5) +
          "\n5-min   Stochastic: " + DoubleToStr(Min5Stochastic,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(Min5Stochastic - Min1Stochastic,5)) +
          " at Price Level " + Bid;
      CommentString =
          SubCommentString +
          "\n\nPURPOSE: Show the price on the chart where different-timeframe stochastics last disagreed." +
          "\n\n1-Min Stochastic: " + DoubleToStr(Min1Stochastic,5) +
          "\n5-min   Stochastic: " + DoubleToStr(Min5Stochastic,5) + 
          "\n\nSto Delta Rate Mark: " + DoubleToStr(valStoDeltaRateMark,5) + 
          "\n\nAccount Type: " + AccountTypeString + " Account";

      valStoDeltaRateMark = Bid;
      GlobalVariableSet(StoDeltaRateMark, valStoDeltaRateMark);

      Print(SubCommentString);

    }      
  }
  Comment(CommentString);

  return;
}

