This script is designed to create a special type of chart called a Renko chart, which unlike regular charts, focuses on price movement rather than time. Here's how it works:
-
Setting the Stage: The script starts by gathering some important information. It asks you, the user, for a "Renko Box Size" (how much the price needs to move to form a new brick), an "offset" ( a starting point to align the bricks), a "Time Frame" ( to relate to regular charts) and a few display settings. It also checks if your broker uses 5 or 6 decimal places for prices and adjusts the "Renko Box Size" accordingly to work in "pips".
-
Creating a "History" File: The script then creates a special file (a
.hst
file) that will store the data for the Renko chart. This file is like a logbook that records the open, high, low, and closing prices for each Renko "brick". -
Filling the Logbook: The script goes back through the historical price data and analyzes it. It simulates building the Renko chart brick by brick.
- It checks if the price has moved enough to create a new brick, either up or down, based on the "Renko Box Size".
- If a new brick is formed, it writes the details (open, high, low, close) into the
.hst
file. - It keeps track of the volume of trades as the chart is built.
- It makes adjustments to the "wicks" (the thin lines that show the highest and lowest prices reached within a brick).
-
Live Updates: After the historical data is processed, the script switches to "live" mode. As the price changes in real-time, the script:
- Monitors the price movement to see if it's enough to form a new Renko brick.
- If a new brick forms, it writes the data to the
.hst
file, updating the Renko chart in real-time. - If the price fluctuates within the range of the current brick, it updates the high and low values and writes the current details of that brick.
-
Displaying the Chart: The script interacts with the charting software to display the Renko chart using the data stored in the
.hst
file. It essentially tells the chart to refresh and show the updated Renko bricks.
In essence, this script takes regular price data and transforms it into a Renko chart, which focuses on price movement in defined increments rather than time, providing a different perspective on market trends.
//+---------------------------------------------------------------------------+
//| EA VERSION
//| RenkoLiveChart_v3.0.mq4
//| Inspired from Renko script by "e4" (renko_live_scr.mq4)
//| Copyleft 2009 LastViking
//|
//| Sep 2009 - Optional wicks added
//| - Conversion back to EA
//| - Auto adjust for 5 and 6 dec brokers added
//| enter RenkoBoxSize as "actual" size e.g. "10" for 10 pips
//| - compensation for "zero compare" problem added
//+---------------------------------------------------------------------------+
#property copyright ""
#property indicator_chart_window
#property indicator_buffers 1
//+------------------------------------------------------------------+
#include <WinUser32.mqh>
#include <stdlib.mqh>
//+------------------------------------------------------------------+
extern int RenkoBoxSize = 5;
extern int BoxOffset = 0;
extern int RenkoTimeFrame = 2; // What time frame to use for the offline renko chart
extern bool StrangeSymbolName = false;
extern bool ShowWicks = false;
extern string Sym = "EURUSDm";
int BoxSize;
//+------------------------------------------------------------------+
int HstHandle = -1;
string SymbolName;
//+------------------------------------------------------------------+
void UpdateChartWindow() {
static int hwnd = 0;
if(hwnd == 0) {
hwnd = WindowHandle(SymbolName, RenkoTimeFrame);
if(hwnd != 0) Print("Chart window detected");
}
if(hwnd != 0) if(PostMessageA(hwnd, WM_COMMAND, 0x822c, 0) == 0) hwnd = 0;
}
int init() {
BoxSize = RenkoBoxSize;
if (Digits == 5)
{BoxSize = BoxSize*10;}
if (Digits == 6)
{BoxSize = BoxSize*100;}
HstHandle = -1;
return(0);
}
//+------------------------------------------------------------------+
int start() {
static int LastFPos = 0;
static double BoxPoints, PrevLow, PrevHigh, PrevOpen, PrevClose, CurVolume, CurHigh, CurLow;
static double CurOpen, CurClose;
static datetime PrevTime;
static double UpWick = 0;
static double DnWick = EMPTY_VALUE;
if(HstHandle < 0) {
// Init
// Error checking
if(!IsConnected()) {
Print("Waiting for connection...");
return(0);
}
if(!IsDllsAllowed()) {
Print("Error: Dll calls must be allowed!");
return(-1);
}
if(MathAbs(BoxOffset) >= BoxSize) {
Print("Error: |BoxOffset| should be less then BoxSize!");
return(-1);
}
switch(RenkoTimeFrame) {
case 1: case 5: case 15: case 30: case 60: case 240:
case 1440: case 10080: case 43200: case 0:
Print("Error: Invald time frame used for offline renko chart (RenkoTimeFrame)!");
return(-1);
}
//
if(StrangeSymbolName) SymbolName = StringSubstr(Sym, 0, 6);
else SymbolName = Sym;
BoxPoints = NormalizeDouble(BoxSize*MarketInfo(Sym, MODE_POINT), MarketInfo(Sym, MODE_DIGITS));
PrevLow = NormalizeDouble(BoxOffset*MarketInfo(Sym, MODE_POINT) + MathFloor(iClose(Sym, 0, iBars(Sym, 0)-1)/BoxPoints)*BoxPoints, MarketInfo(Sym, MODE_DIGITS));
PrevHigh = PrevLow + BoxPoints;
PrevOpen = PrevLow;
PrevClose = PrevHigh;
CurVolume = 1;
PrevTime = iTime(Sym,0,iBars(Sym,0)-1);
// create / open hst file
HstHandle = FileOpenHistory(SymbolName + RenkoTimeFrame + ".hst", FILE_BIN|FILE_WRITE);
if(HstHandle < 0) return(-1);
//
// write hst file header
int HstUnused[13];
FileWriteInteger(HstHandle, 400, LONG_VALUE); // Version
FileWriteString(HstHandle, "", 64); // Copyright
FileWriteString(HstHandle, SymbolName, 12); // Symbol
FileWriteInteger(HstHandle, RenkoTimeFrame, LONG_VALUE); // Period
FileWriteInteger(HstHandle, MarketInfo(Sym, MODE_DIGITS), LONG_VALUE); // Digits
FileWriteInteger(HstHandle, 0, LONG_VALUE); // Time Sign
FileWriteInteger(HstHandle, 0, LONG_VALUE); // Last Sync
FileWriteArray(HstHandle, HstUnused, 0, 13); // Unused
//
// process historical data
int i = iBars(Sym, 0)-2;
while(i >= 0) {
CurVolume += iVolume(Sym,0,i);
UpWick = MathMax(UpWick,iHigh(Sym,0,i));
DnWick = MathMin(DnWick,iLow(Sym,0,i));
if(LastFPos != 0) {
FileSeek(HstHandle, LastFPos, SEEK_SET);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
}
bool UpTrend = iHigh(Sym,0,i)+iLow(Sym,0,i) > PrevHigh+PrevLow;
// update low before high or the revers depending on is closest to prev. renko bar
while(UpTrend && (iLow(Sym,0,i) < PrevLow-BoxPoints || CompareDoubles(iLow(Sym,0,i),PrevLow-BoxPoints))) {
PrevHigh = PrevHigh - BoxPoints;
PrevLow = PrevLow - BoxPoints;
PrevOpen = PrevHigh;
PrevClose = PrevLow;
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE);
FileWriteDouble(HstHandle, PrevOpen, DOUBLE_VALUE);
FileWriteDouble(HstHandle, PrevLow, DOUBLE_VALUE);
if (ShowWicks && UpWick > PrevHigh)
{FileWriteDouble(HstHandle, UpWick, DOUBLE_VALUE);}
else
{FileWriteDouble(HstHandle, PrevHigh, DOUBLE_VALUE);}
UpWick = 0;
DnWick = EMPTY_VALUE;
FileWriteDouble(HstHandle, PrevClose, DOUBLE_VALUE);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
CurVolume = 0;
if(PrevTime < iTime(Sym,0,i)) PrevTime = iTime(Sym,0,i);
else PrevTime++;
}
while(UpTrend && (iHigh(Sym,0,i) > PrevHigh+BoxPoints || CompareDoubles(iHigh(Sym,0,i),PrevHigh+BoxPoints))) {
PrevHigh = PrevHigh + BoxPoints;
PrevLow = PrevLow + BoxPoints;
PrevOpen = PrevLow;
PrevClose = PrevHigh;
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE);
FileWriteDouble(HstHandle, PrevOpen, DOUBLE_VALUE);
if (ShowWicks && DnWick < PrevLow)
{FileWriteDouble(HstHandle, DnWick, DOUBLE_VALUE);}
else
{FileWriteDouble(HstHandle, PrevLow, DOUBLE_VALUE);}
UpWick = 0;
DnWick = EMPTY_VALUE;
FileWriteDouble(HstHandle, PrevHigh, DOUBLE_VALUE);
FileWriteDouble(HstHandle, PrevClose, DOUBLE_VALUE);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
CurVolume = 0;
if(PrevTime < iTime(Sym,0,i)) PrevTime = iTime(Sym,0,i);
else PrevTime++;
}
while(!UpTrend && (iLow(Sym,0,i) < PrevLow-BoxPoints || CompareDoubles(iLow(Sym,0,i),PrevLow-BoxPoints))) {
PrevHigh = PrevHigh - BoxPoints;
PrevLow = PrevLow - BoxPoints;
PrevOpen = PrevHigh;
PrevClose = PrevLow;
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE);
FileWriteDouble(HstHandle, PrevOpen, DOUBLE_VALUE);
FileWriteDouble(HstHandle, PrevLow, DOUBLE_VALUE);
if (ShowWicks && UpWick > PrevHigh)
{FileWriteDouble(HstHandle, UpWick, DOUBLE_VALUE);}
else
{FileWriteDouble(HstHandle, PrevHigh, DOUBLE_VALUE);}
UpWick = 0;
DnWick = EMPTY_VALUE;
FileWriteDouble(HstHandle, PrevClose, DOUBLE_VALUE);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
CurVolume = 0;
if(PrevTime < iTime(Sym,0,i)) PrevTime = iTime(Sym,0,i);
else PrevTime++;
}
i--;
}
FileFlush(HstHandle);
LastFPos = FileTell(HstHandle); // Remember Last pos in file
//
Comment("RenkoLiveChart(" + BoxSize + "): Open Offline ", SymbolName, ",M", RenkoTimeFrame, " to view chart");
CurOpen = PrevClose;
if (UpWick > PrevHigh)
{CurHigh = UpWick;}
else
{CurHigh = PrevHigh;}
if (DnWick < PrevLow)
{CurLow = DnWick;}
else
{CurLow = PrevLow;}
CurClose = iClose(Sym,0,0);
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE); // Time
FileWriteDouble(HstHandle, CurOpen, DOUBLE_VALUE); // Open
FileWriteDouble(HstHandle, CurLow, DOUBLE_VALUE); // Low
FileWriteDouble(HstHandle, CurHigh, DOUBLE_VALUE); // High
FileWriteDouble(HstHandle, CurClose, DOUBLE_VALUE); // Close
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE); // Volume
FileFlush(HstHandle);
UpdateChartWindow();
return(0);
// End historical data / Init
}
//----------------------------------------------------------------------------
// HstHandle not < 0 so we always enter here after history done
// Begin live data feed
//
UpWick = MathMax(UpWick,MarketInfo(Sym, MODE_BID));
DnWick = MathMin(DnWick,MarketInfo(Sym, MODE_BID));
CurVolume++;
FileSeek(HstHandle, LastFPos, SEEK_SET);
// up box
//-------------------------------------------------------------------------
if(MarketInfo(Sym, MODE_BID) > PrevHigh+BoxPoints || CompareDoubles(MarketInfo(Sym, MODE_BID),PrevHigh+BoxPoints)) {
PrevHigh = PrevHigh + BoxPoints;
PrevLow = PrevLow + BoxPoints;
PrevOpen = PrevLow;
PrevClose = PrevHigh;
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE);
FileWriteDouble(HstHandle, PrevOpen, DOUBLE_VALUE);
if (ShowWicks && DnWick < PrevLow)
{FileWriteDouble(HstHandle, DnWick, DOUBLE_VALUE);}
else
{FileWriteDouble(HstHandle, PrevLow, DOUBLE_VALUE);}
UpWick = 0;
DnWick = EMPTY_VALUE;
FileWriteDouble(HstHandle, PrevHigh, DOUBLE_VALUE);
FileWriteDouble(HstHandle, PrevClose, DOUBLE_VALUE);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
FileFlush(HstHandle);
LastFPos = FileTell(HstHandle); // Remeber Last pos in file
if(PrevTime < TimeCurrent()) PrevTime = TimeCurrent();
else PrevTime++;
CurVolume = 0;
CurOpen = PrevClose;
CurHigh = PrevHigh;
CurLow = PrevHigh;
UpdateChartWindow();
}
// down box
//-------------------------------------------------------------------------
else if(MarketInfo(Sym, MODE_BID) < PrevLow-BoxPoints || CompareDoubles(MarketInfo(Sym, MODE_BID),PrevLow-BoxPoints)) {
PrevHigh = PrevHigh - BoxPoints;
PrevLow = PrevLow - BoxPoints;
PrevOpen = PrevHigh;
PrevClose = PrevLow;
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE);
FileWriteDouble(HstHandle, PrevOpen, DOUBLE_VALUE);
FileWriteDouble(HstHandle, PrevLow, DOUBLE_VALUE);
if (ShowWicks && UpWick > PrevHigh)
{FileWriteDouble(HstHandle, UpWick, DOUBLE_VALUE);}
else
{FileWriteDouble(HstHandle, PrevHigh, DOUBLE_VALUE);}
UpWick = 0;
DnWick = EMPTY_VALUE;
FileWriteDouble(HstHandle, PrevClose, DOUBLE_VALUE);
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE);
FileFlush(HstHandle);
LastFPos = FileTell(HstHandle); // Remeber Last pos in file
if(PrevTime < TimeCurrent()) PrevTime = TimeCurrent();
else PrevTime++;
CurVolume = 0;
CurOpen = PrevClose;
CurHigh = PrevLow;
CurLow = PrevLow;
UpdateChartWindow();
}
else {
// no box - high/low not hit
//-------------------------------------------------------------------------
if(MarketInfo(Sym, MODE_BID) > CurHigh) CurHigh = MarketInfo(Sym, MODE_BID);
if(MarketInfo(Sym, MODE_BID) < CurLow) CurLow = MarketInfo(Sym, MODE_BID);
CurClose = MarketInfo(Sym, MODE_BID);
FileWriteInteger(HstHandle, PrevTime, LONG_VALUE); // Time
FileWriteDouble(HstHandle, CurOpen, DOUBLE_VALUE); // Open
FileWriteDouble(HstHandle, CurLow, DOUBLE_VALUE); // Low
FileWriteDouble(HstHandle, CurHigh, DOUBLE_VALUE); // High
FileWriteDouble(HstHandle, CurClose, DOUBLE_VALUE); // Close
FileWriteDouble(HstHandle, CurVolume, DOUBLE_VALUE); // Volume
FileFlush(HstHandle);
UpdateChartWindow();
}
return(0);
}
//+------------------------------------------------------------------+
int deinit() {
if(HstHandle >= 0) {
FileClose(HstHandle);
HstHandle = -1;
}
Comment("");
return(0);
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---