Indicators: Pearson correlation indicator - page 2

 
Here, approximately like this - https://www.mql5.com/en/code/183. The point is that data copying from other symbols is not performed all at once, but one bar at a time. During such copying, from other symbols, the bar will be copied exactly corresponding to the time of the chart bar, on which the indicator is displayed. If there is no corresponding bar, then from an earlier bar (like the iBarShift() function in MQL4). In this indicator one bar at a time is copied, but for correlation, it may be necessary to copy the number corresponding to the correlation period. You can do it differently - copy one bar at a time and put it into the indicator buffer. Using the buffer you can do everything as fast as possible (of course at the expense of more memory consumption). You can do it without an extra buffer, with a couple of static variables.... It's long to explain, it's probably necessary to write an article:)
 
pusheax:

Okay, yesterday we got a little overexcited, I guess you also celebrated "Border Guard Day" like me.

Can you give me a link to the correct synchronisation of bars, because I also use this method of synchronisation by the last bar and that's it?

I won't give you a link (because I haven't met it yet), but I will describe the method.

The method concerns synchronisation of different instruments, although it can be used for synchronisation of different TFs.

I have been dealing with this problem for quite a long time, and even SD made a bug-fix for the bugs of this method that I have identified.

The synchronisation problem is related to the fact that different instruments have a different number of bars. Approximately the same is a false criterion, everything must be exact. Bar to bar. Otherwise, the meaning of synchronisation is lost.

The second aspect of this problem is how to display a bar if there is no bar on the current instrument?

So the essence of the method is simple: data on the instrument are requested strictly by times...

count=CopyRates(symbol,tf,time0,time1,rates); если нужно несколько баров
или
count=CopyRates(symbol,tf,time0,1,rates); если нужен один

and the sample of time is taken from the standard buffer of the indicator time[]. Thus, you always know for sure that you are facing a bar that came synchronously with a bar on another instrument.

Again, if there is no such bar in the current instrument, you will not request it. And if the requested instrument does not have such a bar as a sample, you will get a zero in the count and can normally handle this exception, depending on the logic of your programme.

 

Implementation of synchronisation (in MQL4) for any number of FIs(from here):

double GetPrice( string Symb, int time )
{
  double Price;
 
  Price = iClose(Symb, Period(), iBarShift(Symb, Period(), time));
 
  return(Price);
}
 
int GetNextTime( int CurrTime )
{
  static int Pos[MAX_AMOUNTSYMBOLS];
  int i, MinTime, Tmp = -1;
 
  for (i = 0; i < AmountSymbols; i++)
  {
    Pos[i] = iBarShift(Symbols[i], Period(), CurrTime) - 1;
 
    if (Pos[i] >= 0)
      Tmp = i;
  }
 
  if (Tmp < 0)
    return(Time[0]);
 
  MinTime = iTime(Symbols[Tmp], Period(), Pos[Tmp]);
 
  i = Tmp - 1;
 
  while (i >= 0)
  {
    if (Pos[i] >= 0)
    {
      Tmp = iTime(Symbols[i], Period(), Pos[i]);
 
      if (Tmp < MinTime)
        MinTime = Tmp;
    }
 
    i--;
  }
 
  return(MinTime);
}
 
void GetBaseMatrix()
{
  int i, NextTime;
 
  NextTime = GetNextTime(CurrTime);
 
  while (NextTime < Time[0])
  {
    CurrTime = NextTime;
 
    for (i = 0; i < AmountSymbols; i++)
      BaseMatrix[i][MatrixRows] = 1000 * MathLog(GetPrice(Symbols[i], CurrTime));
 
    Times[MatrixRows] = CurrTime;
 
    MatrixRows++;
 
    NextTime = GetNextTime(CurrTime);
  }
 
  return;
}

By analogy for two symbols (from here):

double GetPrice( string Symb, int time )
{
  double Price;
 
  Price = iClose(Symb, Period(), iBarShift(Symb, Period(), time));
 
  return(Price);
}
 
