//+------------------------------------------------------------------+
//|                                        NeutralHedge osc_v3.1.mq4 |
//|                                            © 2008.07.02 SwingMan |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "© 2008.07.02 SwingMan"
#property link      ""
// source code:
//+------------------------------------------------------------------+
//|                                       OverLay Chart.mq4 Ver.1.10 |
//|                                      Copyright© 2006-2007 S.B.T. |
//|                                     http://sufx.core.t3-ism.net/ |
//+------------------- DO NOT REMOVE THIS HEADER --------------------+
//|  This script is free to use/distribute/modify and re-distribute. |
//|                                  (Limited to noncommercial use.) |
//+------------------------------------------------------------------+
// changes:
//+------------------------------------------------------------------+
// - fewhills  / 2008.07.02
// I have modified the indicator with 2 extra parameters: starting time and TF period.
// The time parameter is the usual MT4 method: yyyy.mm.dd hh:mm
// The TF period is default at 1 Hr TF = 60 
//+------------------------------------------------------------------+
// - SwingMan / 2008.07.02
// v1 - draw histogram of ratios
// v2 - write trading results
// v3 - calculation of threshold with StdDev
//    - take automatic more as40 bars
// v3.1 - mrkam will have moreBars (500...)
//+------------------------------------------------------------------+

#property indicator_separate_window
#property indicator_buffers 2

#property indicator_color1 MediumSeaGreen
#property indicator_color2 Tomato

#property indicator_level1 0
#property indicator_levelcolor Gray
#property indicator_levelstyle STYLE_SOLID

//---- inputs --------------------------------------------------------
extern string SubSymbol = "EURUSD";
extern int moreBars = 0;
extern string StartingTimeCorr = "2008.07.01 00:00";
extern int    TFperiod         = 60;
extern double threshold = 0;
extern double Factor_Threshold = 1.5;
extern string EntryTime = "";
extern string _____Order____ = "BUY=0,  SELL=1";
extern int Order_Main = -1;
extern color threshold_color = Magenta;
extern bool Mirroring = true;
//--------------------------------------------------------------------

//---- constants
string sWinName1 = "NeutralHedge osc_v3.1", sWinName;
string sObject = "NH31_";
int fontSize_Text = 8;
int iLabelCorner = 1;
int xx1 = 80;
int xx2 = 2;
int xx3 = 60;
int xx4 = 30;
int yy0 = 3, yy;
int yStep = 10;

//Indicator Buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];

//-- variables
double dPoint;
int iWindow;
int firstBar;
int _BarsCount, _LastBar;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   dPoint = MarketInfo(Symbol(), MODE_POINT);   
      
   sWinName = sWinName1 + " (" + Symbol() + "-" + SubSymbol + ")";
   IndicatorShortName(sWinName);   
   sObject = sObject + moreBars + "_";
   
   SetIndexBuffer( 0, ExtMapBuffer1 );
   SetIndexBuffer( 1, ExtMapBuffer2 );

   SetIndexStyle( 0, DRAW_HISTOGRAM, STYLE_SOLID, 2);
   SetIndexStyle( 1, DRAW_HISTOGRAM, STYLE_SOLID, 2);
   
   SetIndexEmptyValue( 0, 0.0 );
   SetIndexEmptyValue( 1, 0.0 );

   SetIndexLabel( 0, "BUY -" +Symbol() );
   SetIndexLabel( 1, "SELL-" +Symbol() );
      
   IndicatorDigits(Digits);
   
   DeleteOwnObjects();
   iWindow = WindowFind(sWinName);
   Draw_ThresholdLines();
   
   return(0);
}


