25piprenko
Download scriptThis script is designed to convert standard price movements into a specialized format known as Renko bars. In trading, Renko charts ignore the passage of time and focus exclusively on price movement; a new bar is only created when the price moves a specific distance in one direction.
Here is a breakdown of how the logic functions:
Core Purpose
The script analyzes raw 1-minute price data and calculates the formation of "Renko" bars based on a user-defined range. Instead of just showing you what happened every minute, it records a new entry only when the price has moved enough to justify a "brick" in the Renko structure. It then saves this processed history into a custom file.
Operational Workflow
1. Environment & Requirements Check
- Data Source: The script specifically requires a 1-minute (M1) chart to perform its calculations accurately.
- Permissions: It requires permission to use DLLs (External Libraries) to communicate with the trading platform's window system.
- Broker Detection: It automatically detects if your broker uses "5-digit" pricing (common in modern forex trading) and adjusts the price calculation range accordingly to ensure consistency.
2. File Creation
- The script creates a dedicated history file for the specific currency pair and timeframe you are viewing. This ensures that the converted Renko data is stored organized by asset.
3. Historical Processing (The "Backfill")
- When you first run the script, it looks backward through the available 1-minute history.
- It "replays" the price action to see where Renko bars would have formed in the past.
- If a price move exceeds the defined
BarsRange, the script marks a new bar, identifies its high and low points, and writes this information into your file.
4. Real-Time Monitoring
- Once the history is processed, the script enters a continuous loop to monitor live market ticks.
- It constantly compares the current price against the last recorded Renko "brick."
- If the price continues to move in one direction until it hits the required threshold, it generates the next bar, records the timestamp and price coordinates, and saves them instantly.
5. Communication & Updates
- The script uses a messaging system (
PostMessage) to notify the trading platform that data is being processed. This helps keep the interface updated while the script performs its background calculations.
Summary of User Inputs
- BarsRange: Determines how much price movement is required to create a new Renko bar (e.g., if set to 10 pips, the price must move 10 pips before a new bar appears).
- TimeFrame: Sets the base timeframe for the calculation (optimized for M1).
- MaxBars: Limits how far back into the past the script will go to generate history.
/*
Generated by EX4-TO-MQ4 decompiler V4.0.224.1 []
Website: http://purebeam.biz
E-mail : purebeam@gmail.com
*/
#property copyright "Copyright ?2008, MQL Service"
#property link "http://www.mqlservice.net"
#property show_inputs
#include <WinUser32.mqh>
#import "user32.dll"
int RegisterWindowMessageA(string a0);
#import
extern int BarsRange = 25;
extern int TimeFrame = 2;
extern int MaxBars = 46000;
int g_file_88 = -1;
double LocalPoint;
int LotDigit;
double volume(int ai_0) {
return (iVolume(Symbol(), PERIOD_M1, ai_0));
}
double open(int ai_0) {
return (iOpen(Symbol(), PERIOD_M1, ai_0));
}
double close(int ai_0) {
return (iClose(Symbol(), PERIOD_M1, ai_0));
}
double high(int ai_0) {
return (iHigh(Symbol(), PERIOD_M1, ai_0));
}
double low(int ai_0) {
return (iLow(Symbol(), PERIOD_M1, ai_0));
}
int time(int ai_0) {
return (ai_0);
}
int init() {
LocalPoint = Point*MathPow(10,Digits%2);
LotDigit=MarketInfo( Symbol(), MODE_DIGITS );
return (0);
}
int start() {
int li_16;
int li_28;
double ld_80;
int lia_124[13];
double ld_144;
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 li_0 = RegisterWindowMessageA("MetaTrader4_Internal_Message");
string ls_4 = Symbol();
int li_96 = 0;
int l_count_100 = 0;
int li_104 = 400;
int li_116 = TimeFrame;
int l_digits_120 = Digits;
for (int li_12 = StringFind(ls_4, ".", 0); li_12 > 0; li_12 = StringFind(ls_4, ".", 0)) ls_4 = StringSubstr(ls_4, 0, li_12) + StringSubstr(ls_4, li_12 + 1);
g_file_88 = FileOpenHistory(ls_4 + li_116 + ".hst", FILE_BIN|FILE_WRITE);
if (g_file_88 < 0) {
Alert(WindowExpertName(), ": Cannot create ", ls_4 + TimeFrame + ".hst");
Comment(WindowExpertName(), " aborted: Cannot create ", ls_4 + TimeFrame + ".hst");
return (-1);
}
Print("$Id: //mqlservice/mt4files/experts/scripts/s-Renko bars.mq4#7 $");
string ls_108 = "(C)opyright 2008, MQL Service";
FileWriteInteger(g_file_88, li_104, LONG_VALUE);
FileWriteString(g_file_88, ls_108, 64);
FileWriteString(g_file_88, ls_4, 12);
FileWriteInteger(g_file_88, li_116, LONG_VALUE);
FileWriteInteger(g_file_88, l_digits_120, LONG_VALUE);
FileWriteInteger(g_file_88, 0, LONG_VALUE);
FileWriteInteger(g_file_88, 0, LONG_VALUE);
FileWriteArray(g_file_88, lia_124, 0, 13);
FileFlush(g_file_88);
int li_36 = 60 * li_116;
int li_20 = MathMin(MaxBars, iBars(Symbol(), PERIOD_M1) - 1);
if (li_20 <= 0)
if (MessageBox("No 1M bars available, there will be no history bars!\n\nContinue?", WindowExpertName(), MB_YESNO|MB_ICONQUESTION) == IDNO) return (0);
if (Period() != PERIOD_M1)
if (MessageBox("It should be run on 1M chart!\n\nContinue?", WindowExpertName(), MB_YESNO|MB_ICONQUESTION) == IDNO) return (0);
int li_128 = 1;
if (Digits == 3 || Digits > 4) {
if (MessageBox("5 digits broker detected!\n\nRescale BarsRange?", WindowExpertName(), MB_YESNO|MB_ICONQUESTION) == IDYES) {
BarsRange = 10 * BarsRange;
li_128 = 10;
}
}
int li_24 = time(iTime(Symbol(), PERIOD_M1, li_20));
Print("Starting from ", TimeToStr(li_24, TIME_DATE|TIME_MINUTES|TIME_SECONDS));
int li_32 = FileTell(g_file_88);
double ld_48 = close(li_20);
double ld_56 = ld_48;
double ld_72 = 1.0;
double ld_64 = ld_48;
double ld_40 = ld_48;
double ld_88 = ld_48;
int li_132 = 1;
int li_136 = 1;
int li_140 = 1;
for (li_12 = li_20 - 1; li_12 >= 0; li_12--) {
li_28 = time(iTime(Symbol(), PERIOD_M1, li_12));
if (Volume[li_12] > 0.0) li_140 = MathMax(li_128, MathCeil((high(li_12) - low(li_12)) / Point / Volume[li_12]));
else li_140 = li_128;
li_140 = MathRound(li_140 / li_128) * li_128;
if (open(li_12) > close(li_12)) {
li_16 = high(li_12) / Point;
while (li_16 >= low(li_12) / Point) {
ld_144 = NormalizeDouble(li_16 * Point, Digits);
ld_48 = MathMin(ld_48, ld_144);
ld_56 = MathMax(ld_56, ld_144);
ld_72 += MathRound(MathAbs(ld_64 - ld_144) / Point);
ld_64 = ld_144;
while (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange || MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
li_32 = FileTell(g_file_88);
if (MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
if (li_136 == 2) ld_88 -= BarsRange * Point;
ld_64 = ld_88 - BarsRange * Point;
ld_48 = ld_64;
ld_40 = ld_88;
ld_56 = ld_88;
li_136 = 1;
li_132 = 2;
}
if (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange) {
if (li_132 == 2) ld_88 += BarsRange * Point;
ld_64 = ld_88 + BarsRange * Point;
ld_56 = ld_64;
ld_40 = ld_88;
ld_48 = ld_88;
li_132 = 1;
li_136 = 2;
}
FileWriteInteger(g_file_88, li_24, LONG_VALUE);
FileWriteDouble(g_file_88, ld_40, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_48, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_56, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_64, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_72, DOUBLE_VALUE);
li_24++;
FileFlush(g_file_88);
l_count_100++;
ld_88 = ld_64;
li_24 = MathMax(li_28, li_24);
ld_40 = ld_64;
ld_48 = MathMin(ld_144, ld_64);
ld_56 = MathMax(ld_144, ld_64);
ld_64 = ld_144;
ld_72 = 1.0;
}
li_16 -= li_140;
}
} else {
li_16 = low(li_12) / Point;
while (li_16 <= high(li_12) / Point) {
ld_144 = NormalizeDouble(li_16 * Point, Digits);
ld_48 = MathMin(ld_48, ld_144);
ld_56 = MathMax(ld_56, ld_144);
ld_72 += MathRound(MathAbs(ld_64 - ld_144) / Point);
ld_64 = ld_144;
while (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange || MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
li_32 = FileTell(g_file_88);
if (MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
if (li_136 == 2) ld_88 -= BarsRange * Point;
ld_64 = ld_88 - BarsRange * Point;
ld_48 = ld_64;
ld_40 = ld_88;
ld_56 = ld_88;
li_136 = 1;
li_132 = 2;
}
if (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange) {
if (li_132 == 2) ld_88 += BarsRange * Point;
ld_64 = ld_88 + BarsRange * Point;
ld_56 = ld_64;
ld_40 = ld_88;
ld_48 = ld_88;
li_132 = 1;
li_136 = 2;
}
FileWriteInteger(g_file_88, li_24, LONG_VALUE);
FileWriteDouble(g_file_88, ld_40, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_48, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_56, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_64, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_72, DOUBLE_VALUE);
li_24++;
FileFlush(g_file_88);
l_count_100++;
ld_88 = ld_64;
li_24 = MathMax(li_28, li_24);
ld_40 = ld_64;
ld_48 = MathMin(ld_144, ld_64);
ld_56 = MathMax(ld_144, ld_64);
ld_64 = ld_144;
ld_72 = 1.0;
}
li_16 += li_140;
}
}
}
li_32 = FileTell(g_file_88);
ld_64 = Close[0];
FileWriteInteger(g_file_88, TimeCurrent(), LONG_VALUE);
FileWriteDouble(g_file_88, ld_40, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_48, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_56, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_64, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_72, DOUBLE_VALUE);
FileFlush(g_file_88);
Print(l_count_100, " record(s) written");
if (li_96 == 0) {
li_96 = WindowHandle(ls_4, li_116);
if (li_96 != 0) Print("Chart window detected");
}
_postMessage(li_96, li_0);
li_24 = MathMax(TimeCurrent(), li_24);
while (IsStopped() == FALSE) {
if (RefreshRates()) {
FileSeek(g_file_88, li_32, SEEK_SET);
ld_48 = MathMin(ld_48, Close[0]);
ld_56 = MathMax(ld_56, Close[0]);
ld_72 += MathRound(MathAbs(ld_64 - close(0)) / Point);
if (MathRound((ld_56 - ld_88) / Point) < li_132 * BarsRange && MathRound((ld_88 - ld_48) / Point) < li_136 * BarsRange) {
ld_80 = volume(0);
ld_64 = close(0);
} else {
while (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange || MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
if (MathRound((ld_88 - ld_48) / Point) >= li_136 * BarsRange) {
if (li_136 == 2) ld_88 -= BarsRange * Point;
ld_64 = ld_88 - BarsRange * Point;
ld_48 = ld_64;
ld_40 = ld_88;
ld_56 = ld_88;
li_136 = 1;
li_132 = 2;
}
if (MathRound((ld_56 - ld_88) / Point) >= li_132 * BarsRange) {
if (li_132 == 2) ld_88 += BarsRange * Point;
ld_64 = ld_88 + BarsRange * Point;
ld_56 = ld_64;
ld_40 = ld_88;
ld_48 = ld_88;
li_132 = 1;
li_136 = 2;
}
FileWriteInteger(g_file_88, li_24, LONG_VALUE);
FileWriteDouble(g_file_88, ld_40, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_48, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_56, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_64, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_72, DOUBLE_VALUE);
li_32 = FileTell(g_file_88);
li_24++;
li_24 = MathMax(li_24, TimeCurrent());
ld_88 = ld_64;
li_24 = MathMax(li_28, li_24);
ld_40 = ld_64;
ld_48 = MathMin(Close[0], ld_64);
ld_56 = MathMax(Close[0], ld_64);
ld_64 = Close[0];
ld_72 = 1.0;
}
}
FileWriteInteger(g_file_88, li_24, LONG_VALUE);
FileWriteDouble(g_file_88, ld_40, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_48, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_56, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_64, DOUBLE_VALUE);
FileWriteDouble(g_file_88, ld_72, DOUBLE_VALUE);
FileFlush(g_file_88);
if (li_96 == 0) {
li_96 = WindowHandle(ls_4, li_116);
if (li_96 != 0) Print("Chart window detected");
}
_postMessage(li_96, li_0);
} else Sleep(100);
}
return (0);
}
void _postMessage(int ai_0, int ai_4) {
if (ai_0 != 0) {
PostMessageA(ai_0, WM_COMMAND, 33324, 1);
PostMessageA(ai_0, ai_4, 2, 1);
}
}
void deinit() {
if (g_file_88 >= 0) {
FileClose(g_file_88);
g_file_88 = -1;
}
}
bool _invalid(int ai_0, int ai_4, string as_8) {
if (ai_0 <= ai_4) {
Alert(WindowExpertName() + " " + Symbol() + Period() + " invalid parameter ", as_8, ": ", ai_0, ". Must be grater than ", ai_4);
return (TRUE);
}
return (FALSE);
}
Comments