int GetNextTime( int CurrTime )
{
  static int Pos[TWO_SYMBOLS];
  int i, MinTime, Tmp = -1;
 
  for (i = 0; i < TWO_SYMBOLS; i++)
  {
    Pos[i] = iBarShift(Symbols[i], Period(), CurrTime) - 1;
 
    if (Pos[i] >= 0)
      Tmp = i;
  }
 
  if (Tmp < 0)
    return(Time[0]);
 
  MinTime = iTime(Symbols[Tmp], Period(), Pos[Tmp]);
 
  i = Tmp - 1;
 
  while (i >= 0)
  {
    if (Pos[i] >= 0)
    {
      Tmp = iTime(Symbols[i], Period(), Pos[i]);
 
      if (Tmp < MinTime)
        MinTime = Tmp;
    }
 
    i--;
  }
 
  return(MinTime);
}
 
void GetBaseMatrix()
{
  int i, NextTime;
 
  NextTime = GetNextTime(CurrTime);
 
  while (NextTime < Time[0])
  {
    CurrTime = NextTime;
 
    for (i = 0; i < TWO_SYMBOLS; i++)
      BaseMatrix[i][MatrixRows + Shifts[i]] = MathLog(GetPrice(Symbols[i], CurrTime));
 
    Times[MatrixRows] = CurrTime;
 
    MatrixRows++;
 
    NextTime = GetNextTime(CurrTime);
  }
 
  return;
}
I.e. everything is quite simple. Another thing is that the classical barometric (constant time discretisation) representation of price BPs is not the only one, much less always correct. Sometimes it is extremely useful to synchronise price BPs of another time dimension. That is, by introducing distortions that are non-linear from the point of view of classical time. Correspondingly, then the correlation will show non-linear interrelations of two classical VRs.
 

Thanks for your help!

I was wrong I admit, I didn't think that synchronisation is so complicated.

I will try to figure it out and synchronise bars directly on this indicator as I need it very much.

 

Thank you all for the information!

I rewrote the indicator a bit. Now, supposedly, it should skip bad parts of history.

Since we have started, please check for errors :)

Files:
 
I will speak out once again for the necessity of algorithmic optimisation for all indicators. And also for the built-in mechanism of calculating indicator values in memory (file), so that during the tester optimisation the indicator does not calculate the same thing, but takes ready-made values from there.
 
hrenfx:
I will speak out once again for the necessity of algorithmic optimisation for all indicators. And also for the built-in mechanism of calculating indicator values in memory (file), so that during the tester optimisation the indicator does not calculate the same thing, but takes ready-made values from there.
Could you show an example where this has already been done?
 

Algorithmic optimisation for each indicator is different. For different ways of using correlation, I did, for example, this and this.

Reading from memory the values of indicators calculated in advance for the whole history was done only in my calculator. That is, I don't have a universal mechanism, because I only use my own solutions, which are not beautiful at all. But since I am for the improvement of everything, it would be great to have such a universal mechanism in case of the optimiser of the MT5 tester, because it gives acceleration by several orders of magnitude (experience of using it in my calculator), i.e. it outshines Cloud in terms of efficiency.

 

Hi there

Sometimes I spend time distorting the codes of others, usually the results of an incomplete or incomplete programme, both lack of time and lack of skill.

This time I would try to distort this wonderful indicator, and tried to do something like this:

- Drawing just a line, not a dotted plotting line



#property indicator_type1 DRAW_COLOR_LINE
#property indicator_width1 2

// #property indicator_type2 DRAW_COLOR_HISTOGRAM
// #property indicator_style2 STYLE_DOT
// #property indicator_width2 1

- To add a lot of symbols such as

//--- input parametres
input string _SecondSymbol="EURGBP"; // Symbol

input string _ThirdSymbol="EURAUD"; // Symbol
input string _FourthSymbol="EURCAD"; // Symbol
input string _FifthSymbol="EURCHF"; // Symbol
input string _SixthSymbol="EURNZD"; // Symbol
input string _SeventhSymbol="EURHKD"; // Symbol
input string _EighthSymbol="EURTRY"; // Symbol

Then to create 2 variants of the source code:

- Visual variant: a coloured line for each of the currency pairs correlation 1 thick line which is just the average of 7 lines ((A+B+C+D+E+F+G)/7)

- No visual variant: 1 line only, which is the result of the above formula ((A+B+C+D+D+E+F+G)/7)

Almost like adding 7 (or 8) original Correlation Indicator, but all summed up so that just averages as with the version, one of which is 7 lines + 1 (average), and the other version with 1 line (only average).

something like this:

