Author: wfy05@talkforex.com
Price Data Components
Series array that contains open prices of each barSeries array that contains the lowest prices of each barSeries array that contains the highest prices of each barSeries array that contains close prices for each barSeries array that contains tick volumes of each bar
Miscellaneous
It issuies visual alerts to the screenUses files from the file systemIt writes information to fileIt writes information to fileIt writes information to fileIt writes information to fileIt writes information to file
0 Views
0 Downloads
0 Favorites
USDx_v1
//+------------------------------------------------------------------+
//|                                          Period_Converter_Opt.mq4|
//|                      Copyright ?2005, MetaQuotes Software Corp.  |
//|                                        http://www.metaquotes.net |
//|             Modified by wfy05@talkforex based on Period_Converter|
//|                                        http://www.talkforex.com  |
//+------------------------------------------------------------------+
#property copyright "wfy05@talkforex.com"
#property link      "http://www.mql4.com/codebase/indicators/277/"
#property indicator_chart_window
#property show_inputs

//USDX=50.14348112 x EUR/USD-0.576 x USD/JPY0.136 x GBP/USD-0.119 x USD/ CAD0.091 x USD/SEK0.042 x USD/CHF0.036 

#include <WinUser32.mqh>

extern int     timeframe=15;

extern bool     Enabled = true;
extern int      UpdateInterval = 15000;        // update interval in milliseconds, zero means update real-time.
double   Version = 1.4;             // code version
string   BuildInfo = "2005.12.24 by wfy05@talkforex.com";
int      PeriodMultiplier = 1;      // new period multiplier factor
int      OutputCSVFile = 0;         // also output CSV file?
bool     Debug = false;
bool     My_Alert = false;
int      digits=4;
int      FileHandle = -1;
int      CSVHandle = -1;
int      NewPeriod = 0;
string   New_Symbol = "USDx";

#define OUTPUT_HST_ONLY    0
#define OUTPUT_CSV_HST     1
#define OUTPUT_CSV_ONLY    2


#define  CHART_CMD_UPDATE_DATA            33324

//+------------------------------------------------------------------+
//| TOLHCV                                                           |
//+------------------------------------------------------------------+
double TOLHCV(int Shift, int Selection_Item)
{
double Open_Temp,
       Low_Temp,
       High_Temp,
       Close_Temp,
       Volume_Temp;   
 
   Open_Temp = 50.14348112*
               MathPow(iOpen("EURUSD", timeframe, Shift), -0.576)*
               MathPow(iOpen("USDJPY", timeframe, Shift), 0.136)*
               MathPow(iOpen("GBPUSD", timeframe, Shift), -0.119)*
               MathPow(iOpen("USDCAD", timeframe, Shift), 0.091)*
               MathPow(iOpen("USDSEK", timeframe, Shift), 0.042)*
               MathPow(iOpen("USDCHF", timeframe, Shift), 0.036);

    Low_Temp = 50.14348112*
               MathPow(iLow("EURUSD", timeframe, Shift), -0.576)*
               MathPow(iLow("USDJPY", timeframe, Shift), 0.136)*
               MathPow(iLow("GBPUSD", timeframe, Shift), -0.119)*
               MathPow(iLow("USDCAD", timeframe, Shift), 0.091)*
               MathPow(iLow("USDSEK", timeframe, Shift), 0.042)*
               MathPow(iLow("USDCHF", timeframe, Shift), 0.036);


   High_Temp = 50.14348112*
               MathPow(iHigh("EURUSD", timeframe, Shift), -0.576)*
               MathPow(iHigh("USDJPY", timeframe, Shift), 0.136)*
               MathPow(iHigh("GBPUSD", timeframe, Shift), -0.119)*
               MathPow(iHigh("USDCAD", timeframe, Shift), 0.091)*
               MathPow(iHigh("USDSEK", timeframe, Shift), 0.042)*
               MathPow(iHigh("USDCHF", timeframe, Shift), 0.036);

  Close_Temp = 50.14348112*
               MathPow(iClose("EURUSD", timeframe, Shift), -0.576)*
               MathPow(iClose("USDJPY", timeframe, Shift), 0.136)*
               MathPow(iClose("GBPUSD", timeframe, Shift), -0.119)*
               MathPow(iClose("USDCAD", timeframe, Shift), 0.091)*
               MathPow(iClose("USDSEK", timeframe, Shift), 0.042)*
               MathPow(iClose("USDCHF", timeframe, Shift), 0.036);

  Volume_Temp = 50.14348112*
               MathPow(iVolume("EURUSD", timeframe, Shift), -0.576)*
               MathPow(iVolume("USDJPY", timeframe, Shift), 0.136)*
               MathPow(iVolume("GBPUSD", timeframe, Shift), -0.119)*
               MathPow(iVolume("USDCAD", timeframe, Shift), 0.091)*
               MathPow(iVolume("USDSEK", timeframe, Shift), 0.042)*
               MathPow(iVolume("USDCHF", timeframe, Shift), 0.036);

double Max_Open_Close,
       Min_Open_Close;
/*       
       if (Open_Temp >= Close_Temp) {Max_Open_Close = Open_Temp; Min_Open_Close = Close_Temp;}
       if (Open_Temp < Close_Temp) {Max_Open_Close = Close_Temp; Min_Open_Close = Open_Temp;}
       
         if (Low_Temp >= High_Temp) High_Temp = Low_Temp; Low_Temp = High_Temp;
         
            if (High_Temp <= Max_Open_Close) High_Temp = Max_Open_Close;
            if (Low_Temp >= Min_Open_Close) Low_Temp = Min_Open_Close;
*/

       if (Open_Temp >= Close_Temp) {High_Temp = Open_Temp; Low_Temp = Close_Temp;}
       if (Open_Temp < Close_Temp) {High_Temp = Close_Temp; Low_Temp = Open_Temp;}
   
   switch (Selection_Item)
   {
   case 0: {return(iTime("EURUSD", timeframe, Shift)); break;}
   case 1: {return(Open_Temp); break;}
   case 2: {return(Low_Temp); break;}
   case 3: {return(High_Temp); break;}
   case 4: {return(Close_Temp); break;}
   case 5: {return(Volume_Temp); break;}
   }
}

