//+------------------------------------------------------------------+
//|                                                Rj_HSlice 1.1.mq4 |
//|                           Copyright © 2011, RJ Rjabkov Aleksandr |
//|                                                     rj-a@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, RJ Rjabkov Aleksandr"
#property link      "rj-a@mail.ru"
#property indicator_chart_window
extern int    DepthCalcDay      = 30;
extern double UpdateTime        = 1;
extern int    CalcPeriod        = 1;
extern double PercentDiscrep    = 0.2;
extern bool   ShowLevelsOn      = true;
extern bool   ShowTurningOn     = true;
extern bool   ShowContractOn    = true;
extern bool   BackgroundLevelOn = true;
extern color  ColorLine         = Aqua;
double lBuy[];
double lSell[];
double ValueCall[][2], ValuePut[][2];
static datetime LastTime=0;
static datetime StartTime=1;
int init() {
  return(0);
}
int deinit() {
  for (int i=0; i<4000; i++) {
    ObjectDelete("vhb "+i); 
    ObjectDelete("V "+i);
    ObjectDelete("H "+i);
  }
  Comment("");
  return(0);
}
 
int start() {
  if(LastTime < StartTime) {
    int i, j, MaxVolume, EndTime, VolSlice;
    color ColLine;
    int TimeVisiblBar = WindowBarsPerChart()-WindowFirstVisibleBar();
    double MaxPrice = iHigh(NULL, PERIOD_D1, 0);
    double MinPrice = iLow(NULL, PERIOD_D1, 0);
    for(j=DepthCalcDay; j>=0; j--) {
      MaxPrice = MathMax(MaxPrice, iHigh(NULL, PERIOD_D1, j));
      MinPrice = MathMin(MinPrice, iLow(NULL, PERIOD_D1, j));
    }
    int Range = MathRound((MaxPrice-MinPrice)/Point);
    
    ArrayResize(lBuy, Range+1);
    ArrayInitialize(lBuy, 0.0);
    ArrayResize(lSell, Range+1);
    ArrayInitialize(lSell, 0.0);
    string DataComment="";
    switch(CalcPeriod) {
      case 1: DataComment="ìèíóòíûé"; break;
      case 5: DataComment="ïÿòü ìèíóò"; break;
      case 15: DataComment="ïÿòíàäöàòü ìèíóò"; break;
      case 30: DataComment="òðèäöàòü ìèíóò"; break;
      case 60: DataComment="÷àñîâîé"; break;
      case 240: DataComment="÷åòûðå ÷àñà"; break;
      case 1440: DataComment="äíåâíîé"; break;
      case 10080: DataComment="íåäåëüíûé"; break;
      case 43200: DataComment="ìåñÿ÷íûé"; break;
      default : DataComment="òåêóùèé"; break;
    }
    Comment("\n Ïåðèîä ðàñ÷¸òà äàííûõ: "+DataComment);
    
    if(CalcPeriod>1 && CalcPeriod<5) {CalcPeriod=5; DataComment="ïÿòü ìèíóò";}
    if(CalcPeriod>5 && CalcPeriod<15) {CalcPeriod=15; DataComment="ïÿòíàäöàòü ìèíóò";}
    if(CalcPeriod>15 && CalcPeriod<30) {CalcPeriod=30; DataComment="òðèäöàòü ìèíóò";}
    if(CalcPeriod>30 && CalcPeriod<60) {CalcPeriod=60; DataComment="÷àñîâîé";}
    if(CalcPeriod>60 && CalcPeriod<240) {CalcPeriod=240; DataComment="÷åòûðå ÷àñà";}
    if(CalcPeriod>240 && CalcPeriod<1440) {CalcPeriod=1440; DataComment="äíåâíîé";}
    if(CalcPeriod>1440 && CalcPeriod<10080) {CalcPeriod=10080; DataComment="íåäåëüíûé";}
    if(CalcPeriod>10080 && CalcPeriod<43200) {CalcPeriod=43200; DataComment="ìåñÿ÷íûé";}
    if(CalcPeriod>43200) {CalcPeriod=43200; DataComment="ìåñÿ÷íûé";}
    
    
    for(i=0; i<=Range; i++) {
      lBuy[i]  = iCustom(NULL, CalcPeriod, "Rj_Volume", DepthCalcDay, 0, i);
      lSell[i] = iCustom(NULL, CalcPeriod, "Rj_Volume", DepthCalcDay, 1, i);
    }
    
    if(MathRound(lBuy[ArrayMaximum(lBuy)])>=MathRound(lSell[ArrayMaximum(lSell)])) MaxVolume=MathRound(lBuy[ArrayMaximum(lBuy)]); 
    else MaxVolume=MathRound(lSell[ArrayMaximum(lSell)]);
    
    if(TimeVisiblBar<=2) TimeVisiblBar=50;
    
    for (i=0; i<=4000; i++) {
      ObjectDelete("vhb "+i); 
      ObjectDelete("V "+i);
      ObjectDelete("H "+i);
    }
    
    if(ShowLevelsOn) {
      for(i=0; i<=Range; i++) {
        if(BackgroundLevelOn) {
          if(lBuy[i]>lSell[i]) ColLine=C'64,136,50';
          if(lBuy[i]<lSell[i]) ColLine=C'218,118,125';
          if(lBuy[i]==lSell[i]) ColLine=Aqua;
          ObjectCreate("vhb "+i, OBJ_RECTANGLE, 0, TimeStart(), MinPrice+i*Point, iTime(NULL, PERIOD_D1, DepthCalcDay), MinPrice+(i+1)*Point);
          ObjectSet("vhb "+i, OBJPROP_STYLE, DRAW_HISTOGRAM);
          ObjectSet("vhb "+i, OBJPROP_COLOR, ColLine);
          ObjectSet("vhb "+i, OBJPROP_BACK, true);
        }
        if(!BackgroundLevelOn) {
          if(lBuy[i]>lSell[i]) {
            EndTime = TimeStart()-(TimeVisiblBar-1)*Period()*60;
            ColLine=C'64,136,50';
          }
          if(lBuy[i]<lSell[i]) {
            EndTime = TimeStart()-(TimeVisiblBar-1)*Period()*60;
            ColLine=C'218,118,125';
          }
          if(lBuy[i]==lSell[i]) {
            EndTime = TimeStart()-(TimeVisiblBar-1)*Period()*60;
            ColLine=Aqua;
          }
          ObjectCreate("vhb "+i, OBJ_RECTANGLE, 0, TimeStart(), MinPrice+i*Point, EndTime, MinPrice+(i+1)*Point);
          ObjectSet("vhb "+i, OBJPROP_STYLE, DRAW_HISTOGRAM);
          ObjectSet("vhb "+i, OBJPROP_COLOR, ColLine);
          ObjectSet("vhb "+i, OBJPROP_BACK, true);
        }
      }
    }
    InstallVolume(lBuy, lSell, MinPrice, TimeVisiblBar, ValueCall, ValuePut);
    CalcTurning(ValueCall, ValuePut);
    StartTime=MathRound(TimeCurrent()+UpdateTime*60);
  }
  LastTime = TimeCurrent();
  return(0);
}
//+------------------------------------------------------------------+
datetime TimeStart() {
  int Indention = Time[0]+(WindowBarsPerChart()-WindowFirstVisibleBar())*Period()*60;
  return(Indention);
}
void InstallVolume(double ArrBuy[], double ArrSell[], double pos, int TimePos, double& ArrCall[][], double& ArrPut[][]) {
  int shift, j, indexCall=0, indexPut=0, inc;
  double DifBuy[], DifSell[], exit;
  
  ArrayResize(DifBuy, ArraySize(ArrBuy)+1);
  ArrayInitialize(DifBuy, 0.0);
  ArrayResize(DifSell, ArraySize(ArrBuy)+1);
  ArrayInitialize(DifSell, 0.0);
  ArrayResize(ArrCall, ArraySize(ArrBuy)+1);
  ArrayInitialize(ArrCall, 0.0);
  ArrayResize(ArrPut, ArraySize(ArrBuy)+1);
  ArrayInitialize(ArrPut, 0.0);
  if(Digits==5) inc=10; else inc=100;
  for(shift=0; shift<=ArraySize(ArrBuy); shift++) {
    if(ArrBuy[shift]>ArrSell[shift]) DifBuy[shift]=MathRound((ArrBuy[shift]-ArrSell[shift])*inc);
    if(ArrBuy[shift]<ArrSell[shift]) DifSell[shift]=MathRound((ArrSell[shift]-ArrBuy[shift])*inc);
  }
  for(shift=1; shift<=ArraySize(ArrBuy); shift++) {
    double Value=0.0;
    if(DifBuy[shift-1]!=0.0 && DifBuy[shift]==0.0) {
      j = shift-1;
      while(DifBuy[j]!=0.0) {
        Value += DifBuy[j];
        j--;
      }
      if(ShowTurningOn) {
        ArrCall[indexCall][0]=Value;
        ArrCall[indexCall][1]=pos+(shift+j)*Point/2;
      }
      if(ShowContractOn) {
        exit = pos+(shift+j+4)*Point/2;
        ObjectCreate("V "+shift, OBJ_TEXT, 0, TimeStart()-((TimePos-6)*Period()*60), exit);
        ObjectSetText("V "+shift, DoubleToStr(Value, 0),8,"Tahoma",GreenYellow);
      }
      indexCall++;
    }
    if(DifSell[shift-1]!=0.0 && DifSell[shift]==0.0) {
      j = shift-1;
      while(DifSell[j]!=0.0) {
        Value += DifSell[j];
        j--;
      }
      if(ShowTurningOn) {
        ArrPut[indexPut][0]=Value;
        ArrPut[indexPut][1]=pos+(shift+j)*Point/2;
      }
      if(ShowContractOn) {
        exit = pos+(shift+j+4)*Point/2;
        ObjectCreate("V "+shift, OBJ_TEXT, 0, TimeStart()-((TimePos-15)*Period()*60), exit);
        ObjectSetText("V "+shift, DoubleToStr(Value, 0),8,"Tahoma",Maroon);
      }
      indexPut++;
    }
  }
}
void  CalcTurning(double& ArrCall[][], double& ArrPut[][]) {
  int index;
  int count=ArraySize(ArrPut);
  double ratio, max, min, coordinat;
  for(index=1; index<count; index++) {
    if(ArrCall[index+1][0]==0.0 && ArrPut[index+1][0]==0.0) {
      return;
    } else {
      if(ArrCall[index][1]<ArrPut[index][1]) {
        max=MathMax(ArrCall[index][0], ArrPut[index][0]);
        min=MathMin(ArrCall[index][0], ArrPut[index][0]);
        ratio=max*PercentDiscrep;
        if(max-min<ratio) {
          coordinat=MathRound((ArrCall[index][1]+ArrPut[index][1])/Point/2)*Point;
          InstallTurning(coordinat, index);
        }
        max=MathMax(ArrCall[index][0], ArrPut[index-1][0]);
        min=MathMin(ArrCall[index][0], ArrPut[index-1][0]);
        ratio=max*PercentDiscrep;
        if(max-min<ratio) {
          coordinat=MathRound((ArrCall[index][1]+ArrPut[index-1][1])/Point/2)*Point;
          InstallTurning(coordinat, index);
        }
      }
      if(ArrCall[index][1]>ArrPut[index][1]) {
        max=MathMax(ArrCall[index][0], ArrPut[index][0]);
        min=MathMin(ArrCall[index][0], ArrPut[index][0]);
        ratio=max*PercentDiscrep;
        if(max-min<ratio) {
          coordinat=MathRound((ArrCall[index][1]+ArrPut[index][1])/Point/2)*Point;
          InstallTurning(coordinat, index);
        }
        max=MathMax(ArrCall[index][0], ArrPut[index+1][0]);
        min=MathMin(ArrCall[index][0], ArrPut[index+1][0]);
        ratio=max*PercentDiscrep;
        if(max-min<ratio) {
          coordinat=MathRound((ArrCall[index][1]+ArrPut[index+1][1])/Point/2)*Point;
          InstallTurning(coordinat, index);
        }
      }
    }      
  }
}
void InstallTurning(double coord, int index) {
  if(ShowTurningOn) {
    ObjectCreate("H "+index, OBJ_HLINE, 0,0,0,0,0);
    ObjectSet("H "+index, OBJPROP_PRICE1, coord);
    ObjectSet("H "+index, OBJPROP_COLOR, ColorLine);
    ObjectSet("H "+index, OBJPROP_WIDTH, 2);
    ObjectSet("H "+index, OBJPROP_BACK, false);
  }
}
             
            
            
Comments