buf[i]= (
(v1/sqrt(v2*v3))+
(v4/sqrt(v2*v6))+
(v7/sqrt(v2*v9))+
(v10/sqrt(v2*v12))+
(v13/sqrt(v2*v15))+
(v16/sqrt(v2*v18))+
(v19/sqrt(v2*v21)) 
)/7; // simple average of values.


buf2[i]=buf[i];
c=getPlotColor(buf[i]);
colors1[i]=c;
colors2[i]=c;

For a number of reasons garbled code doesn't do what I want to do because of completely logical errors.

The main problem is with the buffers, synchronisation and recursive indentation part of the code:

if(bars1>bars2)
{
minBars=bars2;
bars2=bars1-bars2;
etc...

+ as well as other logical errors.

some Print() functions have been added to help in the case of tracking variable values and return 0 instructions have been commented out in order to find where the code logically fails.

 

code and file

//+------------------------------------------------------------------+
//| Correlation.mq5 |
//|| Copyright 2012, iC |
//| http://www.icreator.biz/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, iC"
#property link "http://www.icreator.biz/"
#property version "1.00"
//--- indicator settings
#property indicator_separate_window

#property indicator_minimum -1
#property indicator_maximum 1

#property indicator_buffers 25
#property indicator_plots 2

#property indicator_type1 DRAW_COLOR_LINE
#property indicator_width1 2

// #property indicator_type2 DRAW_COLOR_HISTOGRAM
// #property indicator_style2 STYLE_DOT
// #property indicator_width2 1

/*

#property indicator_type2 DRAW_COLOR_LINE
#property indicator_width2 2

#property indicator_type3 DRAW_COLOR_LINE
#property indicator_width3 2

#property indicator_type4 DRAW_COLOR_LINE
#property indicator_width4 2

#property indicator_type5 DRAW_COLOR_LINE
#property indicator_width5 2

#property indicator_type6 DRAW_COLOR_LINE
#property indicator_width6 2

#property indicator_type7 DRAW_COLOR_LINE
#property indicator_width7 2

#property indicator_type8 DRAW_COLOR_LINE
#property indicator_width8 2

*/

//--- defines
#define MAX_COL 64
//--- structures
struct CRGB
{
int r;
int g;
int b;
};
//--- input parametres
input string _SecondSymbol="EURGBP"; // Symbol

input string _ThirdSymbol="EURAUD"; // Symbol
input string _FourthSymbol="EURCAD"; // Symbol
input string _FifthSymbol="EURCHF"; // Symbol
input string _SixthSymbol="EURNZD"; // Symbol
input string _SeventhSymbol="EURHKD"; // Symbol
input string _EighthSymbol="EURTRY"; // Symbol

input int _SettPeriod=100; // Period
input ENUM_APPLIED_PRICE _AppliedPrice=PRICE_CLOSE; // Price
input color _Color1=clrLightGray; // Min correlation.
input color _Color2=clrLime; // Max correlation.

//--- indicator buffers
double buf[],buf2[]
,buf3[],buf4[],buf5[],buf6[],buf7[],buf8[];

double arr1[],arr2[]
,arr3[],arr4[],arr5[],arr6[],arr7[],arr8[];

double colors1[],colors2[];

//--- MA handles
int h1,h2,
h3,h4,h5,h6,h7,h8;
//+------------------------------------------------------------------+
//| Custom indicator initialisation function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0,buf);
SetIndexBuffer(1,colors1,INDICATOR_COLOR_INDEX);

SetIndexBuffer(2,buf2);
SetIndexBuffer(3,colors2,INDICATOR_COLOR_INDEX);

SetIndexBuffer(4,arr1,INDICATOR_CALCULATIONS); // first symbol
SetIndexBuffer(5,arr2,INDICATOR_CALCULATIONS); // second symbol


SetIndexBuffer(6,arr3,INDICATOR_CALCULATIONS); //3rd
SetIndexBuffer(7,arr4,INDICATOR_CALCULATIONS); //4th

SetIndexBuffer(8,arr5,INDICATOR_CALCULATIONS); //5th
SetIndexBuffer(9,arr6,INDICATOR_CALCULATIONS); //6th

SetIndexBuffer(10,arr7,INDICATOR_CALCULATIONS); //7th

SetIndexBuffer(11,arr8,INDICATOR_CALCULATIONS); //8th

/* 
SetIndexBuffer(12,arr9,INDICATOR_CALCULATIONS);
SetIndexBuffer(13,arr10,INDICATOR_CALCULATIONS);

SetIndexBuffer(14,arr11,INDICATOR_CALCULATIONS);
SetIndexBuffer(15,arr12,INDICATOR_CALCULATIONS);

SetIndexBuffer(16,buf3);
SetIndexBuffer(17,colours3,INDICATOR_COLOR_INDEX);

SetIndexBuffer(18,buf4);
SetIndexBuffer(19,colours4,INDICATOR_COLOR_INDEX);

SetIndexBuffer(20,buf5);
SetIndexBuffer(21,colours5,INDICATOR_COLOR_INDEX);

SetIndexBuffer(22,buf6);
SetIndexBuffer(23,colours6,INDICATOR_COLOR_INDEX);

SetIndexBuffer(24,buf7);
SetIndexBuffer(25,colours7,INDICATOR_COLOR_INDEX);

// etc...
*/

PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);