//+------------------------------------------------------------------+
//| Min_Bars                                                         |
//+------------------------------------------------------------------+
int Min_Bars()
{
int Mas_Bars[6];

   Mas_Bars[0]=iBars("EURUSD", timeframe);
   Mas_Bars[1]=iBars("USDJPY", timeframe); 
   Mas_Bars[2]=iBars("GBPUSD", timeframe); 
   Mas_Bars[3]=iBars("USDCAD", timeframe); 
   Mas_Bars[4]=iBars("USDSEK", timeframe); 
   Mas_Bars[5]=iBars("USDCHF", timeframe);

return(Mas_Bars[ArrayMinimum(Mas_Bars, WHOLE_ARRAY, 0)]);

//return(iBars("EURUSD", timeframe));
}

void DebugMsg(string msg)
{
   if (Debug) Alert(msg);
}

void alert(string msg)
{
   if (My_Alert) Alert(msg);
}


int init()
{
/*
   //safe checking for PeriodMultiplier.
   if (PeriodMultiplier <= 1) {
      //only output CSV file
      PeriodMultiplier = 1;
      OutputCSVFile = 2;
   }
*/   
   
   NewPeriod = timeframe * PeriodMultiplier;
   if (OpenHistoryFile() < 0) return (-1);
   WriteHistoryHeader();
//alert("01 - init - WriteHistoryHeader");
   UpdateHistoryFile(Min_Bars()-1, true);
//alert("02 - init - UpdateHistoryFile");
   UpdateChartWindow();
//alert("03 - init - UpdateChartWindow");
   return (0);
}

void deinit()
{
   //Close file handle
   if(FileHandle >=  0) { 
      FileClose(FileHandle); 
      FileHandle = -1; 
   }
   if (CSVHandle >= 0) {
      FileClose(CSVHandle);
      CSVHandle = -1; 
   }
}


int OpenHistoryFile()
{
  
   string name;
    
   name = New_Symbol + NewPeriod;
          
   if (OutputCSVFile != OUTPUT_CSV_ONLY) {
      
      FileHandle = FileOpenHistory(name + ".hst", FILE_BIN|FILE_WRITE);
         
      if (FileHandle < 0) return(-1);
   }
   if (OutputCSVFile != OUTPUT_HST_ONLY) {
      CSVHandle = FileOpen(name + ".csv", FILE_CSV|FILE_WRITE, ',');
      if (CSVHandle < 0) return(-1);
   }
   return (0);
}

int WriteHistoryHeader()
{
  
   string c_copyright;
   int    i_digits = digits;
   int    i_unused[13] = {0};
   int    version = 400;   

   if (FileHandle < 0) return (-1);
   
   c_copyright = "(C)opyright 2003, MetaQuotes Software Corp.";
   FileWriteInteger(FileHandle, version, LONG_VALUE);
   FileWriteString(FileHandle, c_copyright, 64);
   FileWriteString(FileHandle, New_Symbol, 12);
   FileWriteInteger(FileHandle, NewPeriod, LONG_VALUE);
   FileWriteInteger(FileHandle, i_digits, LONG_VALUE);
   FileWriteInteger(FileHandle, 0, LONG_VALUE);       //timesign
   FileWriteInteger(FileHandle, 0, LONG_VALUE);       //last_sync
   FileWriteArray(FileHandle, i_unused, 0, ArraySize(i_unused));
   
   return (0);
}


