CTG-Modify_Date
Download scriptThis script is designed for the MetaTrader 4 platform to create and maintain a customized price chart that accounts for non-trading periods, such as weekends and holidays. It essentially "stretches" or adjusts the historical data so that time flows continuously without the gaps typically left by market closures.
Core Functionality
The primary purpose of this script is to generate a modified history file. Instead of showing empty spaces during days when the market is closed, the script calculates price action and volume to create a seamless progression of data. It then allows you to view this corrected data on a new chart (specifically one using the suffix _M_D).
Key Features and Logic
Custom Timeframe Scaling The script includes a multiplier setting. This allows users to change the standard timeframe of their chart. For example, if you want to view an "H2" (2-hour) timeframe instead of a standard "H1" (1-hour) timeframe, you can adjust the multiplier accordingly.
Weekend and Holiday Handling One of the script's main features is how it handles non-trading days:
- Null Bars: By default, if the market is closed on a weekend, the script can "flatten" the data for those days. It sets the high, low, and close prices to be equal to the opening price, ensuring the chart looks consistent rather than having broken segments.
- Data Continuity: The logic ensures that volume and price movements are aggregated correctly as time passes, preventing the "jumpy" appearance of charts that skip over holidays.
Real-Time Updates The script does not just process old data; it remains active to handle live market movements:
- It constantly monitors incoming price ticks.
- As new price information arrives, it updates the modified history file in real-time.
- It automatically identifies when a new bar is formed and saves the completed data from the previous bar into the history file.
Automatic Chart Refreshing To ensure the user sees the updated data immediately without manual intervention, the script includes a refresh mechanism. Once it detects that you have opened the specific modified chart window, it sends a command to refresh that chart every 2 seconds. This keeps the visual display in sync with the background calculations.
How to Use It
- Run the Script: You place the script on any standard chart (like H1).
- Configuration: You can choose whether to "Null" out the weekend bars via the input settings.
- View Results: After the script runs, it generates a special chart. To see your modified data, you simply open the chart labeled with the
_M_Dsuffix. This new window will display the smoothed, continuous price action generated by the script.
//+------------------------------------------------------------------+
//| CTG-Modify Date.mq4 |
//| CompanyName "CTG" |
//| http://chaostradinggroup.com |
//+------------------------------------------------------------------+
//Ñêðèïò ñîçäàí äëÿ òåðìèíàëà MetaTrader 4, îí èñïðàâëÿåò ãðàôèê, óäëèíÿÿ åãî,
//ñ ó÷åòîì âûõîäíûõ äíåé è ïðàçäíèêîâ.
//
//Çàïóñòèòå òåðìèíàë MetaTrader 4.  âåðõíåì ìåíþ âûáåðèòå çíà÷îê Íàâèãàòîð,â ðàçäåëå Ñêðèïòû
//íàéäèòå CTG Modify Date, çàòåì ïåðåêèíüòå åãî íà ãðàôèê, êîòîðûé âû õîòèòå èñïðàâèòü.
//
//Ó èíäèêàòîðà åñòü îïöèÿ ExtPeriodMultiplier, îíà íóæíà, åñëè âû õîòèòå ïîëó÷èòü íåñòàíäàðòíûé
//ïåðèîä ãðàôèêà, íàïðèìåð èç ïåðèîäà H1 ñäåëàòü ïåðèîä H2 èëè ëþáîé äðóãîé. Äëÿ èçìåíåíèÿ
//ïåðèîäà âàì íóæíî èñïðàâèòü ýòî çíà÷åíèå (Íàïðèìåð: - åñëè âàì íóæåí ïåðèîä ãðàôèêà H8,
//óñòàíîâèòå ExtPeriodMultiplier=8). Åñëè æå âû íå õîòèòå ìåíÿòü ïåðèîä òîãäà îñòàâëÿéòå 1.
//Ñëåäóþùàÿ îïöèÿ ñêðèïòà Nullbars - ýòà îïöèÿ ñëóæèò äëÿ íàãëÿäíîñòè ïîëó÷åííîãî ãðàôèêà,
//îíà îáíóëÿåò high è low ó áàðîâ, êîòîðûå ïðèõîäÿòñÿ íà âûõîäíûå. Ïî óìîë÷àíèþ ýòà îïöèÿ âêëþ÷åíà.
//
//Äàëåå âàì íåîáõîäèìî çàéòè â ãëàâíîå ìåíþ òåðìèíàëà è âûáðàòü îïöèþ îòêðûòü àâòîíîìíî.
//Â ñïèñêå ãðàôèêîâ âûáåðèòå ãðàôèê ñ ïðèïèñêîé M_D è îòêðîéòå åãî.
//Ó âàñ ïîÿâèòñÿ èñïðàâëåííûé ãðàôèê â íîâîì îêíå. Ýòîò ãðàôèê áóäåò îáíîâëÿòüñÿ êàæäûå 2 ñåêóíäû,
//(ïîêà íà ïåðâîì ãðàôèêå âêëþ÷åí ñêðèïò).
#property copyright "Copyright © 2007, ChaosTradingGroup.com"
#property link "http://ChaosTradingGroup.com"
#property show_inputs
#include <WinUser32.mqh>
extern int ExtPeriodMultiplier=1; // new period multiplier factor
extern bool Nullbars=true;
int ExtHandle=-1;
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int i, start_pos, i_time, time0, last_fpos, periodseconds,sk;
double d_open, d_low, d_high, d_close, d_volume, last_volume;
int hwnd=0,cnt=0;
//---- History header
int version=400;
string c_copyright;
string c_symbol=Symbol()+"-M_D";
int i_period=Period()*ExtPeriodMultiplier;
int i_digits=Digits;
int i_unused[13];
switch ( Period() )
{
case 1: sk=60; break;
case 5: sk=300; break;
case 15: sk=900; break;
case 30: sk=1800; break;
case 60: sk=3600; break;
case 240: sk=14400; break;
case 1440: sk=86400; break;
case 10080: sk=604800; break;
case 43200: sk=2592000; break;
default: break;
}
//----
ExtHandle=FileOpenHistory(c_symbol+i_period+".hst", FILE_BIN|FILE_WRITE);
if(ExtHandle < 0) return(-1);
//---- write history file header
c_copyright="Copyright © 2007, ChaosTradingGroup.com";
FileWriteInteger(ExtHandle, version, LONG_VALUE);
FileWriteString(ExtHandle, c_copyright, 64);
FileWriteString(ExtHandle, c_symbol, 12);
FileWriteInteger(ExtHandle, i_period, LONG_VALUE);
FileWriteInteger(ExtHandle, i_digits, LONG_VALUE);
FileWriteInteger(ExtHandle, 0, LONG_VALUE); //timesign
FileWriteInteger(ExtHandle, 0, LONG_VALUE); //last_sync
FileWriteArray(ExtHandle, i_unused, 0, 13);
//---- write history file
periodseconds=i_period*60;
start_pos=Bars-1;
d_open=Open[start_pos];
d_low=Low[start_pos];
d_high=High[start_pos];
d_volume=Volume[start_pos];
//---- normalize open time
i_time=Time[start_pos]/periodseconds;
i_time*=periodseconds;
for(i=Time[start_pos-1];i<=Time[0]; i+=sk)
{
time0=i;
if(time0>=i_time+periodseconds || i==Time[0])
{
if(i==Time[0] && time0<i_time+periodseconds)
{
d_volume+=Volume[0];
if (Low[0]<d_low) d_low=Low[0];
if (High[0]>d_high) d_high=High[0];
d_close=Close[0];
}
last_fpos=FileTell(ExtHandle);
last_volume=Volume[iBarShift(Symbol(),Period(),i)];
if ((Nullbars==true && i_period<=1440 && TimeDayOfWeek(i)==0) || (Nullbars==true && i_period<=1440 && TimeDayOfWeek(i)==6))
{
d_close=d_open;
d_low=d_open;
d_high=d_open;
}
FileWriteInteger(ExtHandle, i_time, LONG_VALUE);
FileWriteDouble(ExtHandle, d_open, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_low, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_high, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_close, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_volume, DOUBLE_VALUE);
FileFlush(ExtHandle);
cnt++;
if(time0>=i_time+periodseconds)
{
i_time=time0/periodseconds;
i_time*=periodseconds;
d_open=Open[iBarShift(Symbol(),Period(),i)];
d_low=Low[iBarShift(Symbol(),Period(),i)];
d_high=High[iBarShift(Symbol(),Period(),i)];
d_close=Close[iBarShift(Symbol(),Period(),i)];
d_volume=last_volume;
}
}
else
{
d_volume+=Volume[i];
if (Low[iBarShift(Symbol(),Period(),i)]<d_low) d_low=Low[iBarShift(Symbol(),Period(),i)];
if (High[iBarShift(Symbol(),Period(),i)]>d_high) d_high=High[iBarShift(Symbol(),Period(),i)];
d_close=Close[iBarShift(Symbol(),Period(),i)];
}
}
FileFlush(ExtHandle);
Print(cnt," record(s) written");
//---- collect incoming ticks
int last_time=LocalTime()-5;
while(IsStopped()==false)
{
int cur_time=LocalTime();
//---- check for new rates
if(RefreshRates())
{
time0=Time[0];
FileSeek(ExtHandle,last_fpos,SEEK_SET);
//---- is there current bar?
if(time0<i_time+periodseconds)
{
d_volume+=Volume[0]-last_volume;
last_volume=Volume[0];
if (Low[0]<d_low) d_low=Low[0];
if (High[0]>d_high) d_high=High[0];
d_close=Close[0];
}
else
{
//---- no, there is new bar
d_volume+=Volume[1]-last_volume;
if (Low[1]<d_low) d_low=Low[1];
if (High[1]>d_high) d_high=High[1];
//---- write previous bar remains
FileWriteInteger(ExtHandle, i_time, LONG_VALUE);
FileWriteDouble(ExtHandle, d_open, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_low, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_high, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_close, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_volume, DOUBLE_VALUE);
last_fpos=FileTell(ExtHandle);
//----
i_time=time0/periodseconds;
i_time*=periodseconds;
d_open=Open[0];
d_low=Low[0];
d_high=High[0];
d_close=Close[0];
d_volume=Volume[0];
last_volume=d_volume;
}
//----
FileWriteInteger(ExtHandle, i_time, LONG_VALUE);
FileWriteDouble(ExtHandle, d_open, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_low, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_high, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_close, DOUBLE_VALUE);
FileWriteDouble(ExtHandle, d_volume, DOUBLE_VALUE);
FileFlush(ExtHandle);
//----
if(hwnd==0)
{
hwnd=WindowHandle(c_symbol,i_period);
if(hwnd!=0) Print("Chart window detected");
}
//---- refresh window not frequently than 1 time in 2 seconds
if(hwnd!=0 && cur_time-last_time>=2)
{
PostMessageA(hwnd,WM_COMMAND,33324,0);
last_time=cur_time;
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void deinit()
{
if(ExtHandle>=0) { FileClose(ExtHandle); ExtHandle=-1; }
}
//+------------------------------------------------------------------+
Comments