#property copyright "Copyright © 2008, MQL Service" #property link "http://www.mqlservice.net" //#property show_inputs #include #include #import "user32.dll" int RegisterWindowMessageW(string lpString); int PostMessageW(int hWnd,int Msg,int wParam,int lParam); #import extern int BarsRange = 3; extern int TimeFrame = 3; extern int MaxBars = 8000; extern bool ShowGaps = true; extern bool RescaleFor5DigitsBroker = true; int HstHandle = -1; string SymbolName; double volume(int pShift) { return (iVolume(NULL, PERIOD_M1, pShift)); } double open(int pShift) { return (iOpen(NULL , PERIOD_M1, pShift)); } double close(int pShift) { return (iClose(NULL , PERIOD_M1, pShift)); } double high(int pShift) { return (iHigh(NULL , PERIOD_M1, pShift)); } double low(int pShift) { return (iLow(NULL , PERIOD_M1, pShift)); } int time(int pShift) { return (pShift); } int start() { int currHigh; int currTime; double tmpVolume; int HstUnused[13]; double currLevel; int localTime; if (_invalid(BarsRange, 0, "BarsRange")) return (0); if (_invalid(TimeFrame, 1, "TimeFrame")) return (0); if (!IsDllsAllowed()) { Alert(WindowExpertName(), ": Please Allow DLL imports to run this script"); Comment(WindowExpertName(), " aborted due to disabled DLL calls"); return (-1); } int MT4InternalMsg = RegisterWindowMessageW("MetaTrader4_Internal_Message"); SymbolName = _Symbol; int hWin = 0; int recordCount = 0; int Version = 401; int Digit = Digits; for (int shift = StringFind(SymbolName, ".", 0); shift > 0; shift = StringFind(SymbolName, ".", 0)) SymbolName = StringSubstr(SymbolName, 0, shift) + StringSubstr(SymbolName, shift + 1); HstHandle = FileOpenHistory(SymbolName + TimeFrame + ".hst", FILE_BIN|FILE_WRITE|FILE_ANSI); FileClose(HstHandle); HstHandle = FileOpenHistory(SymbolName + TimeFrame + ".hst", FILE_BIN|FILE_READ|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI); // HstHandle = FileOpenHistory(SymbolName + TimeFrame + ".hst", FILE_BIN|FILE_WRITE); if (HstHandle < 0) { Alert(WindowExpertName(), ": Cannot create ", SymbolName + TimeFrame + ".hst"); Comment(WindowExpertName(), " aborted: Cannot create ", SymbolName + TimeFrame + ".hst"); return (-1); } // Print("$Id: //mqlservice/mt4files/experts/scripts/s-Constant Range Bars.mq4#14 $"); string Copyright = "(C)opyright 2008, MQL Service & Mladen"; FileWriteInteger(HstHandle, Version, LONG_VALUE); FileWriteString(HstHandle, Copyright, 64); FileWriteString(HstHandle, SymbolName, 12); FileWriteInteger(HstHandle, TimeFrame, LONG_VALUE); FileWriteInteger(HstHandle, Digit, LONG_VALUE); FileWriteInteger(HstHandle, 0, LONG_VALUE); FileWriteInteger(HstHandle, 0, LONG_VALUE); FileWriteArray(HstHandle, HstUnused, 0, 13); FileFlush(HstHandle); int currPos = FileTell(HstHandle); int unusedMinutes = 60 * TimeFrame; //stabilisce il valor minimo fra MaxBars e TotaleBarre nel chart a 1 minuto //e da lм parte la conversione int offset = MathMin(MaxBars, iBars(NULL, PERIOD_M1) - 1); //non ci sono barre if (offset <= 0) if (MessageBox("No 1M bars available, there will be no history bars!\n\nContinue?", WindowExpertName(), MB_YESNO|MB_ICONQUESTION) == IDNO) return (0); //non и il timeframe giusto if (_Period != PERIOD_M1) if (MessageBox("It should be run on 1M chart!\n\nContinue?", WindowExpertName(), MB_YESNO|MB_ICONQUESTION) == IDNO) return (0); //controllo decimali int minSize = 1; if (Digits == 3 || Digits > 4) { if (RescaleFor5DigitsBroker) { BarsRange = 10 * BarsRange; minSize = 10; } } //orario inizio prima barra int startTime = time(iTime(NULL, PERIOD_M1, offset)); // Print("Starting from ", TimeToStr(startTime, TIME_DATE|TIME_MINUTES|TIME_SECONDS)); //valori iniziali: pone L=H=C=O (RangeBar) = close double startLow = close(offset); double startHigh = startLow; double startVolume = 1.0; double startClose = startLow; double startOpen = startLow; int currSize = 1; MqlRates rates; //inizia il ciclo dalla barra successiva for (shift = offset - 1; shift >= 0; shift--) { currTime = time(iTime(NULL, PERIOD_M1, shift)); //se volume>0 и passato almeno un tick; calcola la dimensione della barra if (Volume[shift] > 0.0) currSize = MathMax(minSize, MathCeil((high(shift) - low(shift)) / Point / Volume[shift])); else currSize = minSize; currSize = MathRound(currSize / minSize) * minSize; //se la barra и negativa if (open(shift) > close(shift)) { currHigh = MathRound(high(shift) / Point / minSize) * minSize; while (currHigh >= MathRound(low(shift) / Point / minSize) * minSize) { currLevel = NormalizeDouble(currHigh * Point, Digits); startLow = MathMin(startLow, currLevel); startHigh = MathMax(startHigh, currLevel); startVolume++; if (MathRound((startHigh - startLow) / Point) >= BarsRange + minSize) { currPos = FileTell(HstHandle); if (CompareDoubles(startLow, currLevel)) { if (ShowGaps) startLow = NormalizeDouble(startHigh - BarsRange * Point, Digits); else startLow = NormalizeDouble(startLow + minSize * Point, Digits); startClose = startLow; } if (CompareDoubles(startHigh, currLevel)) { if (ShowGaps) startHigh = NormalizeDouble(startLow + BarsRange * Point, Digits); else startHigh = NormalizeDouble(startHigh - minSize * Point, Digits); startClose = startHigh; } rates.time = startTime; rates.open = startOpen; rates.close = startClose; rates.high = startHigh; rates.low = startLow; rates.tick_volume = startVolume; rates.real_volume = startVolume; FileWriteStruct(HstHandle,rates); //FileWriteInteger(HstHandle, startTime, LONG_VALUE); //FileWriteDouble(HstHandle, startOpen, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startLow, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startHigh, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startClose, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startVolume, DOUBLE_VALUE); //FileFlush(HstHandle); recordCount++; startTime++; startTime = MathMax(currTime, startTime); startOpen = currLevel; startLow = currLevel; startHigh = currLevel; startClose = currLevel; startVolume = 1.0; } else startClose = currLevel; currHigh -= currSize; } } else { currHigh = MathRound(low(shift) / Point / minSize) * minSize; while (currHigh <= MathRound(high(shift) / Point / minSize) * minSize) { currLevel = NormalizeDouble(currHigh * Point, Digits); startLow = MathMin(startLow, currLevel); startHigh = MathMax(startHigh, currLevel); startVolume++; if (MathRound((startHigh - startLow) / Point) >= BarsRange + minSize) { currPos = FileTell(HstHandle); if (CompareDoubles(startLow, currLevel)) { if (ShowGaps) startLow = NormalizeDouble(startHigh - BarsRange * Point, Digits); else startLow = NormalizeDouble(startLow + minSize * Point, Digits); startClose = startLow; } if (CompareDoubles(startHigh, currLevel)) { if (ShowGaps) startHigh = NormalizeDouble(startLow + BarsRange * Point, Digits); else startHigh = NormalizeDouble(startHigh - minSize * Point, Digits); startClose = startHigh; } rates.time = startTime; rates.open = startOpen; rates.close = startClose; rates.high = startHigh; rates.low = startLow; rates.tick_volume = startVolume; rates.real_volume = startVolume; FileWriteStruct(HstHandle,rates); //FileWriteInteger(HstHandle, startTime, LONG_VALUE); //FileWriteDouble(HstHandle, startOpen, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startLow, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startHigh, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startClose, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startVolume, DOUBLE_VALUE); //FileFlush(HstHandle); recordCount++; startTime++; startTime = MathMax(currTime, startTime); startOpen = currLevel; startLow = currLevel; startHigh = currLevel; startClose = currLevel; startVolume = 1.0; } else startClose = currLevel; currHigh += currSize; } } } FileFlush(HstHandle); currPos = FileTell(HstHandle); rates.time = startTime; rates.open = startOpen; rates.close = startClose; rates.high = startHigh; rates.low = startLow; rates.tick_volume = startVolume; rates.real_volume = startVolume; FileWriteStruct(HstHandle,rates); //FileWriteInteger(HstHandle, startTime, LONG_VALUE); //FileWriteDouble(HstHandle, startOpen, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startLow, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startHigh, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startClose, DOUBLE_VALUE); //FileWriteDouble(HstHandle, startVolume, DOUBLE_VALUE); FileFlush(HstHandle); // Print(recordCount, " record(s) written"); //fine storico: refresh if (hWin == 0) { hWin = WindowHandle(SymbolName, TimeFrame); // if (hWin != 0) Print("Chart window detected"); } _postMessage(hWin, MT4InternalMsg); //inizio real time startTime = TimeCurrent(); Comment(WindowExpertName(), " started"); //tutto il realTime и retto dal while() aggiornato ogni 100 msec while (IsStopped() == false) { localTime = TimeLocal(); if (RefreshRates()) { FileSeek(HstHandle, currPos, SEEK_SET); startLow = MathMin(startLow, Close[0]); startHigh = MathMax(startHigh, Close[0]); startVolume++; if (MathRound((startHigh - startLow) / Point / minSize) <= MathRound(BarsRange / minSize)) { tmpVolume = volume(0); startClose = close(0); } else { if (CompareDoubles(startLow, Close[0])) { if (ShowGaps) startLow = NormalizeDouble(startHigh - BarsRange * Point, Digits); else startLow = NormalizeDouble(startLow + minSize * Point, Digits); startClose = startLow; } if (CompareDoubles(startHigh, Close[0])) { if (ShowGaps) startHigh = NormalizeDouble(startLow + BarsRange * Point, Digits); else startHigh = NormalizeDouble(startHigh - minSize * Point, Digits); startClose = startHigh; } rates.time = startTime; rates.open = NormalizeDouble(MathMin(MathMax(startOpen, startLow), startHigh), Digits); rates.low = NormalizeDouble(MathMin(startLow, startHigh), Digits); rates.high = NormalizeDouble(MathMax(startHigh, startLow), Digits); rates.close = NormalizeDouble(MathMin(MathMax(startClose, startLow), startHigh), Digits); rates.tick_volume = NormalizeDouble(startVolume, 0); rates.real_volume = NormalizeDouble(startVolume, 0); FileWriteStruct(HstHandle,rates); //FileWriteInteger(HstHandle, startTime, LONG_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(MathMax(startOpen, startLow), startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(startLow, startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMax(startHigh, startLow), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(MathMax(startClose, startLow), startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(startVolume, 0), DOUBLE_VALUE); FileFlush(HstHandle); currPos = FileTell(HstHandle); startTime++; startTime = MathMax(startTime, TimeCurrent()); startVolume = 1; startOpen = Close[0]; startLow = Close[0]; startHigh = Close[0]; startClose = Close[0]; startVolume = 1.0; tmpVolume = startVolume; } rates.time = startTime; rates.open = NormalizeDouble(MathMin(MathMax(startOpen, startLow), startHigh), Digits); rates.low = NormalizeDouble(MathMin(startLow, startHigh), Digits); rates.high = NormalizeDouble(MathMax(startHigh, startLow), Digits); rates.close = NormalizeDouble(MathMin(MathMax(startClose, startLow), startHigh), Digits); rates.tick_volume = NormalizeDouble(startVolume, 0); rates.real_volume = NormalizeDouble(startVolume, 0); FileWriteStruct(HstHandle,rates); //FileWriteInteger(HstHandle, startTime, LONG_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(MathMax(startOpen, startLow), startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(startLow, startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMax(startHigh, startLow), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(MathMin(MathMax(startClose, startLow), startHigh), Digits), DOUBLE_VALUE); //FileWriteDouble(HstHandle, NormalizeDouble(startVolume, 0), DOUBLE_VALUE); FileFlush(HstHandle); if (hWin == 0) { hWin = WindowHandle(SymbolName, TimeFrame); // if (hWin != 0) Print("Chart window detected"); } hWin = WindowHandle(SymbolName, TimeFrame); _postMessage(hWin, MT4InternalMsg); } else Sleep(100); } Comment(WindowExpertName(), " stopped"); return (0); } void _postMessage(int pHandle, int pMessage) { if (pHandle != 0) { PostMessageW(pHandle, WM_COMMAND, 33324, 0); PostMessageW(pHandle, pMessage, 2, 1); } } void deinit() { if (HstHandle >= 0) { FileClose(HstHandle); // Print(SymbolName, TimeFrame, ".hst closed"); HstHandle = -1; } // Print("Inputs were: ", "BarsRange=", BarsRange, "; ", "TimeFrame=", TimeFrame, "; ", "MaxBars=", MaxBars, "; ", "ShowGaps=", ShowGaps, ";"); } bool _invalid(int pValue, int pInvalidValue, string pString) { if (pValue <= pInvalidValue) { Alert(WindowExpertName() + " " + _Symbol + _Period + " invalid parameter ", pString, ": ", pValue, ". Must be grater than ", pInvalidValue); return (true); } return (false); }