static double d_open, d_low, d_high, d_close, d_volume;
static int i_time;

void WriteHistoryData()
{
   if (FileHandle >= 0) {
      FileWriteInteger(FileHandle, i_time, LONG_VALUE);
      FileWriteDouble(FileHandle, d_open, DOUBLE_VALUE);
      FileWriteDouble(FileHandle, d_low, DOUBLE_VALUE);
      FileWriteDouble(FileHandle, d_high, DOUBLE_VALUE);
      FileWriteDouble(FileHandle, d_close, DOUBLE_VALUE);
      FileWriteDouble(FileHandle, d_volume, DOUBLE_VALUE);
   }
   if (CSVHandle >= 0) {
      int i_digits = digits;
      
      FileWrite(CSVHandle,
         TimeToStr(i_time, TIME_DATE),
         TimeToStr(i_time, TIME_MINUTES),
         DoubleToStr(d_open, i_digits), 
         DoubleToStr(d_high, i_digits), 
         DoubleToStr(d_low, i_digits), 
         DoubleToStr(d_close, i_digits), 
         d_volume);
   }
}

int UpdateHistoryFile(int start_pos, bool init = false)
{
   static int last_fpos, csv_fpos;
   int i, ps;
      
//   if (FileHandle < 0) return (-1);
   // normalize open time
   ps = NewPeriod * 60;   
   i_time = TOLHCV(start_pos, 0)/ps;
   i_time *=  ps;
   if (init) {
         //first time, init data
         d_open = TOLHCV(start_pos, 1);
         d_low = TOLHCV(start_pos, 2);
         d_high = TOLHCV(start_pos, 3);
         d_close = TOLHCV(start_pos, 4);
         d_volume = TOLHCV(start_pos, 5);                           
         i = start_pos - 1;
         if (FileHandle >= 0) last_fpos = FileTell(FileHandle);
         if (CSVHandle >= 0) csv_fpos = FileTell(CSVHandle);
   } else {
         i = start_pos;
         if (FileHandle >= 0) FileSeek(FileHandle,last_fpos,SEEK_SET);
         if (CSVHandle >= 0) FileSeek(CSVHandle, csv_fpos, SEEK_SET);
   }
   if (i < 0) return (-1);

   int cnt = 0;
   int LastBarTime;
   //processing bars
   while (i >= 0) {
      LastBarTime = TOLHCV(i, 0);

      //a new bar
      if (LastBarTime >=  i_time+ps) {
         //write the bar data
         WriteHistoryData();
         cnt++;
         i_time = LastBarTime/ps;
         i_time *= ps;
         d_open = TOLHCV(i, 1);
         d_low = TOLHCV(i, 2);
         d_high = TOLHCV(i, 3);
         d_close = TOLHCV(i, 4);
         d_volume = TOLHCV(i, 5);
      } else {
         //no new bar
         d_volume +=  TOLHCV(i, 5);
         if (TOLHCV(i, 2)<d_low) d_low = TOLHCV(i, 2);
         if (TOLHCV(i, 3)>d_high) d_high = TOLHCV(i, 3);
         d_close = TOLHCV(i, 4);      
      }
      i--;
   }
   
   //record last_fpos before writing last bar.
   if (FileHandle >= 0) last_fpos = FileTell(FileHandle);
   if (CSVHandle >= 0) csv_fpos = FileTell(CSVHandle);
   
   WriteHistoryData();
   cnt++;
   d_volume -=  TOLHCV(0, 5);
   
   //flush the data writen
   if (FileHandle >= 0) FileFlush(FileHandle);
   if (CSVHandle >= 0) FileFlush(CSVHandle);
   return (cnt);
}

int UpdateChartWindow()
{
   static int hwnd = 0;

   if (FileHandle < 0) {
      //no HST file opened, no need updating.
      return (-1);
   }
   if(hwnd == 0) {
      //trying to detect the chart window for updating
      hwnd = WindowHandle(New_Symbol, NewPeriod);
   }
   if(hwnd!= 0) {
      if (IsDllsAllowed() == false) {
         //DLL calls must be allowed
         DebugMsg("Dll calls must be allowed");
         return (-1);
      }
      if (PostMessageA(hwnd,WM_COMMAND,CHART_CMD_UPDATE_DATA,0) == 0) {
         //PostMessage failed, chart window closed
         hwnd = 0;
      } else {
         //PostMessage succeed
         return (0);
      }
   }
   //window not found or PostMessage failed
   return (-1);
}


