Disliked{quote} Ok, Give me some time to have a look for a solution. I will be back asap to start and go step by step.Ignored
Best Regard.
MTH
What is better to learn, MQL or AFL (Amibroker)?? 14 replies
starting with c++ before mql.. how much c++ should one learn? 2 replies
I Will Learn Coding in 1 Month - Give me the 80/20 of MT4 Coding 14 replies
MQL Coding - Let’s talk about how to code mql 0 replies
Book to Learn MQL? 8 replies
Disliked{quote} Ok, Give me some time to have a look for a solution. I will be back asap to start and go step by step.Ignored
class MyClass {
static MyClass* m_pInstance;
}; MyClass* MyClass::m_pInstance = NULL;
class MyClass {
static MyClass* m_pInstance;
public:
int GetId(){ return 5; }
static MyClass* Instance();
}; MyClass* MyClass::Instance() {
if( m_pInstance == NULL ){
m_pInstance = new MyClass();
}
return m_pInstance;
} MyClass::Instance().GetId();
MyClass a;
class MyClass {
static MyClass* m_pInstance;
MyClass(){} // private constructor.
public:
int GetId(){ return 5; }
static MyClass* Instance();
}; MyClass a;
Let's declare our RenkoChart singleton class:
class RenkoChart {
static RenkoChart* m_pInstance;
protected:
RenkoChart();
public:
static RenkoChart* Instance();
}; RenkoChart* RenkoChart::m_pInstance = NULL;
RenkoChart::RenkoChart() {
}
static RenkoChart* RenkoChart::Instance() {
if( m_pInstance == NULL ){
m_pInstance = new RenkoChart();
}
return m_pInstance;
} bool OnInit( int custperiod, int boxsizepips );
class RenkoChart {
static RenkoChart* m_pInstance;
int m_CustomPeriod; // new member
int m_BoxSize; // new member
protected:
RenkoChart();
public:
static RenkoChart* Instance();
bool OnInit( int custperiod, int boxsizepips ); // new method
}; bool RenkoChart::OnInit( int custperiod, int boxsizepips ) {
m_BoxSize = boxsizepips;
m_CustomPeriod = custperiod;
} bool RenkoChart::OnInit( int custperiod, int boxsizepips ) {
m_BoxSize = boxsizepips;
m_CustomPeriod = custperiod;
string CustomPeriodStr = IntegerToString( m_CustomPeriod );
// Create history file
m_FileHandle = FileOpenHistory( Symbol() + CustomPeriodStr + ".hst", FILE_BIN|FILE_WRITE );
if( m_FileHandle < 0 ) {
Print( "Error creating history file: " + IntegerToString(GetLastError()) );
return false;
}
} bool RenkoChart::OnInit( int custperiod, int boxsizepips ) {
m_BoxSize = boxsizepips;
m_CustomPeriod = custperiod;
string CustomPeriodStr = IntegerToString( m_CustomPeriod );
// Create history file
m_FileHandle = FileOpenHistory( Symbol() + CustomPeriodStr + ".hst", FILE_BIN|FILE_WRITE );
if( m_FileHandle < 0 ) {
Print( "Error creating history file: " + IntegerToString(GetLastError()) );
return false;
}
// Get number of bars in chart and initialize index
m_BarCount = Bars;
m_BarIndex = m_BarCount-1;
// Write file header.
int Version = 400;
string CopyRight = "(c) 2014 Broketrader RenkoChart";
string SymbolPair = Symbol();
int TimePeriod = m_CustomPeriod;
int PriceDigits = Digits;
int Unused[13];
ArrayInitialize( Unused, 0 );
FileWriteInteger( m_FileHandle, Version, LONG_VALUE ); // Version
FileWriteString( m_FileHandle, CopyRight, 64 ); // Copyright
FileWriteString( m_FileHandle, SymbolPair, 12 ); // Symbol
FileWriteInteger( m_FileHandle, TimePeriod, LONG_VALUE ); // Period
FileWriteInteger( m_FileHandle, PriceDigits, LONG_VALUE ); // Digits
FileWriteInteger( m_FileHandle, 0, LONG_VALUE ); // Time Sign
FileWriteInteger( m_FileHandle, 0, LONG_VALUE ); // Last Sync
FileWriteArray( m_FileHandle, Unused, 0, 13 ); // Unused
return true;
} class RenkoChart {
static RenkoChart* m_pInstance;
int m_CustomPeriod;
int m_BoxSize;
int m_FileHandle; // new member
int m_BarCount; // new member
int m_BarIndex; // new member
protected:
RenkoChart();
public:
static RenkoChart* Instance();
bool OnInit( int custperiod, int boxsizepips );
}; bool RenkoChart::OnInit( int custperiod, int boxsizepips ) {
m_BoxSize = boxsizepips;
m_CustomPeriod = custperiod;
string CustomPeriodStr = IntegerToString( m_CustomPeriod );
// Create history file
m_FileHandle = FileOpenHistory( Symbol() + CustomPeriodStr + ".hst", FILE_BIN|FILE_WRITE );
if( m_FileHandle < 0 ) {
Print( "Error creating history file: " + IntegerToString(GetLastError()) );
return false;
}
// Get number of bars in chart and initialize index
m_BarCount = Bars;
m_BarIndex = m_BarCount-1;
// Write file header.
int Version = 400;
string CopyRight = "(c) 2014 Broketrader RenkoChart";
string SymbolPair = Symbol();
int TimePeriod = m_CustomPeriod;
int PriceDigits = Digits;
int Unused[13];
ArrayInitialize( Unused, 0 );
FileWriteInteger( m_FileHandle, Version, LONG_VALUE ); // Version
FileWriteString( m_FileHandle, CopyRight, 64 ); // Copyright
FileWriteString( m_FileHandle, SymbolPair, 12 ); // Symbol
FileWriteInteger( m_FileHandle, TimePeriod, LONG_VALUE ); // Period
FileWriteInteger( m_FileHandle, PriceDigits, LONG_VALUE ); // Digits
FileWriteInteger( m_FileHandle, 0, LONG_VALUE ); // Time Sign
FileWriteInteger( m_FileHandle, 0, LONG_VALUE ); // Last Sync
FileWriteArray( m_FileHandle, Unused, 0, 13 ); // Unused
// Write first simple bar.
if( Close[m_BarIndex] > Open[m_BarIndex] ){
m_Rate.m_Open = Low[m_BarIndex];
m_Rate.m_Low = m_Rate.m_Open;
m_Rate.m_High = High[m_BarIndex];
m_Rate.m_Close = m_Rate.m_High;
}
else{
m_Rate.m_Open = High[m_BarIndex];
m_Rate.m_High = m_Rate.m_Open;
m_Rate.m_Low = Low[m_BarIndex];
m_Rate.m_Close = m_Rate.m_Low;
}
m_PrevHigh = m_Rate.m_High;
m_PrevLow = m_Rate.m_Low;
m_Rate.m_Vol = (double)Volume[m_BarIndex];
m_Rate.m_Time = (int)Time[m_BarIndex];
FileWriteStruct( m_FileHandle, m_Rate );
// We prepare for the next bar
m_BarIndex--;
m_Rate.m_Vol = 0;
return true;
} class RenkoChart {
struct RenkoRate{
int m_Time;
double m_Open, m_Low, m_High, m_Close, m_Vol;
}; // Private structure
static RenkoChart* m_pInstance;
int m_CustomPeriod;
int m_BoxSize;
int m_FileHandle;
int m_BarCount;
int m_BarIndex;
RenkoRate m_Rate; // new member
double m_PrevHigh; // new member
double m_PrevLow; // new member
protected:
RenkoChart();
public:
static RenkoChart* Instance();
bool OnInit( int custperiod, int boxsizepips );
}; int OnInit() {
if( ! RenkoChart::Instance().OnInit( 3, BoxSize ) ){
return INIT_FAILED;
}
return INIT_SUCCEEDED;
} RenkoChart::Instance().OnInit( 3, BoxSize )
bool RenkoChart::OnInit( int custperiod, int boxsizepips ) {
.
.
.
// Initiates event driven writing
EventSetMillisecondTimer( 1 );
return true;
} void OnTimer() {
RenkoChart::Instance().OnTimer();
} // Avoid re-entrancy EventKillTimer();
// Compute let's say a maximum of 100000 bars at a time.
for( int i=0; i<100000 && m_BarIndex >= 1; i++, m_BarIndex-- ){
bool NewBar = ComputeRenkoBar( m_BarIndex );
if( NewBar ){
FileWriteStruct( m_FileHandle, m_Rate );
// Reset volume for next bar
m_Rate.m_Vol = 0;
}
} // If we have calculated all bars except the current one...
if( m_BarIndex <= 1 ){
// Finished. Display some termination info and don't rearm the timer anymore.
Comment( "Renko Chart Completed. Please open the M3 offline chart" );
// Store file position for further usage
m_FileCPos = FileTell( m_FileHandle );
// Close and we are done.
FileClose( m_FileHandle );
m_FileHandle = -1;
m_InitDone = true;
}
else{
// Not finished yet. Display some info text and rearm the timer
double Completed = (double)(m_BarCount-m_BarIndex) / (double)m_BarCount * 100;
Comment( "RenkoChart is creating the history file : " + DoubleToStr(Completed,0) + "% Completed" );
EventSetMillisecondTimer( 1 );
} void RenkoChart::OnTimer() {
// Avoid re-entrancy
EventKillTimer();
// Compute let's say a maximum of 100000 bars at a time.
for( int i=0; i<100000 && m_BarIndex >= 1; i++, m_BarIndex-- ){
bool NewBar = ComputeRenkoBar( m_BarIndex );
if( NewBar ){
FileWriteStruct( m_FileHandle, m_Rate );
// Reset volume for next bar
m_Rate.m_Vol = 0;
}
}
// If we have calculated all bars except the current one...
if( m_BarIndex <= 1 ){
// Finished. Display some termination info and don't rearm the timer anymore.
Comment( "Renko Chart Completed. Please open the M3 offline chart" );
// Store file position for further usage
m_FileCPos = FileTell( m_FileHandle );
// Close and we are done.
FileClose( m_FileHandle );
m_FileHandle = -1;
m_InitDone = true;
}
else{
// Not finished yet. Display some info text and rearm the timer
double Completed = (double)(m_BarCount-m_BarIndex) / (double)m_BarCount * 100;
Comment( "RenkoChart is creating the history file : " + DoubleToStr(Completed,0) + "% Completed" );
EventSetMillisecondTimer( 1 );
}
} bool RenkoChart::ComputeRenkoBar( int index ) {
bool Res = false;
if( Close[index] > m_PrevHigh + m_BoxSize*Point ) {
m_Rate.m_Open = m_PrevHigh;
m_Rate.m_Low = m_Rate.m_Open;
m_Rate.m_High = m_Rate.m_Open + m_BoxSize*Point;
m_Rate.m_Close = m_Rate.m_High;
Res = true;
}
else if( Close[index] < m_PrevLow - m_BoxSize*Point ) {
m_Rate.m_Open = m_PrevLow;
m_Rate.m_High = m_Rate.m_Open;
m_Rate.m_Low = m_Rate.m_Open - m_BoxSize*Point;
m_Rate.m_Close = m_Rate.m_Low;
Res = true;
}
if( m_Rate.m_Vol == 0 ){
m_Rate.m_Vol = (double)Volume[m_BarIndex];
}
else{
m_Rate.m_Vol += (double)Volume[m_BarIndex];
}
if( Res ){
m_Rate.m_Time = (int)Time[index];
m_PrevHigh = m_Rate.m_High;
m_PrevLow = m_Rate.m_Low;
}
return Res;
} void OnCalculate( int bars );
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[])
{
RenkoChart::Instance().OnCalculate( Bars );
return(rates_total);
} void RenkoChart::OnCalculate( int bars ) {
// We are still writing the histor file. Do nothing.
if( ! m_InitDone ){
return;
}
// On first call after history file creation, we must reopen the file
if( m_FileHandle == -1 ){
string CustomPeriodStr = IntegerToString( m_CustomPeriod );
m_FileHandle = FileOpenHistory( Symbol() + CustomPeriodStr + ".hst", FILE_BIN|FILE_WRITE|FILE_READ|FILE_SHARE_READ|FILE_SHARE_WRITE );
if( m_FileHandle == -1 ){
Comment( "RenkoChart cannot update history file !" );
return;
}
}
// For all bars in chart that we have not yet computed...
for( m_BarIndex=bars-m_BarCount; m_BarIndex >= 0; m_BarIndex-- ){
if( m_BarIndex == 0 ){
// Update current bar and keep file pos;
// We rewrite last Renko bar values at the same file position
ComputeCurrentBar();
FileSeek( m_FileHandle, m_FileCPos, SEEK_SET );
FileWriteStruct( m_FileHandle, m_Rate );
FileFlush( m_FileHandle );
}
else{
// Look wether a new bar can be drawn (stored)
bool NewBar = ComputeRenkoBar( m_BarIndex );
if( NewBar ){
FileSeek( m_FileHandle, m_FileCPos, SEEK_SET );
FileWriteStruct( m_FileHandle, m_Rate );
// Reset volume for next bar
m_Rate.m_Vol = 0;
FileFlush( m_FileHandle );
m_FileCPos = FileTell( m_FileHandle );
}
}
}
// Call extern functions to force chart redraw
UpdateChartWindow( m_CustomPeriod );
m_BarCount = bars;
} DislikedAttached you will find the final files that you could use as base for your own Renko chart indicator, you are free to share, modify, improve etc. Until the next... . {file} {file}Ignored
DislikedThat's why you need the starter file that I provided Basketv8.mq4 Its all in their And Yes if you then Buy or Sell on the Offline Chart you trade all of the pairs within that chart ( eg 5 pairs then 5 * buy or 5 * sell trades one for each pair) {file}Ignored
Dislikedbroketrader Glad to see this thread and thanks for your efforts. …Ignored