//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{  
   DeleteOwnObjects();
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{   
   double _CurRangeHigh, _CurRangeLow, _CurRangeCenter, _CurClose;
   double _SubRangeHigh, _SubRangeLow, _SubRangeCenter;
   double _SubPoint, _SubDigit;
   double _SubOpen, _SubHigh, _SubLow, _SubClose;
   double _PipsRatio;
   double _GridPips, _GridPrice;
   int _i;

   firstBar = iBarShift(NULL,TFperiod,StrToTime(StartingTimeCorr),true);
   if (firstBar <0 )
   {
      Alert("StartingTimeCorr seems to be wrong."); return (0);
   }
       
   //-- Initialize Buffers
	RefreshRates();
   ArrayInitialize( ExtMapBuffer1, 0.0 );
   ArrayInitialize( ExtMapBuffer2, 0.0 );

   /*//-- Calculate Visible Bars
   _BarsCount = WindowBarsPerChart() + 1;
   int _FirstBar = firstBar; // WindowFirstVisibleBar();
   _LastBar = _FirstBar - _BarsCount + 1;
   if ( _LastBar < 0 ) {
      _LastBar = 0;
      _BarsCount = _FirstBar + 1;
   }*/
   
   //-- Calculate Visible Bars // // v3.1 - mrkam will have 500 bars...
   _BarsCount = WindowBarsPerChart() +  moreBars  +1;
   int _FirstBar = firstBar; // WindowFirstVisibleBar();
   int _LastBar = _FirstBar - _BarsCount +  moreBars  +1 ;
   if ( _LastBar < 0 ) {
      _LastBar = 0;
      _BarsCount = _FirstBar +  moreBars +1 ;
   }

   //-- Calculate Chart Ratio
   _CurRangeHigh = High[Highest(Symbol(), 0, MODE_HIGH, _BarsCount, _LastBar)];
   _CurRangeLow  = Low[Lowest(Symbol(), 0, MODE_LOW, _BarsCount, _LastBar)];
   _CurRangeCenter = ( _CurRangeHigh + _CurRangeLow ) * 0.5;
      
   if ( Mirroring ) {
      _SubRangeHigh = iLow( SubSymbol, 0, Lowest( SubSymbol, 0, MODE_LOW, _BarsCount, _LastBar ) );
      _SubRangeLow  = iHigh( SubSymbol, 0, Highest( SubSymbol, 0, MODE_HIGH, _BarsCount, _LastBar ) );
   } else {
      _SubRangeHigh = iHigh( SubSymbol, 0, Highest( SubSymbol, 0, MODE_HIGH, _BarsCount, _LastBar ) );
      _SubRangeLow  = iLow( SubSymbol, 0, Lowest( SubSymbol, 0, MODE_LOW, _BarsCount, _LastBar ) );
   }

   _SubRangeCenter = ( _SubRangeHigh + _SubRangeLow ) * 0.5;
   _SubPoint = MarketInfo( SubSymbol, MODE_POINT );
   _SubDigit = MarketInfo( SubSymbol, MODE_DIGITS );

   _PipsRatio = ( _CurRangeHigh - _CurRangeLow )  / ( _SubRangeHigh - _SubRangeLow );

   //-- Draw ratio
	for ( _i = _LastBar; _i < _LastBar + _BarsCount; _i ++ ) {
      _SubClose = iClose( SubSymbol, 0, _i ) - _SubRangeCenter;      

      double Close_Sub = _CurRangeCenter + _SubClose * _PipsRatio;     
      double Close_Main = iClose(Symbol(), 0, _i);
      double range = (Close_Main - Close_Sub) / dPoint;      
      range = NormalizeDouble(range,0);
      
      if (range > 0) 
        ExtMapBuffer2[_i] = range; 
      else 
        ExtMapBuffer1[_i] = range;
   } 

   if (threshold == 0) {
      Get_ThresholdValue();
      Draw_ThresholdLines();
   }
   //-- write win/loss
   Write_WinLossTrading();
//----
   return(0);
}
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//    Get Threshold Value
//+------------------------------------------------------------------+
void Get_ThresholdValue()
{
   double RangeCloses[200];
   ArraySetAsSeries(RangeCloses,true);
   
   //int Period_Statistic = firstBar;
   int Period_Statistic = _BarsCount; // = _FirstBar + 1;
   int i = -1;
   
   for ( int _i = _LastBar; _i < _LastBar + _BarsCount; _i ++ )   
   {
      i++;
      if (ExtMapBuffer1[i] > 0 && ExtMapBuffer1[i] != EMPTY_VALUE)
         RangeCloses[i] = ExtMapBuffer1[i];
      else
      if (ExtMapBuffer2[i] > 0 && ExtMapBuffer2[i] != EMPTY_VALUE)
         RangeCloses[i] = ExtMapBuffer2[i];
   }
   
   //-- take only the minim differences
   double MedRanges = iMAOnArray(RangeCloses,0,Period_Statistic,1,MODE_SMA,0);
   double DevRanges = iStdDevOnArray(RangeCloses,0,Period_Statistic,1,MODE_SMA,0);
   threshold = MedRanges + Factor_Threshold * DevRanges;
}   