/*
int PerfCheck(bool Start)
{
   static int StartTime = 0;
   static int Index = 0;
   
   if (Start) {
      StartTime = GetTickCount();
      Index = 0;
      return (StartTime);
   }
   Index++;
   int diff = GetTickCount() - StartTime;
   Alert("Time used [" + Index + "]: " + diff);
   StartTime = GetTickCount();
   return (diff);
}
*/

static int LastStartTime = 0;
static int LastEndTime = 0;
static int LastBarCount = 0;

int reinit()
{
   deinit();
   init();
   LastStartTime = TOLHCV(Min_Bars()-1, 0);
   LastEndTime = TOLHCV(0, 0);
   LastBarCount = Min_Bars();
}

bool IsDataChanged()
{
/*
   static int LastBars = 0, LastTime = 0, LastVolume = 0;
   static double LastOpen = 0, LastClose = 0, LastHigh = 0, LastLow = 0;
   
   if (LastVolume != Volume[0] || LastBars != Bars || LastTime != Time[0]|| 
      LastClose != Close[0] || LastHigh != High[0] || LastLow != Low[0] || 
      LastOpen != Open[0]) {

      LastBars = Bars;
      LastVolume = Volume[0];
      LastTime = Time[0];
      LastClose = Close[0];
      LastHigh = High[0];
      LastLow = Low[0];
      LastOpen = Open[0];
      return (true);
   }
   return (false);
*/
/*
   fast version without float point operation
*/
   static int LastBars = 0, LastTime = 0, LastVolume = 0;
   bool ret;
   
   ret = false;
   if (LastVolume != TOLHCV(0, 5)) {
      LastVolume = TOLHCV(0, 5);
      ret = true;
   }
   if (LastTime != TOLHCV(0, 0)) {
      LastTime = TOLHCV(0, 0);
      ret = true;
   }
   if (LastBars != Min_Bars()) {
      LastBars = Min_Bars();
      ret = true;
   }
   return (ret);
}

int CheckNewData()
{
   static string LastServer = "";
   
   if (Min_Bars() < 2) {
      //the data is not loaded yet.
      DebugMsg("Data not loaded, only " +  Min_Bars() + " Bars");
      return (-1);
   }

   string serv = ServerAddress();
   if (serv == "") {
      //no server yet
      DebugMsg("No server connected");
      return (-1);
   }

   //server changed? check this and reinit to prevent wrong data while changing server.
   if (LastServer != serv) {
      DebugMsg("Server changed from " + LastServer + " to " + serv);
      LastServer = serv;
      reinit();
      return (-1);
   }

   if (!IsDataChanged()) {
      //return if no data changed to save resource
      DebugMsg("No data changed");
      return (-1);
   }

   if (TOLHCV(Min_Bars()-1, 0) != LastStartTime) {
      DebugMsg("Start time changed, new history loaded or server changed");
      reinit();
      return (-1);
   }
      
   int i, cnt;
   
   //try to find LastEndTime bar, which should be Time[0] or Time[1] usually,
   //so the operation is fast
   for (i = 0; i < Min_Bars(); i++) {
      if (TOLHCV(i, 0) <= LastEndTime) {
         break;
      }
   }
   
   if (i >= Min_Bars() || TOLHCV(i, 0) != LastEndTime) {
      DebugMsg("End time " + TimeToStr(LastEndTime) + " not found");
      reinit();
      return (-1);
   }
   
   cnt = Min_Bars() - i;
   if (cnt != LastBarCount) {
      DebugMsg("Data loaded, cnt is " + cnt + " LastBarCount is " + LastBarCount);
      reinit();
      return (-1);
   }

   //no new data loaded, return with LastEndTime position.
   LastBarCount = Min_Bars();
   LastEndTime = TOLHCV(0, 0);
   return (i);
}

//+------------------------------------------------------------------+
//| program start function                                           |
//+------------------------------------------------------------------+
int start()
{
   static int last_time = 0;

   if (!Enabled) return (0);
         
   //always update or update only after certain interval
   if (UpdateInterval !=  0) {
      int cur_time;
      
      cur_time = GetTickCount();
      if (MathAbs(cur_time - last_time) < UpdateInterval) {
         return (0);
      }
      last_time = cur_time;
   }

   //if (Debug) PerfCheck(true);
   int n = CheckNewData();
   //Print(n);

   //if (Debug) PerfCheck(false);   
   if (n < 0) return (0);

   //update history file with new data
   UpdateHistoryFile(n);
   //refresh chart window
   UpdateChartWindow();
   //if (Debug) PerfCheck(false);
   return(0);
}



Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---