Price Data Components
Miscellaneous
0
Views
0
Downloads
0
Favorites
BasketChartCreator
//------------------------------------------------------------------------------------------------
//--- BasketChartCreator.mq4
//--- Copyright © 2015, Khalil Abokwaik.
//--- Originaly posted at "Basket Robots" thread on Forex Factory
//--- Link : http://www.forexfactory.com/showthread.php?t=529896
//------------------------------------------------------------------------------------------------
#property copyright "Copyright © 2015, MetaQuotes Software Corp., Khalil Abokwaik"
#property link "https://www.mql5.com/en/users/abokwaik"
#property description "Basket Chart Creator"
#property description "\nThis script creates MT4 Off-Line Basket Charts for user-defined Baskets of Pairs."
#property description "The code is based on the MT4 standard PeriodConverter script."
#property description "Quality M1 history data for basket pairs is recommended."
#property description "\nCalculations are based on Geometric Mean method."
#property version "1.00"
#property strict
#property show_inputs
#include <WinUser32.mqh>
#define MAX_PRICE 999999999.9
//+--- user inputs ---------------------------------------------------------------+
input string Basket_Name="#COM#";//Basket Chart Name
input ENUM_TIMEFRAMES
Time_Frame=PERIOD_H1;//Basket Time Frame
//-- Commodity Currencies BASKET example
input string Pairs = "AUDUSD,NZDUSD,USDCAD,EURAUD,EURNZD,EURCAD,GBPAUD,GBPNZD,GBPCAD";//Basket Pairs (comma seperated)
input string Pairs_DW = " +1 , +1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ";//Directional Weights (comma seperated)
input string Template_Name="0";//Template to load on basket chart, "0" to disable
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//=- Below are sample currency baskets for YEN, EUR and GBP . These are just examples. -=
//=- However possibilities are only limited by your imagination!. Khalil Abokwaik. -=
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-- YEN BASKET
//input string Pairs = "USDJPY,EURJPY,GBPJPY,AUDJPY,CADJPY,NZDJPY,CHFJPY";//Basket Pairs
//input string Pairs_DW = "-1000 ,-1100 , -1200,-900 ,-900 , -900 , -1000";//Pairs Directional Weight
//input string Pairs_Lot_Multi = " 1 , 1 , 1 , 1 , 1 , 1 , 1 ";//Lot Multiplier
//-- EUR BASKET
//input string Pairs = "EURUSD,EURGBP,EURAUD,EURCAD,EURCHF,EURNZD,EURJPY";//Basket Pairs
//input string Pairs_DW = "+1 ,+1 ,+1 ,+1 ,+1 ,+1 ,+0.01 ";//Pairs Directional Weight
//-- GBP BASKET
//input string Pairs = "GBPUSD,EURGBP,GBPAUD,GBPCAD,GBPCHF,GBPNZD,GBPJPY";//Basket Pairs
//input string Pairs_DW = "+1 ,-1 ,+1 ,+1 ,+1 ,+1 ,+0.01 ";//Pairs Directional Weight
//+------------------------------------------------------------------+
int ExtHandle=-1;
int InpPeriodMultiplier=0;// Period multiplier factor
string symbol;
double low=0;
double high=0;
string pairs[],xxx;
string pair_dw_s[];
double pair_dw[];
double pdw=0;
double irate=0;
int i_digits=4;//Basket Digits
string sep=",";//symbols separator
int j=0;
int symb_cnt=0;
int time_frame=0;
//--- Get the separator code
ushort u_sep=StringGetCharacter(sep,0);
//+------------------------------------------------------------------+
//| script program Initilization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(Period()!=PERIOD_M1) Alert("Generic Basket Creator Script better be attached M1 chart");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime time0;
ulong last_fpos=0;
long last_volume=0;
int i,start_pos,periodseconds;
int hwnd=0,cnt=0;
//---- History header
int file_version=401;
string c_copyright;
string c_symbol=Basket_Name;
int i_period;
int i_unused[13];
MqlRates rate;
time_frame=Time_Frame;
i_period=Period()*time_frame;
//--- set history file handle
ExtHandle=FileOpenHistory(c_symbol+IntegerToString(time_frame)+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);
if(ExtHandle<0)
return;
c_copyright="(C)opyright 2003, MetaQuotes Software Corp.";
ArrayInitialize(i_unused,0);
// initialize symbols
//--------------------------
symb_cnt=StringSplit(Pairs,u_sep,pairs);
StringSplit(Pairs_DW,u_sep,pair_dw_s);
ArrayResize(pair_dw,symb_cnt);
double root=((double) 1/symb_cnt);
for(j=0;j<ArraySize(pair_dw_s);j++)
{
pair_dw[j]=StrToDouble(pair_dw_s[j]);
}
Comment(c_symbol,",",Pairs,",",Pairs_DW); //The comment is specially formatted like this to be red from Expert Advisor
//--- write history file header
FileWriteInteger(ExtHandle,file_version,LONG_VALUE);
FileWriteString(ExtHandle,c_copyright,64);
FileWriteString(ExtHandle,c_symbol,12);
FileWriteInteger(ExtHandle,time_frame,LONG_VALUE);
FileWriteInteger(ExtHandle,i_digits,LONG_VALUE);
FileWriteInteger(ExtHandle,0,LONG_VALUE);
FileWriteInteger(ExtHandle,0,LONG_VALUE);
FileWriteArray(ExtHandle,i_unused,0,13);
//--- write history file
periodseconds=time_frame*60;
start_pos=Bars-1;
rate.open=0.0;
rate.low=MAX_PRICE;
rate.high=0.0;
rate.close=0.0;
rate.spread=0;
rate.tick_volume=100;
for(j=0;j<symb_cnt;j++)
{
if(pair_dw[j]>0)
{
if(rate.open==0) rate.open=NormalizeDouble(iOpen(pairs[j],0,start_pos)*pair_dw[j],i_digits);
else rate.open*=NormalizeDouble(iOpen(pairs[j],0,start_pos)*pair_dw[j],i_digits);
}
else
{
irate=iOpen(pairs[j],0,start_pos);
if(irate>0)
{
if(rate.open==0) rate.open=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.open*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
rate.tick_volume=100;
rate.spread=0;
rate.real_volume=0;
}
rate.open=NormalizeDouble(MathPow(rate.open,root),i_digits);
rate.low=MathMin(rate.low,rate.open);
rate.high=MathMax(rate.high,rate.open);
//--- normalize open time
rate.time=Time[start_pos]/periodseconds;
rate.time*=periodseconds;
for(i=start_pos-1; i>=0; i--)
{
if(IsStopped())
break;
time0=Time[i];
//--- history may be updated
if(i==0)
{
//--- modify index if history was updated
if(RefreshRates())
i=iBarShift(NULL,0,time0);
}
//---
if(time0>=rate.time+periodseconds || i==0)
{
if(i==0 && time0<rate.time+periodseconds)
{
rate.close=0;
for(j=0;j<symb_cnt;j++)
{
rate.tick_volume=100;
if(pair_dw[j]>0)
{
if(rate.close==0) rate.close=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
else rate.close*=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
}
else
{
irate=iClose(pairs[j],0,0);
if(irate>0)
{
if(rate.close==0) rate.close=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.close*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
}
rate.close=NormalizeDouble(MathPow(rate.close,root),i_digits);
low=MathMin(low,MathMin(rate.close,rate.open));
high=MathMax(high,MathMax(rate.close,rate.open));
if(rate.low>low) rate.low=low;
if(rate.high<high) rate.high=high;
}
last_fpos=FileTell(ExtHandle);
last_volume=(long)Volume[i];
FileWriteStruct(ExtHandle,rate);
cnt++;
if(time0>=rate.time+periodseconds)
{
rate.time=time0/periodseconds;
rate.time*=periodseconds;
rate.open=0.0;
rate.low=MAX_PRICE;
rate.high=0.0;
rate.spread=0;
rate.tick_volume=0;
rate.close=0.0;
for(j=0;j<symb_cnt;j++)
{
if(pair_dw[j]>0)
{
if(rate.open==0) rate.open=NormalizeDouble(iOpen(pairs[j],0,i)*pair_dw[j],i_digits);
else rate.open*=NormalizeDouble(iOpen(pairs[j],0,i)*pair_dw[j],i_digits);
if(rate.close==0) rate.close=NormalizeDouble(iClose(pairs[j],0,i)*pair_dw[j],i_digits);
else rate.close*=NormalizeDouble(iClose(pairs[j],0,i)*pair_dw[j],i_digits);
}
else
{
irate=iOpen(pairs[j],0,i);
if(irate>0)
{
if(rate.open==0) rate.open=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.open*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
irate=iClose(pairs[j],0,i);
if(irate>0)
{
if(rate.close==0) rate.close=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.close*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
}
rate.open=NormalizeDouble(MathPow(rate.open,root),i_digits);
rate.close=NormalizeDouble(MathPow(rate.close,root),i_digits);
rate.low=MathMin(rate.low,MathMin(rate.open,rate.close));
rate.high=MathMax(rate.high,MathMax(rate.open,rate.close));
rate.tick_volume=100;
}
}
else
{
low=MAX_PRICE;
high=0.0;
rate.close=0.0;
for(j=0;j<symb_cnt;j++)
{
rate.tick_volume=100;
if(pair_dw[j]>0)
{
if(rate.close==0) rate.close=NormalizeDouble(iClose(pairs[j],0,i)*pair_dw[j],i_digits);
else rate.close*=NormalizeDouble(iClose(pairs[j],0,i)*pair_dw[j],i_digits);
}
else
{
irate=iClose(pairs[j],0,i);
if(irate>0)
{
if(rate.close==0) rate.close=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.close*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
}
rate.close=NormalizeDouble(MathPow(rate.close,root),i_digits);
low=MathMin(low,rate.close);
high=MathMax(high,rate.close);
if(rate.low>low) rate.low=low;
if(rate.high<high) rate.high=high;
}
}
FileFlush(ExtHandle);
Print(cnt," record(s) written");
Alert("Off-Line Chart Created, Look it up in File > Open Offline > ",c_symbol,",",periodName(time_frame));
//--- collect incoming ticks ---------------------------------------------------------------------
datetime last_time=LocalTime()-5;
while(!IsStopped())
{
datetime cur_time=LocalTime();
//--- check for new rates
if(RefreshRates())
{
time0=Time[0];
FileSeek(ExtHandle,last_fpos,SEEK_SET);
//--- is there current bar?
if(time0<rate.time+periodseconds)
{
low=MAX_PRICE;
high=0.0;
rate.close=0.0;
for(j=0;j<symb_cnt;j++)
{
rate.tick_volume=100;
if(pair_dw[j]>0)
{
if(rate.close==0) rate.close=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
else rate.close*=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
}
else
{
irate=iClose(pairs[j],0,0);
if(irate>0)
{
if(rate.close==0) rate.close=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.close*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
}
rate.close=NormalizeDouble(MathPow(rate.close,root),i_digits);
low=MathMin(low,rate.close);
high=MathMax(high,rate.close);
if(rate.low>low) rate.low=low;
if(rate.high<high) rate.high=high;
}
else
{
//--- no, there is new bar
rate.tick_volume=100;
if(rate.low>MathMin(rate.close,rate.open)) rate.low=MathMin(rate.close,rate.open);
if(rate.high<MathMax(rate.close,rate.open)) rate.high=MathMax(rate.close,rate.open);
//--- write previous bar remains
FileWriteStruct(ExtHandle,rate);
last_fpos=FileTell(ExtHandle);
//----**********************
rate.time=time0/periodseconds;
rate.time*=periodseconds;
rate.open=0.0;
rate.low=MAX_PRICE;
rate.high=0.0;
rate.spread=0;
rate.tick_volume=0;
rate.close=0.0;
for(j=0;j<symb_cnt;j++)
{
if(pair_dw[j]>0)
{
if(rate.open==0) rate.open=NormalizeDouble(iOpen(pairs[j],0,0)*pair_dw[j],i_digits);
else rate.open*=NormalizeDouble(iOpen(pairs[j],0,0)*pair_dw[j],i_digits);
if(rate.close==0) rate.close=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
else rate.close*=NormalizeDouble(iClose(pairs[j],0,0)*pair_dw[j],i_digits);
}
else
{
irate=iOpen(pairs[j],0,0);
if(irate>0)
{
if(rate.open==0) rate.open=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.open*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
irate=iClose(pairs[j],0,0);
if(irate>0)
{
if(rate.close==0) rate.close=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
else rate.close*=NormalizeDouble(((double)1/irate)*MathAbs(pair_dw[j]),i_digits);
}
}
}
rate.open=NormalizeDouble(MathPow(rate.open,root),i_digits);
rate.close=NormalizeDouble(MathPow(rate.close,root),i_digits);
rate.low=MathMin(rate.low,MathMin(rate.open,rate.close));
rate.high=MathMax(rate.high,MathMax(rate.open,rate.close));
rate.tick_volume=100;
}
//----
FileWriteStruct(ExtHandle,rate);
FileFlush(ExtHandle);
//---
if(hwnd==0)
{
hwnd=WindowHandle(c_symbol,i_period);
if(hwnd!=0)
{
Print("Chart window detected");
if(Template_Name!="0") apply_template();
}
}
//--- refresh window not frequently than 1 time in 2 seconds
if(hwnd!=0 && cur_time-last_time>=2)
{
PostMessageA(hwnd,WM_COMMAND,33324,0);
last_time=cur_time;
}
}
Sleep(50);
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
if(ExtHandle>=0)
{
FileClose(ExtHandle);
ExtHandle=-1;
}
//---
}
//+------------------------------------------------------------------+
int StringToTimeFrame(string tfs)
{
int tf=0;
if(tfs=="M1" || tfs=="1" ||tfs=="m1") tf=PERIOD_M1;
if(tfs=="M5" || tfs=="5" ||tfs=="m5") tf=PERIOD_M5;
if(tfs=="M15"|| tfs=="15" ||tfs=="m15") tf=PERIOD_M15;
if(tfs=="M30"|| tfs=="30" ||tfs=="m30") tf=PERIOD_M30;
if(tfs=="H1" || tfs=="60" ||tfs=="h1") tf=PERIOD_H1;
if(tfs=="H4" || tfs=="240" ||tfs=="h4") tf=PERIOD_H4;
if(tfs=="D1" || tfs=="1440" ||tfs=="d1") tf=PERIOD_D1;
if(tfs=="W1" || tfs=="10080" ||tfs=="w1") tf=PERIOD_W1;
if(tfs=="MN" || tfs=="43200" ||tfs=="mn") tf=PERIOD_MN1;
if(tf==0) tf=Period();
return(tf);
}
//---------------------
void apply_template()
{
string sym_code="";
long currChart,prevChart=ChartFirst();
currChart=prevChart;
int i=1,limit=100;
while(i<limit)// We have certainly not more than 100 open charts
{
if(currChart<0) break; // Have reached the end of the chart list
sym_code=ChartSymbol(currChart);
if(sym_code==Basket_Name)
{
if(ChartApplyTemplate(currChart,Template_Name))
{
Print("The template ",Template_Name," applied successfully");
Alert("The template ",Template_Name," applied successfully");
}
else
{
Print("Failed to apply template ",Template_Name," error code ",GetLastError());
Alert("Failed to apply template ",Template_Name," error code ",GetLastError());
}
break;
}
prevChart=currChart;// let's save the current chart ID for the ChartNext()
currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
i++;// Do not forget to increase the counter
}
}
//--------------------------------------------------------------
string periodName(int period) // Convert time frame period minutes into string (ex. 60 to H1)
{
switch(period)
{
case 1: return("M1");
case 5: return("M5");
case 15: return("M15");
case 30: return("M30");
case 60: return("H1");
case 240: return("H4");
case 1440: return("D1");
case 10080: return("W1");
case 43200: return("MN1");
default: return("");
}
}
//--------------------------------------------------------------
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
---