//+------------------------------------------------------------------+
//    Draw Threshold Lines
//+------------------------------------------------------------------+
void Write_WinLossTrading()
{
   double WinLoss;
   string text1, text2, sOrder, sEmpty;
      
   //EntryTime = "2008.07.02 20:00";   
   if (EntryTime == "") return;
   yy = yy0;
   
   int entryBar = iBarShift(Symbol(),TFperiod,StrToTime(EntryTime),true);
   double Entry_Main = iClose(Symbol(), 0, entryBar);
   double Entry_Sub  = iClose(SubSymbol, 0, entryBar);
   double Price_Main = iClose(Symbol(), 0, 0);
   double Price_Sub  = iClose(SubSymbol, 0, 0);
   
   WinLoss = 0;   
   if (Order_Main == OP_BUY) {
      WinLoss = (Price_Main - Entry_Main) + (Entry_Sub - Price_Sub);
      sOrder = Symbol() + "-BUY:";
   } else 
   if (Order_Main == OP_SELL) {
      WinLoss = -(Price_Main - Entry_Main) - (Entry_Sub - Price_Sub);
      sOrder = Symbol() + "-SELL:";
   } else {
      Entry_Main = 0;
      Entry_Sub  = 0;
      sOrder = "Order_Main:";
      sEmpty = "EMPTY";
   }
   WinLoss = WinLoss / dPoint;

   //......................................................
   text1 = "Entry time:";
   text2 = EntryTime;
   Write_Label(text1, text2, xx1+10, xx2, yy); yy = yy + yStep;

   //......................................................
   text1 = sOrder;
   if (sOrder == "Order_Main:") {
      text2 = sEmpty;
      int xx5 = xx4;
   } else {
      text2 = DoubleToStr(Entry_Main,Digits) + " / " + DoubleToStr(Entry_Sub,Digits);
      xx5 = xx2;
   }   
   Write_Label(text1, text2, xx1, xx5, yy); yy = yy + yStep;
   
   //......................................................
   text1 = "Current price:";
   text2 = DoubleToStr(Price_Main,Digits) + " / " + DoubleToStr(Price_Sub,Digits);
   Write_Label(text1, text2, xx1, xx2, yy); yy = yy + yStep;
   
   //......................................................
   text1 = "WinLoss:";
   text2 = DoubleToStr(WinLoss,0);
   Write_Label(text1, text2, xx1, xx3, yy); yy = yy + yStep;   
}

void Write_Label(string text1, string text2, int xx1, int xx2, int yy)
{
   color dColor = Orange;
   string name1 = sObject + "1" + yy;
   string name2 = sObject + "2" + yy;
   SetLabelObject(name1, text1, dColor, xx1, yy);
   SetLabelObject(name2, text2, dColor, xx2, yy);
   return;
}

void SetLabelObject(string sName, string sText, color dColor, int xx, int yy)
{
   ObjectCreate(sName, OBJ_LABEL, iWindow, 0, 0);
        ObjectSetText(sName,sText,fontSize_Text, "Arial Bold", dColor);
        ObjectSet(sName, OBJPROP_CORNER, iLabelCorner);
        ObjectSet(sName, OBJPROP_XDISTANCE, xx);
        ObjectSet(sName, OBJPROP_YDISTANCE, yy);
   return;     
}

void DeleteOwnObjects()
{
   int i=0;
   while (i <= ObjectsTotal()) {
      if (StringFind(ObjectName(i), sObject) >= 0) ObjectDelete(ObjectName(i));
      else
      i++;
   }
   return;
}


//+------------------------------------------------------------------+
//    Draw Threshold Lines
//+------------------------------------------------------------------+
void Draw_ThresholdLines()
{
   iWindow = WindowFind(sWinName);
   Draw_Line("threshLineUp"+sObject,  threshold, threshold_color);
   Draw_Line("threshLineDn"+sObject, -threshold, threshold_color);
   return;
}

void Draw_Line(string sName, double value, color iColor)
{   
   ObjectCreate(sName, OBJ_HLINE, iWindow, 0, value);
   ObjectSet(sName, OBJPROP_COLOR, iColor);
   ObjectSet(sName, OBJPROP_STYLE, STYLE_SOLID);
   ObjectSet(sName, OBJPROP_TIME1, 0);
   ObjectSet(sName, OBJPROP_PRICE1, value);
   return;
}

