Author: wfy05@talkforex.com
2 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