PlotIndexSetInteger(0,PLOT_SHOW_DATA,0);
IndicatorSetInteger(INDICATOR_DIGITS,3); 

IndicatorSetString(INDICATOR_SHORTNAME,_Symbol+"/"+_SecondSymbol+", "+IntegerToString(_SettPeriod)+", "+EnumToString(_AppliedPrice)+","); // etc...

setPlotColor(0,_Color1,_Color2);
setPlotColor(1,_Color1,_Color2);

h1=iMA(_Symbol,0,1,0,MODE_EMA,_AppliedPrice);
h2=iMA(_SecondSymbol,0,1,0,MODE_EMA,_AppliedPrice);

// added values.
h3=iMA(_ThirdSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h4=iMA(_FourthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h5=iMA(_FifthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h6=iMA(_SixthSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h7=iMA(_SeventhSymbol,0,1,0,MODE_EMA,_AppliedPrice);
h8=iMA(_EighthSymbol,0,1,0,MODE_EMA,_AppliedPrice);

return 0;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
int i,j,c,limit,bars1,bars2
,bars3,bars4,bars5,bars6,bars7,bars8, 
minBars,toCopy;
double averX1=0,averX2=0
,averX3=0,averX4=0,averX5=0,averX6=0,averX7=0,averX8=0,
v1=0,v2=0,v3=0
,v4=0,v5=0,v6=0,v7=0,v8=0
,v9=0,v10=0,v11=0,v12=0
,v13=0,v14=0,v15=0,v16=0,v17=0
,v18=0,v19=0,v20=0,v21=0;
datetime t1[1],t2[1],
t3[1],t4[1],t5[1],t6[1],t7[1],t8[1];
//--- synchronisation symbols
if( 
(
CopyTime(_Symbol,0,0,1,t1)<1 || 
CopyTime(_SecondSymbol,0,0,1,t2)<1 || 

CopyTime(_ThirdSymbol,0,0,1,t3)<1 || 
CopyTime(_FourthSymbol,0,0,1,t4)<1 || 
CopyTime(_FifthSymbol,0,0,1,t5)<1 || 
CopyTime(_SixthSymbol,0,0,1,t6)<1 || 
CopyTime(_SeventhSymbol,0,0,1,t7)<1 || 
CopyTime(_EighthSymbol,0,0,1,t8)<1
) 
|| 

(
t1[0]!=t2[0]
|| t1[0]!=t3[0]
|| t1[0]!=t4[0]
|| t1[0]!=t5[0]
|| t1[0]!=t6[0]
|| t1[0]!=t7[0]
|| t1[0]!=t8[0]
)
) 
{
Print("Synchronization failed!");
// return 0;
}
//--- check for data

bars1=rates_total;
bars2=Bars(_SecondSymbol,0);

bars3=Bars(_ThirdSymbol,0);
bars4=Bars(_FourthSymbol,0);
bars5=Bars(_FifthSymbol,0);
bars6=Bars(_SixthSymbol,0);
bars7=Bars(_SeventhSymbol,0);
bars8=Bars(_EighthSymbol,0);

// indent the if each other until the minBars is found. // to check out if logic is correct

if(bars1>bars2)
{
minBars=bars2;
bars2=bars1-bars2;
bars1=0;
Print("bars1>bars2; minBars(",minBars,"),=bars2(",bars2,")=bars1(",bars1,")-bars2(",bars2,");");
// }
//else 
if(bars1>bars3)
{
minBars=bars3;
bars3=bars1-bars3;
bars1=0;
Print("bars1>bars3; minBars(",minBars,"),=bars3(",bars3,")=bars1(",bars1,")-bars3(",bars3,");");
// } 
//else 
if(bars1>bars4)
{
minBars=bars4;
bars4=bars1-bars4;
bars1=0;
Print("bars1>bars4; minBars(",minBars,"),=bars4(",bars4,")=bars1(",bars1,")-bars4(",bars4,");");
// } 
//else 
if(bars1>bars5)
{
minBars=bars5;
bars5=bars1-bars5;
bars1=0;
Print("bars1>bars5; minBars(",minBars,"),=bars5(",bars5,")=bars1(",bars1,")-bars5(",bars5,");");
// } 
//else 
if(bars1>bars6)
{
minBars=bars6;
bars6=bars1-bars6;
bars1=0;
Print("bars1>bars6; minBars(",minBars,"),=bars6(",bars6,")=bars1(",bars1,")-bars6(",bars6,");");
// } 
//else 
if(bars1>bars7)
{
minBars=bars7;
bars7=bars1-bars7;
bars1=0;
Print("bars1>bars7; minBars(",minBars,"),=bars7(",bars7,")=bars1(",bars1,")-bars7(",bars7,");");
// } 
//else 
if(bars1>bars8)
{
minBars=bars8;
bars8=bars1-bars8;
bars1=0;
Print("bars1>bars8; minBars(",minBars,"),=bars8(",bars8,")=bars1(",bars1,")-bars8(",bars8,");");
} }}}}}} 

else
{
minBars=bars1;
bars1=bars2-bars1;
bars2=0;
Print("bars1!>bars2,3,4,5,6,7,8; minBars(",minBars,"),=bars1(",bars1,")=bars2(",bars2,")-bars1(",bars1,");");
}
if(minBars<_SettPeriod)
{
Print("Bars is not enough to calculate!");
// return 0;
}
if(BarsCalculated(h1)<minBars)
{
Print("Not all data of MA1 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h2)<minBars)
{
Print("Not all data of MA2 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h3)<minBars)
{
Print("Not all data of MA3 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h4)<minBars)
{
Print("Not all data of MA4 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h5)<minBars)
{
Print("Not all data of MA5 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h6)<minBars)
{
Print("Not all data of MA6 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h7)<minBars)
{
Print("Not all data of MA7 is calculated. Error ",GetLastError());
// return 0;
}
if(BarsCalculated(h8)<minBars)
{
Print("Not all data of MA8 is calculated. Error ",GetLastError());
// return 0;
} 

//--- we can copy not all data
if(prev_calculated>rates_total || 
prev_calculated<=0)
toCopy=minBars;
else
toCopy=rates_total-prev_calculated+1;

if(CopyBuffer(h1,0,0,minBars,arr1)<minBars || 
CopyBuffer(h2,0,0,minBars,arr2)<minBars || 

CopyBuffer(h3,0,0,minBars,arr3)<minBars || 
CopyBuffer(h4,0,0,minBars,arr4)<minBars || 
CopyBuffer(h5,0,0,minBars,arr5)<minBars || 
CopyBuffer(h6,0,0,minBars,arr6)<minBars || 
CopyBuffer(h7,0,0,minBars,arr7)<minBars || 
CopyBuffer(h8,0,0,minBars,arr8)<minBars) 

{
Print("Getting MA buffer failed. Error ",GetLastError());
// return 0;
}
if(prev_calculated>rates_total || 
prev_calculated<=0)
limit=bars1+bars2+_SettPeriod-1
+bars3+bars4+bars5+bars6+bars7+bars8;

else
limit=prev_calculated-1;
//--- 
for(i=limit;i<rates_total;i++)
{
averX1=0; averX2=0; 
averX3=0;averX4=0;averX5=0;averX6=0;averX7=0;averX8=0;
for(j=0;j<_SettPeriod;j++)
{
averX1+=arr1[i-j-bars1]/_SettPeriod;
averX2+=arr2[i-j-bars2]/_SettPeriod;

averX3+=arr3[i-j-bars3]/_SettPeriod;
averX4+=arr4[i-j-bars4]/_SettPeriod;
averX5+=arr5[i-j-bars5]/_SettPeriod;
averX6+=arr6[i-j-bars6]/_SettPeriod;
averX7+=arr7[i-j-bars7]/_SettPeriod;
averX8+=arr8[i-j-bars8]/_SettPeriod;
}

v1=0; v2=0; v3=0;
v4=0;v5=0;v6=0;v7=0;v8=0;
v9=0;v10=0;v11=0;v12=0;v13=0;
v14=0;v15=0;v16=0;v17=0;v18=0;
v19=0;v20=0;v21=0; 
for(j=0;j<_SettPeriod;j++)
{
v1+=(arr1[i-j-bars1]-averX1)*(arr2[i-j-bars2]-averX2);
v2+=pow((arr1[i-j-bars1]-averX1),2);
v3+=pow((arr2[i-j-bars2]-averX2),2);

v4+=(arr1[i-j-bars1]-averX2)*(arr3[i-j-bars3]-averX3);
// v5+=pow((arr1[i-j-bars1]-averX1),2);
v6+=pow((arr3[i-j-bars3]-averX3),2);

v7+=(arr1[i-j-bars1]-averX1)*(arr4[i-j-bars4]-averX4);
// v8+=pow((arr1[i-j-bars1]-averX1),2);
v9+=pow((arr4[i-j-bars4]-averX4),2);

v10+=(arr1[i-j-bars1]-averX1)*(arr5[i-j-bars5]-averX5);
// v11+=pow((arr1[i-j-bars1]-averX1),2);
v12+=pow((arr5[i-j-bars5]-averX5),2);

v13+=(arr1[i-j-bars1]-averX1)*(arr6[i-j-bars6]-averX6);
// v14+=pow((arr1[i-j-bars1]-averX1),2);
v15+=pow((arr6[i-j-bars6]-averX6),2);

v16+=(arr1[i-j-bars1]-averX1)*(arr7[i-j-bars7]-averX7);
// v17+=pow((arr1[i-j-bars1]-averX1),2);
v18+=pow((arr7[i-j-bars7]-averX7),2);

v19+=(arr1[i-j-bars1]-averX1)*(arr8[i-j-bars8]-averX8);
// v20+=pow((arr1[i-j-bars1]-averX1),2);
v21+=pow((arr8[i-j-bars8]-averX8),2);

}
buf[i]= (
(v1/sqrt(v2*v3))+
(v4/sqrt(v2*v6))+
(v7/sqrt(v2*v9))+
(v10/sqrt(v2*v12))+
(v13/sqrt(v2*v15))+
(v16/sqrt(v2*v18))+
(v19/sqrt(v2*v21)) 
)/7; // simple average of values.


buf2[i]=buf[i];
c=getPlotColor(buf[i]);
colors1[i]=c;
colors2[i]=c;
}
return rates_total;
}

//+------------------------------------------------------------------+
//| setPlotColour |
//+------------------------------------------------------------------+
void setPlotColor(int plot,color col1,color col2)
{
int i;
CRGB c1,c2;
double dr,dg,db;
string s;
//--- 
PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,MAX_COL);
ColorToRGB(col1,c1);
ColorToRGB(col2,c2);
dr=(double)(c2.r-c1.r)/MAX_COL;
dg=(double)(c2.g-c1.g)/MAX_COL;
db=(double)(c2.b-c1.b)/MAX_COL;
for(i=0;i<MAX_COL;i++)
{
s=StringFormat("%i,%i,%i",
c1.r+(int)NormalizeDouble(dr*(i+1),0),
c1.g+(int)NormalizeDouble(dg*(i+1),0),
c1.b+(int)NormalizeDouble(db*(i+1),0));
PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor(s));
}
}
//+------------------------------------------------------------------+
//| getPlotColor |
//+------------------------------------------------------------------+
int getPlotColor(double current)
{
return((int)NormalizeDouble((MAX_COL-1)*fabs(current),0));
}
//+------------------------------------------------------------------+
//| ColorToRGB |
//+------------------------------------------------------------------+
void ColorToRGB(color col,CRGB &res)
{
string s,s2;
int n;
//---
s=ColorToString(col);
n=StringFind(s,",");
s2=StringSubstr(s,0,n);
res.r=(int)StringToInteger(s2);
s=StringSubstr(s,n+1);
n=StringFind(s,",");
s2=StringSubstr(s,0,n);
res.g=(int)StringToInteger(s2);
s=StringSubstr(s,n+1);
s2=StringSubstr(s,0);
res.b=(int)StringToInteger(s2);
}
//+------------------------------------------------------------------+
Files: