FPI_v1
Download scriptThis tool is designed to track a specific mathematical relationship between three different currency pairs simultaneously. Rather than looking at a single chart, it calculates a derived value—an "index"—to help traders visualize how these markets move in relation to one another.
Core Logic and Workflow
1. Multi-Symbol Correlation The script identifies three distinct currency symbols (for example: EURUSD, USDCHF, and EURCHF). It continuously monitors the current market price of all three pairs in real-time.
2. The Calculation Engine At every price update (tick), the tool performs a specific calculation to determine its value. It takes the price of the first symbol, multiplies it by the price of the second symbol, and then divides that result by the price of the third symbol. This resulting figure represents a consolidated "synthetic" value.
3. Dynamic Data Processing To ensure the visual data remains relevant and clean, the script manages its own history in several ways:
- Tick Counting: It tracks price movements up to a user-defined limit (e.g., the last 200 ticks), ensuring that the chart doesn't become cluttered with outdated information.
- Data Shifting: As new prices come in, the script automatically moves older data points out of the way to make room for the newest calculations.
- Memory Management: It includes a "cleanup" logic that removes old markers or lines once they exceed the maximum history allowed, keeping the interface smooth and responsive.
4. Visual Organization The indicator provides clear visual cues to help the user navigate the data:
- Separate Window: It operates in its own dedicated window below the main price chart so it does not interfere with your primary price action analysis.
- Delimiters: If enabled, the script automatically draws vertical dotted lines at the start of new price bars. This allows you to see exactly where one time period ends and another begins relative to the calculated index.
- Precision Scaling: The tool automatically adjusts its decimal precision to match the market requirements, ensuring the resulting line is as accurate as possible.
Summary for the User
Essentially, this script acts as a "bridge" between three different markets. It distills complex movements from three separate currency pairs into one single line. By watching this line, you can observe whether these three currencies are moving in harmony or diverging, helping to identify specific market trends that might be difficult to spot by looking at individual charts alone.
//+------------------------------------------------------------------+
//| FPI_v1.mq4 |
//| Copyright © 2009, TrendLaboratory |
//| Many Thanks to Rosh for Ticks indicator |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_maximum 1.001
#property indicator_minimum 0.999
#property indicator_level1 1.0
#property indicator_level2 1.0003
#property indicator_level3 0.9997
//---- buffers
extern string Symbol_1st = "EURUSD";
extern string Symbol_2nd = "USDCHF";
extern string Symbol_3rd = "EURCHF";
extern int UseDelimiter = 1; //Delimiter Mode: 0-off,1-on
extern color DelimColor = Gray; //Color of Bars Delimiter
extern int MaxTicks = 200; //Max Number of ticks
double FPI[];
int tickCounter=0;
int delimeterCounter;
datetime pTime;
string short_name, setup;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, FPI);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
short_name="FPI("+Symbol_1st+","+Symbol_2nd+","+Symbol_3rd+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"FPI");
SetIndexEmptyValue(0,0.0);
setup = short_name+": ";
pTime = Time[0];
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
ObjDel(setup);
//----
return(0);
}
void SetDelimeter()
{
//----
string delimeterName = setup + TimeToStr(Time[0]);
int handle=WindowFind(short_name);
if(!ObjectCreate(delimeterName,OBJ_VLINE,handle,Time[0],0))
{
Print("Error delimiter:",GetLastError());
}
else
{
ObjectSet(delimeterName,OBJPROP_COLOR,DelimColor);
ObjectSet(delimeterName,OBJPROP_STYLE,STYLE_DOT);
}
}
void ShiftArray()
{
for(int cnt=tickCounter-1; cnt > 0; cnt--)
{
FPI[cnt] = FPI[cnt-1];
}
if (UseDelimiter!=0)
{
for (int j=0;j<ObjectsTotal();j++)
{
int NumStr = StringFind(ObjectName(j),setup,0);
if (NumStr == 0)
{
datetime Time1=ObjectGet(ObjectName(j),OBJPROP_TIME1);
int BarTime1=iBarShift(NULL,0,Time1);
Time1 = Time[BarTime1+1];
ObjectSet(ObjectName(j),OBJPROP_TIME1,Time1);
if( BarTime1+1 > MaxTicks )
{
if (!ObjectDelete(ObjectName(j)))
{
int _GetLastError = GetLastError();
Print("ObjectDelete: ",ObjectName(j)," Error #", _GetLastError );
}
}
}
}
}
}
bool isNewBar()
{
bool res=false;
if (Time[0]!=pTime)
{
res=true;
pTime=Time[0];
}
return(res);
}
bool ObjDel(string name)
{
int _GetLastError = 0;
while(ObjFind(name,0,0) > 0)
{
int obtotal = ObjectsTotal();
for (int i = 0; i < obtotal;i++)
{
if (StringFind(ObjectName(i),name,0) >= 0)
{
if (!ObjectDelete(ObjectName(i)))
{
_GetLastError = GetLastError();
Print( "ObjectDelete( \"",ObjectName(i),"\" ) - Error #", _GetLastError );
}
}
}
}
if(_GetLastError > 0) return(false);
else
return (true);
}
//-----
int ObjFind(string name,int start, int num)
{
int cnt = 0;
for (int i = 0; i < ObjectsTotal();i++)
if (StringFind(ObjectName(i),name,start) == num) cnt+=1;
return(cnt);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if(tickCounter == 0)
for(int i=Bars-1;i>=0;i--) FPI[i]=0.0;
tickCounter++;
if(tickCounter >= MaxTicks)
{
tickCounter = MaxTicks;
FPI[tickCounter]=0.0;
}
if (isNewBar()) {if(UseDelimiter == 1) SetDelimeter();}
else
ShiftArray();
double Num1 = MarketInfo(Symbol_1st,MODE_BID);
double Num2 = MarketInfo(Symbol_2nd,MODE_BID);
double DNum = MarketInfo(Symbol_3rd,MODE_BID);
FPI[0]= Num1 * Num2 / DNum;
//----
return(0);
}
Comments