//+------------------------------------------------------------------+ //| IndRange.mq4 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property description "The indicator creates an Range chart" #property strict #property indicator_chart_window //--- input parameter input double SizeRenko=40; //--- int ExtOffPeriod =7; bool first_start =true; // true -> it's first start bool crash =false; // false -> error in the code int HandleHistory =-1; // handle for the opened "*.hst" file datetime time0; // ulong last_fpos =0; // int periodseconds; // int i_period; // MqlRates rate; // long ChartOffID =-1; // ID of the offline chart //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { //--- if(crash) return(rates_total); if(prev_calculated==0 && first_start) // first start { if(CreateHeader(ExtOffPeriod)) first_start=false; else { crash=true; return(rates_total); } //--- FirstWriteHistory(ExtOffPeriod); first_start=false; //--- ResetLastError(); ChartOffID=ChartOpen(Symbol(),PERIOD_M1*ExtOffPeriod); // ExtOffPeriod); // if(ChartOffID==0) { Print("Error open chart: ",GetLastError()); first_start=false; crash=true; return(rates_total); } else Print(__FUNCTION__,"Opening offline chart id=",ChartOffID); } //--- if(prev_calculated==0 && !first_start) // a deeper history downloaded or history blanks filled { Print("a deeper history downloaded or history blanks filled. first_start=",first_start); if(CreateHeader(ExtOffPeriod)) first_start=false; else { crash=true; return(rates_total); } //--- FirstWriteHistory(ExtOffPeriod); first_start=false; } //--- CollectTicks(); //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| The function checks offline mode of the chart | //+------------------------------------------------------------------+ bool IsOffline(const long chart_ID=0) { bool offline=ChartGetInteger(chart_ID,CHART_IS_OFFLINE); return(offline); } //+------------------------------------------------------------------+ //| Create history header | //+------------------------------------------------------------------+ bool CreateHeader(const int offline_period) { //---- History header int file_version=401; string c_copyright; string c_symbol=Symbol(); i_period=PERIOD_M1*offline_period;//Period()*offline_period; // int i_digits=Digits; int i_unused[13]; //--- ResetLastError(); HandleHistory=FileOpenHistory(c_symbol+(string)i_period+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI); if(HandleHistory<0) { Print("Error open ",c_symbol+(string)i_period,".hst file ",GetLastError()); return(false); } c_copyright="(C)opyright 2003, MetaQuotes Software Corp."; ArrayInitialize(i_unused,0); //--- write history file header FileWriteInteger(HandleHistory,file_version,LONG_VALUE); FileWriteString(HandleHistory,c_copyright,64); FileWriteString(HandleHistory,c_symbol,12); FileWriteInteger(HandleHistory,i_period,LONG_VALUE); FileWriteInteger(HandleHistory,i_digits,LONG_VALUE); FileWriteInteger(HandleHistory,0,LONG_VALUE); FileWriteInteger(HandleHistory,0,LONG_VALUE); FileWriteArray(HandleHistory,i_unused,0,13); return(true); } //+------------------------------------------------------------------+ //| First Write History | //+------------------------------------------------------------------+ bool FirstWriteHistory(const int offline_period) { int i,start_pos; int cnt=0; //--- write history file periodseconds=offline_period*60; start_pos=Bars-1; rate.open=Open[start_pos]; rate.close=Close[start_pos]; rate.low=Low[start_pos]; rate.high=High[start_pos]; rate.tick_volume=(long)Volume[start_pos]; rate.spread=0; rate.real_volume=0; //--- normalize open time rate.time=D'1980.07.19 12:30:27'; for(i=start_pos-1; i>=0; i--) { if(IsStopped()) break; while((High[i]-rate.high)>SizeRenko*Point()) { rate.time+=1; rate.open=rate.high; rate.low=rate.open; rate.close=NormalizeDouble(rate.low+SizeRenko*Point(),Digits); rate.high=rate.close; last_fpos=FileTell(HandleHistory); uint byteswritten=FileWriteStruct(HandleHistory,rate); //--- check the number of bytes written if(byteswritten==0) PrintFormat("Error read data. Error code=%d",GetLastError()); else cnt++; } while((Low[i]-rate.low)<-SizeRenko*Point()) { rate.time+=1; rate.open=rate.low; rate.high=rate.open; rate.close=NormalizeDouble(rate.high-SizeRenko*Point(),Digits); rate.low=rate.close; last_fpos=FileTell(HandleHistory); uint byteswritten=FileWriteStruct(HandleHistory,rate); //--- check the number of bytes written if(byteswritten==0) PrintFormat("Error read data. Error code=%d",GetLastError()); else cnt++; } } FileFlush(HandleHistory); PrintFormat("%d record(s) written",cnt); return(true); } //+------------------------------------------------------------------+ //| Collect Ticks | //+------------------------------------------------------------------+ bool CollectTicks() { static datetime last_time;//=TimeLocal()-5; long chart_id=0; datetime cur_time=TimeLocal(); //--- while((Close[0]-rate.high)>SizeRenko*Point()) { rate.time+=1; rate.open=rate.high; rate.low=rate.open; rate.close=NormalizeDouble(rate.low+SizeRenko*Point(),Digits); rate.high=rate.close; last_fpos=FileTell(HandleHistory); uint byteswritten=FileWriteStruct(HandleHistory,rate); //--- check the number of bytes written if(byteswritten==0) PrintFormat("Error read data. Error code=%d",GetLastError()); } while((Close[0]-rate.low)<-SizeRenko*Point()) { rate.time+=1; rate.open=rate.low; rate.high=rate.open; rate.close=NormalizeDouble(rate.high-SizeRenko*Point(),Digits); rate.low=rate.close; last_fpos=FileTell(HandleHistory); uint byteswritten=FileWriteStruct(HandleHistory,rate); //--- check the number of bytes written if(byteswritten==0) PrintFormat("Error read data. Error code=%d",GetLastError()); } //--- refresh window not frequently than 1 time in 2 seconds if(cur_time-last_time>=3) { FileFlush(HandleHistory); ChartSetSymbolPeriod(ChartOffID,Symbol(),i_period); last_time=cur_time; } return(true); } //+------------------------------------------------------------------+ //| Deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(HandleHistory>=0) { FileClose(HandleHistory); HandleHistory=-1; } } //+------------------------------------------------------------------+