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