xMeterMTF
Download scriptOverview of the Price Meter System
The xMeterMTF is a visual analytics tool designed to help traders monitor the relative strength and performance of major global currencies in real-time. Instead of looking at dozens of individual charts, this script consolidates data from multiple currency pairs into a single, easy-to-read "meter" display on your trading platform.
How the Logic Works
The system operates through a three-step process: Data Collection, Strength Calculation, and Visual Rendering.
1. Data Collection & Range Analysis
The script monitors a specific set of major currency pairs (such as EURUSD, USDJPY, etc.). For every pair, it automatically identifies:
- Highs and Lows: It looks at the highest and lowest price points reached over a specific timeframe.
- Current Price: It tracks the live "Bid" and "Ask" prices.
- Relative Position: By comparing the current price to the total range of the day (the distance between the high and the low), the script determines exactly where the currency is sitting within its daily boundaries.
2. Strength Grading
Once the relative position is known, the script converts that movement into a "Grade."
- It calculates how far a currency has moved from its lowest point toward its highest point.
- This value is then mapped against a pre-defined grading table. This ensures that small movements result in lower scores, while significant momentum results in higher power ratings.
- The script also accounts for the "Base" and "Quote" currencies in each pair. For example, if a currency appears as the primary unit in one pair and the secondary unit in another, the script factors both roles into its final calculation to ensure a balanced view of global influence.
3. Visual Display (The Meter)
The final output is a dynamic visual dashboard displayed directly on your chart:
- Weighted Averages: The system takes the individual strengths of all major currencies (USD, EUR, GBP, etc.) and calculates an average "Meter" value for each.
- Color-Coded Indicators: Each currency is assigned a meter with a multi-colored scale. As a currency's strength increases, different segments of its bar change color—moving from Red (weak) through Orange, Gold, and Yellow-Green, eventually reaching Lime (strong).
- Live Updates: The script continuously refreshes this data, providing a "pulse" of the market. At a glance, a trader can see which currencies are gaining dominance and which are losing steam without manually switching between different assets.
Summary for the User
Essentially, this tool acts as a market heat map. It simplifies complex price action into a set of visual gauges, allowing you to see the "power dynamic" of the forex market instantly. It highlights which currencies are currently leading the market and which are lagging, helping you make faster, more informed decisions on where the momentum is heading.
/*
xMeterMTF.mq4
Copyright © 2007, MetaQuotes Software Corp.
Price Meter System ©GPL
Hartono Setiono
5/17/2007 Redsigned based on xMeter_mini.mq4 indicator
*/
#property copyright "x Meter System ©GPL"
#property link "forex-tsd dot com"
#include <stdlib.mqh>
#include <stderror.mqh>
#define ARRSIZE 12 // number of pairs !!!DON'T CHANGE THIS NUMBER!!!
#define PAIRSIZE 7 // number of currencies !!!DON'T CHANGE THIS NUMBER!!!
#define TABSIZE 10 // scale of currency's power !!!DON'T CHANGE THIS NUMBER!!!
#define ORDER 2 // available type of order !!!DON'T CHANGE THIS NUMBER!!!
extern bool AccountIsIBFXmini = false;
extern int mTimeFrame = 1440;
extern int mPeriod=1;
string aPair[ARRSIZE] = {"EURUSD","GBPUSD","AUDUSD","USDJPY","USDCHF","USDCAD",
"EURJPY","EURGBP","EURCHF","EURAUD","GBPJPY","GBPCHF"};
string aMajor[PAIRSIZE] = {"USD","EUR","GBP","CHF","CAD","AUD","JPY"};
int aMajorPos[PAIRSIZE] = {130, 110, 90, 70, 50, 30, 10};
string aOrder[ORDER] = {"BUY ","SELL "};
//+------------------------------------------------------------------+
// expert initialization function |
//+------------------------------------------------------------------+
int init()
{
int err,lastError;
//----
initGraph();
//while (true) // infinite loop for main program
{
//if (IsConnected()) main();
//if (!IsConnected()) objectBlank();
//main();
//WindowRedraw();
//Sleep(1000); // give your PC a breath
}
//----
return(0); // end of init function
}
//+------------------------------------------------------------------+
// expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
ObjectsDeleteAll(0,OBJ_LABEL);
Print("shutdown error - ",ErrorDescription(GetLastError())); // system is detached from platform
//----
return(0); // end of deinit function
}
//+------------------------------------------------------------------+
// expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
main();
//----
return(0); // end of start funtion
}
//+------------------------------------------------------------------+
// expert custom function |
//+------------------------------------------------------------------+
void main() // this a control center
{
//----
double aMeter[PAIRSIZE];
double aHigh[ARRSIZE];
double aLow[ARRSIZE];
double aBid[ARRSIZE];
double aAsk[ARRSIZE];
double aRatio[ARRSIZE];
double aRange[ARRSIZE];
double aLookup[ARRSIZE];
double aStrength[ARRSIZE];
double point;
int index, pindex, cnt;
string mySymbol;
double cmeter;
for (index = 0; index < ARRSIZE; index++) // initialize all pairs required value
{
RefreshRates(); // refresh all currency's instrument
if (AccountIsIBFXmini)
mySymbol = aPair[index]+'m';
else
mySymbol = aPair[index]; // Only look at first 6 characters of pair
point = MarketInfo(mySymbol,MODE_POINT); // get a point basis
aHigh[index] = iHigh(mySymbol,mTimeFrame,iHighest(mySymbol,mTimeFrame,MODE_HIGH,mPeriod,0)); // find highest
aLow[index] = iLow(mySymbol,mTimeFrame,iLowest(mySymbol,mTimeFrame,MODE_LOW,mPeriod,0)); // find lowest
aBid[index] = MarketInfo(mySymbol,MODE_BID); // set a last bid
aAsk[index] = MarketInfo(mySymbol,MODE_ASK); // set a last ask
aRange[index] = MathMax((aHigh[index]-aLow[index])/point,1); // calculate range today
aRatio[index] = (aBid[index]-aLow[index])/aRange[index]/point; // calculate pair ratio
aLookup[index] = iLookup(aRatio[index]*100); // set a pair grade
aStrength[index] = 9-aLookup[index]; // set a pair strengh
}
// calculate all currencies meter
for (pindex=0; pindex<PAIRSIZE; pindex++)
{
cnt=0;
cmeter=0;
for (index = 0; index < ARRSIZE; index++) // initialize all pairs required value
{
if (StringSubstr(aPair[index],0,3)==aMajor[pindex])
{
cnt++;
cmeter = cmeter + aLookup[index];
}
if (StringSubstr(aPair[index],3,3)==aMajor[pindex])
{
cnt++;
cmeter = cmeter + aStrength[index];
}
if (cnt>0) aMeter[pindex]=NormalizeDouble(cmeter / cnt,1); else aMeter[pindex]=-1;
//Print(aMajor[pindex],":",StringSubstr(aPair[index],1,3),":",StringSubstr(aPair[index],4,3),":",cmeter,":",cnt);
}
}
objectBlank();
for (pindex=0; pindex<PAIRSIZE; pindex++)
{
paintCurr(pindex, aMeter[pindex]);
}
paintLine();
//----
}
int iLookup(double ratio) // this function will return a grade value
{ // based on its power.
int aTable[TABSIZE] = {0,3,10,25,40,50,60,75,90,97}; // grade table for currency's power
int index;
if (ratio <= aTable[0]) index = 0;
else if (ratio < aTable[1]) index = 0;
else if (ratio < aTable[2]) index = 1;
else if (ratio < aTable[3]) index = 2;
else if (ratio < aTable[4]) index = 3;
else if (ratio < aTable[5]) index = 4;
else if (ratio < aTable[6]) index = 5;
else if (ratio < aTable[7]) index = 6;
else if (ratio < aTable[8]) index = 7;
else if (ratio < aTable[9]) index = 8;
else index = 9;
return(index); // end of iLookup function
}
void initGraph()
{
int pindex;
ObjectsDeleteAll(0,OBJ_LABEL);
for (pindex=0; pindex<PAIRSIZE; pindex++)
{
objectCreate(aMajor[pindex]+"_1",aMajorPos[pindex],43);
objectCreate(aMajor[pindex]+"_2",aMajorPos[pindex],35);
objectCreate(aMajor[pindex]+"_3",aMajorPos[pindex],27);
objectCreate(aMajor[pindex]+"_4",aMajorPos[pindex],19);
objectCreate(aMajor[pindex]+"_5",aMajorPos[pindex],11);
objectCreate(aMajor[pindex],aMajorPos[pindex]+2,12,aMajor[pindex],7,"Arial Narrow",SkyBlue);
objectCreate(aMajor[pindex]+"p",aMajorPos[pindex]+4,21,DoubleToStr(9,1),8,"Arial Narrow",Silver);
}
objectCreate("line",10,6,"-----------------------------------",10,"Arial",DimGray);
objectCreate("line1",10,27,"-----------------------------------",10,"Arial",DimGray);
objectCreate("line2",10,69,"-----------------------------------",10,"Arial",DimGray);
objectCreate("sign",11,1,"»»» Price Meter System ©GPL «««",8,"Arial Narrow",DimGray);
WindowRedraw();
}
//+------------------------------------------------------------------+
void objectCreate(string name,int x,int y,string text="-",int size=42,
string font="Arial",color colour=CLR_NONE)
{
ObjectCreate(name,OBJ_LABEL,0,0,0);
ObjectSet(name,OBJPROP_CORNER,3);
ObjectSet(name,OBJPROP_COLOR,colour);
ObjectSet(name,OBJPROP_XDISTANCE,x);
ObjectSet(name,OBJPROP_YDISTANCE,y);
ObjectSetText(name,text,size,font,colour);
}
void objectBlank()
{
int pindex;
for (pindex=0; pindex<PAIRSIZE; pindex++)
{
ObjectSet(aMajor[pindex]+"_1",OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex]+"_2",OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex]+"_3",OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex]+"_4",OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex]+"_5",OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex],OBJPROP_COLOR,CLR_NONE);
ObjectSet(aMajor[pindex]+"p",OBJPROP_COLOR,CLR_NONE);
}
ObjectSet("line1",OBJPROP_COLOR,CLR_NONE);
ObjectSet("line2",OBJPROP_COLOR,CLR_NONE);
}
void paintCurr(int pindex, double value)
{
if (value > 0) ObjectSet(aMajor[pindex]+"_5",OBJPROP_COLOR,Red);
if (value > 2) ObjectSet(aMajor[pindex]+"_4",OBJPROP_COLOR,Orange);
if (value > 4) ObjectSet(aMajor[pindex]+"_3",OBJPROP_COLOR,Gold);
if (value > 6) ObjectSet(aMajor[pindex]+"_2",OBJPROP_COLOR,YellowGreen);
if (value > 7) ObjectSet(aMajor[pindex]+"_1",OBJPROP_COLOR,Lime);
ObjectSet(aMajor[pindex],OBJPROP_COLOR,SkyBlue);
ObjectSetText(aMajor[pindex]+"p",DoubleToStr(value,1),8,"Arial Narrow",Silver);
}
void paintLine()
{
ObjectSet("line1",OBJPROP_COLOR,DimGray);
ObjectSet("line2",OBJPROP_COLOR,DimGray);
}
Comments