First commit [09/03/2018]
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestAccountInfo.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include <Trade\AccountInfo.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//---
|
||||
#include "AccountInfoSampleInit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to testing the use of class CAccountInfo. |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Account Info Sample script class |
|
||||
//+------------------------------------------------------------------+
|
||||
class CAccountInfoSample
|
||||
{
|
||||
protected:
|
||||
CAccountInfo m_account;
|
||||
//--- chart objects
|
||||
CChartObjectLabel m_label[19];
|
||||
CChartObjectLabel m_label_info[19];
|
||||
|
||||
public:
|
||||
CAccountInfoSample(void);
|
||||
~CAccountInfoSample(void);
|
||||
//---
|
||||
bool Init(void);
|
||||
void Deinit(void);
|
||||
void Processing(void);
|
||||
|
||||
private:
|
||||
void AccountInfoToChart(void);
|
||||
};
|
||||
//---
|
||||
CAccountInfoSample ExtScript;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CAccountInfoSample::CAccountInfoSample(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CAccountInfoSample::~CAccountInfoSample(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Init. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CAccountInfoSample::Init(void)
|
||||
{
|
||||
int i,sy=10;
|
||||
int dy=16;
|
||||
color color_label;
|
||||
color color_info;
|
||||
//--- tuning colors
|
||||
color_info =(color)(ChartGetInteger(0,CHART_COLOR_BACKGROUND)^0xFFFFFF);
|
||||
color_label=(color)(color_info^0x202020);
|
||||
//---
|
||||
if(ChartGetInteger(0,CHART_SHOW_OHLC))
|
||||
sy+=16;
|
||||
//--- creation Labels[]
|
||||
for(i=0;i<19;i++)
|
||||
{
|
||||
m_label[i].Create(0,"Label"+IntegerToString(i),0,20,sy+dy*i);
|
||||
m_label[i].Description(init_str[i]);
|
||||
m_label[i].Color(color_label);
|
||||
m_label[i].FontSize(8);
|
||||
//---
|
||||
m_label_info[i].Create(0,"LabelInfo"+IntegerToString(i),0,120,sy+dy*i);
|
||||
m_label_info[i].Description(" ");
|
||||
m_label_info[i].Color(color_info);
|
||||
m_label_info[i].FontSize(8);
|
||||
}
|
||||
AccountInfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Deinit. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAccountInfoSample::Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Processing. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAccountInfoSample::Processing(void)
|
||||
{
|
||||
AccountInfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
Sleep(50);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method InfoToChart. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CAccountInfoSample::AccountInfoToChart(void)
|
||||
{
|
||||
m_label_info[0].Description((string)m_account.Login());
|
||||
m_label_info[1].Description(m_account.TradeModeDescription());
|
||||
m_label_info[2].Description((string)m_account.Leverage());
|
||||
m_label_info[3].Description(m_account.MarginModeDescription());
|
||||
m_label_info[4].Description((string)m_account.TradeAllowed());
|
||||
m_label_info[5].Description((string)m_account.TradeExpert());
|
||||
m_label_info[6].Description(DoubleToString(m_account.Balance(),2));
|
||||
m_label_info[7].Description(DoubleToString(m_account.Credit(),2));
|
||||
m_label_info[8].Description(DoubleToString(m_account.Profit(),2));
|
||||
m_label_info[9].Description(DoubleToString(m_account.Equity(),2));
|
||||
m_label_info[10].Description(DoubleToString(m_account.Margin(),2));
|
||||
m_label_info[11].Description(DoubleToString(m_account.FreeMargin(),2));
|
||||
m_label_info[12].Description(DoubleToString(m_account.MarginLevel(),2));
|
||||
m_label_info[13].Description(DoubleToString(m_account.MarginCall(),2));
|
||||
m_label_info[14].Description(DoubleToString(m_account.MarginStopOut(),2));
|
||||
m_label_info[15].Description(m_account.Name());
|
||||
m_label_info[16].Description(m_account.Server());
|
||||
m_label_info[17].Description(m_account.Currency());
|
||||
m_label_info[18].Description(m_account.Company());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(ExtScript.Init()==0)
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
ExtScript.Processing();
|
||||
}
|
||||
//--- call deinit function
|
||||
ExtScript.Deinit();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,17 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| AccountInfoInitSample.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Arrays to initialize graphics objects AccountInfoSample. |
|
||||
//+------------------------------------------------------------------+
|
||||
string init_str[]=
|
||||
{
|
||||
"Login","TradeMode","Leverage","MarginMode","TradeAllowed",
|
||||
"TradeExpert","Balance","Credit","Profit","Equity",
|
||||
"Margin","FreeMargin","MarginLevel","MarginCall","MarginStopOut",
|
||||
"Name","Server","Currency","Company"
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,102 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ArrayDoubleSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include <Arrays\ArrayDouble.mqh>
|
||||
#include <Files\FileBin.mqh>
|
||||
//---
|
||||
const int ExtArraySize=10000;
|
||||
const int ExtArrayAdd=100;
|
||||
string ExtFileName="ArrayDoubleSample.bin";
|
||||
//+------------------------------------------------------------------+
|
||||
//| Example class CArrayDouble |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
int i,pos;
|
||||
double key;
|
||||
CFileBin File;
|
||||
CArrayDouble ArrayDouble;
|
||||
//---
|
||||
printf("Start sample %s.",__FILE__);
|
||||
//--- fill an array of background information
|
||||
//--- open file for reading
|
||||
if(File.Open(ExtFileName,FILE_READ)!=INVALID_HANDLE)
|
||||
{
|
||||
//--- read array from file
|
||||
if(!ArrayDouble.Load(File.Handle()))
|
||||
{
|
||||
//--- error reading from file
|
||||
printf("%s (%4d): error %d",__FILE__,__LINE__,GetLastError());
|
||||
}
|
||||
//--- do not forget close file
|
||||
File.Close();
|
||||
}
|
||||
//--- check whether enough information in the array
|
||||
if(ArrayDouble.Total()<ExtArraySize)
|
||||
{
|
||||
//--- information in the file is not enough, or it is not at all
|
||||
//--- reserve position in the array for the missing information
|
||||
if(!ArrayDouble.Reserve(ExtArraySize-ArrayDouble.Total()))
|
||||
{
|
||||
//--- displaying the log error information
|
||||
printf("%s (%4d): reserve error",__FILE__,__LINE__);
|
||||
//--- remove a previously created array
|
||||
return(__LINE__);
|
||||
}
|
||||
//--- additional fill an array of "random" values
|
||||
for(i=ArrayDouble.Total();i<ExtArraySize;i++)
|
||||
ArrayDouble.Add(MathRand()*MathPow(10,MathRand()%100));
|
||||
}
|
||||
//--- sort array
|
||||
ArrayDouble.Sort();
|
||||
//--- inserts the additional data without violating sorting (ExtArrayAdd items)
|
||||
for(i=0;i<ExtArrayAdd;i++)
|
||||
ArrayDouble.InsertSort(MathRand()*MathPow(10,MathRand()%100));
|
||||
//--- set tolerance "fuzzy" comparison for the search
|
||||
ArrayDouble.Delta(0.1);
|
||||
//--- produce some of the search in sorted array
|
||||
key=MathRand()*MathPow(10,MathRand()%100);
|
||||
if((pos=ArrayDouble.SearchGreat(key))==-1)
|
||||
printf("Search for items greater than %f, not found",key);
|
||||
else
|
||||
{
|
||||
printf("Search for items greater than %f, found %f in the position %d",key,ArrayDouble.At(pos),pos);
|
||||
//--- your actions have found the element
|
||||
//--- ...
|
||||
//---
|
||||
}
|
||||
key=MathRand()*MathPow(10,MathRand()%100);
|
||||
if((pos=ArrayDouble.SearchLess(key))==-1)
|
||||
printf("Search for items less than %f, not found",key);
|
||||
else
|
||||
{
|
||||
printf("Search for items less than %f, found %f in the position %d",key,ArrayDouble.At(pos),pos);
|
||||
//--- your actions have found the element
|
||||
//--- ...
|
||||
//---
|
||||
}
|
||||
//--- Remove from the array of extra data (ExtArrayAdd/2 largest and ExtArrayAdd/2 lowest)
|
||||
ArrayDouble.DeleteRange(ArrayDouble.Total()-ExtArrayAdd/2-1,ArrayDouble.Total());
|
||||
ArrayDouble.DeleteRange(0,ExtArraySize/2);
|
||||
//--- save the modified array of file
|
||||
//--- open file for writing
|
||||
if(File.Open(ExtFileName,FILE_WRITE)!=INVALID_HANDLE)
|
||||
if(ArrayDouble.Save(File.Handle()))
|
||||
{
|
||||
//--- normal completion
|
||||
//--- because when you call the destructor, an open file is closed automatically
|
||||
//--- and explicitly close the file is not necessary but desirable
|
||||
printf("End of sample %s. OK!",__FILE__);
|
||||
return(0);
|
||||
}
|
||||
//--- error with file
|
||||
//--- displaying the log error information
|
||||
printf("%s (%4d): error %d",__FILE__,__LINE__,GetLastError());
|
||||
return(__LINE__);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,211 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CanvasSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Demonstrating Canvas features"
|
||||
//---
|
||||
#include <Canvas\Canvas.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| inputs |
|
||||
//+------------------------------------------------------------------+
|
||||
input int Width=800;
|
||||
input int Height=600;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
int total=1024;
|
||||
int limit=MathMax(Width,Height);
|
||||
int x1,x2,x3,y1,y2,y3,r;
|
||||
int x[],y[];
|
||||
//--- check
|
||||
if(Width<100 || Height<100)
|
||||
{
|
||||
Print("Too simple.");
|
||||
return(-1);
|
||||
}
|
||||
//--- create canvas
|
||||
CCanvas canvas;
|
||||
if(!canvas.CreateBitmapLabel("SampleCanvas",0,0,Width,Height,COLOR_FORMAT_ARGB_RAW))
|
||||
{
|
||||
Print("Error creating canvas: ",GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
//--- deawing
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- start randomizer
|
||||
srand(GetTickCount());
|
||||
//--- draw pixels
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
canvas.PixelSet(x1,y1,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- draw horizontal/vertical lines
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
if(i%2==0)
|
||||
canvas.LineHorizontal(x1,x2,y1,RandomRGB());
|
||||
else
|
||||
canvas.LineVertical(x1,y1,y2,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- draw lines
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
canvas.Line(x1,y1,x2,y2,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- draw filled circles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
r =rand()%limit;
|
||||
canvas.FillCircle(x1,y1,r,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- draw circles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
r =rand()%limit;
|
||||
canvas.Circle(x1,y1,r,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- draw filled rectangles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
canvas.FillRectangle(x1,y1,x2,y2,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- draw rectangles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
canvas.Rectangle(x1,y1,x2,y2,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- draw filled triangles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
x3=rand()%limit;
|
||||
y3=rand()%limit;
|
||||
canvas.FillTriangle(x1,y1,x2,y2,x3,y3,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- draw triangles
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
x1=rand()%limit;
|
||||
y1=rand()%limit;
|
||||
x2=rand()%limit;
|
||||
y2=rand()%limit;
|
||||
x3=rand()%limit;
|
||||
y3=rand()%limit;
|
||||
canvas.Triangle(x1,y1,x2,y2,x3,y3,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//---
|
||||
ArrayResize(x,10);
|
||||
ArrayResize(y,10);
|
||||
//--- draw polyline
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
x[i]=rand()%Width;
|
||||
y[i]=rand()%Height;
|
||||
}
|
||||
canvas.Polyline(x,y,RandomRGB());
|
||||
canvas.Update();
|
||||
//--- draw polygon
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
x[i]=rand()%Width;
|
||||
y[i]=rand()%Height;
|
||||
}
|
||||
canvas.Polygon(x,y,RandomRGB());
|
||||
canvas.Update();
|
||||
//--- filling
|
||||
for(int i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
int xf=rand()%Width;
|
||||
int yf=rand()%Height;
|
||||
canvas.Fill(xf,yf,RandomRGB());
|
||||
canvas.Update();
|
||||
}
|
||||
//--- erase
|
||||
canvas.Erase(XRGB(0x1F,0x1F,0x1F));
|
||||
canvas.Update();
|
||||
//--- draw text
|
||||
string text;
|
||||
x1=Width/2;
|
||||
y1=Height/2;
|
||||
r =y1-50;
|
||||
for(int i=0;i<8;i++)
|
||||
{
|
||||
double a=i*M_PI_4;
|
||||
uint clr=RandomRGB();
|
||||
int deg=(int)(180*a/M_PI);
|
||||
x2=x1+(int)(r*cos(a));
|
||||
y2=y1-(int)(r*sin(a));
|
||||
canvas.LineAA(x1,y1,x2,y2,clr,STYLE_DASHDOTDOT);
|
||||
text="Angle "+IntegerToString(deg);
|
||||
canvas.FontSet(canvas.FontNameGet(),canvas.FontSizeGet(),canvas.FontFlagsGet(),10*deg);
|
||||
canvas.TextOut(x2,y2,text,clr,TA_RIGHT|TA_BOTTOM);
|
||||
canvas.Update();
|
||||
}
|
||||
//--- finish
|
||||
ObjectDelete(0,"SampleCanvas");
|
||||
canvas.Destroy();
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Random RGB color |
|
||||
//+------------------------------------------------------------------+
|
||||
uint RandomRGB(void)
|
||||
{
|
||||
return(XRGB(rand()%255,rand()%255,rand()%255));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,66 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| HistogramChartSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Example of using histogram"
|
||||
//---
|
||||
#include <Canvas\Charts\HistogramChart.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| inputs |
|
||||
//+------------------------------------------------------------------+
|
||||
input bool Accumulative=true;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
int k=100;
|
||||
double arr[10];
|
||||
//--- create chart
|
||||
CHistogramChart chart;
|
||||
if(!chart.CreateBitmapLabel("SampleHistogramChart",10,10,600,450))
|
||||
{
|
||||
Print("Error creating histogram chart: ",GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
if(Accumulative)
|
||||
{
|
||||
chart.Accumulative();
|
||||
chart.VScaleParams(20*k*10,-10*k*10,20);
|
||||
}
|
||||
else
|
||||
chart.VScaleParams(20*k,-10*k,20);
|
||||
chart.ShowValue(true);
|
||||
chart.ShowScaleTop(false);
|
||||
chart.ShowScaleBottom(false);
|
||||
chart.ShowScaleRight(false);
|
||||
chart.ShowLegend();
|
||||
for(int j=0;j<5;j++)
|
||||
{
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
k=-k;
|
||||
if(k>0)
|
||||
arr[i]=k*(i+10-j);
|
||||
else
|
||||
arr[i]=k*(i+10-j)/2;
|
||||
}
|
||||
chart.SeriesAdd(arr,"Item"+IntegerToString(j));
|
||||
}
|
||||
//--- play with values
|
||||
while(!IsStopped())
|
||||
{
|
||||
int i=rand()%5;
|
||||
int j=rand()%10;
|
||||
k=rand()%3000-1000;
|
||||
chart.ValueUpdate(i,j,k);
|
||||
Sleep(200);
|
||||
}
|
||||
//--- finish
|
||||
chart.Destroy();
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,66 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| LineChartSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Example of using line chart"
|
||||
//---
|
||||
#include <Canvas\Charts\LineChart.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| inputs |
|
||||
//+------------------------------------------------------------------+
|
||||
input bool Accumulative=false;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
int k=100;
|
||||
double arr[10];
|
||||
//--- create chart
|
||||
CLineChart chart;
|
||||
//--- create chart
|
||||
if(!chart.CreateBitmapLabel("SampleHistogrammChart",10,10,600,450))
|
||||
{
|
||||
Print("Error creating line chart: ",GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
if(Accumulative)
|
||||
{
|
||||
chart.Accumulative();
|
||||
chart.VScaleParams(20*k*10,-10*k*10,20);
|
||||
}
|
||||
else
|
||||
chart.VScaleParams(20*k,-10*k,15);
|
||||
chart.ShowScaleTop(false);
|
||||
chart.ShowScaleRight(false);
|
||||
chart.ShowLegend();
|
||||
chart.Filled();
|
||||
for(int j=0;j<5;j++)
|
||||
{
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
k=-k;
|
||||
if(k>0)
|
||||
arr[i]=k*(i+10-j);
|
||||
else
|
||||
arr[i]=k*(i+10-j)/2;
|
||||
}
|
||||
chart.SeriesAdd(arr,"Item"+IntegerToString(j));
|
||||
}
|
||||
//--- play with values
|
||||
while(!IsStopped())
|
||||
{
|
||||
int i=rand()%5;
|
||||
int j=rand()%10;
|
||||
k=rand()%3000-1000;
|
||||
chart.ValueUpdate(i,j,k);
|
||||
Sleep(200);
|
||||
}
|
||||
//--- finish
|
||||
chart.Destroy();
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,97 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| PieChartSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Example of using pie chart"
|
||||
//---
|
||||
#include <Canvas\Charts\PieChart.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| inputs |
|
||||
//+------------------------------------------------------------------+
|
||||
input int Width=600;
|
||||
input int Height=450;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- check
|
||||
if(Width<=0 || Height<=0)
|
||||
{
|
||||
Print("Too simple.");
|
||||
return(-1);
|
||||
}
|
||||
//--- create chart
|
||||
CPieChart pie_chart;
|
||||
if(!pie_chart.CreateBitmapLabel("PieChart",10,10,Width,Height))
|
||||
{
|
||||
Print("Error creating pie chart: ",GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
pie_chart.ShowPercent();
|
||||
//--- draw
|
||||
for(uint i=0;i<30;i++)
|
||||
{
|
||||
pie_chart.ValueAdd(100*(i+1),"Item "+IntegerToString(i));
|
||||
Sleep(10);
|
||||
}
|
||||
Sleep(2000);
|
||||
//--- disable legend
|
||||
pie_chart.LegendAlignment(ALIGNMENT_LEFT);
|
||||
Sleep(2000);
|
||||
//--- disable legend
|
||||
pie_chart.LegendAlignment(ALIGNMENT_RIGHT);
|
||||
Sleep(2000);
|
||||
//--- disable legend
|
||||
pie_chart.LegendAlignment(ALIGNMENT_TOP);
|
||||
Sleep(2000);
|
||||
//--- disable legend
|
||||
pie_chart.ShowLegend(false);
|
||||
Sleep(2000);
|
||||
//--- disable percentage
|
||||
pie_chart.ShowPercent(false);
|
||||
Sleep(2000);
|
||||
//--- disable descriptors
|
||||
pie_chart.ShowDescriptors(false);
|
||||
Sleep(2000);
|
||||
//--- enable all
|
||||
pie_chart.ShowLegend();
|
||||
pie_chart.ShowValue();
|
||||
pie_chart.ShowDescriptors();
|
||||
Sleep(2000);
|
||||
//--- or like this
|
||||
pie_chart.ShowFlags(FLAG_SHOW_LEGEND|FLAG_SHOW_DESCRIPTORS|FLAG_SHOW_PERCENT);
|
||||
uint total=pie_chart.DataTotal();
|
||||
//--- play with values
|
||||
for(uint i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
pie_chart.ValueUpdate(i,100*(rand()%10+1));
|
||||
Sleep(1000);
|
||||
}
|
||||
//--- play with colors
|
||||
for(uint i=0;i<total && !IsStopped();i++)
|
||||
{
|
||||
pie_chart.ColorUpdate(i%total,RandomRGB());
|
||||
Sleep(1000);
|
||||
}
|
||||
//--- rotate
|
||||
while(!IsStopped())
|
||||
{
|
||||
pie_chart.DataOffset(pie_chart.DataOffset()+1);
|
||||
Sleep(200);
|
||||
}
|
||||
//--- finish
|
||||
pie_chart.Destroy();
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Random RGB color |
|
||||
//+------------------------------------------------------------------+
|
||||
uint RandomRGB(void)
|
||||
{
|
||||
return(XRGB(rand()%255,rand()%255,rand()%255));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,163 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ChartSampleInit.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Arrays to initialize graphics objects ObjChartSample. |
|
||||
//+------------------------------------------------------------------+
|
||||
#define NUM_PANELS 8
|
||||
#define NUM_LABELS 40
|
||||
#define NUM_EDITS 38
|
||||
#define NUM_BUTTONS 28
|
||||
//--- for Pabel[]
|
||||
string p_str[NUM_PANELS]=
|
||||
{
|
||||
"Modes","Anothers","Scales","Shows","Timeframes","Symbols","Colors",
|
||||
"Read only parameters"
|
||||
};
|
||||
//--- for Label[]
|
||||
int l_x[NUM_LABELS]=
|
||||
{
|
||||
20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,
|
||||
80,140,200,260,20,20,20,20,
|
||||
20,80,110,160,260,290,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20
|
||||
};
|
||||
int l_y[NUM_LABELS]=
|
||||
{
|
||||
14,49,84,151,218,269,346,
|
||||
1,21,41,61,81,101,
|
||||
121,121,121,121,141,161,181,201,
|
||||
241,221,221,221,221,221,
|
||||
21,41,61,81,101,121,141,161,181,201,221,241,261
|
||||
};
|
||||
int l_pan[NUM_LABELS]=
|
||||
{
|
||||
14,49,84,151,218,269,346,
|
||||
7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6
|
||||
};
|
||||
string l_str[]=
|
||||
{
|
||||
"Modes","Anothers","Scales","Shows","Timeframes","Symbols","Read only parameters",
|
||||
"Handle","Visible bars","First bar","Width (bars)","Width (pix)","Win total",
|
||||
"Win 0","Win 1","Win 2","Win 3","Visible","Height (pix)","Price min","Price max",
|
||||
"OnDropped","Win","Price","Time","X","Y",
|
||||
"Background","Foreground","Grid","BarUp","BarDown","CandleBull","CandleBear",
|
||||
"ChartLine","Volumes","LineBid","LineAsk","LineLast","StopLevels"
|
||||
};
|
||||
//--- for Edit[]
|
||||
int e_x[NUM_EDITS]=
|
||||
{
|
||||
220,220,320,320,95,245,120,
|
||||
80,80,80,140,200,260,320,
|
||||
80,80,80,80,
|
||||
80,140,200,260,320,
|
||||
80,140,200,260,320,
|
||||
80,140,200,260,320,
|
||||
80,100,160,260,290
|
||||
};
|
||||
int e_y[NUM_EDITS]=
|
||||
{
|
||||
0,0,0,0,16,16,32,
|
||||
20,100,140,140,140,140,140,
|
||||
0,40,60,80,
|
||||
160,160,160,160,160,
|
||||
180,180,180,180,180,
|
||||
200,200,200,200,200,
|
||||
240,240,240,240,240
|
||||
};
|
||||
int e_sizeX[NUM_EDITS]=
|
||||
{
|
||||
80,80,0,0,75,75,100,
|
||||
60,60,60,60,60,60,0,
|
||||
60,60,60,60,
|
||||
60,60,60,60,0,
|
||||
60,60,60,60,0,
|
||||
60,60,60,60,0,
|
||||
20,60,100,30,30
|
||||
};
|
||||
int e_pan[NUM_EDITS]=
|
||||
{
|
||||
1,2,2,2,2,2,2,
|
||||
7,7,7,7,7,7,7,
|
||||
7,7,7,7,
|
||||
7,7,7,7,7,
|
||||
7,7,7,7,7,
|
||||
7,7,7,7,7,
|
||||
7,7,7,7,7
|
||||
};
|
||||
//--- for Button[]
|
||||
int b_x[NUM_BUTTONS]=
|
||||
{
|
||||
20,120,220,
|
||||
95,170,20,300,300,
|
||||
20,120,300,300,20,170,20,
|
||||
20,95,170,245,20,120,220,
|
||||
20,120,220,
|
||||
20,120,220
|
||||
};
|
||||
int b_y[NUM_BUTTONS]=
|
||||
{
|
||||
0,0,0,
|
||||
0,0,0,0,8,
|
||||
0,0,0,8,16,16,32,
|
||||
0,0,0,0,16,16,16,
|
||||
32,32,32,
|
||||
0,0,0
|
||||
};
|
||||
int b_sizeX[NUM_BUTTONS]=
|
||||
{
|
||||
100,100,100,
|
||||
75,50,75,20,20,
|
||||
100,100,20,20,75,75,100,
|
||||
75,75,75,75,100,100,100,
|
||||
100,100,100,
|
||||
100,100,100
|
||||
};
|
||||
int b_sizeY[NUM_BUTTONS]=
|
||||
{
|
||||
16,16,16,
|
||||
16,16,16,8,8,
|
||||
16,16,8,8,16,16,16,
|
||||
16,16,16,16,16,16,16,
|
||||
16,16,16,
|
||||
16,16,16
|
||||
};
|
||||
string b_str[NUM_BUTTONS]=
|
||||
{
|
||||
"Bars","Candles","Line",
|
||||
"AutoScroll","Shift","Foreground"," "," ",
|
||||
"Scale fix","Scale fix 1/1"," "," ",
|
||||
"Fixed Max","Fixed Min",
|
||||
"Scale PixPerBar",
|
||||
"Show OHLC","Show Bid","Show Ask","Show Last",
|
||||
"Show Separator","Show Grid","Show ObjDescr",
|
||||
"Not Volumes","Tick Volumes","Real Volumes",
|
||||
"Yellow on Black","Green on Black","Black on White"
|
||||
};
|
||||
int b_pan[NUM_BUTTONS]=
|
||||
{
|
||||
0,0,0,
|
||||
1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,
|
||||
3,3,3,
|
||||
6,6,6
|
||||
};
|
||||
//--- for ButtonTF[]
|
||||
string tf_str[]=
|
||||
{
|
||||
"M1","M2","M3","M4","M5","M6","M10","M12","M15","M20","M30",
|
||||
"H1","H2","H3","H4","H6","H12","D1","W1","MN"
|
||||
};
|
||||
int tf_int[]=
|
||||
{
|
||||
1,2,3,4,5,6,10,12,15,20,30,
|
||||
0x4001,0x4002,0x4003,0x4004,0x4006,0x400c,0x4018,0x8001,0xc001
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,775 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ChartSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include <Charts\Chart.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
#include <ChartObjects\ChartObjectPanel.mqh>
|
||||
//---
|
||||
#include "ChartSampleInit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to demonstrate the use of class CChart. |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Chart Sample script class |
|
||||
//+------------------------------------------------------------------+
|
||||
class CChartSample
|
||||
{
|
||||
protected:
|
||||
CChart m_chart; // instance of the class to access properties chart
|
||||
CChartObjectButton *m_button[NUM_BUTTONS]; // array of pointers other buttons
|
||||
CChartObjectButton *m_button_tf[20]; // array of pointers period buttons
|
||||
CChartObjectButton *m_button_sym[]; // array of pointers symbol buttons
|
||||
int m_num_symbols; // number of symbol
|
||||
CChartObjectEdit *m_edit[NUM_EDITS]; // array of pointers other edits
|
||||
CChartObjectEdit *m_edit_color[13]; // array of pointers to colors show
|
||||
CChartObjectEdit *m_edit_rgb[13][3]; // array of pointers to RGB show
|
||||
CChartObjectLabel *m_label[NUM_LABELS]; // array of pointers to labels
|
||||
CChartObjectPanel m_panel[NUM_PANELS]; // array of panels
|
||||
|
||||
public:
|
||||
CChartSample(void);
|
||||
~CChartSample(void);
|
||||
//--- initialization
|
||||
bool Init(void);
|
||||
void Deinit(void);
|
||||
//--- processing
|
||||
void Processing(void);
|
||||
|
||||
private:
|
||||
void CheckPanelModes(void);
|
||||
void CheckPanelAnothers(void);
|
||||
void CheckPanelScales(void);
|
||||
void CheckPanelShows(void);
|
||||
void CheckPanelTimeframes(void);
|
||||
void CheckPanelSymbols(void);
|
||||
void CheckPanelColors(void);
|
||||
void CheckPanelReadOnly(void);
|
||||
};
|
||||
//---
|
||||
CChartSample ExtScript;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
CChartSample::CChartSample(void) : m_num_symbols(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
CChartSample::~CChartSample(void)
|
||||
{
|
||||
//--- does not perform any action
|
||||
//--- all dynamic objects created in the method Init(),
|
||||
//--- will be deleted when deleting panels,
|
||||
//--- to which they were added
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelModes. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelModes(void)
|
||||
{
|
||||
if(m_button[0].State() && m_chart.Mode()!=CHART_BARS)
|
||||
{
|
||||
//--- Set Bars Mode
|
||||
m_button[1].State(false);
|
||||
m_button[2].State(false);
|
||||
m_chart.Mode(CHART_BARS);
|
||||
}
|
||||
if(m_button[1].State() && m_chart.Mode()!=CHART_CANDLES)
|
||||
{
|
||||
//--- Set Candles Mode
|
||||
m_button[0].State(false);
|
||||
m_button[2].State(false);
|
||||
m_chart.Mode(CHART_CANDLES);
|
||||
}
|
||||
if(m_button[2].State() && m_chart.Mode()!=CHART_LINE)
|
||||
{
|
||||
//--- Set Line Mode
|
||||
m_button[0].State(false);
|
||||
m_button[1].State(false);
|
||||
m_chart.Mode(CHART_LINE);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelAnothers. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelAnothers(void)
|
||||
{
|
||||
int i,j;
|
||||
//--- Set Autoscroll
|
||||
if(m_button[3].State())
|
||||
{
|
||||
if(!m_chart.AutoScroll())
|
||||
m_chart.AutoScroll(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.AutoScroll())
|
||||
m_chart.AutoScroll(false);
|
||||
}
|
||||
//--- Set Shift
|
||||
if(m_button[4].State())
|
||||
{
|
||||
if(m_edit[0].Description()=="")
|
||||
m_edit[0].Description(DoubleToString(m_chart.ShiftSize()));
|
||||
else
|
||||
{
|
||||
i=(int)StringToInteger(m_edit[0].Description());
|
||||
j=i;
|
||||
if(i>50)
|
||||
i=50;
|
||||
if(i<10)
|
||||
i=10;
|
||||
if(j!=i)
|
||||
m_edit[0].Description(IntegerToString(i));
|
||||
if(i!=m_chart.ShiftSize())
|
||||
m_chart.ShiftSize(i);
|
||||
}
|
||||
if(!m_chart.Shift())
|
||||
m_chart.Shift(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_edit[0].Description("");
|
||||
if(m_chart.Shift())
|
||||
m_chart.Shift(false);
|
||||
}
|
||||
//--- Set Shift Size
|
||||
if(m_button[6].State())
|
||||
{
|
||||
if(m_button[4].State())
|
||||
{
|
||||
//--- Set Shift Size Up
|
||||
i=(int)StringToInteger(m_edit[0].Description());
|
||||
if(i<50)
|
||||
m_chart.ShiftSize(++i);
|
||||
m_edit[0].Description(IntegerToString(i));
|
||||
}
|
||||
m_button[6].State(false);
|
||||
}
|
||||
if(m_button[7].State())
|
||||
{
|
||||
if(m_button[4].State())
|
||||
{
|
||||
//--- Set Shift Size Down
|
||||
i=(int)StringToInteger(m_edit[0].Description());
|
||||
if(i>10)
|
||||
m_chart.ShiftSize(--i);
|
||||
m_edit[0].Description(IntegerToString(i));
|
||||
}
|
||||
m_button[7].State(false);
|
||||
}
|
||||
m_edit[2].Description(DoubleToString(m_chart.ShiftSize()));
|
||||
//--- Set Foreground
|
||||
if(m_button[5].State())
|
||||
{
|
||||
if(!m_chart.Foreground())
|
||||
m_chart.Foreground(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.Foreground())
|
||||
m_chart.Foreground(false);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelScales. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelScales(void)
|
||||
{
|
||||
int i;
|
||||
double d;
|
||||
//--- Set Scale fix
|
||||
if(m_button[8].State())
|
||||
{
|
||||
if(m_edit[4].Description()=="")
|
||||
{
|
||||
m_edit[4].Description(DoubleToString(m_chart.PriceMax(0),4));
|
||||
m_edit[5].Description(DoubleToString(m_chart.PriceMin(0),4));
|
||||
}
|
||||
if(!m_chart.ScaleFix())
|
||||
m_chart.ScaleFix(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_edit[4].Description()!="")
|
||||
{
|
||||
m_edit[4].Description("");
|
||||
m_edit[5].Description("");
|
||||
}
|
||||
if(m_chart.ScaleFix())
|
||||
m_chart.ScaleFix(false);
|
||||
}
|
||||
//--- Set Scale fix 1 to 1
|
||||
if(m_button[9].State())
|
||||
{
|
||||
if(!m_chart.ScaleFix_11())
|
||||
m_chart.ScaleFix_11(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ScaleFix_11())
|
||||
m_chart.ScaleFix_11(false);
|
||||
}
|
||||
//--- Set Scale
|
||||
if(m_button[10].State())
|
||||
{
|
||||
//--- Set Scale Up
|
||||
i=(int)StringToInteger(m_edit[1].Description());
|
||||
if(i<5)
|
||||
{
|
||||
i++;
|
||||
m_chart.Scale(i);
|
||||
m_edit[1].Description(IntegerToString(i));
|
||||
}
|
||||
m_button[10].State(false);
|
||||
}
|
||||
if(m_button[11].State())
|
||||
{
|
||||
//--- Set Scale Down
|
||||
i=(int)StringToInteger(m_edit[1].Description());
|
||||
if(i>0)
|
||||
{
|
||||
i--;
|
||||
m_chart.Scale(i);
|
||||
m_edit[1].Description(IntegerToString(i));
|
||||
}
|
||||
m_button[11].State(false);
|
||||
}
|
||||
m_edit[3].Description(IntegerToString(m_chart.Scale()));
|
||||
//--- Set Fixed Max
|
||||
if(m_button[12].State())
|
||||
{
|
||||
if(m_chart.ScaleFix())
|
||||
{
|
||||
d=StringToDouble(m_edit[4].Description());
|
||||
if(m_chart.FixedMax()!=d)
|
||||
m_chart.FixedMax(d);
|
||||
m_edit[4].Description(DoubleToString(d,4));
|
||||
}
|
||||
else
|
||||
m_edit[4].Description("");
|
||||
m_button[12].State(false);
|
||||
}
|
||||
//--- Set Fixed Min
|
||||
if(m_button[13].State())
|
||||
{
|
||||
if(m_chart.ScaleFix())
|
||||
{
|
||||
d=StringToDouble(m_edit[5].Description());
|
||||
if(m_chart.FixedMin()!=d)
|
||||
m_chart.FixedMin(d);
|
||||
m_edit[5].Description(DoubleToString(d,4));
|
||||
}
|
||||
else
|
||||
m_edit[5].Description("");
|
||||
m_button[13].State(false);
|
||||
}
|
||||
//--- Set Scale PPB
|
||||
if(m_button[14].State())
|
||||
{
|
||||
if(m_edit[6].Description()=="")
|
||||
{
|
||||
d=m_chart.PointsPerBar();
|
||||
if(d==0.0)
|
||||
{
|
||||
d=1.0;
|
||||
m_chart.PointsPerBar(d);
|
||||
}
|
||||
m_edit[6].Description(DoubleToString(d,4));
|
||||
}
|
||||
if(!m_chart.ScalePPB())
|
||||
m_chart.ScalePPB(true);
|
||||
d=StringToDouble(m_edit[6].Description());
|
||||
if(m_chart.PointsPerBar()!=d)
|
||||
m_chart.PointsPerBar(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_edit[6].Description("");
|
||||
if(m_chart.ScalePPB())
|
||||
m_chart.ScalePPB(false);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelShows. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelShows(void)
|
||||
{
|
||||
//--- Set Show OHLC
|
||||
if(m_button[15].State())
|
||||
{
|
||||
if(!m_chart.ShowOHLC())
|
||||
m_chart.ShowOHLC(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowOHLC())
|
||||
m_chart.ShowOHLC(false);
|
||||
}
|
||||
//--- Set Show Bid
|
||||
if(m_button[16].State())
|
||||
{
|
||||
if(!m_chart.ShowLineBid())
|
||||
m_chart.ShowLineBid(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowLineBid())
|
||||
m_chart.ShowLineBid(false);
|
||||
}
|
||||
//--- Set Show Ask
|
||||
if(m_button[17].State())
|
||||
{
|
||||
if(!m_chart.ShowLineAsk())
|
||||
m_chart.ShowLineAsk(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowLineAsk())
|
||||
m_chart.ShowLineAsk(false);
|
||||
}
|
||||
//--- Set Show Last
|
||||
if(m_button[18].State())
|
||||
{
|
||||
if(!m_chart.ShowLastLine())
|
||||
m_chart.ShowLastLine(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowLastLine())
|
||||
m_chart.ShowLastLine(false);
|
||||
}
|
||||
//--- Set Show Separator
|
||||
if(m_button[19].State())
|
||||
{
|
||||
if(!m_chart.ShowPeriodSep())
|
||||
m_chart.ShowPeriodSep(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowPeriodSep())
|
||||
m_chart.ShowPeriodSep(false);
|
||||
}
|
||||
//--- Set Show Grid
|
||||
if(m_button[20].State())
|
||||
{
|
||||
if(!m_chart.ShowGrid())
|
||||
m_chart.ShowGrid(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowGrid())
|
||||
m_chart.ShowGrid(false);
|
||||
}
|
||||
//--- Set Show Objects Descriptor
|
||||
if(m_button[21].State())
|
||||
{
|
||||
if(!m_chart.ShowObjectDescr())
|
||||
m_chart.ShowObjectDescr(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_chart.ShowObjectDescr())
|
||||
m_chart.ShowObjectDescr(false);
|
||||
}
|
||||
//--- Set Show Not Volumes
|
||||
if(m_button[22].State())
|
||||
{
|
||||
m_chart.ShowVolumes((ENUM_CHART_VOLUME_MODE)0);
|
||||
m_button[22].State(false);
|
||||
}
|
||||
//--- Set Show Tick Volumes
|
||||
if(m_button[23].State())
|
||||
{
|
||||
m_chart.ShowVolumes((ENUM_CHART_VOLUME_MODE)1);
|
||||
m_button[23].State(false);
|
||||
}
|
||||
//--- Set Show Real Volumes
|
||||
if(m_button[24].State())
|
||||
{
|
||||
m_chart.ShowVolumes((ENUM_CHART_VOLUME_MODE)2);
|
||||
m_button[24].State(false);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelTimeframes. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelTimeframes(void)
|
||||
{
|
||||
int i,j;
|
||||
//--- No Set Period PERIOD_MN
|
||||
if(m_button_tf[19].State())
|
||||
m_button_tf[19].State(false);
|
||||
//--- Set Period
|
||||
for(i=0;i<20;i++)
|
||||
if(m_button_tf[i].State())
|
||||
{
|
||||
if(m_chart.Period()!=tf_int[i])
|
||||
m_chart.SetSymbolPeriod(m_chart.Symbol(),(ENUM_TIMEFRAMES)tf_int[i]);
|
||||
else
|
||||
continue;
|
||||
for(j=0;j<20;j++)
|
||||
if(i!=j)
|
||||
m_button_tf[j].State(false);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelSymbols. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelSymbols(void)
|
||||
{
|
||||
int i,j;
|
||||
//--- Set Symbol
|
||||
for(i=0;i<m_num_symbols;i++)
|
||||
if(m_button_sym[i].State())
|
||||
{
|
||||
if(m_chart.Symbol()!=SymbolName(i,true))
|
||||
{
|
||||
m_chart.SetSymbolPeriod(SymbolName(i,true),m_chart.Period());
|
||||
//--- by changing the symbol switch OFF ScaleFix if it is ON
|
||||
m_button[8].State(false);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
for(j=0;j<m_num_symbols;j++)
|
||||
if(i!=j)
|
||||
m_button_sym[j].State(false);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelColors. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelColors(void)
|
||||
{
|
||||
int i;
|
||||
color c;
|
||||
static color yellow_on_black[]={Black,White,LightSlateGray,Yellow,Yellow,Black,White,Yellow,LimeGreen,LightSlateGray,Red,C'0,192,0',Red};
|
||||
static color green_on_black[] ={Black,White,LightSlateGray,Lime,Lime,Black,White,Lime,LimeGreen,LightSlateGray,Red,C'0,192,0',Red};
|
||||
static color black_on_white[] ={White,Black,Silver,Black,Black,White,Black,Black,Green,Silver,Silver,Silver,OrangeRed};
|
||||
static int color_id[]=
|
||||
{
|
||||
CHART_COLOR_BACKGROUND,CHART_COLOR_FOREGROUND,CHART_COLOR_GRID,CHART_COLOR_CHART_UP,
|
||||
CHART_COLOR_CHART_DOWN,CHART_COLOR_CANDLE_BULL,CHART_COLOR_CANDLE_BEAR,CHART_COLOR_CHART_LINE,
|
||||
CHART_COLOR_VOLUME,CHART_COLOR_BID,CHART_COLOR_ASK,CHART_COLOR_LAST,CHART_COLOR_STOP_LEVEL
|
||||
};
|
||||
//---
|
||||
if(m_button[25].State())
|
||||
{
|
||||
//--- Set "Yellow on Black"
|
||||
m_button[25].State(false);
|
||||
for(i=0;i<13;i++)
|
||||
m_chart.SetInteger((ENUM_CHART_PROPERTY_INTEGER)color_id[i],yellow_on_black[i]);
|
||||
}
|
||||
if(m_button[26].State())
|
||||
{
|
||||
//--- Set "Green on Black"
|
||||
m_button[26].State(false);
|
||||
for(i=0;i<13;i++)
|
||||
m_chart.SetInteger((ENUM_CHART_PROPERTY_INTEGER)color_id[i],green_on_black[i]);
|
||||
}
|
||||
if(m_button[27].State())
|
||||
{
|
||||
//--- Set "Black on White" palette
|
||||
m_button[27].State(false);
|
||||
for(i=0;i<13;i++)
|
||||
m_chart.SetInteger((ENUM_CHART_PROPERTY_INTEGER)color_id[i],black_on_white[i]);
|
||||
}
|
||||
//--- tuning colors
|
||||
color color_label=(color)(m_chart.ColorBackground()^0xFFFFFF);
|
||||
for(i=7;i<NUM_LABELS;i++)
|
||||
m_label[i].Color(color_label);
|
||||
for(i=0;i<13;i++)
|
||||
{
|
||||
c=(color)m_chart.GetInteger((ENUM_CHART_PROPERTY_INTEGER)color_id[i]);
|
||||
m_edit_color[i].BackColor(c);
|
||||
m_edit_rgb[i][0].Description((string)((c&0xFF0000)>>16));
|
||||
m_edit_rgb[i][1].Description((string)((c&0xFF00)>>8));
|
||||
m_edit_rgb[i][2].Description((string)(c&0xFF));
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method CheckPanelReadOnly. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::CheckPanelReadOnly(void)
|
||||
{
|
||||
int i,j;
|
||||
//--- Get VisibleBars
|
||||
m_edit[7].Description((string)m_chart.VisibleBars());
|
||||
//--- Get WindowsTotal
|
||||
m_edit[8].Description((string)(j=m_chart.WindowsTotal()));
|
||||
j%=6;
|
||||
//--- Get WindowIsVisible[i]
|
||||
for(i=0;i<j;i++)
|
||||
m_edit[9+i].Description((string)m_chart.WindowIsVisible(i));
|
||||
//--- Get WindowHandle
|
||||
m_edit[14].Description((string)m_chart.WindowHandle());
|
||||
//--- Get FirstVisibleBar
|
||||
m_edit[15].Description((string)m_chart.FirstVisibleBar());
|
||||
//--- Get WidthInBars
|
||||
m_edit[16].Description((string)m_chart.WidthInBars());
|
||||
//--- Get WidthInPixels
|
||||
m_edit[17].Description((string)m_chart.WidthInPixels());
|
||||
//--- Get HeightInPixels[i]
|
||||
for(i=0;i<j;i++)
|
||||
m_edit[18+i].Description((string)m_chart.HeightInPixels(i));
|
||||
//--- Get PriceMin[i]
|
||||
for(i=0;i<j;i++)
|
||||
m_edit[23+i].Description(DoubleToString(m_chart.PriceMin(i),4));
|
||||
//--- Get PriceMax[i]
|
||||
for(i=0;i<j;i++)
|
||||
m_edit[28+i].Description(DoubleToString(m_chart.PriceMax(i),4));
|
||||
//--- Get WindowOnDropped
|
||||
m_edit[33].Description((string)m_chart.WindowOnDropped());
|
||||
//--- Get PriceOnDropped
|
||||
m_edit[34].Description(DoubleToString(m_chart.PriceOnDropped(),4));
|
||||
//--- Get TimeOnDropped
|
||||
m_edit[35].Description(TimeToString(m_chart.TimeOnDropped()));
|
||||
//--- Get XOnDropped
|
||||
m_edit[36].Description((string)m_chart.XOnDropped());
|
||||
//--- YOnDropped
|
||||
m_edit[37].Description((string)m_chart.YOnDropped());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Init. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CChartSample::Init(void)
|
||||
{
|
||||
int i,j,x;
|
||||
int sx,sy=16;
|
||||
color color_label;
|
||||
//---
|
||||
if((m_num_symbols=SymbolsTotal(true))==0)
|
||||
return(false);
|
||||
//---
|
||||
if(m_chart.Open(SymbolName(0,true),PERIOD_M1)==0)
|
||||
{
|
||||
printf("Chart not created");
|
||||
return(false);
|
||||
}
|
||||
//--- tuning colors
|
||||
color_label=(color)(m_chart.ColorBackground()^0xFFFFFF);
|
||||
//--- create m_panel[]
|
||||
for(i=0;i<NUM_PANELS;i++)
|
||||
{
|
||||
m_panel[i].Create(m_chart.ChartId(),"Panel"+IntegerToString(i),0,10,sy,150,16);
|
||||
m_panel[i].Description(p_str[i]);
|
||||
m_panel[i].Color(Black);
|
||||
m_panel[i].FontSize(8);
|
||||
m_panel[i].State(true);
|
||||
sy+=m_panel[i].Y_Size();
|
||||
}
|
||||
sy=4;
|
||||
//--- creation m_label[]
|
||||
for(i=7;i<NUM_LABELS;i++)
|
||||
{
|
||||
if((m_label[i]=new CChartObjectLabel)==NULL)
|
||||
return(false);
|
||||
m_label[i].Create(m_chart.ChartId(),"Label"+IntegerToString(i),0,l_x[i],sy+l_y[i]);
|
||||
m_label[i].Description(l_str[i]);
|
||||
m_label[i].Color(color_label);
|
||||
if(i>=7)
|
||||
m_label[i].FontSize(8);
|
||||
if(l_pan[i]<NUM_PANELS)
|
||||
m_panel[l_pan[i]].Attach(m_label[i]);
|
||||
}
|
||||
//--- creation m_button[]
|
||||
for(i=0;i<NUM_BUTTONS;i++)
|
||||
{
|
||||
if((m_button[i]=new CChartObjectButton)==NULL)
|
||||
return(false);
|
||||
m_button[i].Create(m_chart.ChartId(),"Button"+IntegerToString(i),0,b_x[i],sy+b_y[i],b_sizeX[i],b_sizeY[i]);
|
||||
m_button[i].Description(b_str[i]);
|
||||
m_button[i].Color(Black);
|
||||
m_button[i].FontSize(8);
|
||||
if(b_pan[i]<NUM_PANELS)
|
||||
m_panel[b_pan[i]].Attach(m_button[i]);
|
||||
}
|
||||
//--- creation m_edit[]
|
||||
for(i=0;i<NUM_EDITS;i++)
|
||||
{
|
||||
if((m_edit[i]=new CChartObjectEdit)==NULL)
|
||||
return(false);
|
||||
m_edit[i].Create(m_chart.ChartId(),"Edit"+IntegerToString(i),0,e_x[i],sy+e_y[i],e_sizeX[i],16);
|
||||
m_edit[i].FontSize(8);
|
||||
if(e_pan[i]<NUM_PANELS)
|
||||
m_panel[e_pan[i]].Attach(m_edit[i]);
|
||||
}
|
||||
//--- creation m_edit_color[] and m_edit_rgb[][]
|
||||
for(i=0;i<13;i++)
|
||||
{
|
||||
if((m_edit_color[i]=new CChartObjectEdit)==NULL)
|
||||
return(false);
|
||||
m_edit_color[i].Create(m_chart.ChartId(),"EditColor"+IntegerToString(i),0,80,20+20*i,16,16);
|
||||
m_edit_color[i].FontSize(8);
|
||||
m_panel[6].Attach(m_edit_color[i]);
|
||||
for(j=0;j<3;j++)
|
||||
{
|
||||
if((m_edit_rgb[i][j]=new CChartObjectEdit)==NULL)
|
||||
return(false);
|
||||
m_edit_rgb[i][j].Create(m_chart.ChartId(),"EditRGB"+IntegerToString(i)+"_"+IntegerToString(j),0,100+80*j,20+20*i,50,16);
|
||||
m_edit_rgb[i][j].FontSize(8);
|
||||
m_panel[6].Attach(m_edit_rgb[i][j]);
|
||||
}
|
||||
}
|
||||
//--- creation m_button_tf[]
|
||||
for(i=0;i<20;i++)
|
||||
{
|
||||
x=28*(i%11);
|
||||
if(i%11<4)
|
||||
{
|
||||
sx=26;
|
||||
x-=2*(i%11);
|
||||
}
|
||||
else
|
||||
{
|
||||
x-=8;
|
||||
sx=28;
|
||||
}
|
||||
if(i>16)
|
||||
x+=28;
|
||||
if(i>17)
|
||||
x+=28;
|
||||
if((m_button_tf[i]=new CChartObjectButton)==NULL)
|
||||
return(false);
|
||||
m_button_tf[i].Create(m_chart.ChartId(),"ButtonTF"+IntegerToString(i),0,20+x,16*(i/11),sx,16);
|
||||
if(m_chart.Period()==tf_int[i])
|
||||
m_button_tf[i].State(true);
|
||||
m_button_tf[i].Description(tf_str[i]);
|
||||
m_button_tf[i].Color(Blue);
|
||||
m_button_tf[i].FontSize(8);
|
||||
m_panel[4].Attach(m_button_tf[i]);
|
||||
}
|
||||
//--- creation m_button_sym[]
|
||||
ArrayResize(m_button_sym,m_num_symbols);
|
||||
for(i=0;i<m_num_symbols;i++)
|
||||
{
|
||||
if((m_button_sym[i]=new CChartObjectButton)==NULL)
|
||||
return(false);
|
||||
m_button_sym[i].Create(m_chart.ChartId(),"ButtonS"+IntegerToString(i),0,20+60*(i%5),16*(i/5),60,16);
|
||||
m_button_sym[i].Description(SymbolName(i,true));
|
||||
if(m_chart.Symbol()==SymbolName(i,true))
|
||||
m_button_sym[i].State(true);
|
||||
m_button_sym[i].Color(Green);
|
||||
m_button_sym[i].FontSize(8);
|
||||
m_panel[5].Attach(m_button_sym[i]);
|
||||
}
|
||||
//--- initial installation of the objects
|
||||
m_button[0].State(true);
|
||||
m_button[1].State(false);
|
||||
m_button[2].State(false);
|
||||
m_button[3].State(m_chart.AutoScroll());
|
||||
m_button[4].State(m_chart.Shift());
|
||||
m_button[5].State(m_chart.Foreground());
|
||||
m_button[6].State(false);
|
||||
m_button[7].State(false);
|
||||
m_button[8].State(m_chart.ScaleFix());
|
||||
m_button[9].State(m_chart.ScaleFix_11());
|
||||
m_button[10].State(false);
|
||||
m_button[11].State(false);
|
||||
m_button[12].State(false);
|
||||
m_button[13].State(false);
|
||||
m_button[14].State(m_chart.ScalePPB());
|
||||
m_button[15].State(m_chart.ShowOHLC());
|
||||
m_button[16].State(m_chart.ShowLineBid());
|
||||
m_button[17].State(m_chart.ShowLineAsk());
|
||||
m_button[18].State(m_chart.ShowLastLine());
|
||||
m_button[19].State(m_chart.ShowPeriodSep());
|
||||
m_button[20].State(m_chart.ShowGrid());
|
||||
m_button[21].State(m_chart.ShowObjectDescr());
|
||||
m_button[22].State(false);
|
||||
//--- initial installation of the chart
|
||||
if(m_chart.Shift())
|
||||
m_edit[0].Description(DoubleToString(m_chart.ShiftSize()));
|
||||
else
|
||||
m_edit[0].Description("");
|
||||
m_edit[1].Description(IntegerToString(m_chart.Scale()));
|
||||
m_edit[2].Description(m_edit[0].Description());
|
||||
m_edit[3].Description(m_edit[1].Description());
|
||||
if(m_chart.ScaleFix())
|
||||
{
|
||||
m_edit[4].Description(DoubleToString(m_chart.PriceMax(0),4));
|
||||
m_edit[5].Description(DoubleToString(m_chart.PriceMin(0),4));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_edit[4].Description("");
|
||||
m_edit[5].Description("");
|
||||
}
|
||||
if(m_chart.ScalePPB())
|
||||
m_edit[6].Description(DoubleToString(m_chart.PointsPerBar(),4));
|
||||
else
|
||||
m_edit[6].Description("");
|
||||
//--- tune m_panel[]
|
||||
sy=16;
|
||||
for(i=0;i<NUM_PANELS;i++)
|
||||
{
|
||||
m_panel[i].Y_Distance(sy);
|
||||
sy+=m_panel[i].Y_Size();
|
||||
}
|
||||
//--- redraw chart
|
||||
m_chart.Redraw();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Deinit. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Processing. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CChartSample::Processing(void)
|
||||
{
|
||||
int i;
|
||||
int sy=0;
|
||||
//---
|
||||
for(i=0;i<NUM_PANELS;i++)
|
||||
if(m_panel[i].CheckState())
|
||||
{
|
||||
sy=m_panel[i].Y_Distance()+m_panel[i].Y_Size();
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
for(;i<NUM_PANELS;i++)
|
||||
{
|
||||
m_panel[i].Y_Distance(sy);
|
||||
sy+=m_panel[i].Y_Size();
|
||||
}
|
||||
CheckPanelModes();
|
||||
CheckPanelAnothers();
|
||||
CheckPanelScales();
|
||||
CheckPanelShows();
|
||||
CheckPanelTimeframes();
|
||||
CheckPanelSymbols();
|
||||
CheckPanelColors();
|
||||
CheckPanelReadOnly();
|
||||
//--- chart redrawn (with the processing of events)
|
||||
m_chart.Redraw();
|
||||
Sleep(50);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(ExtScript.Init())
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
ExtScript.Processing();
|
||||
}
|
||||
//--- call deinit function
|
||||
ExtScript.Deinit();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,187 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sphere.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Arrays\ArrayObj.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSphere. |
|
||||
//| Appointment: Class of the graphical object "Sphere". |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSphere : public CArrayObj
|
||||
{
|
||||
private:
|
||||
int m_id; // sphere idintifier
|
||||
color m_color; // sphere color
|
||||
int m_num_parallel; // number of parallels
|
||||
int m_num_meridian; // number of meridians
|
||||
int m_radius; // sphere radius in pixels
|
||||
int m_center_X; // coordinate of the center X
|
||||
int m_center_Y; // coordinate of the center Y
|
||||
CSphere *m_orbite_center; // "sun"
|
||||
double m_orbite_radius; // orbital radius
|
||||
double m_orbite_fi_X; // angle of inclination to the axis X
|
||||
double m_orbite_fi_Y; // angle of inclination to the axis Y
|
||||
double m_orbite_fi_Z; // angle of inclination to the axis Z
|
||||
double m_d_fi_orb; // angular velocity of the orbit
|
||||
//--- working variables
|
||||
double m_fi_orb;
|
||||
double m_fi_x;
|
||||
double m_fi_y;
|
||||
double m_fi_z;
|
||||
|
||||
public:
|
||||
CSphere(void);
|
||||
~CSphere(void);
|
||||
//--- methods of access to protected data
|
||||
int CenterX(void) const { return(m_center_X); }
|
||||
int CenterY(void) const { return(m_center_Y); }
|
||||
//---
|
||||
bool Create(const int id,const color c,const int x,const int y,const int r,const int p,const int m,const string str);
|
||||
void SetOrbite(CSphere *sun,const double fi_x,const double fi_y,const double fi_z,const double d_fi_orb);
|
||||
void Recalculate(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSphere::CSphere(void) : m_id(0),
|
||||
m_color(0),
|
||||
m_num_parallel(0),
|
||||
m_num_meridian(0),
|
||||
m_radius(0),
|
||||
m_center_X(0),
|
||||
m_center_Y(0),
|
||||
m_orbite_center(NULL),
|
||||
m_orbite_radius(0.0),
|
||||
m_orbite_fi_X(0.0),
|
||||
m_orbite_fi_Y(0.0),
|
||||
m_orbite_fi_Z(0.0),
|
||||
m_d_fi_orb(0.0),
|
||||
m_fi_orb(0.0),
|
||||
m_fi_x(0.0),
|
||||
m_fi_y(0.0),
|
||||
m_fi_z(0.0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSphere::~CSphere(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSphere::Create(const int id,const color c,const int x,const int y,const int r,const int p,const int m,const string str)
|
||||
{
|
||||
CArrayObj *arr;
|
||||
CChartObjectLabel *label;
|
||||
//---
|
||||
m_id=id;
|
||||
m_color =c;
|
||||
m_num_parallel=(p>r/3) ? r/3 : p;
|
||||
m_num_meridian=(m>r/3) ? r/3 : m;
|
||||
m_radius =r;
|
||||
m_center_X =x;
|
||||
m_center_Y =y;
|
||||
if(!Reserve(p)) return(false);
|
||||
//--- loop parallels
|
||||
for(int i=0;i<p;i++)
|
||||
{
|
||||
arr=new CArrayObj;
|
||||
if(arr==NULL)
|
||||
return(false);
|
||||
if(!arr.Reserve(m))
|
||||
return(false);
|
||||
//--- loop meridians
|
||||
for(int j=0;j<m;j++)
|
||||
{
|
||||
label=new CChartObjectLabel;
|
||||
if(label==NULL)
|
||||
return(false);
|
||||
label.Create(0,"ar"+string(id)+"_"+string(j)+"_"+string(i),0,0,0);
|
||||
label.Color(m_color);
|
||||
label.Description(str);
|
||||
arr.Add(label);
|
||||
}
|
||||
Add(arr);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Setting |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSphere::SetOrbite(CSphere *sun,const double fi_x,const double fi_y,const double fi_z,const double d_fi_orb)
|
||||
{
|
||||
m_orbite_center=sun;
|
||||
m_orbite_fi_X=fi_x;
|
||||
m_orbite_fi_Y=fi_y;
|
||||
m_d_fi_orb=d_fi_orb;
|
||||
m_orbite_fi_Z=fi_z;
|
||||
m_orbite_radius=MathSqrt(MathPow(m_center_X-m_orbite_center.CenterX(),2)+MathPow(m_center_Y-m_orbite_center.CenterY(),2))/2;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recalculation of the sphere. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSphere::Recalculate(void)
|
||||
{
|
||||
CArrayObj *arr;
|
||||
CChartObjectLabel *label;
|
||||
//---
|
||||
double d_fi_m,d_fi_p;
|
||||
double x,y,z;
|
||||
int i,q;
|
||||
double idx3=0;
|
||||
double idx4=0;
|
||||
//---
|
||||
d_fi_m=2*M_PI/m_num_meridian;
|
||||
d_fi_p=M_PI/m_num_parallel;
|
||||
//---
|
||||
idx3=idx4;
|
||||
if(m_orbite_center!=NULL)
|
||||
{
|
||||
//--- calculation of the coordinates of the dynamic center of the orbit
|
||||
m_fi_orb+=m_d_fi_orb;
|
||||
m_center_X=(int)(m_orbite_center.CenterX()+m_orbite_radius*(MathSin(m_fi_orb)+MathCos(m_orbite_fi_X)*MathSin(m_orbite_fi_Y)));
|
||||
m_center_Y=(int)(m_orbite_center.CenterY()+m_orbite_radius*(MathCos(m_fi_orb)+MathSin(m_orbite_fi_X)*MathCos(m_orbite_fi_Y)));
|
||||
}
|
||||
q=-m_num_parallel/2-1;
|
||||
//--- loop parallels
|
||||
for(int j=0;j<m_num_parallel;j++)
|
||||
{
|
||||
q++;
|
||||
arr=At(j);
|
||||
//--- loop meridians
|
||||
for(i=0;i<m_num_meridian;i++)
|
||||
{
|
||||
//--- calculation of the coordinates of the point of excluding traffic
|
||||
x=m_radius*MathSin(d_fi_m*i)*MathCos(d_fi_p*q);
|
||||
y=m_radius*MathSin(d_fi_p*q);
|
||||
z=m_radius*MathCos(d_fi_m*i)*MathCos(d_fi_p*q);
|
||||
//--- recalculation of the coordinates of the point of view of traffic
|
||||
label=arr.At(i);
|
||||
label.X_Distance(m_center_X+x2d_(x,y,z,m_fi_x,m_fi_y,m_fi_z));
|
||||
label.Y_Distance(m_center_Y+y2d_(x,y,z,m_fi_x,m_fi_y,m_fi_z));
|
||||
}
|
||||
idx3=idx3+0.5*m_id;
|
||||
}
|
||||
//---
|
||||
m_fi_z=m_fi_z+MathSin(idx3*0.08)/32+MathCos(idx3*0.16)*0.01;
|
||||
m_fi_x=m_fi_x+MathCos(idx3*0.08)*0.016+MathCos(idx3*0.12)*0.008;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| auxiliary function |
|
||||
//+------------------------------------------------------------------+
|
||||
int x2d_(double x_,double y_,double z_,double fi_x_,double fi_y_,double fi_z_)
|
||||
{
|
||||
return((int)(x_*MathCos(fi_z_)+y_*MathSin(fi_z_)));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| auxiliary function |
|
||||
//+------------------------------------------------------------------+
|
||||
int y2d_(double x_,double y_,double z_,double fi_x_,double fi_y_,double fi_z_)
|
||||
{
|
||||
return((int)((-x_*MathSin(fi_z_)+y_*MathCos(fi_z_))*MathCos(fi_x_)+z_*MathSin(fi_x_)));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,81 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SphereSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include "Sphere.mqh"
|
||||
//---
|
||||
string ArrowChar="*";
|
||||
int SleepTime=50;
|
||||
//---
|
||||
#define NUM_SPHERES 5
|
||||
#define VISIBLE 0
|
||||
#define INVISIBLE 1
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to demonstrate the use of arrays. |
|
||||
//+------------------------------------------------------------------+
|
||||
CSphere Sphere[NUM_SPHERES];
|
||||
//--- arrays to initialize spheres
|
||||
int arrX[NUM_SPHERES]={100,100,300,500,500};
|
||||
int arrY[NUM_SPHERES]={100,500,300,500,350};
|
||||
int arrR[NUM_SPHERES]={30,40,100,60,20};
|
||||
int arrP[NUM_SPHERES]={10,13,30,20,7};
|
||||
int arrM[NUM_SPHERES]={10,13,30,20,7};
|
||||
color arrC[NUM_SPHERES]={Red,Blue,Yellow,Green,Gray};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int Init(void)
|
||||
{
|
||||
int i;
|
||||
//--- creating objects
|
||||
for(i=0;i<NUM_SPHERES;i++)
|
||||
if(!Sphere[i].Create(i,arrC[i],arrX[i],arrY[i],arrR[i],arrP[i],arrM[i],ArrowChar))
|
||||
break;
|
||||
if(i!=NUM_SPHERES)
|
||||
{
|
||||
printf("Error creating sphere %d",i);
|
||||
return(-1);
|
||||
}
|
||||
//--- configuring orbits
|
||||
Sphere[0].SetOrbite(GetPointer(Sphere[2]),M_PI/4,-M_PI/8,0,0.1);
|
||||
Sphere[1].SetOrbite(GetPointer(Sphere[2]),-M_PI/8,-M_PI/16,M_PI/8,0.02);
|
||||
Sphere[3].SetOrbite(GetPointer(Sphere[2]),M_PI/8,M_PI/4,M_PI/8,0.05);
|
||||
Sphere[4].SetOrbite(GetPointer(Sphere[3]),M_PI/4,M_PI/8,M_PI/8,0.1);
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(Init()==0)
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
{
|
||||
//--- öèêë ïî îáúåêòàì
|
||||
for(int i=0;i<NUM_SPHERES;i++)
|
||||
Sphere[i].Recalculate();
|
||||
ChartRedraw();
|
||||
Sleep(SleepTime);
|
||||
}
|
||||
}
|
||||
//--- call deinit function
|
||||
Deinit();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,217 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BitonicSort.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
//--- COpenCL class
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
#resource "Kernels/bitonicsort.cl" as string cl_program
|
||||
//+------------------------------------------------------------------+
|
||||
//| QuickSortAscending |
|
||||
//+------------------------------------------------------------------+
|
||||
//| The function sorts array[] QuickSort algorithm. |
|
||||
//| |
|
||||
//| Arguments: |
|
||||
//| array : Array with values to sort |
|
||||
//| first : First element index |
|
||||
//| last : Last element index |
|
||||
//| |
|
||||
//| Return value: None |
|
||||
//+------------------------------------------------------------------+
|
||||
void QuickSortAscending(double &array[],int first,int last)
|
||||
{
|
||||
int i,j;
|
||||
double p_double,t_double;
|
||||
if(first<0 || last<0)
|
||||
return;
|
||||
i=first;
|
||||
j=last;
|
||||
while(i<last)
|
||||
{
|
||||
p_double=array[(first+last)>>1];
|
||||
while(i<j)
|
||||
{
|
||||
while(array[i]<p_double)
|
||||
{
|
||||
if(i==ArraySize(array)-1)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
while(array[j]>p_double)
|
||||
{
|
||||
if(j==0)
|
||||
break;
|
||||
j--;
|
||||
}
|
||||
if(i<=j)
|
||||
{
|
||||
//-- swap elements i and j
|
||||
t_double=array[i];
|
||||
array[i]=array[j];
|
||||
array[j]=t_double;
|
||||
i++;
|
||||
if(j==0)
|
||||
break;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
if(first<j)
|
||||
QuickSortAscending(array,first,j);
|
||||
first=i;
|
||||
j=last;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| QuickSort_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool QuickSort_CPU(double &data_array[],ulong &time_cpu)
|
||||
{
|
||||
int data_count=ArraySize(data_array);
|
||||
if(data_count<=1)
|
||||
return(false);
|
||||
//--- sort values on CPU
|
||||
time_cpu=GetMicrosecondCount();
|
||||
QuickSortAscending(data_array,0,data_count-1);
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu)/1000);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| BitonicSort_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool BitonicSort_GPU(COpenCL &OpenCL,double &data_array[],ulong &time_gpu)
|
||||
{
|
||||
int data_count=ArraySize(data_array);
|
||||
if(data_count<=1)
|
||||
return(false);
|
||||
//--- check support working with double
|
||||
if(!OpenCL.SupportDouble())
|
||||
{
|
||||
PrintFormat("Working with double (cl_khr_fp64) is not supported on the device.");
|
||||
return(false);
|
||||
}
|
||||
OpenCL.SetKernelsCount(1);
|
||||
OpenCL.KernelCreate(0,"BitonicSort_GPU");
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(1);
|
||||
if(!OpenCL.BufferFromArray(0,data_array,0,data_count,CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
OpenCL.SetArgumentBuffer(0,0,0);
|
||||
//---
|
||||
uint work_offset[1]={0};
|
||||
uint global_size[1];
|
||||
global_size[0]=data_count>>1;
|
||||
//---
|
||||
uint passes_total=0;
|
||||
uint stages_total=0;
|
||||
//---
|
||||
for(uint temp=data_count; temp>1; temp>>=1)
|
||||
stages_total++;
|
||||
//--- GPU calculation start
|
||||
time_gpu=GetMicrosecondCount();
|
||||
for(uint stage=0; stage<stages_total; stage++)
|
||||
{
|
||||
//--- set stage of the algorithm
|
||||
OpenCL.SetArgument(0,1,stage);
|
||||
for(uint pass=0; pass<stage+1; pass++)
|
||||
{
|
||||
//--- set pass of the current stage
|
||||
OpenCL.SetArgument(0,2,pass);
|
||||
//--- execute kernel
|
||||
if(!OpenCL.Execute(0,1,work_offset,global_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
passes_total++;
|
||||
}
|
||||
}
|
||||
//---
|
||||
if(!OpenCL.BufferRead(0,data_array,0,0,data_count))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for data array C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finish
|
||||
time_gpu=ulong((GetMicrosecondCount()-time_gpu)/1000);
|
||||
PrintFormat("Bitonic sort finished. Total stages=%d, total passes=%d",stages_total,passes_total);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareDataArray |
|
||||
//+------------------------------------------------------------------+
|
||||
bool PrepareDataArray(long global_memory_size,double &data[],int &data_count)
|
||||
{
|
||||
int pwr_max=(int)(MathLog(global_memory_size/sizeof(float))/MathLog(2));
|
||||
int pwr=(int)MathMax(15,pwr_max-4);
|
||||
data_count=(int)MathPow(2,pwr);
|
||||
//--- prepare array and generate random data
|
||||
if(ArrayResize(data,data_count)<data_count)
|
||||
{
|
||||
Print("Error in ArrayResize. Error code=",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
for(int i=0; i<data_count; i++)
|
||||
data[i]=(double)(100000000*MathRand()/32767.0);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//--- OpenCL
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
long global_memory_size=0;
|
||||
if(!OpenCL.GetGlobalMemorySize(global_memory_size))
|
||||
{
|
||||
Print("Error in request of global memory size. Error code=",GetLastError());
|
||||
return;
|
||||
}
|
||||
double data_cpu[];
|
||||
int data_count;
|
||||
//--- prepare array with random values
|
||||
if(PrepareDataArray(global_memory_size,data_cpu,data_count)==false)
|
||||
return;
|
||||
//--- copy array values for sorting on GPU
|
||||
double data_gpu[];
|
||||
if(ArrayCopy(data_gpu,data_cpu,0,0,data_count)!=data_count)
|
||||
return;
|
||||
//--- Quick sort values using CPU
|
||||
ulong time_cpu=0;
|
||||
if(!QuickSort_CPU(data_cpu,time_cpu))
|
||||
return;
|
||||
//--- Bitonic sort values using GPU
|
||||
ulong time_gpu=0;
|
||||
if(!BitonicSort_GPU(OpenCL,data_gpu,time_gpu))
|
||||
return;
|
||||
//--- remove OpenCL objects
|
||||
OpenCL.Shutdown();
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
PrintFormat("time CPU=%d ms, time GPU =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- check calculations
|
||||
double total_error=0;
|
||||
for(int i=0; i<data_count; i++)
|
||||
{
|
||||
total_error+=MathAbs(data_gpu[i]-data_cpu[i]);
|
||||
}
|
||||
PrintFormat("Total error = %f",total_error);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,311 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
#include <Math/Stat/Math.mqh>
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
|
||||
#resource "Kernels/fft.cl" as string cl_program
|
||||
#define kernel_init "fft_init"
|
||||
#define kernel_stage "fft_stage"
|
||||
#define kernel_scale "fft_scale"
|
||||
#define NUM_POINTS 16384
|
||||
#define FFT_DIRECTION 1
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fast Fourier transform and its inverse (both recursively) |
|
||||
//| Copyright (C) 2004, Jerome R. Breitenbach. All rights reserved. |
|
||||
//| Reference: |
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recursive direct FFT transform |
|
||||
//+------------------------------------------------------------------+
|
||||
void fft(const int N,double &x_real[],double &x_imag[],double &X_real[],double &X_imag[])
|
||||
{
|
||||
//--- prepare temporary arrays
|
||||
double XX_real[],XX_imag[];
|
||||
ArrayResize(XX_real,N);
|
||||
ArrayResize(XX_imag,N);
|
||||
//--- calculate FFT by a recursion
|
||||
fft_rec(N,0,1,x_real,x_imag,X_real,X_imag,XX_real,XX_imag);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recursive inverse FFT transform |
|
||||
//+------------------------------------------------------------------+
|
||||
void ifft(const int N,double &x_real[],double &x_imag[],double &X_real[],double &X_imag[])
|
||||
{
|
||||
int N2=N/2; // half the number of points in IFFT
|
||||
//--- calculate IFFT via reciprocity property of DFT
|
||||
fft(N,X_real,X_imag,x_real,x_imag);
|
||||
x_real[0]=x_real[0]/N;
|
||||
x_imag[0]=x_imag[0]/N;
|
||||
x_real[N2]=x_real[N2]/N;
|
||||
x_imag[N2]=x_imag[N2]/N;
|
||||
for(int i=1; i<N2; i++)
|
||||
{
|
||||
double tmp0=x_real[i]/N;
|
||||
double tmp1=x_imag[i]/N;
|
||||
x_real[i]=x_real[N-i]/N;
|
||||
x_imag[i]=x_imag[N-i]/N;
|
||||
x_real[N-i]=tmp0;
|
||||
x_imag[N-i]=tmp1;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT recursion |
|
||||
//+------------------------------------------------------------------+
|
||||
void fft_rec(const int N,const int offset,const int delta,double &x_real[],double &x_imag[],double &X_real[],double &X_imag[],double &XX_real[],double &XX_imag[])
|
||||
{
|
||||
static const double TWO_PI=(double)(2*M_PI);
|
||||
int N2=N/2; // half the number of points in FFT
|
||||
int k00,k01,k10,k11; // indices for butterflies
|
||||
if(N!=2)
|
||||
{
|
||||
//--- perform recursive step
|
||||
//--- calculate two (N/2)-point DFT's
|
||||
fft_rec(N2,offset,2*delta,x_real,x_imag,XX_real,XX_imag,X_real,X_imag);
|
||||
fft_rec(N2,offset+delta,2*delta,x_real,x_imag,XX_real,XX_imag,X_real,X_imag);
|
||||
//--- combine the two (N/2)-point DFT's into one N-point DFT
|
||||
for(int k=0; k<N2; k++)
|
||||
{
|
||||
k00 = offset + k*delta;
|
||||
k01 = k00 + N2*delta;
|
||||
k10 = offset + 2*k*delta;
|
||||
k11 = k10 + delta;
|
||||
double cs=(double)MathCos(TWO_PI*k/(double)N);
|
||||
double sn=(double)MathSin(TWO_PI*k/(double)N);
|
||||
double tmp0 = cs*XX_real[k11] + sn*XX_imag[k11];
|
||||
double tmp1 = cs*XX_imag[k11] - sn*XX_real[k11];
|
||||
X_real[k01] = XX_real[k10] - tmp0;
|
||||
X_imag[k01] = XX_imag[k10] - tmp1;
|
||||
X_real[k00] = XX_real[k10] + tmp0;
|
||||
X_imag[k00] = XX_imag[k10] + tmp1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- perform 2-point DFT
|
||||
k00=offset;
|
||||
k01=k00+delta;
|
||||
X_real[k01] = x_real[k00] - x_real[k01];
|
||||
X_imag[k01] = x_imag[k00] - x_imag[k01];
|
||||
X_real[k00] = x_real[k00] + x_real[k01];
|
||||
X_imag[k00] = x_imag[k00] + x_imag[k01];
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool FFT_CPU(int direction,int power,double &data_real[],double &data_imag[],ulong &time_cpu)
|
||||
{
|
||||
//--- calculate the number of points
|
||||
int N=1;
|
||||
for(int i=0;i<power;i++)
|
||||
N*=2;
|
||||
//---prepare temporary arrays
|
||||
double XX_real[],XX_imag[];
|
||||
ArrayResize(XX_real,N);
|
||||
ArrayResize(XX_imag,N);
|
||||
//--- CPU calculation start
|
||||
time_cpu=GetMicrosecondCount();
|
||||
if(direction>0)
|
||||
fft(N,data_real,data_imag,XX_real,XX_imag);
|
||||
else
|
||||
ifft(N,XX_real,XX_imag,data_real,data_imag);
|
||||
//--- CPU calculation finished
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu));
|
||||
//--- copy calculated data
|
||||
ArrayCopy(data_real,XX_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(data_imag,XX_imag,0,0,WHOLE_ARRAY);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool FFT_GPU(int direction,int power,double &data_real[],double &data_imag[],ulong &time_gpu)
|
||||
{
|
||||
//--- calculate the number of points
|
||||
int num_points=1;
|
||||
for(int i=0;i<power;i++)
|
||||
num_points*=2;
|
||||
//--- prepare data array for GPU calculation
|
||||
double data[];
|
||||
ArrayResize(data,2*num_points);
|
||||
for(int i=0; i<num_points; i++)
|
||||
{
|
||||
data[2*i]=data_real[i];
|
||||
data[2*i+1]=data_imag[i];
|
||||
}
|
||||
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- check support working with double
|
||||
if(!OpenCL.SupportDouble())
|
||||
{
|
||||
PrintFormat("Working with double (cl_khr_fp64) is not supported on the device.");
|
||||
return(false);
|
||||
}
|
||||
//--- create kernels
|
||||
OpenCL.SetKernelsCount(3);
|
||||
OpenCL.KernelCreate(0,kernel_init);
|
||||
OpenCL.KernelCreate(1,kernel_stage);
|
||||
OpenCL.KernelCreate(2,kernel_scale);
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(2);
|
||||
if(!OpenCL.BufferFromArray(0,data,0,2*num_points,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for input buffer. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferCreate(1,2*num_points*sizeof(double),CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for data buffer. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- determine maximum work-group size
|
||||
int local_size=(int)CLGetInfoInteger(OpenCL.GetKernel(0),CL_KERNEL_WORK_GROUP_SIZE);
|
||||
//--- determine local memory size
|
||||
uint local_mem_size=(uint)CLGetInfoInteger(OpenCL.GetContext(),CL_DEVICE_LOCAL_MEM_SIZE);
|
||||
int points_per_group=(int)local_mem_size/(2*sizeof(double));
|
||||
if(points_per_group>num_points)
|
||||
points_per_group=num_points;
|
||||
//--- set kernel arguments
|
||||
OpenCL.SetArgumentBuffer(0,0,0);
|
||||
OpenCL.SetArgumentBuffer(0,1,1);
|
||||
OpenCL.SetArgumentLocalMemory(0,2,local_mem_size);
|
||||
OpenCL.SetArgument(0,3,points_per_group);
|
||||
OpenCL.SetArgument(0,4,num_points);
|
||||
OpenCL.SetArgument(0,5,direction);
|
||||
//--- OpenCL execute settings
|
||||
int task_dimension=1;
|
||||
uint global_size=(uint)((num_points/points_per_group)*local_size);
|
||||
uint global_work_offset[1]={0};
|
||||
uint global_work_size[1];
|
||||
global_work_size[0]=global_size;
|
||||
uint local_work_size[1];
|
||||
local_work_size[0]=local_size;
|
||||
//--- GPU calculation start
|
||||
time_gpu=GetMicrosecondCount();
|
||||
//-- execute kernel fft_init
|
||||
if(!OpenCL.Execute(0,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_init: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//-- further stages of the FFT
|
||||
if(num_points>points_per_group)
|
||||
{
|
||||
//--- set arguments for kernel 1
|
||||
OpenCL.SetArgumentBuffer(1,0,1);
|
||||
OpenCL.SetArgument(1,2,points_per_group);
|
||||
OpenCL.SetArgument(1,3,direction);
|
||||
for(int stage=2; stage<=num_points/points_per_group; stage<<=1)
|
||||
{
|
||||
OpenCL.SetArgument(1,1,stage);
|
||||
//-- execute kernel fft_stage
|
||||
if(!OpenCL.Execute(1,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_stage: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- scale values if performing the inverse FFT
|
||||
if(direction<0)
|
||||
{
|
||||
OpenCL.SetArgumentBuffer(2,0,1);
|
||||
OpenCL.SetArgument(2,1,points_per_group);
|
||||
OpenCL.SetArgument(2,2,num_points);
|
||||
//-- execute kernel fft_scale
|
||||
if(!OpenCL.Execute(2,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_scale: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- read the results from GPU memory
|
||||
if(!OpenCL.BufferRead(1,data,0,0,2*num_points))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for data_buffer2. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time_gpu=ulong((GetMicrosecondCount()-time_gpu));
|
||||
//--- copy calculated data and release OpenCL handles
|
||||
for(int i=0; i<num_points; i++)
|
||||
{
|
||||
data_real[i]=data[2*i];
|
||||
data_imag[i]=data[2*i+1];
|
||||
}
|
||||
OpenCL.Shutdown();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
int datacount=NUM_POINTS;
|
||||
int power=(int)(MathLog(NUM_POINTS)/M_LN2);
|
||||
if(MathPow(2,power)!=datacount)
|
||||
{
|
||||
PrintFormat("Number of elements must be power of 2. Elements: %d",datacount);
|
||||
return;
|
||||
}
|
||||
//--- prepare data for FFT calculation
|
||||
double data_real[],data_imag[];
|
||||
ArrayResize(data_real,datacount);
|
||||
ArrayResize(data_imag,datacount);
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
data_real[i]=(double)i;
|
||||
data_imag[i]=0;
|
||||
}
|
||||
int direction=FFT_DIRECTION;
|
||||
//--- data arrays for CPU calculation
|
||||
double CPU_real[],CPU_imag[];
|
||||
ArrayCopy(CPU_real,data_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(CPU_imag,data_imag,0,0,WHOLE_ARRAY);
|
||||
ulong time_cpu=0;
|
||||
//--- calculate FFT using CPU
|
||||
FFT_CPU(direction,power,CPU_real,CPU_imag,time_cpu);
|
||||
|
||||
//--- data arrays for GPU calculation
|
||||
double GPU_real[],GPU_imag[];
|
||||
ArrayCopy(GPU_real,data_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(GPU_imag,data_imag,0,0,WHOLE_ARRAY);
|
||||
ulong time_gpu=0;
|
||||
//--- calculate FFT using GPU
|
||||
if(!FFT_GPU(direction,power,GPU_real,GPU_imag,time_gpu))
|
||||
{
|
||||
PrintFormat("Error in calculation FFT on GPU.");
|
||||
return;
|
||||
}
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
PrintFormat("FFT calculation for %d points.",datacount);
|
||||
PrintFormat("time CPU=%d microseconds, time GPU =%d microseconds, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- determine average error
|
||||
double average_error=0.0;
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
average_error += MathAbs(CPU_real[i]-GPU_real[i]);
|
||||
average_error += MathAbs(CPU_imag[i]-GPU_imag[i]);
|
||||
}
|
||||
average_error=average_error/(datacount*2);
|
||||
PrintFormat("Average error = %f",average_error);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,31 @@
|
||||
//--- by default some GPU doesn't support doubles
|
||||
//--- cl_khr_fp64 directive is used to enable work with doubles
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel |
|
||||
//| The bitonic sort kernel does an ascending sort. |
|
||||
//+-----------------------------------------------------------+
|
||||
//| R. Banger,K. Bhattacharyya, OpenCL Programming by Example:|
|
||||
//| A comprehensive guide on OpenCL programming with examples |
|
||||
//| PACKT Publishing, 2013. |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void BitonicSort_GPU(__global double *data,const uint stage,const uint pass)
|
||||
{
|
||||
uint id=get_global_id(0);
|
||||
uint distance = 1<<(stage-pass);
|
||||
uint left_id =(id &(distance-1));
|
||||
left_id+=(id>>(stage-pass))*(distance<<1);
|
||||
uint right_id=left_id+distance;
|
||||
double left_value=data[left_id];
|
||||
double right_value=data[right_id];
|
||||
uint same_direction=(id>>stage)&0x1;
|
||||
uint temp = same_direction?right_id:temp;
|
||||
right_id = same_direction?left_id:right_id;
|
||||
left_id = same_direction?temp:left_id;
|
||||
int compare_res=(left_value<right_value);
|
||||
double greater = compare_res?right_value:left_value;
|
||||
double lesser = compare_res?left_value:right_value;
|
||||
data[left_id] = lesser;
|
||||
data[right_id]= greater;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,156 @@
|
||||
//--- by default some GPU doesn't support doubles
|
||||
//--- cl_khr_fp64 directive is used to enable work with doubles
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_init OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_init(__global double2 *in_data,
|
||||
__global double2 *out_data,
|
||||
__local double2 *l_data,
|
||||
uint points_per_group,uint size,int dir)
|
||||
{
|
||||
uint4 br,index;
|
||||
uint points_per_item,g_addr,l_addr,i,fft_index,stage,N2;
|
||||
double2 x1,x2,x3,x4,sum12,diff12,sum34,diff34;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
l_addr = get_local_id(0)*points_per_item;
|
||||
g_addr = get_group_id(0)*points_per_group + l_addr;
|
||||
//--- load data from bit-reversed addresses and perform 4-point FFTs
|
||||
for(i=0; i<points_per_item; i+=4)
|
||||
{
|
||||
index=(uint4)(g_addr,g_addr+1,g_addr+2,g_addr+3);
|
||||
fft_index=size/2;
|
||||
stage=1;
|
||||
N2 =(uint)log2((double)size)-1;
|
||||
br =(index<< N2) & fft_index;
|
||||
br|=(index>> N2) & stage;
|
||||
//--- bit-reverse addresses
|
||||
while(N2>1)
|
||||
{
|
||||
N2-=2;
|
||||
fft_index>>=1;
|
||||
stage<<=1;
|
||||
br |= (index << N2) & fft_index;
|
||||
br |= (index >> N2) & stage;
|
||||
}
|
||||
//--- load global data
|
||||
x1 = in_data[br.s0];
|
||||
x2 = in_data[br.s1];
|
||||
x3 = in_data[br.s2];
|
||||
x4 = in_data[br.s3];
|
||||
|
||||
sum12=x1+x2;
|
||||
diff12= x1-x2;
|
||||
sum34 = x3+x4;
|
||||
diff34=(double2)(x3.s1-x4.s1,x4.s0-x3.s0)*dir;
|
||||
l_data[l_addr]=sum12+sum34;
|
||||
l_data[l_addr+1] = diff12 + diff34;
|
||||
l_data[l_addr+2] = sum12 - sum34;
|
||||
l_data[l_addr+3] = diff12 - diff34;
|
||||
l_addr += 4;
|
||||
g_addr += 4;
|
||||
}
|
||||
//--- perform initial stages of the FFT - each of length N2*2
|
||||
for(N2=4; N2<points_per_item; N2<<=1)
|
||||
{
|
||||
l_addr=get_local_id(0)*points_per_item;
|
||||
for(fft_index=0; fft_index<points_per_item; fft_index+=2*N2)
|
||||
{
|
||||
x1=l_data[l_addr];
|
||||
l_data[l_addr]+=l_data[l_addr+N2];
|
||||
l_data[l_addr+N2]=x1-l_data[l_addr+N2];
|
||||
for(i=1; i<N2; i++)
|
||||
{
|
||||
x3.s0=cos(M_PI_F*i/N2);
|
||||
x3.s1=dir*sin(M_PI_F*i/N2);
|
||||
x2=(double2)(l_data[l_addr+N2+i].s0*x3.s0+l_data[l_addr+N2+i].s1*x3.s1,l_data[l_addr+N2+i].s1*x3.s0-l_data[l_addr+N2+i].s0*x3.s1);
|
||||
l_data[l_addr+N2+i]=l_data[l_addr+i]-x2;
|
||||
l_data[l_addr+i]+=x2;
|
||||
}
|
||||
l_addr+=2*N2;
|
||||
}
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
//--- perform FFT with other items in group - each of length N2*2
|
||||
stage=2;
|
||||
for(N2=points_per_item; N2<points_per_group; N2<<=1)
|
||||
{
|
||||
br.s0=(get_local_id(0)+(get_local_id(0)/stage)*stage) *(points_per_item/2);
|
||||
size = br.s0 % (N2*2);
|
||||
for(i=br.s0; i<br.s0+points_per_item/2; i++)
|
||||
{
|
||||
x3.s0=cos(M_PI_F*size/N2);
|
||||
x3.s1=dir*sin(M_PI_F*size/N2);
|
||||
x2=(double2)(l_data[N2+i].s0*x3.s0+l_data[N2+i].s1*x3.s1,l_data[N2+i].s1*x3.s0-l_data[N2+i].s0*x3.s1);
|
||||
l_data[N2+i]=l_data[i]-x2;
|
||||
l_data[i]+=x2;
|
||||
size++;
|
||||
}
|
||||
stage<<=1;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
//--- store results in global memory
|
||||
l_addr = get_local_id(0)*points_per_item;
|
||||
g_addr = get_group_id(0)*points_per_group + l_addr;
|
||||
for(i=0; i<points_per_item; i+=4)
|
||||
{
|
||||
out_data[g_addr]=l_data[l_addr];
|
||||
out_data[g_addr+1] = l_data[l_addr+1];
|
||||
out_data[g_addr+2] = l_data[l_addr+2];
|
||||
out_data[g_addr+3] = l_data[l_addr+3];
|
||||
g_addr += 4;
|
||||
l_addr += 4;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_stage OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_stage(__global double2 *g_data,uint stage,uint points_per_group,int dir)
|
||||
{
|
||||
uint points_per_item,addr,N,ang,i;
|
||||
double c,s;
|
||||
double2 input1,input2,w;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
addr=(get_group_id(0)+(get_group_id(0)/stage)*stage)*(points_per_group/2)+get_local_id(0)*(points_per_item/2);
|
||||
N=points_per_group*(stage/2);
|
||||
ang=addr%(N*2);
|
||||
|
||||
for(i=addr; i<addr+points_per_item/2; i++)
|
||||
{
|
||||
c = cos(M_PI_F*ang/N);
|
||||
s = dir*sin(M_PI_F*ang/N);
|
||||
input1 = g_data[i];
|
||||
input2 = g_data[i+N];
|
||||
w=(double2)(input2.s0*c+input2.s1*s,input2.s1*c-input2.s0*s);
|
||||
g_data[i]=input1+w;
|
||||
g_data[i+N]=input1-w;
|
||||
ang++;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_scale OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_scale(__global double2 *g_data,uint points_per_group,uint scale)
|
||||
{
|
||||
uint points_per_item,addr,i;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
addr=get_group_id(0)*points_per_group+get_local_id(0)*points_per_item;
|
||||
|
||||
for(i=addr; i<addr+points_per_item; i++)
|
||||
{
|
||||
g_data[i]/=scale;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,69 @@
|
||||
//--- by default some GPU doesn't support doubles
|
||||
//--- cl_khr_fp64 directive is used to enable work with doubles
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel for matrix multiplication |
|
||||
//| using global work groups |
|
||||
//+-----------------------------------------------------------+
|
||||
//| http://gpgpu-computing4.blogspot.ru/2009/09/ |
|
||||
//| /matrix-multiplication-2-opencl.html |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void MatrixMult_GPU1(__global double *matrix_a,
|
||||
__global double *matrix_b,
|
||||
__global double *matrix_c,
|
||||
int rows_a,int cols_a,int cols_b)
|
||||
{
|
||||
int i=get_global_id(0);
|
||||
int j=get_global_id(1);
|
||||
double sum=0.0;
|
||||
for(int k=0; k<cols_a; k++)
|
||||
{
|
||||
sum+=matrix_a[cols_a*i+k]*matrix_b[cols_b*k+j];
|
||||
}
|
||||
matrix_c[cols_b*i+j]=sum;
|
||||
}
|
||||
#define BLOCK_SIZE 10
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel for matrix multiplication |
|
||||
//| using local groups with common local memory |
|
||||
//+-----------------------------------------------------------+
|
||||
//| http://gpgpu-computing4.blogspot.ru/2009/10/ |
|
||||
//| /matrix-multiplication-3-opencl.html |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void MatrixMult_GPU2(__global double *matrix_a,
|
||||
__global double *matrix_b,
|
||||
__global double *matrix_c,
|
||||
int rows_a,int cols_a,int cols_b)
|
||||
{
|
||||
int group_i=get_group_id(0);
|
||||
int group_j=get_group_id(1);
|
||||
|
||||
int i=get_local_id(0);
|
||||
int j=get_local_id(1);
|
||||
|
||||
int offset_b=BLOCK_SIZE*group_i;
|
||||
int offset_a_start=cols_a*BLOCK_SIZE*group_j;
|
||||
double sum=(float)0.0;
|
||||
|
||||
for(int offset_a=offset_a_start;
|
||||
offset_a<offset_a_start+cols_a;
|
||||
offset_a+=BLOCK_SIZE,
|
||||
offset_b+=BLOCK_SIZE*cols_b)
|
||||
{
|
||||
__local double submatrix_a[BLOCK_SIZE][BLOCK_SIZE];
|
||||
__local double submatrix_b[BLOCK_SIZE][BLOCK_SIZE];
|
||||
|
||||
submatrix_a[i][j]=matrix_a[offset_a+cols_a*i+j];
|
||||
submatrix_b[i][j]=matrix_b[offset_b+cols_b*i+j];
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
for(int k=0; k<BLOCK_SIZE; k++)
|
||||
sum+=submatrix_a[i][k]*submatrix_b[k][j];
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
int offset_c=BLOCK_SIZE*(cols_b*group_j+group_i);
|
||||
matrix_c[offset_c+cols_b*i+j]=sum;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,51 @@
|
||||
//--- by default some GPU doesn't support doubles
|
||||
//--- cl_khr_fp64 directive is used to enable work with doubles
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
//+------------------------------------------------------------------+
|
||||
//| Morlet wavelet function |
|
||||
//+------------------------------------------------------------------+
|
||||
double Morlet(const double t)
|
||||
{
|
||||
return exp(-t*t*0.5)*cos(M_2_PI*t);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| OpenCL kernel function |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void Wavelet_GPU(__global double *data,int datacount,int x_size,int y_size,__global double *result)
|
||||
{
|
||||
size_t i = get_global_id(0);
|
||||
size_t j = get_global_id(1);
|
||||
double a1=(double)10e-10;
|
||||
double a2=(double)15.0;
|
||||
double da=(a2-a1)/(double)y_size;
|
||||
double db=((double)datacount-(double)0.0)/x_size;
|
||||
double a=a1+j*da;
|
||||
double b=0+i*db;
|
||||
uint norm=1;
|
||||
double B=(double)1.0; //Morlet
|
||||
double B_inv=(double)1.0/B;
|
||||
double a_inv=(double)1.0/a;
|
||||
double dt=(double)1.0;
|
||||
double coef=(double)0.0;
|
||||
if(norm==0)
|
||||
coef=sqrt(a_inv);
|
||||
else
|
||||
{
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
double arg=(dt*k-b)*a_inv;
|
||||
arg=-B_inv*arg*arg;
|
||||
coef=coef+exp(arg);
|
||||
}
|
||||
}
|
||||
double sum=(float)0.0;
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
double arg=(dt*k-b)*a_inv;
|
||||
sum+=data[k]*Morlet(arg);
|
||||
}
|
||||
sum=sum/coef;
|
||||
uint pos=(int)(j*x_size+i);
|
||||
result[pos]=sum;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,225 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
//--- OpenCL kernels
|
||||
#resource "Kernels/matrixmult.cl" as string cl_program
|
||||
#define BLOCK_SIZE 10
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool MatrixMult_CPU(const double &matrix_a[],const double &matrix_b[],double &matrix_c[],
|
||||
const int rows_a,const int cols_a,const int cols_b,ulong &time_cpu)
|
||||
{
|
||||
int size=rows_a*cols_b;
|
||||
if(ArrayResize(matrix_c,size)!=size)
|
||||
return(false);
|
||||
//--- CPU calculation started
|
||||
time_cpu=GetMicrosecondCount();
|
||||
for(int i=0; i<rows_a; i++)
|
||||
{
|
||||
for(int j=0; j<cols_b; j++)
|
||||
{
|
||||
double sum=0.0;
|
||||
for(int k=0; k<cols_a; k++)
|
||||
{
|
||||
sum+=matrix_a[cols_a*i+k]*matrix_b[cols_b*k+j];
|
||||
}
|
||||
matrix_c[cols_b*i+j]=sum;
|
||||
}
|
||||
}
|
||||
//--- CPU calculation finished
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu)/1000);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool MatrixMult_GPU(const double &matrix_a[],const double &matrix_b[],double &matrix1_c[],double &matrix2_c[],
|
||||
const int rows_a,const int cols_a,const int cols_b,const int size_a,const int size_b,
|
||||
const int size_c,ulong &time1_gpu,ulong &time2_gpu)
|
||||
{
|
||||
const int task_dimension=2;
|
||||
//--- prepare matrices for result
|
||||
if(ArrayResize(matrix1_c,size_c)!=size_c || ArrayResize(matrix2_c,size_c)!=size_c)
|
||||
return(false);
|
||||
ArrayFill(matrix1_c,0,size_c,(double)0.0);
|
||||
ArrayFill(matrix2_c,0,size_c,(double)0.0);
|
||||
//--- OpenCL
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- check support working with double
|
||||
if(!OpenCL.SupportDouble())
|
||||
{
|
||||
PrintFormat("Working with double (cl_khr_fp64) is not supported on the device.");
|
||||
return(false);
|
||||
}
|
||||
//--- create kernels
|
||||
OpenCL.SetKernelsCount(2);
|
||||
OpenCL.KernelCreate(0,"MatrixMult_GPU1");
|
||||
OpenCL.KernelCreate(1,"MatrixMult_GPU2");
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(3);
|
||||
//---
|
||||
if(!OpenCL.BufferFromArray(0,matrix_a,0,size_a,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for matrix A. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferFromArray(1,matrix_b,0,size_b,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for matrix B. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferCreate(2,size_c*sizeof(double),CL_MEM_WRITE_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for matrix C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- prepare arguments for kernel 0
|
||||
int kernel_index=0;
|
||||
OpenCL.SetArgumentBuffer(kernel_index,0,0);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,1,1);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,2,2);
|
||||
OpenCL.SetArgument(kernel_index,3,rows_a);
|
||||
OpenCL.SetArgument(kernel_index,4,cols_a);
|
||||
OpenCL.SetArgument(kernel_index,5,cols_b);
|
||||
//--- set task dimension a_rows x b_cols
|
||||
uint global_work_size[2];
|
||||
//--- set dimensions
|
||||
global_work_size[0]=rows_a;
|
||||
global_work_size[1]=cols_b;
|
||||
uint global_work_offset[2]={0,0};
|
||||
//--- GPU calculation start kernel 0
|
||||
time1_gpu=GetMicrosecondCount();
|
||||
if(!OpenCL.Execute(kernel_index,task_dimension,global_work_offset,global_work_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferRead(2,matrix1_c,0,0,size_c))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for matrix1 C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time1_gpu=ulong((GetMicrosecondCount()-time1_gpu)/1000);
|
||||
|
||||
//--- prepare arguments for kernel 1
|
||||
kernel_index=1;
|
||||
//--- set arguments
|
||||
OpenCL.SetArgumentBuffer(kernel_index,0,0);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,1,1);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,2,2);
|
||||
OpenCL.SetArgument(kernel_index,3,rows_a);
|
||||
OpenCL.SetArgument(kernel_index,4,cols_a);
|
||||
OpenCL.SetArgument(kernel_index,5,cols_b);
|
||||
uint local_work_size[2];
|
||||
local_work_size[0]=BLOCK_SIZE;
|
||||
local_work_size[1]=BLOCK_SIZE;
|
||||
//--- GPU calculation start, kernel1
|
||||
time2_gpu=GetMicrosecondCount();
|
||||
if(!OpenCL.Execute(kernel_index,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferRead(2,matrix2_c,0,0,size_c))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for matrix2 C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time2_gpu=ulong((GetMicrosecondCount()-time2_gpu)/1000);
|
||||
//--- remove OpenCL objects
|
||||
OpenCL.Shutdown();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//--- matrix A 1000x2000
|
||||
int rows_a=1000;
|
||||
int cols_a=2000;
|
||||
//--- matrix B 2000x1000
|
||||
int rows_b=cols_a;
|
||||
int cols_b=1000;
|
||||
//--- matrix C 1000x1000
|
||||
int rows_c=rows_a;
|
||||
int cols_c=cols_b;
|
||||
//--- matrix A: size=rows_a*cols_a
|
||||
int size_a=rows_a*cols_a;
|
||||
int size_b=rows_b*cols_b;
|
||||
int size_c=rows_c*cols_c;
|
||||
//--- prepare matrix A
|
||||
double matrix_a[];
|
||||
ArrayResize(matrix_a,rows_a*cols_a);
|
||||
for(int i=0; i<rows_a; i++)
|
||||
for(int j=0; j<cols_a; j++)
|
||||
{
|
||||
matrix_a[i*cols_a+j]=(double)(10*MathRand()/32767);
|
||||
}
|
||||
//--- prepare matrix B
|
||||
double matrix_b[];
|
||||
ArrayResize(matrix_b,rows_b*cols_b);
|
||||
for(int i=0; i<rows_b; i++)
|
||||
for(int j=0; j<cols_b; j++)
|
||||
{
|
||||
matrix_b[i*cols_b+j]=(double)(10*MathRand()/32767);
|
||||
}
|
||||
//--- CPU: calculate matrix product matrix_a*matrix_b
|
||||
double matrix_c_cpu[];
|
||||
ulong time_cpu=0;
|
||||
if(!MatrixMult_CPU(matrix_a,matrix_b,matrix_c_cpu,rows_a,cols_a,cols_b,time_cpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on CPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//--- calculate matrix product using GPU
|
||||
double matrix_c_gpu_method1[];
|
||||
double matrix_c_gpu_method2[];
|
||||
ulong time_gpu_method1=0;
|
||||
ulong time_gpu_method2=0;
|
||||
if(!MatrixMult_GPU(matrix_a,matrix_b,matrix_c_gpu_method1,matrix_c_gpu_method2,rows_a,cols_a,cols_b,size_a,size_b,size_c,time_gpu_method1,time_gpu_method2))
|
||||
{
|
||||
PrintFormat("Error in calculation on GPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio1=0;
|
||||
double CPU_GPU_ratio2=0;
|
||||
if(time_gpu_method1!=0)
|
||||
CPU_GPU_ratio1=1.0*time_cpu/time_gpu_method1;
|
||||
if(time_gpu_method2!=0)
|
||||
CPU_GPU_ratio2=1.0*time_cpu/time_gpu_method2;
|
||||
PrintFormat("time CPU=%d ms, time GPU global work groups =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu_method1,CPU_GPU_ratio1);
|
||||
PrintFormat("time CPU=%d ms, time GPU local work groups =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu_method2,CPU_GPU_ratio2);
|
||||
//--- check calculations
|
||||
double total_error1=0;
|
||||
double total_error2=0;
|
||||
for(int i=0; i<rows_c; i++)
|
||||
{
|
||||
for(int j=0; j<cols_c; j++)
|
||||
{
|
||||
int pos=cols_c*i+j;
|
||||
total_error1+=MathAbs(matrix_c_gpu_method1[pos]-matrix_c_cpu[pos]);
|
||||
total_error2+=MathAbs(matrix_c_gpu_method2[pos]-matrix_c_cpu[pos]);
|
||||
}
|
||||
}
|
||||
PrintFormat("Total error for method 1 = %f",total_error1);
|
||||
PrintFormat("Total error for method 2 = %f",total_error2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,419 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Wavelet.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
#include <Math/Stat/Math.mqh>
|
||||
#include <Graphics/Graphic.mqh>
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
|
||||
#define CPU_DATA 1
|
||||
#define GPU_DATA 2
|
||||
|
||||
#define SIZE_X 600
|
||||
#define SIZE_Y 200
|
||||
|
||||
#resource "Kernels/wavelet.cl" as string cl_program
|
||||
//+------------------------------------------------------------------+
|
||||
//| CWavelet |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWavelet
|
||||
{
|
||||
protected:
|
||||
int m_xsize;
|
||||
int m_ysize;
|
||||
int m_maxcolor;
|
||||
string m_res_name;
|
||||
string m_label_name;
|
||||
uchar m_palette[3*256];
|
||||
//---
|
||||
double m_data[];
|
||||
double m_wavelet_data_CPU[];
|
||||
double m_wavelet_data_GPU[];
|
||||
uint m_bmp_buffer[];
|
||||
|
||||
COpenCL m_OpenCL;
|
||||
|
||||
double Morlet(const double t);
|
||||
void ShowWaveletData(const double &m_wavelet_data[]);
|
||||
int GetPalColor(const int index);
|
||||
void Blend(const uint c1,const uint c2,const uint r1,const uint g1,const uint b1,const uint r2,const uint g2,const uint b2);
|
||||
bool WaveletCPU(const double &data[],const int datacount,const int x_size,const int y_size,const int i,const int j,const bool norm,double &result[]);
|
||||
public:
|
||||
//---
|
||||
void Create(const string name,const int x0,const int y0,const int x_size,const int y_size);
|
||||
bool CalculateWavelet_CPU(const double &data[],uint &time);
|
||||
bool CalculateWavelet_GPU(double &data[],uint &time);
|
||||
void ShowWavelet(const int mode);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Morlet wavelet function |
|
||||
//+------------------------------------------------------------------+
|
||||
double CWavelet::Morlet(const double t)
|
||||
{
|
||||
double v=t;
|
||||
double res=MathExp(-v*v*0.5)*MathCos(M_2_PI*v);
|
||||
return ((double)res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| GetPalColor |
|
||||
//+------------------------------------------------------------------+
|
||||
int CWavelet::GetPalColor(const int index)
|
||||
{
|
||||
int ind=index;
|
||||
if(ind<=0)
|
||||
ind=0;
|
||||
if(ind>255)
|
||||
ind=255;
|
||||
int idx=3*(ind);
|
||||
uchar r=m_palette[idx];
|
||||
uchar g=m_palette[idx+1];
|
||||
uchar b=m_palette[idx+2];
|
||||
//---
|
||||
return(b+256*g+65536*r);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gradient palette |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::Blend(const uint c1,const uint c2,const uint r1,const uint g1,const uint b1,const uint r2,const uint g2,const uint b2)
|
||||
{
|
||||
int n=int(c2-c1);
|
||||
for(int i=0; i<=n; i++)
|
||||
{
|
||||
if((c1+i+2)<ArraySize(m_palette))
|
||||
{
|
||||
m_palette[3*(c1+i)]=uchar(MathRound(1*(r1*(n-i)+r2*i)*1.0/n));
|
||||
m_palette[3*(c1+i)+1]=uchar(MathRound(1*(g1*(n-i)+g2*i)*1.0/n));
|
||||
m_palette[3*(c1+i)+2]=uchar(MathRound(1*(b1*(n-i)+b2*i)*1.0/n));
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::Create(const string name,const int x0,const int y0,const int x_size,const int y_size)
|
||||
{
|
||||
//---
|
||||
m_xsize=x_size;
|
||||
m_ysize=y_size;
|
||||
int size=m_xsize*m_ysize;
|
||||
ArrayResize(m_bmp_buffer,size);
|
||||
ArrayFill(m_bmp_buffer,0,size,0);
|
||||
ArrayResize(m_wavelet_data_CPU,size);
|
||||
ArrayResize(m_wavelet_data_GPU,size);
|
||||
ArrayFill(m_wavelet_data_CPU,0,size,0);
|
||||
ArrayFill(m_wavelet_data_GPU,0,size,0);
|
||||
m_res_name=name;
|
||||
m_label_name=m_res_name;
|
||||
StringToUpper(m_label_name);
|
||||
ResourceCreate(m_res_name,m_bmp_buffer,m_xsize,m_ysize,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);
|
||||
ObjectCreate(0,m_label_name,OBJ_BITMAP_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,m_label_name,OBJPROP_XDISTANCE,x0);
|
||||
ObjectSetInteger(0,m_label_name,OBJPROP_YDISTANCE,y0);
|
||||
ObjectSetString(0,m_label_name,OBJPROP_BMPFILE,NULL);
|
||||
ObjectSetString(0,m_label_name,OBJPROP_BMPFILE,"::"+m_label_name);
|
||||
//---
|
||||
m_maxcolor=100;
|
||||
Blend(0,20,0,0,95,0,0,246);
|
||||
Blend(21,40,0,0,246,0,236,226);
|
||||
Blend(41,60,0,236,226,226,246,0);
|
||||
Blend(61,80,226,246,0,226,0,0);
|
||||
Blend(81,100,226,0,0,123,0,0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| WaveletCPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::WaveletCPU(const double &data[],const int datacount,const int x_size,const int y_size,const int i,const int j,const bool norm,double &result[])
|
||||
{
|
||||
double a1=(double)10e-10;
|
||||
double a2=(double)15.0;
|
||||
double da=(double)(a2-a1)/y_size;
|
||||
double db=(double)(datacount-0)/x_size;
|
||||
int pos=j*x_size+i;
|
||||
//---
|
||||
double a=a1+j*da;
|
||||
double b=i*db;
|
||||
double B=(double)1.0; //Morlet
|
||||
double B_inv=(double)1.0/B;
|
||||
double a_inv=(double)1/a;
|
||||
double dt=(double)1.0;
|
||||
double coef=(double)0.0;
|
||||
if(!norm)
|
||||
coef=(double)MathSqrt(a_inv);
|
||||
else
|
||||
{
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
double arg=(dt*k-b)*a_inv;
|
||||
arg=-B_inv*arg*arg;
|
||||
coef+=(double)MathExp(arg);
|
||||
}
|
||||
}
|
||||
double sum=0.0;
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
double arg=(dt*k-b)*a_inv;
|
||||
sum+=data[k]*Morlet(arg);
|
||||
}
|
||||
sum/=coef;
|
||||
result[pos]=sum;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| CalculateWavelet_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::CalculateWavelet_CPU(const double &data[],uint &time)
|
||||
{
|
||||
time=GetTickCount();
|
||||
int datacount=ArraySize(data);
|
||||
ArrayCopy(m_data,data,0,0,WHOLE_ARRAY);
|
||||
for(int i=0; i<m_xsize; i++)
|
||||
{
|
||||
for(int j=0; j<m_ysize; j++)
|
||||
{
|
||||
WaveletCPU(m_data,datacount,m_xsize,m_ysize,i,j,true,m_wavelet_data_CPU);
|
||||
}
|
||||
}
|
||||
time=GetTickCount()-time;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| CalculateWavelet_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::CalculateWavelet_GPU(double &data[],uint &time)
|
||||
{
|
||||
int datacount=ArraySize(data);
|
||||
if(!m_OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- check support working with double
|
||||
if(!m_OpenCL.SupportDouble())
|
||||
{
|
||||
PrintFormat("Working with double (cl_khr_fp64) is not supported on the device.");
|
||||
return(false);
|
||||
}
|
||||
//---
|
||||
m_OpenCL.SetKernelsCount(1);
|
||||
m_OpenCL.KernelCreate(0,"Wavelet_GPU");
|
||||
//---
|
||||
m_OpenCL.SetBuffersCount(2);
|
||||
if(!m_OpenCL.BufferFromArray(0,data,0,datacount,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!m_OpenCL.BufferCreate(1,m_xsize*m_ysize*sizeof(double),CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
m_OpenCL.SetArgumentBuffer(0,0,0);
|
||||
m_OpenCL.SetArgumentBuffer(0,4,1);
|
||||
//---
|
||||
ArrayResize(m_wavelet_data_GPU,m_xsize*m_ysize);
|
||||
uint work[2];
|
||||
uint offset[2]={0,0};
|
||||
//--- set dimensions
|
||||
work[0]=m_xsize;
|
||||
work[1]=m_ysize;
|
||||
//--- set parameters and write data to buffer
|
||||
m_OpenCL.SetArgument(0,1,datacount);
|
||||
m_OpenCL.SetArgument(0,2,m_xsize);
|
||||
m_OpenCL.SetArgument(0,3,m_ysize);
|
||||
time=GetTickCount();
|
||||
//--- GPU calculation start
|
||||
if(!m_OpenCL.Execute(0,2,offset,work))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!m_OpenCL.BufferRead(1,m_wavelet_data_GPU,0,0,m_xsize*m_ysize))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for m_wavelet_data_GPU array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finish
|
||||
time=GetTickCount()-time;
|
||||
//---
|
||||
m_OpenCL.Shutdown();
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ShowWavelet |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::ShowWavelet(const int mode)
|
||||
{
|
||||
if(mode==CPU_DATA)
|
||||
ShowWaveletData(m_wavelet_data_CPU);
|
||||
else
|
||||
if(mode==GPU_DATA)
|
||||
ShowWaveletData(m_wavelet_data_GPU);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ShowWaveletData |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::ShowWaveletData(const double &m_wavelet_data[])
|
||||
{
|
||||
//--- calculate min/max and range
|
||||
int count=ArraySize(m_wavelet_data);
|
||||
double min_value=m_wavelet_data[0];
|
||||
double max_value=m_wavelet_data[0];
|
||||
for(int i=1; i<count; i++)
|
||||
{
|
||||
min_value=MathMin(min_value,m_wavelet_data[i]);
|
||||
max_value=MathMax(max_value,m_wavelet_data[i]);
|
||||
}
|
||||
double range=max_value-min_value;
|
||||
if(range>0)
|
||||
{
|
||||
for(int j=0; j<m_ysize; j++)
|
||||
{
|
||||
for(int i=0; i<m_xsize; i++)
|
||||
{
|
||||
int pos=j*m_xsize+i;
|
||||
int colindex=int(m_maxcolor*(m_wavelet_data[pos]-min_value)/range);
|
||||
m_bmp_buffer[pos]=GetPalColor(colindex);
|
||||
}
|
||||
}
|
||||
//--- show image
|
||||
ResourceCreate(m_res_name,m_bmp_buffer,m_xsize,m_ysize,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);
|
||||
ChartRedraw();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Weirstrass function |
|
||||
//+------------------------------------------------------------------+
|
||||
double Weirstrass(double x,double a,double b)
|
||||
{
|
||||
double sum=0.0;
|
||||
double b0=b;
|
||||
double a0=a;
|
||||
for(int n=0; n<35; n++)
|
||||
{
|
||||
double v=b0*(double)MathCos(a0*M_PI*x);
|
||||
sum=sum+v;
|
||||
a0=a0*a;
|
||||
b0=b0*b;
|
||||
}
|
||||
return(sum);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareModelData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PrepareModelData(double &price_data[],const int datacount)
|
||||
{
|
||||
ArrayResize(price_data,datacount);
|
||||
//--- Weirstrass function
|
||||
double x1=0;
|
||||
double x2=2;
|
||||
double dx=(x2-x1)/datacount;
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
price_data[i]=Weirstrass(x1+dx*i,(double)3,(double)0.62);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PreparePriceData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PreparePriceData(const string symbol,ENUM_TIMEFRAMES timeframe,double &price_data[],const int datacount)
|
||||
{
|
||||
ArrayResize(price_data,datacount);
|
||||
CopyClose(symbol,timeframe,0,datacount,price_data);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareMomentumData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PrepareMomentumData(double &price_data[],double &momentum_data[],const int momentum_period)
|
||||
{
|
||||
int size=ArraySize(price_data);
|
||||
int datacount=size-momentum_period;
|
||||
//---
|
||||
ArrayResize(momentum_data,datacount);
|
||||
for(int i=0; i<datacount; i+=1)
|
||||
{
|
||||
momentum_data[i]=price_data[i+momentum_period]-price_data[i];
|
||||
}
|
||||
ArrayCopy(price_data,price_data,momentum_period,0,datacount);
|
||||
ArrayResize(price_data,datacount);
|
||||
//--- rescale momentum data
|
||||
double min_value=momentum_data[0];
|
||||
double max_value=momentum_data[0];
|
||||
for(int i=1; i<datacount; i++)
|
||||
{
|
||||
double value=momentum_data[i];
|
||||
if(momentum_data[i]>max_value)
|
||||
max_value=value;
|
||||
|
||||
if(momentum_data[i]<min_value)
|
||||
min_value=value;
|
||||
}
|
||||
double range=max_value-min_value;
|
||||
for(int i=0; i<datacount; i+=1)
|
||||
momentum_data[i]=-1+2*(momentum_data[i]-min_value)/range;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//---
|
||||
int momentum_period=8;
|
||||
double price_data[];
|
||||
double momentum_data[];
|
||||
PrepareModelData(price_data,SIZE_X+momentum_period);
|
||||
//PreparePriceData("EURUSD",PERIOD_M1,price_data,SIZE_X+momentum_period);
|
||||
PrepareMomentumData(price_data,momentum_data,momentum_period);
|
||||
//---
|
||||
CGraphic graph_price;
|
||||
CGraphic graph_momentum;
|
||||
graph_price.Create(0,"price",0,0,0,SIZE_X+130+6,SIZE_Y);
|
||||
graph_price.XAxis().MaxGrace(0);
|
||||
graph_price.HistorySymbolSize(10);
|
||||
graph_price.CurveAdd(price_data,ColorToARGB(clrRed,255),CURVE_LINES,"Price");
|
||||
graph_price.CurvePlotAll();
|
||||
graph_price.Redraw(true);
|
||||
graph_price.Update();
|
||||
//---
|
||||
graph_momentum.Create(0,"momentum",0,0,SIZE_Y,SIZE_X+130+6,SIZE_Y+SIZE_Y);
|
||||
graph_momentum.XAxis().MaxGrace(0);
|
||||
graph_momentum.HistorySymbolSize(10);
|
||||
graph_momentum.CurveAdd(momentum_data,ColorToARGB(clrBlue,255),CURVE_LINES,"Momentum");
|
||||
graph_momentum.CurvePlotAll();
|
||||
graph_momentum.Redraw(true);
|
||||
graph_momentum.Update();
|
||||
//---
|
||||
CWavelet wavelet;
|
||||
//---
|
||||
uint time_cpu=0;
|
||||
wavelet.Create("Wavelet",50,2*SIZE_Y,SIZE_X,SIZE_Y);
|
||||
if(!wavelet.CalculateWavelet_CPU(momentum_data,time_cpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on CPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//wavelet.ShowWavelet(CPU_DATA);
|
||||
uint time_gpu=0;
|
||||
if(!wavelet.CalculateWavelet_GPU(momentum_data,time_gpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on GPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
wavelet.ShowWavelet(GPU_DATA);
|
||||
//---
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
//---
|
||||
PrintFormat("time CPU=%d ms, time GPU=%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- Sleep 10 seconds
|
||||
Sleep(10000);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,213 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| BitonicSort.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
//--- COpenCL class
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
#resource "Kernels/bitonicsort.cl" as string cl_program
|
||||
//+------------------------------------------------------------------+
|
||||
//| QuickSortAscending |
|
||||
//+------------------------------------------------------------------+
|
||||
//| The function sorts array[] QuickSort algorithm. |
|
||||
//| |
|
||||
//| Arguments: |
|
||||
//| array : Array with values to sort |
|
||||
//| first : First element index |
|
||||
//| last : Last element index |
|
||||
//| |
|
||||
//| Return value: None |
|
||||
//+------------------------------------------------------------------+
|
||||
void QuickSortAscending(float &array[],int first,int last)
|
||||
{
|
||||
int i,j;
|
||||
float p_float,t_float;
|
||||
if(first<0 || last<0)
|
||||
return;
|
||||
i=first;
|
||||
j=last;
|
||||
while(i<last)
|
||||
{
|
||||
p_float=array[(first+last)>>1];
|
||||
while(i<j)
|
||||
{
|
||||
while(array[i]<p_float)
|
||||
{
|
||||
if(i==ArraySize(array)-1)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
while(array[j]>p_float)
|
||||
{
|
||||
if(j==0)
|
||||
break;
|
||||
j--;
|
||||
}
|
||||
if(i<=j)
|
||||
{
|
||||
//-- swap elements i and j
|
||||
t_float=array[i];
|
||||
array[i]=array[j];
|
||||
array[j]=t_float;
|
||||
i++;
|
||||
if(j==0)
|
||||
break;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
if(first<j)
|
||||
QuickSortAscending(array,first,j);
|
||||
first=i;
|
||||
j=last;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| QuickSort_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool QuickSort_CPU(float &data_array[],ulong &time_cpu)
|
||||
{
|
||||
int data_count=ArraySize(data_array);
|
||||
if(data_count<=1)
|
||||
return(false);
|
||||
//--- sort values on CPU
|
||||
time_cpu=GetMicrosecondCount();
|
||||
QuickSortAscending(data_array,0,data_count-1);
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu)/1000);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| BitonicSort_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool BitonicSort_GPU(COpenCL &OpenCL,float &data_array[],ulong &time_gpu)
|
||||
{
|
||||
int data_count=ArraySize(data_array);
|
||||
if(data_count<=1)
|
||||
return(false);
|
||||
|
||||
OpenCL.SetKernelsCount(1);
|
||||
OpenCL.KernelCreate(0,"BitonicSort_GPU");
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(1);
|
||||
if(!OpenCL.BufferFromArray(0,data_array,0,data_count,CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
OpenCL.SetArgumentBuffer(0,0,0);
|
||||
//---
|
||||
uint work_offset[1]={0};
|
||||
uint global_size[1];
|
||||
global_size[0]=data_count>>1;
|
||||
//---
|
||||
uint passes_total=0;
|
||||
uint stages_total=0;
|
||||
//---
|
||||
for(uint temp=data_count; temp>1; temp>>=1)
|
||||
stages_total++;
|
||||
//--- GPU calculation start
|
||||
time_gpu=GetMicrosecondCount();
|
||||
for(uint stage=0; stage<stages_total; stage++)
|
||||
{
|
||||
//--- set stage of the algorithm
|
||||
OpenCL.SetArgument(0,1,stage);
|
||||
for(uint pass=0; pass<stage+1; pass++)
|
||||
{
|
||||
//--- set pass of the current stage
|
||||
OpenCL.SetArgument(0,2,pass);
|
||||
//--- execute kernel
|
||||
if(!OpenCL.Execute(0,1,work_offset,global_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
passes_total++;
|
||||
}
|
||||
}
|
||||
//---
|
||||
if(!OpenCL.BufferRead(0,data_array,0,0,data_count))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for data array C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finish
|
||||
time_gpu=ulong((GetMicrosecondCount()-time_gpu)/1000);
|
||||
PrintFormat("Bitonic sort finished. Total stages=%d, total passes=%d",stages_total,passes_total);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareDataArray |
|
||||
//+------------------------------------------------------------------+
|
||||
bool PrepareDataArray(ulong global_memory_size,float &data[],int &data_count)
|
||||
{
|
||||
int pwr_max=(int)(MathLog(global_memory_size/sizeof(float))/MathLog(2));
|
||||
int pwr=(int)MathMax(15,pwr_max-4);
|
||||
data_count=(int)MathPow(2,pwr);
|
||||
//--- prepare array and generate random data
|
||||
if(ArrayResize(data,data_count)<data_count)
|
||||
{
|
||||
Print("Error in ArrayResize. Error code=",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
for(int i=0; i<data_count; i++)
|
||||
data[i]=(float)(100000000*MathRand()/32767.0);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//--- OpenCL
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
long global_memory_size=0;
|
||||
if(!OpenCL.GetGlobalMemorySize(global_memory_size))
|
||||
{
|
||||
Print("Error in request of global memory size. Error code=",GetLastError());
|
||||
return;
|
||||
}
|
||||
float data_cpu[];
|
||||
int data_count;
|
||||
//--- prepare array with random values
|
||||
if(PrepareDataArray(global_memory_size,data_cpu,data_count)==false)
|
||||
return;
|
||||
//--- copy array values for sorting on GPU
|
||||
float data_gpu[];
|
||||
if(ArrayCopy(data_gpu,data_cpu,0,0,data_count)!=data_count)
|
||||
return;
|
||||
//--- Quick sort values using CPU
|
||||
ulong time_cpu=0;
|
||||
if(!QuickSort_CPU(data_cpu,time_cpu))
|
||||
return;
|
||||
//--- Bitonic sort values using GPU
|
||||
ulong time_gpu=0;
|
||||
if(!BitonicSort_GPU(OpenCL,data_gpu,time_gpu))
|
||||
return;
|
||||
//--- remove OpenCL objects
|
||||
OpenCL.Shutdown();
|
||||
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
PrintFormat("time CPU=%d ms, time GPU =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- check calculations
|
||||
float total_error=0;
|
||||
for(int i=0; i<data_count; i++)
|
||||
{
|
||||
total_error+=MathAbs(data_gpu[i]-data_cpu[i]);
|
||||
}
|
||||
PrintFormat("Total error = %f",total_error);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,306 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
#include <Math/Stat/Math.mqh>
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
|
||||
#resource "Kernels/fft.cl" as string cl_program
|
||||
#define kernel_init "fft_init"
|
||||
#define kernel_stage "fft_stage"
|
||||
#define kernel_scale "fft_scale"
|
||||
#define NUM_POINTS 16384
|
||||
#define FFT_DIRECTION 1
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fast Fourier transform and its inverse (both recursively) |
|
||||
//| Copyright (C) 2004, Jerome R. Breitenbach. All rights reserved. |
|
||||
//| Reference: |
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recursive direct FFT transform |
|
||||
//+------------------------------------------------------------------+
|
||||
void fft(const int N,float &x_real[],float &x_imag[],float &X_real[],float &X_imag[])
|
||||
{
|
||||
//--- prepare temporary arrays
|
||||
float XX_real[],XX_imag[];
|
||||
ArrayResize(XX_real,N);
|
||||
ArrayResize(XX_imag,N);
|
||||
//--- calculate FFT by a recursion
|
||||
fft_rec(N,0,1,x_real,x_imag,X_real,X_imag,XX_real,XX_imag);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Recursive inverse FFT transform |
|
||||
//+------------------------------------------------------------------+
|
||||
void ifft(const int N,float &x_real[],float &x_imag[],float &X_real[],float &X_imag[])
|
||||
{
|
||||
int N2=N/2; // half the number of points in IFFT
|
||||
//--- calculate IFFT via reciprocity property of DFT
|
||||
fft(N,X_real,X_imag,x_real,x_imag);
|
||||
x_real[0]=x_real[0]/N;
|
||||
x_imag[0]=x_imag[0]/N;
|
||||
x_real[N2]=x_real[N2]/N;
|
||||
x_imag[N2]=x_imag[N2]/N;
|
||||
for(int i=1; i<N2; i++)
|
||||
{
|
||||
float tmp0=x_real[i]/N;
|
||||
float tmp1=x_imag[i]/N;
|
||||
x_real[i]=x_real[N-i]/N;
|
||||
x_imag[i]=x_imag[N-i]/N;
|
||||
x_real[N-i]=tmp0;
|
||||
x_imag[N-i]=tmp1;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT recursion |
|
||||
//+------------------------------------------------------------------+
|
||||
void fft_rec(const int N,const int offset,const int delta,float &x_real[],float &x_imag[],float &X_real[],float &X_imag[],float &XX_real[],float &XX_imag[])
|
||||
{
|
||||
static const float TWO_PI=(float)(2*M_PI);
|
||||
int N2=N/2; // half the number of points in FFT
|
||||
int k00,k01,k10,k11; // indices for butterflies
|
||||
if(N!=2)
|
||||
{
|
||||
//--- perform recursive step
|
||||
//--- calculate two (N/2)-point DFT's
|
||||
fft_rec(N2,offset,2*delta,x_real,x_imag,XX_real,XX_imag,X_real,X_imag);
|
||||
fft_rec(N2,offset+delta,2*delta,x_real,x_imag,XX_real,XX_imag,X_real,X_imag);
|
||||
//--- combine the two (N/2)-point DFT's into one N-point DFT
|
||||
for(int k=0; k<N2; k++)
|
||||
{
|
||||
k00 = offset + k*delta;
|
||||
k01 = k00 + N2*delta;
|
||||
k10 = offset + 2*k*delta;
|
||||
k11 = k10 + delta;
|
||||
float cs=(float)MathCos(TWO_PI*k/(float)N);
|
||||
float sn=(float)MathSin(TWO_PI*k/(float)N);
|
||||
float tmp0 = cs*XX_real[k11] + sn*XX_imag[k11];
|
||||
float tmp1 = cs*XX_imag[k11] - sn*XX_real[k11];
|
||||
X_real[k01] = XX_real[k10] - tmp0;
|
||||
X_imag[k01] = XX_imag[k10] - tmp1;
|
||||
X_real[k00] = XX_real[k10] + tmp0;
|
||||
X_imag[k00] = XX_imag[k10] + tmp1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- perform 2-point DFT
|
||||
k00=offset;
|
||||
k01=k00+delta;
|
||||
X_real[k01] = x_real[k00] - x_real[k01];
|
||||
X_imag[k01] = x_imag[k00] - x_imag[k01];
|
||||
X_real[k00] = x_real[k00] + x_real[k01];
|
||||
X_imag[k00] = x_imag[k00] + x_imag[k01];
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool FFT_CPU(int direction,int power,float &data_real[],float &data_imag[],ulong &time_cpu)
|
||||
{
|
||||
//--- calculate the number of points
|
||||
int N=1;
|
||||
for(int i=0;i<power;i++)
|
||||
N*=2;
|
||||
//---prepare temporary arrays
|
||||
float XX_real[],XX_imag[];
|
||||
ArrayResize(XX_real,N);
|
||||
ArrayResize(XX_imag,N);
|
||||
//--- CPU calculation start
|
||||
time_cpu=GetMicrosecondCount();
|
||||
if(direction>0)
|
||||
fft(N,data_real,data_imag,XX_real,XX_imag);
|
||||
else
|
||||
ifft(N,XX_real,XX_imag,data_real,data_imag);
|
||||
//--- CPU calculation finished
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu));
|
||||
//--- copy calculated data
|
||||
ArrayCopy(data_real,XX_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(data_imag,XX_imag,0,0,WHOLE_ARRAY);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| FFT_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool FFT_GPU(int direction,int power,float &data_real[],float &data_imag[],ulong &time_gpu)
|
||||
{
|
||||
//--- calculate the number of points
|
||||
int num_points=1;
|
||||
for(int i=0;i<power;i++)
|
||||
num_points*=2;
|
||||
//--- prepare data array for GPU calculation
|
||||
float data[];
|
||||
ArrayResize(data,2*num_points);
|
||||
for(int i=0; i<num_points; i++)
|
||||
{
|
||||
data[2*i]=data_real[i];
|
||||
data[2*i+1]=data_imag[i];
|
||||
}
|
||||
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- create kernels
|
||||
OpenCL.SetKernelsCount(3);
|
||||
OpenCL.KernelCreate(0,kernel_init);
|
||||
OpenCL.KernelCreate(1,kernel_stage);
|
||||
OpenCL.KernelCreate(2,kernel_scale);
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(2);
|
||||
if(!OpenCL.BufferFromArray(0,data,0,2*num_points,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for input buffer. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferCreate(1,2*num_points*sizeof(float),CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for data buffer. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- determine maximum work-group size
|
||||
int local_size=(int)CLGetInfoInteger(OpenCL.GetKernel(0),CL_KERNEL_WORK_GROUP_SIZE);
|
||||
//--- determine local memory size
|
||||
uint local_mem_size=(uint)CLGetInfoInteger(OpenCL.GetContext(),CL_DEVICE_LOCAL_MEM_SIZE);
|
||||
int points_per_group=(int)local_mem_size/(2*sizeof(float));
|
||||
if(points_per_group>num_points)
|
||||
points_per_group=num_points;
|
||||
//--- set kernel arguments
|
||||
OpenCL.SetArgumentBuffer(0,0,0);
|
||||
OpenCL.SetArgumentBuffer(0,1,1);
|
||||
OpenCL.SetArgumentLocalMemory(0,2,local_mem_size);
|
||||
OpenCL.SetArgument(0,3,points_per_group);
|
||||
OpenCL.SetArgument(0,4,num_points);
|
||||
OpenCL.SetArgument(0,5,direction);
|
||||
//--- OpenCL execute settings
|
||||
int task_dimension=1;
|
||||
uint global_size=(uint)((num_points/points_per_group)*local_size);
|
||||
uint global_work_offset[1]={0};
|
||||
uint global_work_size[1];
|
||||
global_work_size[0]=global_size;
|
||||
uint local_work_size[1];
|
||||
local_work_size[0]=local_size;
|
||||
//--- GPU calculation start
|
||||
time_gpu=GetMicrosecondCount();
|
||||
//-- execute kernel fft_init
|
||||
if(!OpenCL.Execute(0,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_init: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//-- further stages of the FFT
|
||||
if(num_points>points_per_group)
|
||||
{
|
||||
//--- set arguments for kernel 1
|
||||
OpenCL.SetArgumentBuffer(1,0,1);
|
||||
OpenCL.SetArgument(1,2,points_per_group);
|
||||
OpenCL.SetArgument(1,3,direction);
|
||||
for(int stage=2; stage<=num_points/points_per_group; stage<<=1)
|
||||
{
|
||||
OpenCL.SetArgument(1,1,stage);
|
||||
//-- execute kernel fft_stage
|
||||
if(!OpenCL.Execute(1,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_stage: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- scale values if performing the inverse FFT
|
||||
if(direction<0)
|
||||
{
|
||||
OpenCL.SetArgumentBuffer(2,0,1);
|
||||
OpenCL.SetArgument(2,1,points_per_group);
|
||||
OpenCL.SetArgument(2,2,num_points);
|
||||
//-- execute kernel fft_scale
|
||||
if(!OpenCL.Execute(2,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("fft_scale: Error in CLExecute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- read the results from GPU memory
|
||||
if(!OpenCL.BufferRead(1,data,0,0,2*num_points))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for data_buffer2. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time_gpu=ulong((GetMicrosecondCount()-time_gpu));
|
||||
//--- copy calculated data and release OpenCL handles
|
||||
for(int i=0; i<num_points; i++)
|
||||
{
|
||||
data_real[i]=data[2*i];
|
||||
data_imag[i]=data[2*i+1];
|
||||
}
|
||||
OpenCL.Shutdown();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
int datacount=NUM_POINTS;
|
||||
int power=(int)(MathLog(NUM_POINTS)/M_LN2);
|
||||
if(MathPow(2,power)!=datacount)
|
||||
{
|
||||
PrintFormat("Number of elements must be power of 2. Elements: %d",datacount);
|
||||
return;
|
||||
}
|
||||
//--- prepare data for FFT calculation
|
||||
float data_real[],data_imag[];
|
||||
ArrayResize(data_real,datacount);
|
||||
ArrayResize(data_imag,datacount);
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
data_real[i]=(float)i;
|
||||
data_imag[i]=0;
|
||||
}
|
||||
|
||||
int direction=FFT_DIRECTION;
|
||||
//--- data arrays for CPU calculation
|
||||
float CPU_real[],CPU_imag[];
|
||||
ArrayCopy(CPU_real,data_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(CPU_imag,data_imag,0,0,WHOLE_ARRAY);
|
||||
ulong time_cpu=0;
|
||||
//--- calculate FFT using CPU
|
||||
FFT_CPU(direction,power,CPU_real,CPU_imag,time_cpu);
|
||||
|
||||
//--- data arrays for GPU calculation
|
||||
float GPU_real[],GPU_imag[];
|
||||
ArrayCopy(GPU_real,data_real,0,0,WHOLE_ARRAY);
|
||||
ArrayCopy(GPU_imag,data_imag,0,0,WHOLE_ARRAY);
|
||||
ulong time_gpu=0;
|
||||
//--- calculate FFT using GPU
|
||||
if(!FFT_GPU(direction,power,GPU_real,GPU_imag,time_gpu))
|
||||
{
|
||||
PrintFormat("Error in calculation FFT on GPU.");
|
||||
return;
|
||||
}
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
PrintFormat("FFT calculation for %d points.",datacount);
|
||||
PrintFormat("time CPU=%d microseconds, time GPU =%d microseconds, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- determine average error
|
||||
float average_error=0.0;
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
average_error += (float)MathAbs(CPU_real[i]-GPU_real[i]);
|
||||
average_error += (float)MathAbs(CPU_imag[i]-GPU_imag[i]);
|
||||
}
|
||||
average_error=average_error/(datacount*2);
|
||||
PrintFormat("Average error = %f",average_error);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,28 @@
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel |
|
||||
//| The bitonic sort kernel does an ascending sort. |
|
||||
//+-----------------------------------------------------------+
|
||||
//| R. Banger,K. Bhattacharyya, OpenCL Programming by Example:|
|
||||
//| A comprehensive guide on OpenCL programming with examples |
|
||||
//| PACKT Publishing, 2013. |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void BitonicSort_GPU(__global float *data,const uint stage,const uint pass)
|
||||
{
|
||||
uint id=get_global_id(0);
|
||||
uint distance = 1<<(stage-pass);
|
||||
uint left_id =(id &(distance-1));
|
||||
left_id+=(id>>(stage-pass))*(distance<<1);
|
||||
uint right_id=left_id+distance;
|
||||
float left_value=data[left_id];
|
||||
float right_value=data[right_id];
|
||||
uint same_direction=(id>>stage)&0x1;
|
||||
uint temp = same_direction?right_id:temp;
|
||||
right_id = same_direction?left_id:right_id;
|
||||
left_id = same_direction?temp:left_id;
|
||||
int compare_res=(left_value<right_value);
|
||||
float greater = compare_res?right_value:left_value;
|
||||
float lesser = compare_res?left_value:right_value;
|
||||
data[left_id] = lesser;
|
||||
data[right_id]= greater;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,153 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_init OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_init(__global float2 *in_data,
|
||||
__global float2 *out_data,
|
||||
__local float2 *l_data,
|
||||
uint points_per_group,uint size,int dir)
|
||||
{
|
||||
uint4 br,index;
|
||||
uint points_per_item,g_addr,l_addr,i,fft_index,stage,N2;
|
||||
float2 x1,x2,x3,x4,sum12,diff12,sum34,diff34;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
l_addr = get_local_id(0)*points_per_item;
|
||||
g_addr = get_group_id(0)*points_per_group + l_addr;
|
||||
//--- load data from bit-reversed addresses and perform 4-point FFTs
|
||||
for(i=0; i<points_per_item; i+=4)
|
||||
{
|
||||
index=(uint4)(g_addr,g_addr+1,g_addr+2,g_addr+3);
|
||||
fft_index=size/2;
|
||||
stage=1;
|
||||
N2 =(uint)log2((float)size)-1;
|
||||
br =(index<< N2) & fft_index;
|
||||
br|=(index>> N2) & stage;
|
||||
//--- bit-reverse addresses
|
||||
while(N2>1)
|
||||
{
|
||||
N2-=2;
|
||||
fft_index>>=1;
|
||||
stage<<=1;
|
||||
br |= (index << N2) & fft_index;
|
||||
br |= (index >> N2) & stage;
|
||||
}
|
||||
//--- load global data
|
||||
x1 = in_data[br.s0];
|
||||
x2 = in_data[br.s1];
|
||||
x3 = in_data[br.s2];
|
||||
x4 = in_data[br.s3];
|
||||
|
||||
sum12=x1+x2;
|
||||
diff12= x1-x2;
|
||||
sum34 = x3+x4;
|
||||
diff34=(float2)(x3.s1-x4.s1,x4.s0-x3.s0)*dir;
|
||||
l_data[l_addr]=sum12+sum34;
|
||||
l_data[l_addr+1] = diff12 + diff34;
|
||||
l_data[l_addr+2] = sum12 - sum34;
|
||||
l_data[l_addr+3] = diff12 - diff34;
|
||||
l_addr += 4;
|
||||
g_addr += 4;
|
||||
}
|
||||
//--- perform initial stages of the FFT - each of length N2*2
|
||||
for(N2=4; N2<points_per_item; N2<<=1)
|
||||
{
|
||||
l_addr=get_local_id(0)*points_per_item;
|
||||
for(fft_index=0; fft_index<points_per_item; fft_index+=2*N2)
|
||||
{
|
||||
x1=l_data[l_addr];
|
||||
l_data[l_addr]+=l_data[l_addr+N2];
|
||||
l_data[l_addr+N2]=x1-l_data[l_addr+N2];
|
||||
for(i=1; i<N2; i++)
|
||||
{
|
||||
x3.s0=cos(M_PI_F*i/N2);
|
||||
x3.s1=dir*sin(M_PI_F*i/N2);
|
||||
x2=(float2)(l_data[l_addr+N2+i].s0*x3.s0+l_data[l_addr+N2+i].s1*x3.s1,l_data[l_addr+N2+i].s1*x3.s0-l_data[l_addr+N2+i].s0*x3.s1);
|
||||
l_data[l_addr+N2+i]=l_data[l_addr+i]-x2;
|
||||
l_data[l_addr+i]+=x2;
|
||||
}
|
||||
l_addr+=2*N2;
|
||||
}
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
//--- perform FFT with other items in group - each of length N2*2
|
||||
stage=2;
|
||||
for(N2=points_per_item; N2<points_per_group; N2<<=1)
|
||||
{
|
||||
br.s0=(get_local_id(0)+(get_local_id(0)/stage)*stage) *(points_per_item/2);
|
||||
size = br.s0 % (N2*2);
|
||||
for(i=br.s0; i<br.s0+points_per_item/2; i++)
|
||||
{
|
||||
x3.s0=cos(M_PI_F*size/N2);
|
||||
x3.s1=dir*sin(M_PI_F*size/N2);
|
||||
x2=(float2)(l_data[N2+i].s0*x3.s0+l_data[N2+i].s1*x3.s1,l_data[N2+i].s1*x3.s0-l_data[N2+i].s0*x3.s1);
|
||||
l_data[N2+i]=l_data[i]-x2;
|
||||
l_data[i]+=x2;
|
||||
size++;
|
||||
}
|
||||
stage<<=1;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
//--- store results in global memory
|
||||
l_addr = get_local_id(0)*points_per_item;
|
||||
g_addr = get_group_id(0)*points_per_group + l_addr;
|
||||
for(i=0; i<points_per_item; i+=4)
|
||||
{
|
||||
out_data[g_addr]=l_data[l_addr];
|
||||
out_data[g_addr+1] = l_data[l_addr+1];
|
||||
out_data[g_addr+2] = l_data[l_addr+2];
|
||||
out_data[g_addr+3] = l_data[l_addr+3];
|
||||
g_addr += 4;
|
||||
l_addr += 4;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_stage OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_stage(__global float2 *g_data,uint stage,uint points_per_group,int dir)
|
||||
{
|
||||
uint points_per_item,addr,N,ang,i;
|
||||
float c,s;
|
||||
float2 input1,input2,w;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
addr=(get_group_id(0)+(get_group_id(0)/stage)*stage)*(points_per_group/2)+get_local_id(0)*(points_per_item/2);
|
||||
N=points_per_group*(stage/2);
|
||||
ang=addr%(N*2);
|
||||
|
||||
for(i=addr; i<addr+points_per_item/2; i++)
|
||||
{
|
||||
c = cos(M_PI_F*ang/N);
|
||||
s = dir*sin(M_PI_F*ang/N);
|
||||
input1 = g_data[i];
|
||||
input2 = g_data[i+N];
|
||||
w=(float2)(input2.s0*c+input2.s1*s,input2.s1*c-input2.s0*s);
|
||||
g_data[i]=input1+w;
|
||||
g_data[i+N]=input1-w;
|
||||
ang++;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| fft_scale OpenCL kernel for Fast Fourier Transfrom |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Matthew Scarpino, "OpenCL in Action: How to accelerate graphics |
|
||||
//| and computations", Manning, 2012, Chapter 14. |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void fft_scale(__global float2 *g_data,uint points_per_group,uint scale)
|
||||
{
|
||||
uint points_per_item,addr,i;
|
||||
|
||||
points_per_item=points_per_group/get_local_size(0);
|
||||
addr=get_group_id(0)*points_per_group+get_local_id(0)*points_per_item;
|
||||
|
||||
for(i=addr; i<addr+points_per_item; i++)
|
||||
{
|
||||
g_data[i]/=scale;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,66 @@
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel for matrix multiplication |
|
||||
//| using global work groups |
|
||||
//+-----------------------------------------------------------+
|
||||
//| http://gpgpu-computing4.blogspot.ru/2009/09/ |
|
||||
//| /matrix-multiplication-2-opencl.html |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void MatrixMult_GPU1(__global float *matrix_a,
|
||||
__global float *matrix_b,
|
||||
__global float *matrix_c,
|
||||
int rows_a,int cols_a,int cols_b)
|
||||
{
|
||||
int i=get_global_id(0);
|
||||
int j=get_global_id(1);
|
||||
float sum=0.0;
|
||||
for(int k=0; k<cols_a; k++)
|
||||
{
|
||||
sum+=matrix_a[cols_a*i+k]*matrix_b[cols_b*k+j];
|
||||
}
|
||||
matrix_c[cols_b*i+j]=sum;
|
||||
}
|
||||
#define BLOCK_SIZE 10
|
||||
//+-----------------------------------------------------------+
|
||||
//| OpenCL kernel for matrix multiplication |
|
||||
//| using local groups with common local memory |
|
||||
//+-----------------------------------------------------------+
|
||||
//| http://gpgpu-computing4.blogspot.ru/2009/10/ |
|
||||
//| /matrix-multiplication-3-opencl.html |
|
||||
//+-----------------------------------------------------------+
|
||||
__kernel void MatrixMult_GPU2(__global float *matrix_a,
|
||||
__global float *matrix_b,
|
||||
__global float *matrix_c,
|
||||
int rows_a,int cols_a,int cols_b)
|
||||
{
|
||||
int group_i=get_group_id(0);
|
||||
int group_j=get_group_id(1);
|
||||
|
||||
int i=get_local_id(0);
|
||||
int j=get_local_id(1);
|
||||
|
||||
int offset_b=BLOCK_SIZE*group_i;
|
||||
int offset_a_start=cols_a*BLOCK_SIZE*group_j;
|
||||
float sum=(float)0.0;
|
||||
|
||||
for(int offset_a=offset_a_start;
|
||||
offset_a<offset_a_start+cols_a;
|
||||
offset_a+=BLOCK_SIZE,
|
||||
offset_b+=BLOCK_SIZE*cols_b)
|
||||
{
|
||||
__local float submatrix_a[BLOCK_SIZE][BLOCK_SIZE];
|
||||
__local float submatrix_b[BLOCK_SIZE][BLOCK_SIZE];
|
||||
|
||||
submatrix_a[i][j]=matrix_a[offset_a+cols_a*i+j];
|
||||
submatrix_b[i][j]=matrix_b[offset_b+cols_b*i+j];
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
for(int k=0; k<BLOCK_SIZE; k++)
|
||||
sum+=submatrix_a[i][k]*submatrix_b[k][j];
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
int offset_c=BLOCK_SIZE*(cols_b*group_j+group_i);
|
||||
matrix_c[offset_c+cols_b*i+j]=sum;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,48 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Morlet wavelet function |
|
||||
//+------------------------------------------------------------------+
|
||||
float Morlet(const float t)
|
||||
{
|
||||
return exp(-t*t*0.5)*cos(M_2_PI*t);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| OpenCL kernel function |
|
||||
//+------------------------------------------------------------------+
|
||||
__kernel void Wavelet_GPU(__global float *data,int datacount,int x_size,int y_size,__global float *result)
|
||||
{
|
||||
size_t i = get_global_id(0);
|
||||
size_t j = get_global_id(1);
|
||||
float a1=(float)10e-10;
|
||||
float a2=(float)15.0;
|
||||
float da=(a2-a1)/(float)y_size;
|
||||
float db=((float)datacount-(float)0.0)/x_size;
|
||||
float a=a1+j*da;
|
||||
float b=0+i*db;
|
||||
uint norm=1;
|
||||
float B=(float)1.0; //Morlet
|
||||
float B_inv=(float)1.0/B;
|
||||
float a_inv=(float)1.0/a;
|
||||
float dt=(float)1.0;
|
||||
float coef=(float)0.0;
|
||||
if(norm==0)
|
||||
coef=sqrt(a_inv);
|
||||
else
|
||||
{
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
float arg=(dt*k-b)*a_inv;
|
||||
arg=-B_inv*arg*arg;
|
||||
coef=coef+exp(arg);
|
||||
}
|
||||
}
|
||||
float sum=(float)0.0;
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
float arg=(dt*k-b)*a_inv;
|
||||
sum+=data[k]*Morlet(arg);
|
||||
}
|
||||
sum=sum/coef;
|
||||
uint pos=(int)(j*x_size+i);
|
||||
result[pos]=sum;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,219 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
//--- OpenCL kernels
|
||||
#resource "Kernels/matrixmult.cl" as string cl_program
|
||||
#define BLOCK_SIZE 10
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool MatrixMult_CPU(const float &matrix_a[],const float &matrix_b[],float &matrix_c[],
|
||||
const int rows_a,const int cols_a,const int cols_b,ulong &time_cpu)
|
||||
{
|
||||
int size=rows_a*cols_b;
|
||||
if(ArrayResize(matrix_c,size)!=size)
|
||||
return(false);
|
||||
//--- CPU calculation started
|
||||
time_cpu=GetMicrosecondCount();
|
||||
for(int i=0; i<rows_a; i++)
|
||||
{
|
||||
for(int j=0; j<cols_b; j++)
|
||||
{
|
||||
float sum=0.0;
|
||||
for(int k=0; k<cols_a; k++)
|
||||
{
|
||||
sum+=matrix_a[cols_a*i+k]*matrix_b[cols_b*k+j];
|
||||
}
|
||||
matrix_c[cols_b*i+j]=sum;
|
||||
}
|
||||
}
|
||||
//--- CPU calculation finished
|
||||
time_cpu=ulong((GetMicrosecondCount()-time_cpu)/1000);
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| MatrixMult_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool MatrixMult_GPU(const float &matrix_a[],const float &matrix_b[],float &matrix1_c[],float &matrix2_c[],
|
||||
const int rows_a,const int cols_a,const int cols_b,const int size_a,const int size_b,
|
||||
const int size_c,ulong &time1_gpu,ulong &time2_gpu)
|
||||
{
|
||||
const int task_dimension=2;
|
||||
//--- prepare matrices for result
|
||||
if(ArrayResize(matrix1_c,size_c)!=size_c || ArrayResize(matrix2_c,size_c)!=size_c)
|
||||
return(false);
|
||||
ArrayFill(matrix1_c,0,size_c,(float)0.0);
|
||||
ArrayFill(matrix2_c,0,size_c,(float)0.0);
|
||||
//--- OpenCL
|
||||
COpenCL OpenCL;
|
||||
if(!OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- create kernels
|
||||
OpenCL.SetKernelsCount(2);
|
||||
OpenCL.KernelCreate(0,"MatrixMult_GPU1");
|
||||
OpenCL.KernelCreate(1,"MatrixMult_GPU2");
|
||||
//--- create buffers
|
||||
OpenCL.SetBuffersCount(3);
|
||||
//---
|
||||
if(!OpenCL.BufferFromArray(0,matrix_a,0,size_a,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for matrix A. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferFromArray(1,matrix_b,0,size_b,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for matrix B. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferCreate(2,size_c*sizeof(float),CL_MEM_WRITE_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for matrix C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- prepare arguments for kernel 0
|
||||
int kernel_index=0;
|
||||
OpenCL.SetArgumentBuffer(kernel_index,0,0);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,1,1);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,2,2);
|
||||
OpenCL.SetArgument(kernel_index,3,rows_a);
|
||||
OpenCL.SetArgument(kernel_index,4,cols_a);
|
||||
OpenCL.SetArgument(kernel_index,5,cols_b);
|
||||
//--- set task dimension a_rows x b_cols
|
||||
uint global_work_size[2];
|
||||
//--- set dimensions
|
||||
global_work_size[0]=rows_a;
|
||||
global_work_size[1]=cols_b;
|
||||
uint global_work_offset[2]={0,0};
|
||||
//--- GPU calculation start kernel 0
|
||||
time1_gpu=GetMicrosecondCount();
|
||||
if(!OpenCL.Execute(kernel_index,task_dimension,global_work_offset,global_work_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferRead(2,matrix1_c,0,0,size_c))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for matrix1 C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time1_gpu=ulong((GetMicrosecondCount()-time1_gpu)/1000);
|
||||
|
||||
//--- prepare arguments for kernel 1
|
||||
kernel_index=1;
|
||||
//--- set arguments
|
||||
OpenCL.SetArgumentBuffer(kernel_index,0,0);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,1,1);
|
||||
OpenCL.SetArgumentBuffer(kernel_index,2,2);
|
||||
OpenCL.SetArgument(kernel_index,3,rows_a);
|
||||
OpenCL.SetArgument(kernel_index,4,cols_a);
|
||||
OpenCL.SetArgument(kernel_index,5,cols_b);
|
||||
uint local_work_size[2];
|
||||
local_work_size[0]=BLOCK_SIZE;
|
||||
local_work_size[1]=BLOCK_SIZE;
|
||||
//--- GPU calculation start, kernel1
|
||||
time2_gpu=GetMicrosecondCount();
|
||||
if(!OpenCL.Execute(kernel_index,task_dimension,global_work_offset,global_work_size,local_work_size))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!OpenCL.BufferRead(2,matrix2_c,0,0,size_c))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for matrix2 C. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finished
|
||||
time2_gpu=ulong((GetMicrosecondCount()-time2_gpu)/1000);
|
||||
//--- remove OpenCL objects
|
||||
OpenCL.Shutdown();
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//--- matrix A 1000x2000
|
||||
int rows_a=1000;
|
||||
int cols_a=2000;
|
||||
//--- matrix B 2000x1000
|
||||
int rows_b=cols_a;
|
||||
int cols_b=1000;
|
||||
//--- matrix C 1000x1000
|
||||
int rows_c=rows_a;
|
||||
int cols_c=cols_b;
|
||||
//--- matrix A: size=rows_a*cols_a
|
||||
int size_a=rows_a*cols_a;
|
||||
int size_b=rows_b*cols_b;
|
||||
int size_c=rows_c*cols_c;
|
||||
//--- prepare matrix A
|
||||
float matrix_a[];
|
||||
ArrayResize(matrix_a,rows_a*cols_a);
|
||||
for(int i=0; i<rows_a; i++)
|
||||
for(int j=0; j<cols_a; j++)
|
||||
{
|
||||
matrix_a[i*cols_a+j]=(float)(10*MathRand()/32767);
|
||||
}
|
||||
//--- prepare matrix B
|
||||
float matrix_b[];
|
||||
ArrayResize(matrix_b,rows_b*cols_b);
|
||||
for(int i=0; i<rows_b; i++)
|
||||
for(int j=0; j<cols_b; j++)
|
||||
{
|
||||
matrix_b[i*cols_b+j]=(float)(10*MathRand()/32767);
|
||||
}
|
||||
//--- CPU: calculate matrix product matrix_a*matrix_b
|
||||
float matrix_c_cpu[];
|
||||
ulong time_cpu=0;
|
||||
if(!MatrixMult_CPU(matrix_a,matrix_b,matrix_c_cpu,rows_a,cols_a,cols_b,time_cpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on CPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//--- calculate matrix product using GPU
|
||||
float matrix_c_gpu_method1[];
|
||||
float matrix_c_gpu_method2[];
|
||||
ulong time_gpu_method1=0;
|
||||
ulong time_gpu_method2=0;
|
||||
if(!MatrixMult_GPU(matrix_a,matrix_b,matrix_c_gpu_method1,matrix_c_gpu_method2,rows_a,cols_a,cols_b,size_a,size_b,size_c,time_gpu_method1,time_gpu_method2))
|
||||
{
|
||||
PrintFormat("Error in calculation on GPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//--- calculate CPU/GPU ratio
|
||||
double CPU_GPU_ratio1=0;
|
||||
double CPU_GPU_ratio2=0;
|
||||
if(time_gpu_method1!=0)
|
||||
CPU_GPU_ratio1=1.0*time_cpu/time_gpu_method1;
|
||||
if(time_gpu_method2!=0)
|
||||
CPU_GPU_ratio2=1.0*time_cpu/time_gpu_method2;
|
||||
PrintFormat("time CPU=%d ms, time GPU global work groups =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu_method1,CPU_GPU_ratio1);
|
||||
PrintFormat("time CPU=%d ms, time GPU local work groups =%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu_method2,CPU_GPU_ratio2);
|
||||
//--- check calculations
|
||||
float total_error1=0;
|
||||
float total_error2=0;
|
||||
for(int i=0; i<rows_c; i++)
|
||||
{
|
||||
for(int j=0; j<cols_c; j++)
|
||||
{
|
||||
int pos=cols_c*i+j;
|
||||
total_error1+=MathAbs(matrix_c_gpu_method1[pos]-matrix_c_cpu[pos]);
|
||||
total_error2+=MathAbs(matrix_c_gpu_method2[pos]-matrix_c_cpu[pos]);
|
||||
}
|
||||
}
|
||||
PrintFormat("Total error for method 1 = %f",total_error1);
|
||||
PrintFormat("Total error for method 2 = %f",total_error2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,436 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Wavelet.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
#include <Math/Stat/Math.mqh>
|
||||
#include <Graphics/Graphic.mqh>
|
||||
#include <OpenCL/OpenCL.mqh>
|
||||
|
||||
#define CPU_DATA 1
|
||||
#define GPU_DATA 2
|
||||
|
||||
#define SIZE_X 600
|
||||
#define SIZE_Y 200
|
||||
|
||||
#resource "Kernels/wavelet.cl" as string cl_program
|
||||
//+------------------------------------------------------------------+
|
||||
//| CWavelet |
|
||||
//+------------------------------------------------------------------+
|
||||
class CWavelet
|
||||
{
|
||||
protected:
|
||||
int m_xsize;
|
||||
int m_ysize;
|
||||
int m_maxcolor;
|
||||
string m_res_name;
|
||||
string m_label_name;
|
||||
uchar m_palette[3*256];
|
||||
//---
|
||||
float m_data[];
|
||||
float m_wavelet_data_CPU[];
|
||||
float m_wavelet_data_GPU[];
|
||||
uint m_bmp_buffer[];
|
||||
|
||||
COpenCL m_OpenCL;
|
||||
|
||||
float Morlet(const float t);
|
||||
void ShowWaveletData(const float &m_wavelet_data[]);
|
||||
int GetPalColor(const int index);
|
||||
void Blend(const uint c1,const uint c2,const uint r1,const uint g1,const uint b1,const uint r2,const uint g2,const uint b2);
|
||||
bool WaveletCPU(const float &data[],const int datacount,const int x_size,const int y_size,const int i,const int j,const bool norm,float &result[]);
|
||||
public:
|
||||
//---
|
||||
void Create(const string name,const int x0,const int y0,const int x_size,const int y_size);
|
||||
bool CalculateWavelet_CPU(const float &data[],uint &time);
|
||||
bool CalculateWavelet_GPU(float &data[],uint &time);
|
||||
void ShowWavelet(const int mode);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Morlet wavelet function |
|
||||
//+------------------------------------------------------------------+
|
||||
float CWavelet::Morlet(const float t)
|
||||
{
|
||||
double v=t;
|
||||
double res=MathExp(-v*v*0.5)*MathCos(M_2_PI*v);
|
||||
return ((float)res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| GetPalColor |
|
||||
//+------------------------------------------------------------------+
|
||||
int CWavelet::GetPalColor(const int index)
|
||||
{
|
||||
int ind=index;
|
||||
if(ind<=0)
|
||||
ind=0;
|
||||
if(ind>255)
|
||||
ind=255;
|
||||
int idx=3*(ind);
|
||||
uchar r=m_palette[idx];
|
||||
uchar g=m_palette[idx+1];
|
||||
uchar b=m_palette[idx+2];
|
||||
//---
|
||||
return(b+256*g+65536*r);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gradient palette |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::Blend(const uint c1,const uint c2,const uint r1,const uint g1,const uint b1,const uint r2,const uint g2,const uint b2)
|
||||
{
|
||||
int n=int(c2-c1);
|
||||
for(int i=0; i<=n; i++)
|
||||
{
|
||||
if((c1+i+2)<ArraySize(m_palette))
|
||||
{
|
||||
m_palette[3*(c1+i)]=uchar(MathRound(1*(r1*(n-i)+r2*i)*1.0/n));
|
||||
m_palette[3*(c1+i)+1]=uchar(MathRound(1*(g1*(n-i)+g2*i)*1.0/n));
|
||||
m_palette[3*(c1+i)+2]=uchar(MathRound(1*(b1*(n-i)+b2*i)*1.0/n));
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::Create(const string name,const int x0,const int y0,const int x_size,const int y_size)
|
||||
{
|
||||
//---
|
||||
m_xsize=x_size;
|
||||
m_ysize=y_size;
|
||||
int size=m_xsize*m_ysize;
|
||||
ArrayResize(m_bmp_buffer,size);
|
||||
ArrayFill(m_bmp_buffer,0,size,0);
|
||||
ArrayResize(m_wavelet_data_CPU,size);
|
||||
ArrayResize(m_wavelet_data_GPU,size);
|
||||
ArrayFill(m_wavelet_data_CPU,0,size,0);
|
||||
ArrayFill(m_wavelet_data_GPU,0,size,0);
|
||||
m_res_name=name;
|
||||
m_label_name=m_res_name;
|
||||
StringToUpper(m_label_name);
|
||||
ResourceCreate(m_res_name,m_bmp_buffer,m_xsize,m_ysize,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);
|
||||
ObjectCreate(0,m_label_name,OBJ_BITMAP_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,m_label_name,OBJPROP_XDISTANCE,x0);
|
||||
ObjectSetInteger(0,m_label_name,OBJPROP_YDISTANCE,y0);
|
||||
ObjectSetString(0,m_label_name,OBJPROP_BMPFILE,NULL);
|
||||
ObjectSetString(0,m_label_name,OBJPROP_BMPFILE,"::"+m_label_name);
|
||||
m_maxcolor=100;
|
||||
//Blend(0,100,0,0,0,255,255,255);
|
||||
Blend(0,20,0,0,95,0,0,246);
|
||||
Blend(21,40,0,0,246,0,236,226);
|
||||
Blend(41,60,0,236,226,226,246,0);
|
||||
Blend(61,80,226,246,0,226,0,0);
|
||||
Blend(81,100,226,0,0,123,0,0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| WaveletCPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::WaveletCPU(const float &data[],const int datacount,const int x_size,const int y_size,const int i,const int j,const bool norm,float &result[])
|
||||
{
|
||||
float a1=(float)10e-10;
|
||||
float a2=(float)15.0;
|
||||
float da=(float)(a2-a1)/y_size;
|
||||
float db=(float)(datacount-0)/x_size;
|
||||
int pos=j*x_size+i;
|
||||
//---
|
||||
float a=a1+j*da;
|
||||
float b=i*db;
|
||||
float B=(float)1.0; //Morlet
|
||||
float B_inv=(float)1.0/B;
|
||||
float a_inv=(float)1/a;
|
||||
float dt=(float)1.0;
|
||||
float coef=(float)0.0;
|
||||
if(!norm)
|
||||
coef=(float)MathSqrt(a_inv);
|
||||
else
|
||||
{
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
float arg=(dt*k-b)*a_inv;
|
||||
arg=-B_inv*arg*arg;
|
||||
coef+=(float)MathExp(arg);
|
||||
}
|
||||
}
|
||||
float sum=0.0;
|
||||
for(int k=0; k<datacount; k++)
|
||||
{
|
||||
float arg=(dt*k-b)*a_inv;
|
||||
sum+=data[k]*Morlet(arg);
|
||||
}
|
||||
sum/=coef;
|
||||
result[pos]=sum;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| CalculateWavelet_CPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::CalculateWavelet_CPU(const float &data[],uint &time)
|
||||
{
|
||||
time=GetTickCount();
|
||||
int datacount=ArraySize(data);
|
||||
ArrayCopy(m_data,data,0,0,WHOLE_ARRAY);
|
||||
for(int i=0; i<m_xsize; i++)
|
||||
{
|
||||
for(int j=0; j<m_ysize; j++)
|
||||
{
|
||||
WaveletCPU(m_data,datacount,m_xsize,m_ysize,i,j,true,m_wavelet_data_CPU);
|
||||
}
|
||||
}
|
||||
time=GetTickCount()-time;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| CalculateWavelet_GPU |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CWavelet::CalculateWavelet_GPU(float &data[],uint &time)
|
||||
{
|
||||
int datacount=ArraySize(data);
|
||||
if(!m_OpenCL.Initialize(cl_program,true))
|
||||
{
|
||||
PrintFormat("Error in OpenCL initialization. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//---
|
||||
m_OpenCL.SetKernelsCount(1);
|
||||
m_OpenCL.KernelCreate(0,"Wavelet_GPU");
|
||||
//---
|
||||
m_OpenCL.SetBuffersCount(2);
|
||||
if(!m_OpenCL.BufferFromArray(0,data,0,datacount,CL_MEM_READ_ONLY))
|
||||
{
|
||||
PrintFormat("Error in BufferFromArray for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!m_OpenCL.BufferCreate(1,m_xsize*m_ysize*sizeof(float),CL_MEM_READ_WRITE))
|
||||
{
|
||||
PrintFormat("Error in BufferCreate for data array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
m_OpenCL.SetArgumentBuffer(0,0,0);
|
||||
m_OpenCL.SetArgumentBuffer(0,4,1);
|
||||
//---
|
||||
ArrayResize(m_wavelet_data_GPU,m_xsize*m_ysize);
|
||||
uint work[2];
|
||||
uint offset[2]={0,0};
|
||||
//--- set dimensions
|
||||
work[0]=m_xsize;
|
||||
work[1]=m_ysize;
|
||||
//--- set parameters and write data to buffer
|
||||
m_OpenCL.SetArgument(0,1,datacount);
|
||||
m_OpenCL.SetArgument(0,2,m_xsize);
|
||||
m_OpenCL.SetArgument(0,3,m_ysize);
|
||||
time=GetTickCount();
|
||||
//--- GPU calculation start
|
||||
if(!m_OpenCL.Execute(0,2,offset,work))
|
||||
{
|
||||
PrintFormat("Error in Execute. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
if(!m_OpenCL.BufferRead(1,m_wavelet_data_GPU,0,0,m_xsize*m_ysize))
|
||||
{
|
||||
PrintFormat("Error in BufferRead for m_wavelet_data_GPU array. Error code=%d",GetLastError());
|
||||
return(false);
|
||||
}
|
||||
//--- GPU calculation finish
|
||||
time=GetTickCount()-time;
|
||||
//---
|
||||
m_OpenCL.Shutdown();
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ShowWavelet |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::ShowWavelet(const int mode)
|
||||
{
|
||||
if(mode==CPU_DATA)
|
||||
ShowWaveletData(m_wavelet_data_CPU);
|
||||
else
|
||||
if(mode==GPU_DATA)
|
||||
ShowWaveletData(m_wavelet_data_GPU);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ShowWaveletData |
|
||||
//+------------------------------------------------------------------+
|
||||
void CWavelet::ShowWaveletData(const float &m_wavelet_data[])
|
||||
{
|
||||
//--- calculate min/max and range
|
||||
int count=ArraySize(m_wavelet_data);
|
||||
float min_value=m_wavelet_data[0];
|
||||
float max_value=m_wavelet_data[0];
|
||||
for(int i=1; i<count; i++)
|
||||
{
|
||||
min_value=MathMin(min_value,m_wavelet_data[i]);
|
||||
max_value=MathMax(max_value,m_wavelet_data[i]);
|
||||
}
|
||||
float range=max_value-min_value;
|
||||
if(range>0)
|
||||
{
|
||||
for(int j=0; j<m_ysize; j++)
|
||||
{
|
||||
for(int i=0; i<m_xsize; i++)
|
||||
{
|
||||
int pos=j*m_xsize+i;
|
||||
int colindex=int(m_maxcolor*(m_wavelet_data[pos]-min_value)/range);
|
||||
m_bmp_buffer[pos]=GetPalColor(colindex);
|
||||
}
|
||||
}
|
||||
//--- show image
|
||||
ResourceCreate(m_res_name,m_bmp_buffer,m_xsize,m_ysize,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);
|
||||
ChartRedraw();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Weirstrass function |
|
||||
//+------------------------------------------------------------------+
|
||||
float Weirstrass(float x,float a,float b)
|
||||
{
|
||||
float sum=0.0;
|
||||
float b0=b;
|
||||
float a0=a;
|
||||
for(int n=0; n<35; n++)
|
||||
{
|
||||
float v=b0*(float)MathCos(a0*M_PI*x);
|
||||
sum=sum+v;
|
||||
a0=a0*a;
|
||||
b0=b0*b;
|
||||
}
|
||||
return(sum);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareModelData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PrepareModelData(float &price_data[],const int datacount)
|
||||
{
|
||||
ArrayResize(price_data,datacount);
|
||||
//--- Weirstrass function
|
||||
float x1=0;
|
||||
float x2=2;
|
||||
float dx=(x2-x1)/datacount;
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
price_data[i]=Weirstrass(x1+dx*i,(float)3,(float)0.62);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PreparePriceData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PreparePriceData(const string symbol,ENUM_TIMEFRAMES timeframe,float &price_data[],const int datacount)
|
||||
{
|
||||
ArrayResize(price_data,datacount);
|
||||
|
||||
double price_data_double[];
|
||||
CopyClose(symbol,timeframe,0,datacount,price_data_double);
|
||||
|
||||
int size=ArraySize(price_data_double);
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
price_data[i]=(float)price_data_double[i];
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| PrepareMomentumData |
|
||||
//+------------------------------------------------------------------+
|
||||
void PrepareMomentumData(float &price_data[],float &momentum_data[],const int momentum_period)
|
||||
{
|
||||
int size=ArraySize(price_data);
|
||||
int datacount=size-momentum_period;
|
||||
//---
|
||||
ArrayResize(momentum_data,datacount);
|
||||
for(int i=0; i<datacount; i+=1)
|
||||
{
|
||||
momentum_data[i]=price_data[i+momentum_period]-price_data[i];
|
||||
}
|
||||
ArrayCopy(price_data,price_data,momentum_period,0,datacount);
|
||||
ArrayResize(price_data,datacount);
|
||||
//--- rescale momentum data
|
||||
float min_value=momentum_data[0];
|
||||
float max_value=momentum_data[0];
|
||||
for(int i=1; i<datacount; i++)
|
||||
{
|
||||
float value=momentum_data[i];
|
||||
if(momentum_data[i]>max_value)
|
||||
max_value=value;
|
||||
|
||||
if(momentum_data[i]<min_value)
|
||||
min_value=value;
|
||||
}
|
||||
float range=max_value-min_value;
|
||||
for(int i=0; i<datacount; i+=1)
|
||||
momentum_data[i]=-1+2*(momentum_data[i]-min_value)/range;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//---
|
||||
int momentum_period=8;
|
||||
float price_data[];
|
||||
float momentum_data[];
|
||||
PrepareModelData(price_data,SIZE_X+momentum_period);
|
||||
//PreparePriceData("EURUSD",PERIOD_M1,price_data,SIZE_X+momentum_period);
|
||||
PrepareMomentumData(price_data,momentum_data,momentum_period);
|
||||
|
||||
double price_data_double[];
|
||||
double momentum_data_double[];
|
||||
|
||||
int datacount=ArraySize(price_data);
|
||||
ArrayResize(price_data_double,datacount);
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
price_data_double[i]=(double)price_data[i];
|
||||
}
|
||||
datacount=ArraySize(momentum_data);
|
||||
ArrayResize(momentum_data_double,datacount);
|
||||
for(int i=0; i<datacount; i++)
|
||||
{
|
||||
momentum_data_double[i]=(double)momentum_data[i];
|
||||
}
|
||||
|
||||
CGraphic graph_price;
|
||||
CGraphic graph_momentum;
|
||||
graph_price.Create(0,"price",0,0,0,SIZE_X+130+6,SIZE_Y);
|
||||
graph_price.XAxis().MaxGrace(0);
|
||||
graph_price.HistorySymbolSize(10);
|
||||
graph_price.CurveAdd(price_data_double,ColorToARGB(clrRed,255),CURVE_LINES,"Price");
|
||||
graph_price.CurvePlotAll();
|
||||
graph_price.Redraw(true);
|
||||
graph_price.Update();
|
||||
//---
|
||||
graph_momentum.Create(0,"momentum",0,0,SIZE_Y,SIZE_X+130+6,SIZE_Y+SIZE_Y);
|
||||
graph_momentum.XAxis().MaxGrace(0);
|
||||
graph_momentum.HistorySymbolSize(10);
|
||||
graph_momentum.CurveAdd(momentum_data_double,ColorToARGB(clrBlue,255),CURVE_LINES,"Momentum");
|
||||
graph_momentum.CurvePlotAll();
|
||||
graph_momentum.Redraw(true);
|
||||
graph_momentum.Update();
|
||||
//---
|
||||
uint time_cpu=0;
|
||||
CWavelet wavelet;
|
||||
wavelet.Create("Wavelet",50,2*SIZE_Y,SIZE_X,SIZE_Y);
|
||||
if(!wavelet.CalculateWavelet_CPU(momentum_data,time_cpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on CPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
//wavelet.ShowWavelet(CPU_DATA);
|
||||
uint time_gpu=0;
|
||||
if(!wavelet.CalculateWavelet_GPU(momentum_data,time_gpu))
|
||||
{
|
||||
PrintFormat("Error in calculation on GPU. Error code=%d",GetLastError());
|
||||
return;
|
||||
}
|
||||
wavelet.ShowWavelet(GPU_DATA);
|
||||
//---
|
||||
double CPU_GPU_ratio=0;
|
||||
if(time_gpu!=0)
|
||||
CPU_GPU_ratio=1.0*time_cpu/time_gpu;
|
||||
//---
|
||||
PrintFormat("time CPU=%d ms, time GPU=%d ms, CPU/GPU ratio: %f",time_cpu,time_gpu,CPU_GPU_ratio);
|
||||
//--- Sleep 10 seconds
|
||||
Sleep(10000);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,200 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| OrderInfoSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include <Trade\OrderInfo.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//---
|
||||
#include "OrderInfoSampleInit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to testing the use of class COrderInfo. |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Order Info Sample script class |
|
||||
//+------------------------------------------------------------------+
|
||||
class COrderInfoSample
|
||||
{
|
||||
protected:
|
||||
COrderInfo m_order;
|
||||
//--- chart objects
|
||||
CChartObjectButton m_button_prev;
|
||||
CChartObjectButton m_button_next;
|
||||
CChartObjectLabel m_label[20];
|
||||
CChartObjectLabel m_label_info[20];
|
||||
//---
|
||||
int m_curr_ord;
|
||||
int m_total_ord;
|
||||
|
||||
public:
|
||||
COrderInfoSample(void);
|
||||
~COrderInfoSample(void);
|
||||
//---
|
||||
bool Init(void);
|
||||
void Deinit(void);
|
||||
void Processing(void);
|
||||
|
||||
private:
|
||||
void InfoToChart(void);
|
||||
};
|
||||
//---
|
||||
COrderInfoSample ExtScript;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
COrderInfoSample::COrderInfoSample(void) : m_curr_ord(-1),
|
||||
m_total_ord(-1)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
COrderInfoSample::~COrderInfoSample(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Init. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool COrderInfoSample::Init(void)
|
||||
{
|
||||
int i,sy=10;
|
||||
int dy=16;
|
||||
color color_label;
|
||||
color color_info;
|
||||
//--- tuning colors
|
||||
color_info =(color)(ChartGetInteger(0,CHART_COLOR_BACKGROUND)^0xFFFFFF);
|
||||
color_label=(color)(color_info^0x202020);
|
||||
//---
|
||||
if(ChartGetInteger(0,CHART_SHOW_OHLC))
|
||||
sy+=16;
|
||||
//--- creation Buttons
|
||||
m_button_prev.Create(0,"ButtonPrev",0,10,sy,100,20);
|
||||
m_button_prev.Description("Prev Order");
|
||||
m_button_prev.Color(Red);
|
||||
m_button_prev.FontSize(8);
|
||||
//---
|
||||
m_button_next.Create(0,"ButtonNext",0,110,sy,100,20);
|
||||
m_button_next.Description("Next Order");
|
||||
m_button_next.Color(Red);
|
||||
m_button_next.FontSize(8);
|
||||
//---
|
||||
sy+=20;
|
||||
//--- creation Labels[]
|
||||
for(i=0;i<20;i++)
|
||||
{
|
||||
m_label[i].Create(0,"Label"+IntegerToString(i),0,20,sy+dy*i);
|
||||
m_label[i].Description(init_str[i]);
|
||||
m_label[i].Color(color_label);
|
||||
m_label[i].FontSize(8);
|
||||
//---
|
||||
m_label_info[i].Create(0,"LabelInfo"+IntegerToString(i),0,120,sy+dy*i);
|
||||
m_label_info[i].Description(" ");
|
||||
m_label_info[i].Color(color_info);
|
||||
m_label_info[i].FontSize(8);
|
||||
}
|
||||
InfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Deinit. |
|
||||
//+------------------------------------------------------------------+
|
||||
void COrderInfoSample::Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Processing. |
|
||||
//+------------------------------------------------------------------+
|
||||
void COrderInfoSample::Processing(void)
|
||||
{
|
||||
ulong ticket;
|
||||
//---
|
||||
if(m_total_ord!=OrdersTotal())
|
||||
{
|
||||
m_total_ord=OrdersTotal();
|
||||
if(m_total_ord==0)
|
||||
{
|
||||
m_label_info[0].Description("0");
|
||||
m_label_info[1].Description("");
|
||||
m_curr_ord=-1;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label_info[0].Description(IntegerToString(m_total_ord));
|
||||
if(m_curr_ord==-1)
|
||||
m_curr_ord=0;
|
||||
if(m_curr_ord>=m_total_ord)
|
||||
m_curr_ord=m_total_ord-1;
|
||||
m_label_info[1].Description(IntegerToString(m_curr_ord));
|
||||
}
|
||||
}
|
||||
if(m_button_prev.State())
|
||||
{
|
||||
m_button_prev.State(false);
|
||||
if(m_curr_ord>=0)
|
||||
m_label_info[1].Description(IntegerToString(--m_curr_ord));
|
||||
}
|
||||
if(m_button_next.State())
|
||||
{
|
||||
m_button_next.State(false);
|
||||
if(m_curr_ord<m_total_ord-1)
|
||||
m_label_info[1].Description(IntegerToString(++m_curr_ord));
|
||||
}
|
||||
ticket=OrderGetTicket(m_curr_ord);
|
||||
if(OrderSelect(ticket))
|
||||
{
|
||||
m_label_info[2].Description(IntegerToString(ticket));
|
||||
InfoToChart();
|
||||
}
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
Sleep(250);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method InfoToChart. |
|
||||
//+------------------------------------------------------------------+
|
||||
void COrderInfoSample::InfoToChart(void)
|
||||
{
|
||||
m_label_info[3].Description(m_order.Symbol());
|
||||
m_label_info[4].Description(TimeToString(m_order.TimeSetup()));
|
||||
m_label_info[5].Description(m_order.TypeDescription());
|
||||
m_label_info[6].Description(m_order.StateDescription());
|
||||
m_label_info[7].Description(TimeToString(m_order.TimeExpiration()));
|
||||
m_label_info[8].Description(TimeToString(m_order.TimeDone()));
|
||||
m_label_info[9].Description(m_order.TypeFillingDescription());
|
||||
m_label_info[10].Description(m_order.TypeTimeDescription());
|
||||
m_label_info[11].Description(IntegerToString(m_order.Magic()));
|
||||
m_label_info[12].Description(DoubleToString(m_order.VolumeInitial()));
|
||||
m_label_info[13].Description(DoubleToString(m_order.VolumeCurrent()));
|
||||
m_label_info[14].Description(DoubleToString(m_order.PriceOpen()));
|
||||
m_label_info[15].Description(DoubleToString(m_order.StopLoss()));
|
||||
m_label_info[16].Description(DoubleToString(m_order.TakeProfit()));
|
||||
m_label_info[17].Description(DoubleToString(m_order.PriceCurrent()));
|
||||
m_label_info[18].Description(DoubleToString(m_order.PriceStopLimit()));
|
||||
m_label_info[19].Description(m_order.Comment());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(ExtScript.Init()==0)
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
ExtScript.Processing();
|
||||
}
|
||||
//--- call deinit function
|
||||
ExtScript.Deinit();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,17 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| OrderInfoSampleInit.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Arrays to initialize graphics objects OrderInfoSample. |
|
||||
//+------------------------------------------------------------------+
|
||||
string init_str[]=
|
||||
{
|
||||
"Total","Current","Ticket","Symbol","TimeSetup",
|
||||
"Type","State","TimeExpiration","TimeDone","TypeFilling",
|
||||
"TypeTime","Expert","VolumeInit","VolumeCurr","PriceOpen",
|
||||
"StopLoss","TakeProfit","PriceCurr","PriceStopLimit","Comment"
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,196 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| PositionInfoSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#include <Trade\PositionInfo.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//---
|
||||
#include "PositionInfoSampleInit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to testing the use of class CPositionInfo. |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Position Info Sample script class |
|
||||
//+------------------------------------------------------------------+
|
||||
class CPositionInfoSample
|
||||
{
|
||||
protected:
|
||||
CPositionInfo m_position;
|
||||
//--- chart objects
|
||||
CChartObjectButton m_button_prev;
|
||||
CChartObjectButton m_button_next;
|
||||
CChartObjectLabel m_label[19];
|
||||
CChartObjectLabel m_label_info[19];
|
||||
//---
|
||||
int curr_pos;
|
||||
int total_pos;
|
||||
|
||||
public:
|
||||
CPositionInfoSample(void);
|
||||
~CPositionInfoSample(void);
|
||||
//---
|
||||
bool Init();
|
||||
void Deinit();
|
||||
void Processing();
|
||||
|
||||
private:
|
||||
void CheckButtons();
|
||||
void InfoToChart();
|
||||
};
|
||||
//---
|
||||
CPositionInfoSample ExtScript;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPositionInfoSample::CPositionInfoSample(void) : curr_pos(-1),
|
||||
total_pos(-1)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CPositionInfoSample::~CPositionInfoSample(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Init. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CPositionInfoSample::Init(void)
|
||||
{
|
||||
int i,sy=10;
|
||||
int dy=16;
|
||||
color color_label;
|
||||
color color_info;
|
||||
//--- tuning colors
|
||||
color_info =(color)(ChartGetInteger(0,CHART_COLOR_BACKGROUND)^0xFFFFFF);
|
||||
color_label=(color)(color_info^0x202020);
|
||||
//---
|
||||
if(ChartGetInteger(0,CHART_SHOW_OHLC))
|
||||
sy+=16;
|
||||
//--- creation Buttons
|
||||
m_button_prev.Create(0,"ButtonPrev",0,10,sy,100,20);
|
||||
m_button_prev.Description("Prev Position");
|
||||
m_button_prev.Color(Red);
|
||||
m_button_prev.FontSize(8);
|
||||
//---
|
||||
m_button_next.Create(0,"ButtonNext",0,110,sy,100,20);
|
||||
m_button_next.Description("Next Position");
|
||||
m_button_next.Color(Red);
|
||||
m_button_next.FontSize(8);
|
||||
//---
|
||||
sy+=20;
|
||||
//--- creation Labels[]
|
||||
for(i=0;i<13;i++)
|
||||
{
|
||||
m_label[i].Create(0,"Label"+IntegerToString(i),0,20,sy+dy*i);
|
||||
m_label[i].Description(init_str[i]);
|
||||
m_label[i].Color(color_label);
|
||||
m_label[i].FontSize(8);
|
||||
//---
|
||||
m_label_info[i].Create(0,"LabelInfo"+IntegerToString(i),0,120,sy+dy*i);
|
||||
m_label_info[i].Description(" ");
|
||||
m_label_info[i].Color(color_info);
|
||||
m_label_info[i].FontSize(8);
|
||||
}
|
||||
InfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Deinit. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CPositionInfoSample::Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Processing. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CPositionInfoSample::Processing(void)
|
||||
{
|
||||
if(total_pos!=PositionsTotal())
|
||||
{
|
||||
total_pos=PositionsTotal();
|
||||
if(total_pos==0)
|
||||
{
|
||||
m_label_info[0].Description("0");
|
||||
m_label_info[1].Description("");
|
||||
curr_pos=-1;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label_info[0].Description(IntegerToString(total_pos));
|
||||
if(curr_pos==-1)
|
||||
curr_pos=0;
|
||||
if(curr_pos>=total_pos)
|
||||
curr_pos=total_pos-1;
|
||||
m_label_info[1].Description(IntegerToString(curr_pos));
|
||||
}
|
||||
}
|
||||
CheckButtons();
|
||||
PositionSelect(PositionGetSymbol(curr_pos));
|
||||
InfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
Sleep(250);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method InfoToChart. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CPositionInfoSample::CheckButtons(void)
|
||||
{
|
||||
if(m_button_prev.State())
|
||||
{
|
||||
m_button_prev.State(false);
|
||||
if(curr_pos>0)
|
||||
m_label_info[1].Description(IntegerToString(--curr_pos));
|
||||
}
|
||||
if(m_button_next.State())
|
||||
{
|
||||
m_button_next.State(false);
|
||||
if(curr_pos<total_pos-1)
|
||||
m_label_info[1].Description(IntegerToString(++curr_pos));
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Function for display position info |
|
||||
//+------------------------------------------------------------------+
|
||||
void CPositionInfoSample::InfoToChart(void)
|
||||
{
|
||||
m_label_info[2].Description(m_position.Symbol());
|
||||
m_label_info[3].Description(TimeToString(m_position.Time()));
|
||||
m_label_info[4].Description(m_position.TypeDescription());
|
||||
m_label_info[5].Description(DoubleToString(m_position.Volume()));
|
||||
m_label_info[6].Description(DoubleToString(m_position.PriceOpen()));
|
||||
m_label_info[7].Description(DoubleToString(m_position.StopLoss()));
|
||||
m_label_info[8].Description(DoubleToString(m_position.TakeProfit()));
|
||||
m_label_info[9].Description(DoubleToString(m_position.PriceCurrent()));
|
||||
m_label_info[10].Description(DoubleToString(m_position.Commission()));
|
||||
m_label_info[11].Description(DoubleToString(m_position.Swap()));
|
||||
m_label_info[12].Description(DoubleToString(m_position.Profit()));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(ExtScript.Init()==0)
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
ExtScript.Processing();
|
||||
}
|
||||
//--- call deinit function
|
||||
ExtScript.Deinit();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,16 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| PositionInfoSampleInit.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Arrays to initialize graphics objects PositionInfoSample. |
|
||||
//+------------------------------------------------------------------+
|
||||
string init_str[]=
|
||||
{
|
||||
"Total","Current","Symbol","Time","Type",
|
||||
"Volume","PriceOpen","StopLoss","TakeProfit","PriceCurrent",
|
||||
"Commission","Swap","Profit"
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,214 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SymbolInfoSample.mq5 |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
//---
|
||||
#property script_show_inputs
|
||||
//---
|
||||
input bool InpMarketWatch=true;
|
||||
//---
|
||||
#include <Trade\SymbolInfo.mqh>
|
||||
#include <ChartObjects\ChartObjectsTxtControls.mqh>
|
||||
//---
|
||||
#include "SymbolInfoSampleInit.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script to sample the use of class CSymbolInfo. |
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
//| Symbol Info Sample script class |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSymbolInfoSample
|
||||
{
|
||||
protected:
|
||||
CSymbolInfo m_symbol;
|
||||
//--- chart objects
|
||||
CChartObjectButton m_buttons[];
|
||||
int m_num_symbols;
|
||||
CChartObjectLabel m_label[40];
|
||||
CChartObjectLabel m_label_info[40];
|
||||
//---
|
||||
int m_symbol_idx;
|
||||
|
||||
public:
|
||||
CSymbolInfoSample(void);
|
||||
~CSymbolInfoSample(void);
|
||||
//---
|
||||
bool Init(void);
|
||||
void Deinit(void);
|
||||
void Processing(void);
|
||||
|
||||
private:
|
||||
void InfoToChart(void);
|
||||
};
|
||||
//---
|
||||
CSymbolInfoSample ExtScript;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSymbolInfoSample::CSymbolInfoSample(void) : m_symbol_idx(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSymbolInfoSample::~CSymbolInfoSample(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Init. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSymbolInfoSample::Init(void)
|
||||
{
|
||||
int i,sy=10;
|
||||
int dy=16;
|
||||
color color_label;
|
||||
color color_info;
|
||||
//--- tuning colors
|
||||
color_info =(color)(ChartGetInteger(0,CHART_COLOR_BACKGROUND)^0xFFFFFF);
|
||||
color_label=(color)(color_info^0x202020);
|
||||
//---
|
||||
if(ChartGetInteger(0,CHART_SHOW_OHLC)) sy+=16;
|
||||
//---
|
||||
m_num_symbols=SymbolsTotal(InpMarketWatch);
|
||||
ArrayResize(m_buttons,m_num_symbols);
|
||||
//--- creation Button[]
|
||||
for(i=0;i<m_num_symbols;i++)
|
||||
{
|
||||
m_buttons[i].Create(0,"Button"+IntegerToString(i),0,10+50*(i%10),sy+20*(i/10),50,20);
|
||||
m_buttons[i].Description(SymbolName(i,InpMarketWatch));
|
||||
m_buttons[i].Color(Red);
|
||||
m_buttons[i].FontSize(8);
|
||||
}
|
||||
m_symbol_idx=0;
|
||||
m_buttons[0].State(true);
|
||||
m_symbol.Name(m_buttons[0].Description());
|
||||
sy+=20*(1+i/10);
|
||||
//--- creation Labels[]
|
||||
for(i=0;i<40;i++)
|
||||
{
|
||||
m_label[i].Create(0,"Label"+IntegerToString(i),0,init_l_x[i],sy+dy*init_l_y[i]);
|
||||
m_label[i].Description(init_l_str[i]);
|
||||
m_label[i].Color(color_label);
|
||||
m_label[i].FontSize(8);
|
||||
//---
|
||||
m_label_info[i].Create(0,"LabelInfo"+IntegerToString(i),0,init_li_x[i],sy+dy*init_l_y[i]);
|
||||
m_label_info[i].Description(" ");
|
||||
m_label_info[i].Color(color_info);
|
||||
m_label_info[i].FontSize(8);
|
||||
}
|
||||
InfoToChart();
|
||||
//--- redraw chart
|
||||
ChartRedraw();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Deinit. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSymbolInfoSample::Deinit(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method Processing. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSymbolInfoSample::Processing(void)
|
||||
{
|
||||
int i;
|
||||
//---
|
||||
if(!m_buttons[m_symbol_idx].State())
|
||||
m_buttons[m_symbol_idx].State(true);
|
||||
for(i=0;i<m_num_symbols;i++)
|
||||
{
|
||||
if(m_buttons[i].State() && m_symbol_idx!=i)
|
||||
{
|
||||
m_buttons[m_symbol_idx].State(false);
|
||||
m_symbol_idx=i;
|
||||
m_symbol.Name(m_buttons[i].Description());
|
||||
}
|
||||
}
|
||||
m_symbol.RefreshRates();
|
||||
InfoToChart();
|
||||
//--- redraw chart (with the processing of events)
|
||||
ChartRedraw();
|
||||
Sleep(50);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Method InfoToChart. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSymbolInfoSample::InfoToChart(void)
|
||||
{
|
||||
int digits=m_symbol.Digits();
|
||||
//--- display volumes
|
||||
m_label_info[0].Description((string)m_symbol.Volume());
|
||||
m_label_info[1].Description((string)m_symbol.VolumeHigh());
|
||||
m_label_info[2].Description((string)m_symbol.VolumeLow());
|
||||
//--- display miscellaneous
|
||||
m_label_info[5].Description(TimeToString(m_symbol.Time()));
|
||||
m_label_info[6].Description((string)m_symbol.Digits());
|
||||
m_label_info[7].Description((string)m_symbol.Spread());
|
||||
m_label_info[8].Description((string)m_symbol.TicksBookDepth());
|
||||
//--- display terms of trade
|
||||
m_label_info[9].Description(m_symbol.TradeCalcModeDescription());
|
||||
m_label_info[10].Description(m_symbol.TradeModeDescription());
|
||||
//--- display trade levels
|
||||
m_label_info[11].Description((string)m_symbol.StopsLevel());
|
||||
m_label_info[12].Description((string)m_symbol.FreezeLevel());
|
||||
//--- display execution terms of trade
|
||||
m_label_info[13].Description(m_symbol.TradeExecutionDescription());
|
||||
//--- display swap terms of trade
|
||||
m_label_info[14].Description(m_symbol.SwapModeDescription());
|
||||
m_label_info[15].Description(m_symbol.SwapRollover3daysDescription());
|
||||
//--- display bid
|
||||
m_label_info[16].Description(DoubleToString(m_symbol.Bid(),digits));
|
||||
m_label_info[17].Description(DoubleToString(m_symbol.BidHigh(),digits));
|
||||
m_label_info[18].Description(DoubleToString(m_symbol.BidLow(),digits));
|
||||
//--- display ask
|
||||
m_label_info[19].Description(DoubleToString(m_symbol.Ask(),digits));
|
||||
m_label_info[20].Description(DoubleToString(m_symbol.AskHigh(),digits));
|
||||
m_label_info[21].Description(DoubleToString(m_symbol.AskLow(),digits));
|
||||
//--- display last
|
||||
m_label_info[22].Description(DoubleToString(m_symbol.Last(),digits));
|
||||
m_label_info[23].Description(DoubleToString(m_symbol.LastHigh(),digits));
|
||||
m_label_info[24].Description(DoubleToString(m_symbol.LastLow(),digits));
|
||||
//--- display tick
|
||||
m_label_info[25].Description(DoubleToString(m_symbol.Point(),digits));
|
||||
m_label_info[26].Description(DoubleToString(m_symbol.TickValue()));
|
||||
m_label_info[27].Description(DoubleToString(m_symbol.TickSize()));
|
||||
m_label_info[28].Description(DoubleToString(m_symbol.ContractSize()));
|
||||
//--- display lots
|
||||
m_label_info[29].Description(DoubleToString(m_symbol.LotsMin(),2));
|
||||
m_label_info[30].Description(DoubleToString(m_symbol.LotsMax(),2));
|
||||
m_label_info[31].Description(DoubleToString(m_symbol.LotsStep(),2));
|
||||
//--- display swaps
|
||||
m_label_info[32].Description(DoubleToString(m_symbol.SwapLong(),2));
|
||||
m_label_info[33].Description(DoubleToString(m_symbol.SwapShort(),2));
|
||||
//--- display currency
|
||||
m_label_info[34].Description(m_symbol.CurrencyBase());
|
||||
m_label_info[35].Description(m_symbol.CurrencyProfit());
|
||||
m_label_info[36].Description(m_symbol.CurrencyMargin());
|
||||
//--- display another
|
||||
m_label_info[37].Description(m_symbol.Bank());
|
||||
m_label_info[38].Description(m_symbol.Description());
|
||||
m_label_info[39].Description(m_symbol.Path());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnStart(void)
|
||||
{
|
||||
//--- call init function
|
||||
if(ExtScript.Init()==0)
|
||||
{
|
||||
//--- cycle until the script is not halted
|
||||
while(!IsStopped())
|
||||
ExtScript.Processing();
|
||||
}
|
||||
//--- call deinit function
|
||||
ExtScript.Deinit();
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,40 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSymbolInfoInit.mqh |
|
||||
//| Copyright 2009-2017, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//---
|
||||
//+------------------------------------------------------------------+
|
||||
//| Arrays to initialize graphics objects SymbolInfoSample. |
|
||||
//+------------------------------------------------------------------+
|
||||
//--- for ExtLabel[]
|
||||
int init_l_x[]=
|
||||
{
|
||||
20,220,420,220,420,20,20,220,20,20,
|
||||
20,20,220,20,20,20,20,220,420,20,
|
||||
220,420,20,220,420,20,20,220,20,20,
|
||||
220,420,20,220,20,220,420,20,20,20
|
||||
};
|
||||
int init_l_y[]=
|
||||
{
|
||||
1,1,1,2,2,3,4,4,5,6,
|
||||
7,8,8,9,10,11,12,12,12,13,
|
||||
13,13,14,14,14,15,16,16,17,18,
|
||||
18,18,19,19,20,20,20,21,22,23
|
||||
};
|
||||
string init_l_str[]=
|
||||
{
|
||||
"Volume","VolumeHigh","VolumeLow","VolumeBid","VolumeAsk","Time","Digits","Spread","TicksBookDepth","TradeCalcMode",
|
||||
"TradeMode","StopsLevel","FreezeLevel","TradeExecution","SwapMode","SwapRollover3days","Bid","BidHigh","BidLow","Ask",
|
||||
"AskHigh","AskLow","Last","LastHigh","LastLow","Point","TickValue","TickSize","ContractSize","VolumeMin",
|
||||
"VolumeMax","VolumeStep","SwapLong","SwapShort","CurrencyBase","CurrencyProfit","CurrencyMargin","Bank","Description","Path"
|
||||
};
|
||||
//--- for ExtLabelInfo[]
|
||||
int init_li_x[]=
|
||||
{
|
||||
120,320,520,320,520,120,120,320,120,120,
|
||||
120,120,320,120,120,120,120,320,520,120,
|
||||
320,520,120,320,520,120,120,320,120,120,
|
||||
320,520,120,320,120,320,520,120,120,120
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,427 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestClasses.mq5 |
|
||||
//| Copyright 2003-2012 Sergey Bochkanov (ALGLIB project) |
|
||||
//| Copyright 2012-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Implementation of ALGLIB library in MetaQuotes Language 5 |
|
||||
//| |
|
||||
//| The features of the library include: |
|
||||
//| - Linear algebra (direct algorithms, EVD, SVD) |
|
||||
//| - Solving systems of linear and non-linear equations |
|
||||
//| - Interpolation |
|
||||
//| - Optimization |
|
||||
//| - FFT (Fast Fourier Transform) |
|
||||
//| - Numerical integration |
|
||||
//| - Linear and nonlinear least-squares fitting |
|
||||
//| - Ordinary differential equations |
|
||||
//| - Computation of special functions |
|
||||
//| - Descriptive statistics and hypothesis testing |
|
||||
//| - Data analysis - classification, regression |
|
||||
//| - Implementing linear algebra algorithms, interpolation, etc. |
|
||||
//| in high-precision arithmetic (using MPFR) |
|
||||
//| |
|
||||
//| This file is free software; you can redistribute it and/or |
|
||||
//| modify it under the terms of the GNU General Public License as |
|
||||
//| published by the Free Software Foundation (www.fsf.org); either |
|
||||
//| version 2 of the License, or (at your option) any later version. |
|
||||
//| |
|
||||
//| This program is distributed in the hope that it will be useful, |
|
||||
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
//| GNU General Public License for more details. |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "TestClasses.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Testing script |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
uint seed;
|
||||
int result;
|
||||
bool silent;
|
||||
//--- setting this option to generate random numbers
|
||||
_RandomSeed=GetTickCount();
|
||||
//--- initialization
|
||||
seed=_RandomSeed;
|
||||
result=0;
|
||||
silent=true;
|
||||
//--- start time
|
||||
Print(TimeLocal());
|
||||
//--- seed
|
||||
PrintFormat("RandomSeed = %d",seed);
|
||||
//--- check class
|
||||
if(CTestHQRndUnit::TestHQRnd(silent))
|
||||
PrintFormat("CHighQualityRand: OK");
|
||||
else
|
||||
PrintFormat("CHighQualityRand: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestTSortUnit::TestTSort(silent))
|
||||
PrintFormat("CTSort: OK");
|
||||
else
|
||||
PrintFormat("CTSort: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestNearestNeighborUnit::TestNearestNeighbor(silent))
|
||||
PrintFormat("CNearestNeighbor: OK");
|
||||
else
|
||||
PrintFormat("CNearestNeighbor: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestAblasUnit::TestAblas(silent))
|
||||
PrintFormat("CAblas: OK");
|
||||
else
|
||||
PrintFormat("CAblas: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestBaseStatUnit::TestBaseStat(silent))
|
||||
PrintFormat("CBaseStat: OK");
|
||||
else
|
||||
PrintFormat("CBaseStat: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestBdSSUnit::TestBdSS(silent))
|
||||
PrintFormat("CBdSS: OK");
|
||||
else
|
||||
PrintFormat("CBdSS: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestDForestUnit::TestDForest(silent))
|
||||
PrintFormat("CDForest: OK");
|
||||
else
|
||||
PrintFormat("CDForest: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestBlasUnit::TestBlas(silent))
|
||||
PrintFormat("CBlas: OK");
|
||||
else
|
||||
PrintFormat("CBlas: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestKMeansUnit::TestKMeans(silent))
|
||||
PrintFormat("CKMeans: OK");
|
||||
else
|
||||
PrintFormat("CKMeans: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestHblasUnit::TestHblas(silent))
|
||||
PrintFormat("CHblas: OK");
|
||||
else
|
||||
PrintFormat("CHblas: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestReflectionsUnit::TestReflections(silent))
|
||||
PrintFormat("CReflections: OK");
|
||||
else
|
||||
PrintFormat("CReflections: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestCReflectionsUnit::TestCReflections(silent))
|
||||
PrintFormat("CComplexReflections: OK");
|
||||
else
|
||||
PrintFormat("CComplexReflections: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSblasUnit::TestSblas(silent))
|
||||
PrintFormat("CSblas: OK");
|
||||
else
|
||||
PrintFormat("CSblas: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestOrtFacUnit::TestOrtFac(silent))
|
||||
PrintFormat("COrtFac: OK");
|
||||
else
|
||||
PrintFormat("COrtFac: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestEVDUnit::TestEVD(silent))
|
||||
PrintFormat("CEigenVDetect: OK");
|
||||
else
|
||||
PrintFormat("CEigenVDetect: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMatGenUnit::TestMatGen(silent))
|
||||
PrintFormat("CMatGen: OK");
|
||||
else
|
||||
PrintFormat("CMatGen: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestTrFacUnit::TestTrFac(silent))
|
||||
PrintFormat("CTrFac: OK");
|
||||
else
|
||||
PrintFormat("CTrFac: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestTrLinSolveUnit::TestTrLinSolve(silent))
|
||||
PrintFormat("CTrLinSolve: OK");
|
||||
else
|
||||
PrintFormat("CTrLinSolve: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSafeSolveUnit::TestSafeSolve(silent))
|
||||
PrintFormat("CSafeSolve: OK");
|
||||
else
|
||||
PrintFormat("CSafeSolve: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestRCondUnit::TestRCond(silent))
|
||||
PrintFormat("CRCond: OK");
|
||||
else
|
||||
PrintFormat("CRCond: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMatInvUnit::TestMatInv(silent))
|
||||
PrintFormat("CMatInv: OK");
|
||||
else
|
||||
PrintFormat("CMatInv: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLDAUnit::TestLDA(silent))
|
||||
PrintFormat("CLDA: OK");
|
||||
else
|
||||
PrintFormat("CLDA: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestGammaFuncUnit::TestGammaFunc(silent))
|
||||
PrintFormat("CGammaFunc: OK");
|
||||
else
|
||||
PrintFormat("CGammaFunc: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestBdSVDUnit::TestBdSVD(silent))
|
||||
PrintFormat("CBdSingValueDecompose: OK");
|
||||
else
|
||||
PrintFormat("CBdSingValueDecompose: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSVDUnit::TestSVD(silent))
|
||||
PrintFormat("CSingValueDecompose: OK");
|
||||
else
|
||||
PrintFormat("CSingValueDecompose: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLinRegUnit::TestLinReg(silent))
|
||||
PrintFormat("CLinReg: OK");
|
||||
else
|
||||
PrintFormat("CLinReg: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestXBlasUnit::TestXBlas(silent))
|
||||
PrintFormat("CXblas: OK");
|
||||
else
|
||||
PrintFormat("CXblas: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestDenseSolverUnit::TestDenseSolver(silent))
|
||||
PrintFormat("CDenseSolver: OK");
|
||||
else
|
||||
PrintFormat("CDenseSolver: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLinMinUnit::TestLinMin(silent))
|
||||
PrintFormat("CLinMin: OK");
|
||||
else
|
||||
PrintFormat("CLinMin: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMinCGUnit::TestMinCG(silent))
|
||||
PrintFormat("CMinCG: OK");
|
||||
else
|
||||
PrintFormat("CMinCG: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMinBLEICUnit::TestMinBLEIC(silent))
|
||||
PrintFormat("CMinBLEIC: OK");
|
||||
else
|
||||
PrintFormat("CMinBLEIC: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMCPDUnit::TestMCPD(silent))
|
||||
PrintFormat("CMarkovCPD: OK");
|
||||
else
|
||||
PrintFormat("CMarkovCPD: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestFblsUnit::TestFbls(silent))
|
||||
PrintFormat("CFbls: OK");
|
||||
else
|
||||
PrintFormat("CFbls: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMinLBFGSUnit::TestMinLBFGS(silent))
|
||||
PrintFormat("CMinLBFGS: OK");
|
||||
else
|
||||
PrintFormat("CMinLBFGS: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMLPTrainUnit::TestMLPTrain(silent))
|
||||
PrintFormat("CMLPTrain: OK");
|
||||
else
|
||||
PrintFormat("CMLPTrain: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMLPEUnit::TestMLPE(silent))
|
||||
PrintFormat("CMLPE: OK");
|
||||
else
|
||||
PrintFormat("CMLPE: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestPCAUnit::TestPCA(silent))
|
||||
PrintFormat("CPCAnalysis: OK");
|
||||
else
|
||||
PrintFormat("CPCAnalysis: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestODESolverUnit::TestODESolver(silent))
|
||||
PrintFormat("CODESolver: OK");
|
||||
else
|
||||
PrintFormat("CODESolver: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestFFTUnit::TestFFT(silent))
|
||||
PrintFormat("CFastFourierTransform: OK");
|
||||
else
|
||||
PrintFormat("CFastFourierTransform: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestConvUnit::TestConv(silent))
|
||||
PrintFormat("CConv: OK");
|
||||
else
|
||||
PrintFormat("CConv: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestCorrUnit::TestCorr(silent))
|
||||
PrintFormat("CCorr: OK");
|
||||
else
|
||||
PrintFormat("CCorr: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestFHTUnit::TestFHT(silent))
|
||||
PrintFormat("CFastHartleyTransform: OK");
|
||||
else
|
||||
PrintFormat("CFastHartleyTransform: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestGQUnit::TestGQ(silent))
|
||||
PrintFormat("CGaussQ: OK");
|
||||
else
|
||||
PrintFormat("CGaussQ: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestGKQUnit::TestGKQ(silent))
|
||||
PrintFormat("CGaussKronrodQ: OK");
|
||||
else
|
||||
PrintFormat("CGaussKronrodQ: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestAutoGKUnit::TestAutoGK(silent))
|
||||
PrintFormat("CAutoGK: OK");
|
||||
else
|
||||
PrintFormat("CAutoGK: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestIDWIntUnit::TestIDWInt(silent))
|
||||
PrintFormat("CIDWInt: OK");
|
||||
else
|
||||
PrintFormat("CIDWInt: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestRatIntUnit::TestRatInt(silent))
|
||||
PrintFormat("CRatInt: OK");
|
||||
else
|
||||
PrintFormat("CRatInt: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestPolIntUnit::TestPolInt(silent))
|
||||
PrintFormat("CPolInt: OK");
|
||||
else
|
||||
PrintFormat("CPolInt: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSpline1DUnit::TestSpline1D(silent))
|
||||
PrintFormat("CSpline1D: OK");
|
||||
else
|
||||
PrintFormat("CSpline1D: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestMinLMUnit::TestMinLM(silent))
|
||||
PrintFormat("CMinLM: OK");
|
||||
else
|
||||
PrintFormat("CMinLM: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLSFitUnit::TestLSFit(silent))
|
||||
PrintFormat("CLSFit: OK");
|
||||
else
|
||||
PrintFormat("CLSFit: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestPSplineUnit::TestPSpline(silent))
|
||||
PrintFormat("CPSpline: OK");
|
||||
else
|
||||
PrintFormat("CPSpline: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSpline2DUnit::TestSpline2D(silent))
|
||||
PrintFormat("CSpline2D: OK");
|
||||
else
|
||||
PrintFormat("CSpline2D: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSpdGEVDUnit::TestSpdGEVD(silent))
|
||||
PrintFormat("CSpdGEVD: OK");
|
||||
else
|
||||
PrintFormat("CSpdGEVD: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestInverseUpdateUnit::TestInverseUpdate(silent))
|
||||
PrintFormat("CInverseUpdate: OK");
|
||||
else
|
||||
PrintFormat("CInverseUpdate: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestSchurUnit::TestSchur(silent))
|
||||
PrintFormat("CSchur: OK");
|
||||
else
|
||||
PrintFormat("CSchur: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestNlEqUnit::TestNlEq(silent))
|
||||
PrintFormat("CNlEq: OK");
|
||||
else
|
||||
PrintFormat("CNlEq: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestChebyshevUnit::TestChebyshev(silent))
|
||||
PrintFormat("CChebyshev: OK");
|
||||
else
|
||||
PrintFormat("CChebyshev: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestHermiteUnit::TestHermite(silent))
|
||||
PrintFormat("CHermite: OK");
|
||||
else
|
||||
PrintFormat("CHermite: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLaguerreUnit::TestLaguerre(silent))
|
||||
PrintFormat("CLaguerre: OK");
|
||||
else
|
||||
PrintFormat("CLaguerre: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestLegendreUnit::TestLegendre(silent))
|
||||
PrintFormat("CLegendre: OK");
|
||||
else
|
||||
PrintFormat("CLegendre: FAILED(seed=%d)",seed);
|
||||
//--- check class
|
||||
_RandomSeed=seed;
|
||||
if(CTestAlglibBasicsUnit::TestAlglibBasics(silent))
|
||||
PrintFormat("AlglibBasics: OK");
|
||||
else
|
||||
PrintFormat("AlglibBasics: FAILED(seed=%d)",seed);
|
||||
//--- finish time
|
||||
Print(TimeLocal());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestInterfaces.mq5 |
|
||||
//| Copyright 2003-2012 Sergey Bochkanov (ALGLIB project) |
|
||||
//| Copyright 2012-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Implementation of ALGLIB library in MetaQuotes Language 5 |
|
||||
//| |
|
||||
//| The features of the library include: |
|
||||
//| - Linear algebra (direct algorithms, EVD, SVD) |
|
||||
//| - Solving systems of linear and non-linear equations |
|
||||
//| - Interpolation |
|
||||
//| - Optimization |
|
||||
//| - FFT (Fast Fourier Transform) |
|
||||
//| - Numerical integration |
|
||||
//| - Linear and nonlinear least-squares fitting |
|
||||
//| - Ordinary differential equations |
|
||||
//| - Computation of special functions |
|
||||
//| - Descriptive statistics and hypothesis testing |
|
||||
//| - Data analysis - classification, regression |
|
||||
//| - Implementing linear algebra algorithms, interpolation, etc. |
|
||||
//| in high-precision arithmetic (using MPFR) |
|
||||
//| |
|
||||
//| This program is free software; you can redistribute it and/or |
|
||||
//| modify it under the terms of the GNU General Public License as |
|
||||
//| published by the Free Software Foundation (www.fsf.org); either |
|
||||
//| version 2 of the License, or (at your option) any later version. |
|
||||
//| |
|
||||
//| This program is distributed in the hope that it will be useful, |
|
||||
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
//| GNU General Public License for more details. |
|
||||
//+------------------------------------------------------------------+
|
||||
#include "TestInterfaces.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Testing script |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
//--- total result
|
||||
bool _TotalResult=true;
|
||||
//--- temp result
|
||||
bool _TestResult;
|
||||
//--- spoil scenario
|
||||
int _spoil_scenario;
|
||||
Print("MQL5 interface tests. Please wait...");
|
||||
Print("0/91");
|
||||
//--- testing
|
||||
TEST_NNeighbor_D_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_NNeighbor_T_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_NNeighbor_D_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_D_Base(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_D_C2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_D_CM(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_D_CM2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_T_Base(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_BaseStat_T_CovCorr(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_D_R1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_D_C1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_D_SPD1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_D_HPD1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_T_R1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_T_C1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_E_SPD1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatInv_E_HPD1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinCG_D_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinCG_D_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinCG_NumDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinCG_FTRIM(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinBLEIC_D_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinBLEIC_D_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinBLEIC_NumDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinBLEIC_FTRIM(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MCPD_Simple1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MCPD_Simple2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLBFGS_D_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLBFGS_D_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLBFGS_NumDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLBFGS_FTRIM(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_ODESolver_D1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_FFT_Complex_D1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_FFT_Complex_D2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_FFT_Real_D1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_FFT_Real_D2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_FFT_Complex_E1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_AutoGK_D1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_D_CalcDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_D_Conv(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_D_Spec(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_3(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_4(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_5(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_6(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_7(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_8(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_9(_spoil_scenario,_TestResult,_TotalResult);
|
||||
//--- 50 blocks were successful
|
||||
Print("50/91");
|
||||
TEST_PolInt_T_10(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_11(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_12(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_PolInt_T_13(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_Spline1D_D_Linear(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_Spline1D_D_Cubic(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_Spline1D_D_GridDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_Spline1D_D_ConvDiff(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinQP_D_U1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinQP_D_BC1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_D_V(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_D_VJ(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_D_FGH(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_D_VB(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_D_Restarts(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_T_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MinLM_T_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_NLF(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_NLFG(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_NLFGH(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_NLFB(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_NLScale(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_Lin(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_Linc(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_Pol(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_Polc(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_D_Spline(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_T_PolFit_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_T_PolFit_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_LSFit_T_PolFit_3(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_D_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_D_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_D_3(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_D_4(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_D_5(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_0(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_1(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_2(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_3(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_4(_spoil_scenario,_TestResult,_TotalResult);
|
||||
TEST_MatDet_T_5(_spoil_scenario,_TestResult,_TotalResult);
|
||||
//--- all blocks were successful
|
||||
Print("91/91");
|
||||
//--- print total result
|
||||
Print("Result = ",_TotalResult);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,661 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFuzzy.mq5 |
|
||||
//| Copyright 2015-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
//| Implementation of Fuzzy library in MetaQuotes Language 5 |
|
||||
//| |
|
||||
//| The features of the library include: |
|
||||
//| - Create Mamdani fuzzy model |
|
||||
//| - Create Sugeno fuzzy model |
|
||||
//| - Normal membership function |
|
||||
//| - Triangular membership function |
|
||||
//| - Trapezoidal membership function |
|
||||
//| - Constant membership function |
|
||||
//| - Defuzzification method of center of gravity (COG) |
|
||||
//| - Defuzzification method of bisector of area (BOA) |
|
||||
//| - Defuzzification method of mean of maxima (MeOM) |
|
||||
//| |
|
||||
//| This file is free software; you can redistribute it and/or |
|
||||
//| modify it under the terms of the GNU General Public License as |
|
||||
//| published by the Free Software Foundation (www.fsf.org); either |
|
||||
//| version 2 of the License, or (at your option) any later version. |
|
||||
//| |
|
||||
//| This program is distributed in the hope that it will be useful, |
|
||||
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
//| GNU General Public License for more details. |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Math\Fuzzy\MamdaniFuzzySystem.mqh>
|
||||
#include <Math\Fuzzy\SugenoFuzzySystem.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_NormalCombinationMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_NormalCombinationMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4.0,5.1,0.1};
|
||||
double b1=1.2;
|
||||
double sigma1=0.45;
|
||||
double b2=3.1;
|
||||
double sigma2=0.9;
|
||||
CNormalCombinationMembershipFunction function(b1,sigma1,b2,sigma2);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=0.0;
|
||||
if(x[i]<1.2)
|
||||
{
|
||||
expected=MathExp(MathPow(x[i]-b1,2)/(-2.0*MathPow(0.45,2)));
|
||||
}
|
||||
else if(x[i]>3.1)
|
||||
{
|
||||
expected=MathExp(MathPow(x[i]-b2,2)/(-2.0*MathPow(0.9,2)));
|
||||
}
|
||||
if(MathAbs(actual-expected)>1e-20)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_GeneralizedBellShapedMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_GeneralizedBellShapedMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,5.1,0.1};
|
||||
double a = 2.4;
|
||||
double b = 0.9;
|
||||
double c = 1.33;
|
||||
CGeneralizedBellShapedMembershipFunction function(a,b,c);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=1/(1+MathPow(MathAbs((x[i]-a)/c),2*b));
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_SigmoidalMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_SigmoidalMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,4.1,0.1};
|
||||
double a = 1.75;
|
||||
double c = -M_PI/2;
|
||||
CSigmoidalMembershipFunction function(a,c);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=1/(1.0+MathExp(-a *(x[i]-c)));
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_ProductTwoSigmoidalMembershipFunctions() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_ProductTwoSigmoidalMembershipFunctions()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4.0,4.1,0.1};
|
||||
double a1 = -1.75;
|
||||
double c1 = -M_PI/2.0;
|
||||
double a2 = 0.972;
|
||||
double c2 = 0.43;
|
||||
CProductTwoSigmoidalMembershipFunctions function(a1,c1,a2,c2);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=((1.0/(1.0+MathExp(-a1 *(x[i]-c1)))) *
|
||||
(1.0/(1.0+MathExp(-a2 *(x[i]-c2)))));
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_TrapezoidMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_TrapezoidMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,3.1,0.1};
|
||||
double x1 = -4;
|
||||
double x2 = -4;
|
||||
double x3 = 2;
|
||||
double x4 = M_PI;
|
||||
CTrapezoidMembershipFunction function(x1,x2,x3,x4);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=1.0;
|
||||
if(x[i]>2 && x[i]<M_PI)
|
||||
{
|
||||
expected=(-x[i]/(x4-x3))+(x4/(x4-x3));
|
||||
}
|
||||
else if(x[i]>M_PI)
|
||||
{
|
||||
expected=0;
|
||||
}
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_NormalMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_NormalMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,5.1,0.1};
|
||||
double b=1.33;
|
||||
double sigma=0.45;
|
||||
CNormalMembershipFunction function(b,sigma);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=MathExp(MathPow(x[i]-1.33,2.0)/(-2.0*MathPow(0.45,2.0)));
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_TriangularMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_TriangularMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,4.1,0.1};
|
||||
double x1 = -M_PI;
|
||||
double x2 = -M_E/2.0;
|
||||
double x3 = M_PI/5.0;
|
||||
CTriangularMembershipFunction function(x1,x2,x3);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=0;
|
||||
if(x[i]==x2)
|
||||
{
|
||||
expected=1;
|
||||
}
|
||||
else if(x[i]>x1 && x[i]<x2)
|
||||
{
|
||||
expected=(x[i]/(x2-x1)) -(x1/(x2-x1));
|
||||
}
|
||||
else if(x[i]>x2 && x[i]<x3)
|
||||
{
|
||||
expected=(-x[i]/(x3-x2))+(x3/(x3-x2));
|
||||
}
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_ConstantMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_ConstantMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4,4.1,0.1};
|
||||
double value=1.0;
|
||||
CConstantMembershipFunction function(1.0);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=function.GetValue(x[i]);
|
||||
double expected=value;
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_P_S_Z_ShapedMembershipFunction() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_P_S_Z_ShapedMembershipFunction()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-20;
|
||||
double x[]={-4.0,4.1,0.1};
|
||||
CS_ShapedMembershipFunction sfunction(-1.0/137.0,M_PI/2.0);
|
||||
CZ_ShapedMembershipFunction zfunction(MathExp(1.0),M_PI);
|
||||
CP_ShapedMembershipFunction pfunction(-1.0/137.0,M_PI/2.0,MathExp(1.0),M_PI);
|
||||
for(int i=0; i<ArraySize(x); i++)
|
||||
{
|
||||
double actual=pfunction.GetValue(x[i]);
|
||||
double expected=sfunction.GetValue(x[i])*zfunction.GetValue(x[i]);
|
||||
if(actual!=expected)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_Bisector() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_Bisector()
|
||||
{
|
||||
double delta=1e-10;
|
||||
CMamdaniFuzzySystem system();
|
||||
system.DefuzzificationMethod(BisectorDef);
|
||||
CTriangularMembershipFunction *function=new CTriangularMembershipFunction(0,5,5);
|
||||
double actual=system.Defuzzify(function,0,5);
|
||||
double expected=3.5;
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_Centroid() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_Centroid()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-1;
|
||||
CMamdaniFuzzySystem system();
|
||||
system.DefuzzificationMethod(CentroidDef);
|
||||
double mean[]={-5,-3,-1,1,3,5};
|
||||
double sigma[]={1,2};
|
||||
for(int i=0; i<ArraySize(mean); i++)
|
||||
{
|
||||
for(int j=0; j<ArraySize(sigma); j++)
|
||||
{
|
||||
CNormalMembershipFunction *function=new CNormalMembershipFunction(mean[i],sigma[j]);
|
||||
double actual=system.Defuzzify(function,-10,10);
|
||||
double expected=mean[i];
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_Defuzzification() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_Defuzzification()
|
||||
{
|
||||
bool result=true;
|
||||
double delta=1e-12;
|
||||
CMamdaniFuzzySystem system();
|
||||
double actual=0.0;
|
||||
double expected=0.0;
|
||||
//---
|
||||
system.DefuzzificationMethod(CentroidDef);
|
||||
actual=system.Defuzzify(new CNormalMembershipFunction(0,2),-10,10);
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
//---
|
||||
system.DefuzzificationMethod(BisectorDef);
|
||||
actual=system.Defuzzify(new CNormalMembershipFunction(0,2),-10,10);
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
//---
|
||||
system.DefuzzificationMethod(AverageMaximumDef);
|
||||
actual=system.Defuzzify(new CNormalMembershipFunction(0,2),-10,10);
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
//---
|
||||
system.DefuzzificationMethod(SmallestMaximumDef);
|
||||
actual=system.Defuzzify(new CNormalMembershipFunction(0,2),-10,10);
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
//---
|
||||
system.DefuzzificationMethod(LargestMaximumDef);
|
||||
actual=system.Defuzzify(new CNormalMembershipFunction(0,2),-10,10);
|
||||
if(MathAbs(actual-expected)>=delta)
|
||||
{
|
||||
Print("Expected: ",expected," +/- ",delta," ; But was: ",actual);
|
||||
result=false;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_TipingProblem() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_TipingProblem()
|
||||
{
|
||||
//--- Mamdani Fuzzy System
|
||||
CMamdaniFuzzySystem *fsTips=new CMamdaniFuzzySystem();
|
||||
//--- Create first input variables for the system
|
||||
CFuzzyVariable *fvService=new CFuzzyVariable("service",0.0,10.0);
|
||||
fvService.Terms().Add(new CFuzzyTerm("poor", new CTriangularMembershipFunction(-5.0, 0.0, 5.0)));
|
||||
fvService.Terms().Add(new CFuzzyTerm("good", new CTriangularMembershipFunction(0.0, 5.0, 10.0)));
|
||||
fvService.Terms().Add(new CFuzzyTerm("excellent", new CTriangularMembershipFunction(5.0, 10.0, 15.0)));
|
||||
fsTips.Input().Add(fvService);
|
||||
//--- Create second input variables for the system
|
||||
CFuzzyVariable *fvFood=new CFuzzyVariable("food",0.0,10.0);
|
||||
fvFood.Terms().Add(new CFuzzyTerm("rancid", new CTrapezoidMembershipFunction(0.0, 0.0, 1.0, 3.0)));
|
||||
fvFood.Terms().Add(new CFuzzyTerm("delicious", new CTrapezoidMembershipFunction(7.0, 9.0, 10.0, 10.0)));
|
||||
fsTips.Input().Add(fvFood);
|
||||
//--- Create Output
|
||||
CFuzzyVariable *fvTips=new CFuzzyVariable("tips",0.0,30.0);
|
||||
fvTips.Terms().Add(new CFuzzyTerm("cheap", new CTriangularMembershipFunction(0.0, 5.0, 10.0)));
|
||||
fvTips.Terms().Add(new CFuzzyTerm("average", new CTriangularMembershipFunction(10.0, 15.0, 20.0)));
|
||||
fvTips.Terms().Add(new CFuzzyTerm("generous", new CTriangularMembershipFunction(20.0, 25.0, 30.0)));
|
||||
fsTips.Output().Add(fvTips);
|
||||
//--- Create three Mamdani fuzzy rule
|
||||
CMamdaniFuzzyRule *rule1 = fsTips.ParseRule("if (service is poor ) or (food is rancid) then tips is cheap");
|
||||
CMamdaniFuzzyRule *rule2 = fsTips.ParseRule("if ((service is good)) then tips is average");
|
||||
CMamdaniFuzzyRule *rule3 = fsTips.ParseRule("if (service is excellent) or (food is delicious) then (tips is generous)");
|
||||
//--- Add three Mamdani fuzzy rule in system
|
||||
fsTips.Rules().Add(rule1);
|
||||
fsTips.Rules().Add(rule2);
|
||||
fsTips.Rules().Add(rule3);
|
||||
//--- Set input value
|
||||
CList *in=new CList;
|
||||
CDictionary_Obj_Double *p_od_Service=new CDictionary_Obj_Double;
|
||||
CDictionary_Obj_Double *p_od_Food=new CDictionary_Obj_Double;
|
||||
//--- Testing values
|
||||
double Food=6.5;
|
||||
double Service=9.8;
|
||||
double expected=24.3;
|
||||
p_od_Service.SetAll(fvService,Service);
|
||||
p_od_Food.SetAll(fvFood,Food);
|
||||
in.Add(p_od_Service);
|
||||
in.Add(p_od_Food);
|
||||
//--- Get result
|
||||
CList *result;
|
||||
CDictionary_Obj_Double *p_od_Tips;
|
||||
result=fsTips.Calculate(in);
|
||||
p_od_Tips=result.GetNodeAtIndex(0);
|
||||
double actual=NormalizeDouble(p_od_Tips.Value(),1);
|
||||
delete in;
|
||||
delete result;
|
||||
delete fsTips;
|
||||
if(expected!=actual)
|
||||
{
|
||||
Print("Expected: ",expected," ; But was: ",actual);
|
||||
//--- failed
|
||||
return (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- success
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Test_TypicalFuzzyControlSystem() |
|
||||
//+------------------------------------------------------------------+
|
||||
bool Test_TypicalFuzzyControlSystem()
|
||||
{
|
||||
//--- Sugeno Fuzzy System
|
||||
CSugenoFuzzySystem *fsCruiseControl=new CSugenoFuzzySystem();
|
||||
//--- Create first input variables for the system
|
||||
CFuzzyVariable *fvSpeedError=new CFuzzyVariable("SpeedError",-20.0,20.0);
|
||||
fvSpeedError.Terms().Add(new CFuzzyTerm("slower",new CTriangularMembershipFunction(-35.0,-20.0,-5.0)));
|
||||
fvSpeedError.Terms().Add(new CFuzzyTerm("zero", new CTriangularMembershipFunction(-15.0, -0.0, 15.0)));
|
||||
fvSpeedError.Terms().Add(new CFuzzyTerm("faster", new CTriangularMembershipFunction(5.0, 20.0, 35.0)));
|
||||
fsCruiseControl.Input().Add(fvSpeedError);
|
||||
//--- Create second input variables for the system
|
||||
CFuzzyVariable *fvSpeedErrorDot=new CFuzzyVariable("SpeedErrorDot",-5.0,5.0);
|
||||
fvSpeedErrorDot.Terms().Add(new CFuzzyTerm("slower", new CTriangularMembershipFunction(-9.0, -5.0, -1.0)));
|
||||
fvSpeedErrorDot.Terms().Add(new CFuzzyTerm("zero", new CTriangularMembershipFunction(-4.0, -0.0, 4.0)));
|
||||
fvSpeedErrorDot.Terms().Add(new CFuzzyTerm("faster", new CTriangularMembershipFunction(1.0, 5.0, 9.0)));
|
||||
fsCruiseControl.Input().Add(fvSpeedErrorDot);
|
||||
//--- Create Output
|
||||
CSugenoVariable *svAccelerate=new CSugenoVariable("Accelerate");
|
||||
double coeff1[3]={0.0,0.0,0.0};
|
||||
svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("zero",coeff1));
|
||||
double coeff2[3]={0.0,0.0,1.0};
|
||||
svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("faster",coeff2));
|
||||
double coeff3[3]={0.0,0.0,-1.0};
|
||||
svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("slower",coeff3));
|
||||
double coeff4[3]={-0.04,-0.1,0.0};
|
||||
svAccelerate.Functions().Add(fsCruiseControl.CreateSugenoFunction("func",coeff4));
|
||||
fsCruiseControl.Output().Add(svAccelerate);
|
||||
//--- Craete Sugeno fuzzy rules
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"slower","slower","faster");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"slower","zero","faster");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"slower","faster","zero");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"zero","slower","faster");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"zero","zero","func");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"zero","faster","slower");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"faster","slower","zero");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"faster","zero","slower");
|
||||
AddSugenoFuzzyRule(fsCruiseControl,fvSpeedError,fvSpeedErrorDot,svAccelerate,"faster","faster","slower");
|
||||
//--- Set input value and get result
|
||||
CList *in=new CList;
|
||||
CDictionary_Obj_Double *p_od_Error=new CDictionary_Obj_Double;
|
||||
CDictionary_Obj_Double *p_od_ErrorDot=new CDictionary_Obj_Double;
|
||||
double Speed_Error=18.3;
|
||||
double Speed_ErrorDot=-3.5;
|
||||
double expected=-16.7;
|
||||
p_od_Error.SetAll(fvSpeedError,Speed_Error);
|
||||
p_od_ErrorDot.SetAll(fvSpeedErrorDot,Speed_ErrorDot);
|
||||
in.Add(p_od_Error);
|
||||
in.Add(p_od_ErrorDot);
|
||||
//--- Get result
|
||||
CList *result;
|
||||
CDictionary_Obj_Double *p_od_Accelerate;
|
||||
result=fsCruiseControl.Calculate(in);
|
||||
p_od_Accelerate=result.GetNodeAtIndex(0);
|
||||
double actual=NormalizeDouble(p_od_Accelerate.Value()*100,1);
|
||||
delete in;
|
||||
delete result;
|
||||
delete fsCruiseControl;
|
||||
if(expected!=actual)
|
||||
{
|
||||
Print("Expected: ",expected," ; But was: ",actual);
|
||||
//--- failed
|
||||
return (false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- success
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| AddSugenoFuzzyRule() |
|
||||
//+------------------------------------------------------------------+
|
||||
void AddSugenoFuzzyRule(CSugenoFuzzySystem *fs,CFuzzyVariable *fv1,CFuzzyVariable *fv2,CSugenoVariable *sv,
|
||||
const string value1,const string value2,const string result)
|
||||
{
|
||||
CSugenoFuzzyRule *rule=fs.EmptyRule();
|
||||
rule.Conclusion(new CSingleCondition());
|
||||
rule.Condition().Op(OperatorType::And);
|
||||
rule.Condition().ConditionsList().Add(rule.CreateCondition(fv1, fv1.GetTermByName(value1)));
|
||||
rule.Condition().ConditionsList().Add(rule.CreateCondition(fv2, fv2.GetTermByName(value2)));
|
||||
rule.Conclusion().Var(sv);
|
||||
INamedValue *sf=sv.GetFuncByName(result);
|
||||
rule.Conclusion().Term(sf);
|
||||
fs.Rules().Add(rule);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMembersipFunctions |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMembersipFunctions(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: calculation of the values for combination two normal membership function",test_name);
|
||||
if(!Test_NormalCombinationMembershipFunction())
|
||||
return (false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: calculation of the values for generalized bell-shaped membership function",test_name);
|
||||
if(!Test_GeneralizedBellShapedMembershipFunction())
|
||||
return (false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: calculation of the values for sigmoidal membership function",test_name);
|
||||
if(!Test_SigmoidalMembershipFunction())
|
||||
return (false);
|
||||
//--- test 4
|
||||
PrintFormat("%s: Test 4: calculation of the values for product two sigmoidal membership function",test_name);
|
||||
if(!Test_ProductTwoSigmoidalMembershipFunctions())
|
||||
return (false);
|
||||
//--- test 5
|
||||
PrintFormat("%s: Test 5: calculation of the values for trapezoid membership function",test_name);
|
||||
if(!Test_TrapezoidMembershipFunction())
|
||||
return (false);
|
||||
//--- test 6
|
||||
PrintFormat("%s: Test 6: calculation of the values for normal membership function",test_name);
|
||||
if(!Test_NormalMembershipFunction())
|
||||
return (false);
|
||||
//--- test 7
|
||||
PrintFormat("%s: Test 7: calculation of the values for triangular membership function",test_name);
|
||||
if(!Test_TriangularMembershipFunction())
|
||||
return (false);
|
||||
//--- test 8
|
||||
PrintFormat("%s: Test 8: calculation of the values for constant membership function",test_name);
|
||||
if(!Test_ConstantMembershipFunction())
|
||||
return (false);
|
||||
//--- test 9
|
||||
PrintFormat("%s: Test 9: comparing the results of calculations 'P' shaped function and product 'S' and 'Z' shaped function",test_name);
|
||||
if(!Test_P_S_Z_ShapedMembershipFunction())
|
||||
return (false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestDefuzzificationMethods |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestDefuzzificationMethods(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: application of the Bisector defuzzification for a triangular membership function",test_name);
|
||||
if(!Test_Bisector())
|
||||
return (false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: application of the Centroid defuzzification for a normal membership function",test_name);
|
||||
if(!Test_Centroid())
|
||||
return (false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: application of the Bisector, Centroid, Middle, Smallest, and Largest of Maximum defuzzification for a normal membership function",test_name);
|
||||
if(!Test_Defuzzification())
|
||||
return (false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFuzzySystems |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestFuzzySystems(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: calculate result for Mamdani fuzzy system",test_name);
|
||||
if(!Test_TipingProblem())
|
||||
return (false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: calculate result for Sugeno fuzzy system",test_name);
|
||||
if(!Test_TypicalFuzzyControlSystem())
|
||||
return (false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return (true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFuzzy |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestFuzzy(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
//--- Membersip functions
|
||||
tests_performed++;
|
||||
string test_name="Membersip functions test";
|
||||
if(TestMembersipFunctions(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Defuzzification methods
|
||||
tests_performed++;
|
||||
test_name="Defuzzification methods test";
|
||||
if(TestDefuzzificationMethods(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Fuzzy systems
|
||||
tests_performed++;
|
||||
test_name="Fuzzy systems test";
|
||||
if(TestFuzzySystems(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
return;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| UnitTests() |
|
||||
//+------------------------------------------------------------------+
|
||||
void UnitTests(const string package_name)
|
||||
{
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestFuzzy(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
UnitTests("Fuzzy");
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,987 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestArrayList.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\HashSet.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestAddRange_AsArrayList. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestAddRange_AsArrayList(const int count,const int add_length)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone for source list
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- crete added list
|
||||
CArrayList<int>list_added(add_length);
|
||||
for(int i=0; i<add_length; i++)
|
||||
list_added.Add(MathRand());
|
||||
//--- add range
|
||||
list_test.AddRange(GetPointer(list_added));
|
||||
//--- check first path
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_clone;
|
||||
list_test.TryGetValue(i,value_test);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_test!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
//--- check second path
|
||||
for(int i=0; i<add_length; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_added;
|
||||
list_test.TryGetValue(i+count,value_test);
|
||||
list_added.TryGetValue(i,value_added);
|
||||
if(value_test!=value_added)
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestAddRange_AsArray. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestAddRange_AsArray(const int count,const int add_length)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone for source list
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- crete added array
|
||||
int array_added[];
|
||||
ArrayResize(array_added,add_length);
|
||||
for(int i=0; i<add_length; i++)
|
||||
array_added[i]=MathRand();
|
||||
//--- add range
|
||||
list_test.AddRange(array_added);
|
||||
//--- check first path
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_clone;
|
||||
list_test.TryGetValue(i,value_test);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_test!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
//--- check second path
|
||||
for(int i=0; i<add_length; i++)
|
||||
{
|
||||
int value_test;
|
||||
list_test.TryGetValue(i+count,value_test);
|
||||
if(value_test!=array_added[i])
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestAddRange_AsNULL. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestAddRange_AsNULL(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone for source list
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- crete added collection
|
||||
ICollection<int>*null=NULL;
|
||||
//--- add range
|
||||
list_test.AddRange(null);
|
||||
//--- check first path
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_clone;
|
||||
list_test.TryGetValue(i,value_test);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_test!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
//--- check count
|
||||
if(count!=list_test.Count())
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestAddRange. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestAddRange(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Adds the elements of the first list to the end of the second list.",test_name);
|
||||
if(!TestAddRange_AsArrayList(10,7))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Adds the elements of the array to the end of the list.",test_name);
|
||||
if(!TestAddRange_AsArray(10,7))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Adds NULL object as ICollection to the end of the list.",test_name);
|
||||
if(!TestAddRange_AsNULL(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestBinarySearch_Validations. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestBinarySearch_Validations(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- sort list
|
||||
list_test.Sort();
|
||||
//--- copy list to array
|
||||
int array[];
|
||||
if(list_test.CopyTo(array)!=count)
|
||||
return(false);
|
||||
//--- create random element
|
||||
int element=MathRand();
|
||||
//--- find element in array
|
||||
int index1=ArrayBsearch(array,element);
|
||||
//--- find element in list
|
||||
int index2= list_test.BinarySearch(0,count,element,NULL);
|
||||
if(index1!=index2)
|
||||
return(false);
|
||||
if(list_test.BinarySearch(0,count+1,element,NULL)!=-1)
|
||||
return(false);
|
||||
if(list_test.BinarySearch(-1,count,element,NULL)!=-1)
|
||||
return(false);
|
||||
if(list_test.BinarySearch(0,-1,element,NULL)!=-1)
|
||||
return(false);
|
||||
if(list_test.BinarySearch(count+1,count,element,NULL)!=-1)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestBinarySearch_WithoutDuplicates. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestBinarySearch_WithoutDuplicates(const int count)
|
||||
{
|
||||
//--- create set
|
||||
CHashSet<int>set();
|
||||
for(int i=0; i<count; i++)
|
||||
set.Add(MathRand());
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(GetPointer(set));
|
||||
//--- sort list
|
||||
list_test.Sort();
|
||||
//--- find all elements
|
||||
for(int i=0; i<list_test.Count(); i++)
|
||||
{
|
||||
int value;
|
||||
list_test.TryGetValue(i,value);
|
||||
if(i!=list_test.BinarySearch(value))
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestBinarySearch_WithDuplicates. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestBinarySearch_WithDuplicates(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- add duplicate
|
||||
int value0;
|
||||
list_test.TryGetValue(0, value0);
|
||||
list_test.Add(value0);
|
||||
//--- sort list
|
||||
list_test.Sort();
|
||||
//--- find all elements
|
||||
for(int i=0; i<list_test.Count(); i++)
|
||||
{
|
||||
int value;
|
||||
list_test.TryGetValue(i,value);
|
||||
if(list_test.BinarySearch(value)<0)
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestBinarySearch. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestBinarySearch(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Validation of incorrect input parameters for BinarySearch method.",test_name);
|
||||
if(!TestBinarySearch_Validations(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of BinarySearch method on sorted list without duplicate values.",test_name);
|
||||
if(!TestBinarySearch_WithoutDuplicates(10))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Validation of BinarySearch method on sorted list with duplicate values.",test_name);
|
||||
if(!TestBinarySearch_WithDuplicates(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestIndexOf_NonExistingValues. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestIndexOf_NonExistingValues(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create value
|
||||
int value=-1;
|
||||
//--- try find index of value
|
||||
if(list_test.IndexOf(value)>=0)
|
||||
return(false);
|
||||
if(list_test.LastIndexOf(value)>=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestIndexOf_OrderIsCorrect. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestIndexOf_OrderIsCorrect(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- add duplicates
|
||||
list_test.AddRange(GetPointer(list_test));
|
||||
list_test.AddRange(GetPointer(list_test));
|
||||
list_test.AddRange(GetPointer(list_test));
|
||||
//--- find values
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
for(int j=0; j<4; j++)
|
||||
{
|
||||
int index=(j *count)+i;
|
||||
int value;
|
||||
list_clone.TryGetValue(i,value);
|
||||
if(index!=list_test.IndexOf(value,(count*j)))
|
||||
return(false);
|
||||
if(index!=list_test.IndexOf(value,(count*j),count))
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestIndexOf_OutOfRange. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestIndexOf_OutOfRange(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- crete some element
|
||||
int element=MathRand();
|
||||
//--- try to find index of element
|
||||
if(list_test.IndexOf(element,count+1)!=-1 ||
|
||||
list_test.IndexOf(element,count+10)!=-1 ||
|
||||
list_test.IndexOf(element, count-1)!=-1 ||
|
||||
list_test.IndexOf(element,INT_MIN)!=-1 ||
|
||||
list_test.IndexOf(element,count,1)!=-1 ||
|
||||
list_test.IndexOf(element,count+1,1)!=-1 ||
|
||||
list_test.IndexOf(element,count/2,count/2+2)!=-1 ||
|
||||
list_test.IndexOf(element, 0, -1)!=-1 ||
|
||||
list_test.IndexOf(element, -1, 1)!=-1)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestIndexOf. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestIndexOf(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Validation of IndexOf and LastIndexOf methods for value in the list which does not contains it.",test_name);
|
||||
if(!TestIndexOf_NonExistingValues(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of IndexOf method on the list with duplicate values and correct input parameters.",test_name);
|
||||
if(!TestIndexOf_OrderIsCorrect(10))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Validation of IndexOf method on the list with duplicate values and incorrect input parameters.",test_name);
|
||||
if(!TestIndexOf_OutOfRange(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_BasicInsert. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_BasicInsert(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- create random array
|
||||
int element=MathRand();
|
||||
//--- insert
|
||||
int index=count/2;
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Insert(index,element);
|
||||
//--- check
|
||||
if(!list_test.Contains(element))
|
||||
return(false);
|
||||
if(list_test.Count()!=2*count)
|
||||
return(false);
|
||||
for(int i=0; i<index; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_clone;
|
||||
list_test.TryGetValue(i,value_test);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_test!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
for(int i=index; i<index+count; i++)
|
||||
{
|
||||
int value;
|
||||
list_test.TryGetValue(i,value);
|
||||
if(value!=element)
|
||||
return(false);
|
||||
}
|
||||
for(int i=index+count; i<2*count; i++)
|
||||
{
|
||||
int value_test;
|
||||
int value_clone;
|
||||
list_test.TryGetValue(i,value_test);
|
||||
list_clone.TryGetValue(i-count,value_clone);
|
||||
if(value_test!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
//--- create bad indexes
|
||||
int bad[6];
|
||||
bad[0] = list_test.Count()+1;
|
||||
bad[1] = list_test.Count()+2;
|
||||
bad[2] = INT_MAX;
|
||||
bad[3] = -1;
|
||||
bad[4] = -2;
|
||||
bad[5] = INT_MIN;
|
||||
//--- try insert by bad indexes
|
||||
for(int i=0; i<ArraySize(bad); i++)
|
||||
if(list_test.Insert(bad[i],MathRand()))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_InsertRange. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_InsertRange(const int count)
|
||||
{
|
||||
//--- create x list
|
||||
CArrayList<int>list_x(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_x.Add(MathRand());
|
||||
//--- create y list
|
||||
CArrayList<int>list_y(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_y.Add(MathRand());
|
||||
//--- insert y to x
|
||||
int index=count/2;
|
||||
list_x.InsertRange(index,GetPointer(list_y));
|
||||
//--- check elements
|
||||
for(int i=index; i<index+count; i++)
|
||||
{
|
||||
int value_x;
|
||||
int value_y;
|
||||
list_x.TryGetValue(i,value_x);
|
||||
list_y.TryGetValue(i-index,value_y);
|
||||
if(value_x!=value_y)
|
||||
return(false);
|
||||
}
|
||||
//--- insert range into itself
|
||||
CArrayList<int>list(GetPointer(list_y));
|
||||
list.InsertRange(index,GetPointer(list));
|
||||
//--- check elements
|
||||
for(int i=0; i<index; i++)
|
||||
{
|
||||
int value1;
|
||||
int value2;
|
||||
list.TryGetValue(i,value1);
|
||||
list.TryGetValue(i+index,value2);
|
||||
if(value1!=value2)
|
||||
return(false);
|
||||
}
|
||||
//--- test arrays
|
||||
int array_x[];
|
||||
int array_y[];
|
||||
ArrayResize(array_x,count);
|
||||
ArrayResize(array_y,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
array_x[i]=MathRand();
|
||||
array_y[i]=MathRand();
|
||||
}
|
||||
CArrayList<int>list_new_x(array_x);
|
||||
//--- insert array
|
||||
list_new_x.InsertRange(index,array_y);
|
||||
//--- check elements
|
||||
for(int i=0; i<index; i++)
|
||||
{
|
||||
int value;
|
||||
list_new_x.TryGetValue(i,value);
|
||||
if(value!=array_x[i])
|
||||
return(false);
|
||||
}
|
||||
for(int i=index; i<index+count; i++)
|
||||
{
|
||||
int value;
|
||||
list_new_x.TryGetValue(i,value);
|
||||
if(value!=array_y[i-index])
|
||||
return(false);
|
||||
}
|
||||
for(int i=index+count; i<2*count; i++)
|
||||
{
|
||||
int value;
|
||||
list_new_x.TryGetValue(i,value);
|
||||
if(value!=array_x[i-count])
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Contains. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Contains(const int count)
|
||||
{
|
||||
//--- create source array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(array);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
if(!list_test.Contains(array[i]))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Remove. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Remove(const int count)
|
||||
{
|
||||
//--- create source array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(array);
|
||||
list_test.Sort();
|
||||
//--- remove elements
|
||||
for(int i=0; i<count; i++)
|
||||
if(!list_test.Remove(array[i]))
|
||||
return(false);
|
||||
//--- check count
|
||||
if(list_test.Count()>0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Clear. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Clear(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
//--- check
|
||||
if(list_test.Count()!=0)
|
||||
return(false);
|
||||
if(list_test.Capacity()!=count)
|
||||
return(false);
|
||||
//--- fill list
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- check
|
||||
if(list_test.Count()!=count)
|
||||
return(false);
|
||||
//--- clear list
|
||||
list_test.Clear();
|
||||
//--- check
|
||||
if(list_test.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Complex validation of Insert method with correct and incorrect input parameters.",test_name);
|
||||
if(!TestMisc_BasicInsert(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Inserts the array and ICollection object into the list at the specified index.",test_name);
|
||||
if(!TestMisc_InsertRange(10))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Testing Contains method for each element of the list.",test_name);
|
||||
if(!TestMisc_Contains(10))
|
||||
return(false);
|
||||
//--- test 4
|
||||
PrintFormat("%s: Test 4: Remove all element the list and check count after.",test_name);
|
||||
if(!TestMisc_Remove(10))
|
||||
return(false);
|
||||
//--- test 5
|
||||
PrintFormat("%s: Test 5: Clear the list and check count after.",test_name);
|
||||
if(!TestMisc_Clear(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove_Range. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove_Range(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- create paremeters
|
||||
int values[9][2]=
|
||||
{
|
||||
{3, 3},
|
||||
{0, 10},
|
||||
{10, 0},
|
||||
{5, 5},
|
||||
{0, 5},
|
||||
{1, 9},
|
||||
{9, 1},
|
||||
{2, 8},
|
||||
{8, 2}
|
||||
};
|
||||
//--- remove range
|
||||
for(int j=0; j<9; j++)
|
||||
{
|
||||
CArrayList<int>list_actual(GetPointer(list_test));
|
||||
int rindex = values[j][0];
|
||||
int rcount = values[j][1];
|
||||
if(!list_actual.RemoveRange(rindex,rcount))
|
||||
return(false);
|
||||
if(list_actual.Count()!=count-rcount)
|
||||
return(false);
|
||||
for(int i=0; i<rindex; i++)
|
||||
{
|
||||
int value_actual;
|
||||
int value_clone;
|
||||
list_actual.TryGetValue(i,value_actual);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_actual!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
for(int i=rindex; i<count-rcount;i++)
|
||||
{
|
||||
int value_actual;
|
||||
int value_clone;
|
||||
list_actual.TryGetValue(i,value_actual);
|
||||
list_clone.TryGetValue(i+rcount,value_clone);
|
||||
if(value_actual!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove_Invalid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove_Invalid(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create invalid paremeters
|
||||
int values[21][2];
|
||||
values[0][0]=count; values[0][1]=1;
|
||||
values[1][0]=count+1; values[1][1]=0;
|
||||
values[2][0]=count+1; values[2][1]=1;
|
||||
values[3][0]=count; values[3][1]=2;
|
||||
values[4][0]=count/2; values[4][1]=count/2+1;
|
||||
values[5][0]=count-1; values[5][1]=2;
|
||||
values[6][0]=count-2; values[6][1]=3;
|
||||
values[7][0]=1; values[7][1]=count;
|
||||
values[8][0]=0; values[8][1]=count+1;
|
||||
values[9][0]=1; values[9][1]=count+1;
|
||||
values[10][0]=2; values[10][1]=count;
|
||||
values[11][0]=count/2+1; values[11][1]=count/2;
|
||||
values[12][0]=2; values[12][1]=count-1;
|
||||
values[13][0]=3; values[13][1]=count-2;
|
||||
values[14][0]=-1; values[14][1]=-1;
|
||||
values[15][0]=-1; values[15][1]=0;
|
||||
values[16][0]=-1; values[16][1]=1;
|
||||
values[17][0]=-1; values[17][1]=2;
|
||||
values[18][0]=0; values[18][1]=-1;
|
||||
values[19][0]=1; values[19][1]=-1;
|
||||
values[20][0]=2; values[20][1]=-1;
|
||||
//--- remove range
|
||||
for(int j=0; j<21; j++)
|
||||
{
|
||||
int rindex = values[j][0];
|
||||
int rcount = values[j][1];
|
||||
if(list_test.RemoveRange(rindex,rcount))
|
||||
return(false);
|
||||
}
|
||||
//--- check count
|
||||
if(list_test.Count()!=count)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing RemoveRange method on the list with correct input parameters.",test_name);
|
||||
if(!TestRemove_Range(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Testing RemoveRange method on the list with incorrect input parameters.",test_name);
|
||||
if(!TestRemove_Invalid(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestReverse_Range. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestReverse_Range(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create clone
|
||||
CArrayList<int>list_clone(GetPointer(list_test));
|
||||
//--- create paremeters
|
||||
int values[9][2]=
|
||||
{
|
||||
{3, 3},
|
||||
{0, 10},
|
||||
{10, 0},
|
||||
{5, 5},
|
||||
{0, 5},
|
||||
{1, 9},
|
||||
{9, 1},
|
||||
{2, 8},
|
||||
{8, 2}
|
||||
};
|
||||
//--- reverse list
|
||||
for(int j=0; j<9; j++)
|
||||
{
|
||||
int rindex = values[j][0];
|
||||
int rcount = values[j][1];
|
||||
CArrayList<int>list_actual(GetPointer(list_test));
|
||||
list_actual.Reverse(rindex,rcount);
|
||||
for(int i=0; i<rindex; i++)
|
||||
{
|
||||
int value_actual;
|
||||
int value_clone;
|
||||
list_actual.TryGetValue(i,value_actual);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_actual!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
int k=0;
|
||||
for(int i=rindex; i<rindex+rcount; i++)
|
||||
{
|
||||
int value_actual;
|
||||
int value_clone;
|
||||
list_actual.TryGetValue(i,value_actual);
|
||||
list_clone.TryGetValue(rindex+rcount-(k+1),value_clone);
|
||||
if(value_actual!=value_clone)
|
||||
return(false);
|
||||
k++;
|
||||
}
|
||||
for(int i=rindex+rcount; i<list_clone.Count(); i++)
|
||||
{
|
||||
int value_actual;
|
||||
int value_clone;
|
||||
list_actual.TryGetValue(i,value_actual);
|
||||
list_clone.TryGetValue(i,value_clone);
|
||||
if(value_actual!=value_clone)
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestReverse_Invalid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestReverse_Invalid(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create invalid paremeters
|
||||
int values[21][2];
|
||||
values[0][0]=count; values[0][1]=1;
|
||||
values[1][0]=count+1; values[1][1]=0;
|
||||
values[2][0]=count+1; values[2][1]=1;
|
||||
values[3][0]=count; values[3][1]=2;
|
||||
values[4][0]=count/2; values[4][1]=count/2+1;
|
||||
values[5][0]=count-1; values[5][1]=2;
|
||||
values[6][0]=count-2; values[6][1]=3;
|
||||
values[7][0]=1; values[7][1]=count;
|
||||
values[8][0]=0; values[8][1]=count+1;
|
||||
values[9][0]=1; values[9][1]=count+1;
|
||||
values[10][0]=2; values[10][1]=count;
|
||||
values[11][0]=count/2+1; values[11][1]=count/2;
|
||||
values[12][0]=2; values[12][1]=count-1;
|
||||
values[13][0]=3; values[13][1]=count-2;
|
||||
values[14][0]=-1; values[14][1]=-1;
|
||||
values[15][0]=-1; values[15][1]=0;
|
||||
values[16][0]=-1; values[16][1]=1;
|
||||
values[17][0]=-1; values[17][1]=2;
|
||||
values[18][0]=0; values[18][1]=-1;
|
||||
values[19][0]=1; values[19][1]=-1;
|
||||
values[20][0]=2; values[20][1]=-1;
|
||||
//--- remove range
|
||||
for(int j=0; j<21; j++)
|
||||
{
|
||||
int rindex = values[j][0];
|
||||
int rcount = values[j][1];
|
||||
if(list_test.Reverse(rindex,rcount))
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestReverse. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestReverse(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Reverse method on the list with correct input parameters.",test_name);
|
||||
if(!TestReverse_Range(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Testing Reverse method on the list with correct input parameters.",test_name);
|
||||
if(!TestReverse_Invalid(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSort_WithDuplicates. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestSort_WithDuplicates(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- add duplicates
|
||||
int value0;
|
||||
list_test.TryGetValue(0, value0);
|
||||
list_test.Add(value0);
|
||||
//--- create comparer
|
||||
CDefaultComparer<int>comaprer;
|
||||
//--- sort list
|
||||
list_test.Sort();
|
||||
//--- check
|
||||
for(int i=0; i<count-1; i++)
|
||||
{
|
||||
int value1;
|
||||
int value2;
|
||||
list_test.TryGetValue(i, value1);
|
||||
list_test.TryGetValue(i+1, value2);
|
||||
if(comaprer.Compare(value1,value2)>0)
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSort_Invalid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestSort_Invalid(const int count)
|
||||
{
|
||||
//--- create source list
|
||||
CArrayList<int>list_test(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list_test.Add(MathRand());
|
||||
//--- create invalid paremeters
|
||||
int values[11][2]=
|
||||
{
|
||||
{-1,-1},
|
||||
{-1,0},
|
||||
{-1,1},
|
||||
{-1,2},
|
||||
{-2,0},
|
||||
{INT_MIN, 0},
|
||||
{0,-1},
|
||||
{0,-2},
|
||||
{0,INT_MIN},
|
||||
{1,-1},
|
||||
{2,-1},
|
||||
};
|
||||
//--- reverse list
|
||||
for(int j=0; j<11; j++)
|
||||
{
|
||||
int rindex = values[j][0];
|
||||
int rcount = values[j][1];
|
||||
if(list_test.Reverse(rindex,rcount))
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSort. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestSort(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Sort method on the list with correct input parameters.",test_name);
|
||||
if(!TestSort_WithDuplicates(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Testing Sort method on the list with incorrect input parameters.",test_name);
|
||||
if(!TestSort_Invalid(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestArrayList. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestArrayList(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- AddRange functions
|
||||
tests_performed++;
|
||||
test_name="AddRange functions test";
|
||||
if(TestAddRange(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- BinarySearch functions
|
||||
tests_performed++;
|
||||
test_name="BinarySearch functions test";
|
||||
if(TestBinarySearch(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- IndexOf functions
|
||||
tests_performed++;
|
||||
test_name="IndexOf functions test";
|
||||
if(TestIndexOf(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Remove functions
|
||||
tests_performed++;
|
||||
test_name="Remove functions test";
|
||||
if(TestRemove(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Reverse functions
|
||||
tests_performed++;
|
||||
test_name="Reverse functions test";
|
||||
if(TestReverse(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- Sort functions
|
||||
tests_performed++;
|
||||
test_name="Sort functions test";
|
||||
if(TestSort(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestArrayList(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,186 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestHashMap.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\HashMap.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Constructor(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CDefaultEqualityComparer<int>comparer();
|
||||
CHashMap<int,string>map_test(GetPointer(comparer));
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- create map on map
|
||||
CHashMap<int,string>map_copy(GetPointer(map_test));
|
||||
//--- check
|
||||
if(map_copy.Count()!=map_test.Count())
|
||||
return(false);
|
||||
if(map_test.Comparer()!=GetPointer(comparer))
|
||||
return(false);
|
||||
if(map_copy.Comparer()==GetPointer(comparer))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Contains. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Contains(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CHashMap<int,string>map_test();
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- create elemet
|
||||
int element=keys[0];
|
||||
while(map_test.Contains(element,(string)element) && map_test.ContainsKey(element))
|
||||
element++;
|
||||
//--- check
|
||||
if(map_test.Contains(element,(string)element) || map_test.ContainsKey(element))
|
||||
return(false);
|
||||
//--- add element to map
|
||||
map_test.Add(element,"new");
|
||||
//--- check
|
||||
if(!map_test.Contains(element,"new") ||
|
||||
!map_test.ContainsKey(element) ||
|
||||
!map_test.ContainsValue("new"))
|
||||
return(false);
|
||||
//--- clear
|
||||
map_test.Clear();
|
||||
//--- check
|
||||
if(map_test.Contains(keys[0],values[0]) ||
|
||||
map_test.ContainsKey(keys[0]) ||
|
||||
map_test.ContainsValue(values[0]))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Remove. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Remove(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CHashMap<int,string>map_test();
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- create element
|
||||
int element=-1;
|
||||
//--- remove element which not contained in map
|
||||
//--- check
|
||||
if(map_test.Remove(element))
|
||||
return(false);
|
||||
if(map_test.Count()!=count)
|
||||
return(false);
|
||||
//--- add element to map
|
||||
map_test.Add(element,(string)element);
|
||||
//--- remove element
|
||||
if(!map_test.Remove(element))
|
||||
return(false);
|
||||
//--- check
|
||||
string value="test";
|
||||
if(map_test.TryGetValue(element,value))
|
||||
return(false);
|
||||
if(value!="test")
|
||||
return(false);
|
||||
//--- remove all elements
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
CKeyValuePair<int,string>pair(keys[i],values[i]);
|
||||
if(!map_test.Remove(GetPointer(pair)))
|
||||
return(false);
|
||||
}
|
||||
//--- check
|
||||
if(map_test.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of map based on another map.",test_name);
|
||||
if(!TestMisc_Constructor(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Complex validation of Contains, ContainsKey and ContainsValues methods.",test_name);
|
||||
if(!TestMisc_Contains(16))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Complex validation of Remove method for elements which contains and does not conatains in the map.",test_name);
|
||||
if(!TestMisc_Remove(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestHashMap. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestHashMap(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestHashMap(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,147 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestHashSet.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\HashSet.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Constructor(const int count)
|
||||
{
|
||||
//--- create array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create array with duplicates
|
||||
int array_duplicates[];
|
||||
ArrayResize(array_duplicates,count*2);
|
||||
for(int i=0; i<count; i++)
|
||||
array_duplicates[i]=array[i];
|
||||
for(int i=0; i<count; i++)
|
||||
array_duplicates[count+i]=array[i];
|
||||
//--- create source set
|
||||
CDefaultEqualityComparer<int>comparer();
|
||||
CHashSet<int>set_test1(array);
|
||||
CHashSet<int>set_test2(array_duplicates,GetPointer(comparer));
|
||||
//--- check
|
||||
if(set_test1.Count()!=set_test2.Count())
|
||||
return(false);
|
||||
if(GetPointer(comparer)==set_test1.Comparer())
|
||||
return(false);
|
||||
if(GetPointer(comparer)!=set_test2.Comparer())
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_TrimExpress. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_TrimExpress(const int count)
|
||||
{
|
||||
//--- create array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source set
|
||||
CHashSet<int>set_test();
|
||||
for(int i=0; i<count; i++)
|
||||
set_test.Add(array[i]);
|
||||
//--- copy set to array
|
||||
int expected[];
|
||||
set_test.CopyTo(expected);
|
||||
//--- trim
|
||||
set_test.TrimExcess();
|
||||
set_test.TrimExcess();
|
||||
set_test.TrimExcess();
|
||||
//--- copy set to array
|
||||
int actual[];
|
||||
set_test.CopyTo(actual);
|
||||
//--- check
|
||||
if(ArrayCompare(actual,expected)!=0)
|
||||
return(false);
|
||||
//--- get first element
|
||||
int elemnet=actual[0];
|
||||
//--- trim
|
||||
set_test.TrimExcess();
|
||||
//--- remove
|
||||
if(!set_test.Remove(elemnet))
|
||||
return(false);
|
||||
//--- trim
|
||||
set_test.TrimExcess();
|
||||
//--- check
|
||||
ArrayFree(actual);
|
||||
set_test.CopyTo(actual);
|
||||
for(int i=0; i<count-1;i++)
|
||||
if(expected[i+1]!=actual[i])
|
||||
return(false);
|
||||
//--- trim and clear
|
||||
set_test.TrimExcess();
|
||||
set_test.Clear();
|
||||
set_test.TrimExcess();
|
||||
//--- check
|
||||
if(set_test.Count()!=0)
|
||||
return(false);
|
||||
//--- add values
|
||||
for(int i=0; i<count; i++)
|
||||
set_test.Add(array[i]);
|
||||
//--- trim
|
||||
set_test.TrimExcess();
|
||||
//--- check
|
||||
if(set_test.Count()!=ArraySize(expected))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of set based on array with and without duplicates.",test_name);
|
||||
if(!TestMisc_Constructor(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Complex validation of TrimExpress method after adding, removing element and cleaning.",test_name);
|
||||
if(!TestMisc_TrimExpress(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestHashSet. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestHashSet(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestHashSet(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,259 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestQueue.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\Queue.mqh>
|
||||
#include <Generic\ArrayList.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor_Valid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor_Valid(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create list
|
||||
CArrayList<int>list(array);
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test1(array);
|
||||
CQueue<int>queue_test2(GetPointer(list));
|
||||
CQueue<int>queue_test3(count);
|
||||
for(int i=0; i<count; i++)
|
||||
queue_test3.Add(array[i]);
|
||||
//--- check count
|
||||
if(queue_test1.Count()!=count)
|
||||
return(false);
|
||||
if(queue_test2.Count()!=count)
|
||||
return(false);
|
||||
if(queue_test3.Count()!=count)
|
||||
return(false);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
if(array[i]!=queue_test1.Dequeue())
|
||||
return(false);
|
||||
if(array[i]!=queue_test2.Dequeue())
|
||||
return(false);
|
||||
if(array[i]!=queue_test3.Dequeue())
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor_Invalid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor_Invalid(const int count)
|
||||
{
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test1(-1);
|
||||
CQueue<int>queue_test2(INT_MIN);
|
||||
//--- check
|
||||
if(queue_test1.Count()!=0)
|
||||
return(false);
|
||||
if(queue_test2.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of queue with array, ICollection object and correct capacity.",test_name);
|
||||
if(!TestConstructor_Valid(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Testing Constructor of queue with incorrect capacity.",test_name);
|
||||
if(!TestConstructor_Invalid(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Dequeue. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Dequeue(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test(array);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
if(queue_test.Dequeue()!=array[i])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(queue_test.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Peek. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Peek(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test(array);
|
||||
//--- check element
|
||||
if(queue_test.Peek()!=array[0])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(queue_test.Count()!=count)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Complex. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Complex(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test(count);
|
||||
//--- enqueue values
|
||||
for(int i=0; i<count; i++)
|
||||
if(!queue_test.Enqueue(array[i]))
|
||||
return(false);
|
||||
//--- check count
|
||||
if(queue_test.Count()!=count)
|
||||
return(false);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
if(array[i]!=queue_test.Dequeue())
|
||||
return(false);
|
||||
if(count-i-1!=queue_test.Count())
|
||||
return(false);
|
||||
}
|
||||
//--- recheck
|
||||
queue_test.Enqueue(0);
|
||||
if(queue_test.Dequeue()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_TrimExcess. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_TrimExcess(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source queue
|
||||
CQueue<int>queue_test(array);
|
||||
//--- trim
|
||||
queue_test.TrimExcess();
|
||||
int removed=queue_test.Dequeue();
|
||||
queue_test.TrimExcess();
|
||||
//--- check element
|
||||
if(queue_test.Peek()!=array[1])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(queue_test.Count()!=count-1)
|
||||
return(false);
|
||||
//--- trim and clear
|
||||
queue_test.TrimExcess();
|
||||
queue_test.Clear();
|
||||
queue_test.TrimExcess();
|
||||
//--- check count
|
||||
if(queue_test.Count()!=0)
|
||||
return(false);
|
||||
//--- add elemnt and trim
|
||||
queue_test.Add(0);
|
||||
queue_test.TrimExcess();
|
||||
//--- check count
|
||||
if(queue_test.Count()!=1)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Validation of Dequeue method for all element of the queue and check count after.",test_name);
|
||||
if(!TestMisc_Dequeue(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of Peek method for all element of the queue and check count after.",test_name);
|
||||
if(!TestMisc_Peek(10))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Complex validation of Enqueue and Dequeue methods.",test_name);
|
||||
if(!TestMisc_Complex(10))
|
||||
return(false);
|
||||
//--- test 4
|
||||
PrintFormat("%s: Test 4: Testing TrimExcess method on the queue after filling, clearing and adding elements.",test_name);
|
||||
if(!TestMisc_TrimExcess(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestQueue. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestQueue(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Constructor functions
|
||||
tests_performed++;
|
||||
test_name="TestConstructor functions test";
|
||||
if(TestConstructor(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- AddRange functions
|
||||
tests_performed++;
|
||||
test_name="TestMisc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestQueue(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,361 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRedBlackTree.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\RedBlackTree.mqh>
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\HashSet.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Constructor(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CDefaultComparer<int>comparer();
|
||||
CRedBlackTree<int>tree_test1(GetPointer(list),GetPointer(comparer));
|
||||
CRedBlackTree<int>tree_test2(GetPointer(tree_test1));
|
||||
//--- check
|
||||
if(tree_test1.Count()!=tree_test2.Count())
|
||||
return(false);
|
||||
if(tree_test1.Comparer()!=GetPointer(comparer))
|
||||
return(false);
|
||||
if(tree_test2.Comparer()==GetPointer(comparer))
|
||||
return(false);
|
||||
//--- get unique sorted values
|
||||
CHashSet<int>set(GetPointer(list));
|
||||
int expected[];
|
||||
set.CopyTo(expected);
|
||||
ArraySort(expected);
|
||||
//--- check
|
||||
int actual1[];
|
||||
int actual2[];
|
||||
tree_test1.CopyTo(actual1);
|
||||
tree_test1.CopyTo(actual2);
|
||||
for(int i=0; i<ArraySize(expected); i++)
|
||||
if(actual1[i]!=expected[i] || actual2[i]!=expected[i])
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Contains. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Contains(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- check
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
int value;
|
||||
list.TryGetValue(i,value);
|
||||
if(!tree_test.Contains(value))
|
||||
return(false);
|
||||
}
|
||||
//--- clear tree
|
||||
tree_test.Clear();
|
||||
//--- check
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
int value;
|
||||
list.TryGetValue(i,value);
|
||||
if(tree_test.Contains(value))
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Add. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Add(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- check
|
||||
if(tree_test.Count()>count)
|
||||
return(false);
|
||||
//--- create new unique element
|
||||
int element=MathRand();
|
||||
while(tree_test.Contains(element))
|
||||
element=MathRand();
|
||||
//--- add new unique element
|
||||
if(!tree_test.Add(element))
|
||||
return(false);
|
||||
if(tree_test.Add(element))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of map based on several different ICollection objects with and without comparer.",test_name);
|
||||
if(!TestMisc_Constructor(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of Contains method before and after cleaning the tree.",test_name);
|
||||
if(!TestMisc_Contains(16))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Simple validation of Add method.",test_name);
|
||||
if(!TestMisc_Add(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFind_Max. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestFind_Max(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- get max
|
||||
list.Sort();
|
||||
CRedBlackTreeNode<int>*max_node=tree_test.FindMax();
|
||||
int expected;
|
||||
list.TryGetValue(count-1,expected);
|
||||
int actual=max_node.Value();
|
||||
//--- check
|
||||
if(expected!=actual)
|
||||
return(false);
|
||||
if(tree_test.Find(expected)!=max_node)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFind_Min. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestFind_Min(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- get max
|
||||
list.Sort();
|
||||
CRedBlackTreeNode<int>*min_node=tree_test.FindMin();
|
||||
int expected;
|
||||
list.TryGetValue(0, expected);
|
||||
int actual=min_node.Value();
|
||||
//--- check
|
||||
if(expected!=actual)
|
||||
return(false);
|
||||
if(tree_test.Find(expected)!=min_node)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestFind. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestFind(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Simple validation of FindMax method for tree.",test_name);
|
||||
if(!TestFind_Max(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Simple validation of FindMin method for tree.",test_name);
|
||||
if(!TestFind_Min(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove_Node. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove_Node(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- get max and min
|
||||
list.Sort();
|
||||
int min;
|
||||
int max;
|
||||
list.TryGetValue(0, min);
|
||||
list.TryGetValue(count-1, max);
|
||||
//--- check
|
||||
if(tree_test.Count()>0)
|
||||
{
|
||||
//--- remove min value
|
||||
if(!tree_test.Remove(min))
|
||||
return(false);
|
||||
}
|
||||
if(tree_test.Count()>0)
|
||||
{
|
||||
//--- remove max node
|
||||
CRedBlackTreeNode<int>*node=tree_test.FindMax();
|
||||
if(!tree_test.Remove(node))
|
||||
return(false);
|
||||
}
|
||||
//--- get unique sorted values
|
||||
CHashSet<int>set(GetPointer(list));
|
||||
set.Remove(min);
|
||||
set.Remove(max);
|
||||
int expected[];
|
||||
set.CopyTo(expected);
|
||||
ArraySort(expected);
|
||||
//--- check
|
||||
int actual[];
|
||||
tree_test.CopyTo(actual);
|
||||
if(ArrayCompare(expected,actual)!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove_Max. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove_Max(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- get unique sorted values
|
||||
CHashSet<int>set(GetPointer(list));
|
||||
int expected[];
|
||||
set.CopyTo(expected);
|
||||
ArraySort(expected);
|
||||
//--- check
|
||||
for(int i=0; i<ArraySize(expected); i++)
|
||||
{
|
||||
int actual[];
|
||||
tree_test.CopyTo(actual);
|
||||
if(ArrayCompare(expected,actual,0,0,count-i)!=0)
|
||||
return(false);
|
||||
tree_test.RemoveMax();
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove_Min. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove_Min(const int count)
|
||||
{
|
||||
//--- create list
|
||||
CArrayList<int>list(count);
|
||||
for(int i=0; i<count; i++)
|
||||
list.Add(MathRand());
|
||||
//--- create source tree
|
||||
CRedBlackTree<int>tree_test(GetPointer(list));
|
||||
//--- get unique sorted values
|
||||
CHashSet<int>set(GetPointer(list));
|
||||
int expected[];
|
||||
set.CopyTo(expected);
|
||||
ArraySort(expected);
|
||||
//--- check
|
||||
for(int i=0; i<ArraySize(expected); i++)
|
||||
{
|
||||
int actual[];
|
||||
tree_test.CopyTo(actual);
|
||||
if(ArrayCompare(expected,actual,i,0,count-i)!=0)
|
||||
return(false);
|
||||
tree_test.RemoveMin();
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRemove. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestRemove(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 2: Validation of Remove method used independent element and specified node of tree.",test_name);
|
||||
if(!TestRemove_Node(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of RemoveMax method for cleaning the tree.",test_name);
|
||||
if(!TestRemove_Max(16))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Validation of RemoveMin method for cleaning the tree.",test_name);
|
||||
if(!TestRemove_Min(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestRedBlackTree. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestRedBlackTree(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
//--- Find functions
|
||||
tests_performed++;
|
||||
test_name="Find functions test";
|
||||
if(TestFind(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
//--- Remove functions
|
||||
tests_performed++;
|
||||
test_name="Remove functions test";
|
||||
if(TestRemove(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestRedBlackTree(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,187 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSortedMap.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\SortedMap.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Constructor(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CDefaultComparer<int>comparer();
|
||||
CSortedMap<int,string>map_test(GetPointer(comparer));
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- create map on map
|
||||
CSortedMap<int,string>map_copy(GetPointer(map_test));
|
||||
//--- check
|
||||
if(map_copy.Count()!=map_test.Count())
|
||||
return(false);
|
||||
if(map_test.Comparer()!=GetPointer(comparer))
|
||||
return(false);
|
||||
if(map_copy.Comparer()==GetPointer(comparer))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Contains. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Contains(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CSortedMap<int,string>map_test();
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- create elemet
|
||||
int element=keys[0];
|
||||
while(map_test.Contains(element,(string)element) && map_test.ContainsKey(element))
|
||||
element++;
|
||||
//--- check
|
||||
if(map_test.Contains(element,(string)element) || map_test.ContainsKey(element))
|
||||
return(false);
|
||||
//--- add element to map
|
||||
map_test.Add(element,"new");
|
||||
//--- check
|
||||
if(!map_test.Contains(element,"new") ||
|
||||
!map_test.ContainsKey(element) ||
|
||||
!map_test.ContainsValue("new"))
|
||||
return(false);
|
||||
//--- clear
|
||||
map_test.Clear();
|
||||
//--- check
|
||||
if(map_test.Contains(keys[0],values[0]) ||
|
||||
map_test.ContainsKey(keys[0]) ||
|
||||
map_test.ContainsValue(values[0]))
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Ordering. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Ordering(const int count)
|
||||
{
|
||||
//--- create arrays
|
||||
int keys[];
|
||||
string values[];
|
||||
ArrayResize(keys,count);
|
||||
ArrayResize(values,count);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
keys[i]=i+1;
|
||||
values[i]=(string)(i+1);
|
||||
}
|
||||
//--- create source map
|
||||
CSortedMap<int,string>map_test();
|
||||
for(int i=0; i<count; i++)
|
||||
map_test.Add(keys[i],values[i]);
|
||||
//--- copy map to array
|
||||
CKeyValuePair<int,string>*pairs[];
|
||||
int size=map_test.CopyTo(pairs);
|
||||
//--- check
|
||||
CDefaultComparer<CKeyValuePair<int,string>*>comparer();
|
||||
CArrayList<CKeyValuePair<int,string>*>expected(pairs);
|
||||
expected.Sort(GetPointer(comparer));
|
||||
int actual_keys[];
|
||||
string actual_values[];
|
||||
map_test.CopyTo(actual_keys,actual_values);
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
CKeyValuePair<int,string>*pair;
|
||||
expected.TryGetValue(i,pair);
|
||||
if(pair.Key()!=actual_keys[i] || pair.Value()!=actual_values[i])
|
||||
return(false);
|
||||
//--- check TryGetValue
|
||||
string value;
|
||||
if(!map_test.TryGetValue(pair.Key(),value))
|
||||
return(false);
|
||||
if(pair.Value()!=value)
|
||||
return(false);
|
||||
}
|
||||
//--- delete pairs
|
||||
for(int i=0; i<ArraySize(pairs); i++)
|
||||
{
|
||||
CKeyValuePair<int,string>*pair;
|
||||
expected.TryGetValue(i,pair);
|
||||
delete pair;
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of map based on another map.",test_name);
|
||||
if(!TestMisc_Constructor(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Complex validation of Contains, ContainsKey and ContainsValues methods.",test_name);
|
||||
if(!TestMisc_Contains(16))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Testing the ordering of elements in the map.",test_name);
|
||||
if(!TestMisc_Ordering(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSortedMap. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestSortedMap(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestSortedMap(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,147 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSortedSet.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\ArrayList.mqh>
|
||||
#include <Generic\SortedSet.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Constructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Constructor(const int count)
|
||||
{
|
||||
//--- create array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create array with duplicates
|
||||
int array_duplicates[];
|
||||
ArrayResize(array_duplicates,count*2);
|
||||
for(int i=0; i<count; i++)
|
||||
array_duplicates[i]=array[i];
|
||||
for(int i=0; i<count; i++)
|
||||
array_duplicates[count+i]=array[i];
|
||||
//--- create source set
|
||||
CDefaultComparer<int>comparer();
|
||||
CSortedSet<int>set_test1(array);
|
||||
CSortedSet<int>set_test2(array_duplicates,GetPointer(comparer));
|
||||
//--- check
|
||||
if(set_test1.Count()!=set_test2.Count())
|
||||
return(false);
|
||||
if(GetPointer(comparer)==set_test1.Comparer())
|
||||
return(false);
|
||||
if(GetPointer(comparer)!=set_test2.Comparer())
|
||||
return(false);
|
||||
//--- check ordering of the first set
|
||||
int check_array[];
|
||||
set_test1.CopyTo(check_array);
|
||||
for(int i=0; i<ArraySize(check_array)-1; i++)
|
||||
if(comparer.Compare(check_array[i],check_array[i+1])>0 && check_array[i]>check_array[i+1])
|
||||
return(false);
|
||||
//--- check ordering of the second set
|
||||
ArrayFree(check_array);
|
||||
set_test2.CopyTo(check_array);
|
||||
for(int i=0; i<ArraySize(check_array)-1; i++)
|
||||
if(comparer.Compare(check_array[i],check_array[i+1])>0 && check_array[i]>check_array[i+1])
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_GetViewBetween. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_GetViewBetween(const int count)
|
||||
{
|
||||
int view[];
|
||||
int check_array[];
|
||||
//--- create array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source set
|
||||
CSortedSet<int>set_test(array);
|
||||
//--- calculate max and min
|
||||
int min = array[ArrayMinimum(array)];
|
||||
int max = array[ArrayMaximum(array)];
|
||||
if(!set_test.GetViewBetween(view,min,max))
|
||||
return(false);
|
||||
//--- get view
|
||||
set_test.GetViewBetween(view,min,max);
|
||||
//--- check
|
||||
set_test.CopyTo(check_array);
|
||||
if(ArrayCompare(check_array,view)!=0)
|
||||
return(false);
|
||||
//--- lower value greater than upper value
|
||||
min=array[ArrayMaximum(array)];
|
||||
max=array[ArrayMinimum(array)];
|
||||
//--- get view
|
||||
ArrayFree(view);
|
||||
if(set_test.GetViewBetween(view,min,max))
|
||||
return(false);
|
||||
//--- check
|
||||
if(ArraySize(view)!=0)
|
||||
return(false);
|
||||
//--- minimum lower value and maximum upper value
|
||||
min=INT_MIN;
|
||||
max=INT_MAX;
|
||||
//--- get view
|
||||
ArrayFree(view);
|
||||
if(!set_test.GetViewBetween(view,min,max))
|
||||
return(false);
|
||||
//--- check
|
||||
if(ArrayCompare(check_array,view)!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of set based of array with and without duplicates.",test_name);
|
||||
if(!TestMisc_Constructor(16))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Complex validation of GetViewBetween method with correct and incorrect input parameters.",test_name);
|
||||
if(!TestMisc_GetViewBetween(16))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestSortedSet. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestSortedSet(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Misc functions
|
||||
tests_performed++;
|
||||
test_name="Misc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestSortedSet(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,259 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestStack.mq5 |
|
||||
//| Copyright 2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Generic\Stack.mqh>
|
||||
#include <Generic\ArrayList.mqh>
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor_Valid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor_Valid(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create list
|
||||
CArrayList<int>list(array);
|
||||
//--- create source stack
|
||||
CStack<int>stack_test1(array);
|
||||
CStack<int>stack_test2(GetPointer(list));
|
||||
CStack<int>stack_test3(count);
|
||||
for(int i=0; i<count; i++)
|
||||
stack_test3.Add(array[i]);
|
||||
//--- check count
|
||||
if(stack_test1.Count()!=count)
|
||||
return(false);
|
||||
if(stack_test2.Count()!=count)
|
||||
return(false);
|
||||
if(stack_test3.Count()!=count)
|
||||
return(false);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
if(array[count-1-i]!=stack_test1.Pop())
|
||||
return(false);
|
||||
if(array[count-1-i]!=stack_test2.Pop())
|
||||
return(false);
|
||||
if(array[count-1-i]!=stack_test3.Pop())
|
||||
return(false);
|
||||
}
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor_Invalid. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor_Invalid(const int count)
|
||||
{
|
||||
//--- create source stack
|
||||
CStack<int>stack_test1(-1);
|
||||
CStack<int>stack_test2(INT_MIN);
|
||||
//--- check
|
||||
if(stack_test1.Count()!=0)
|
||||
return(false);
|
||||
if(stack_test2.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestConstructor. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestConstructor(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Testing Constructor of stack with array, ICollection object and correct capacity.",test_name);
|
||||
if(!TestConstructor_Valid(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Testing Constructor of stack with incorrect capacity.",test_name);
|
||||
if(!TestConstructor_Invalid(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Pop. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Pop(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source stack
|
||||
CStack<int>stack_test(array);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
if(stack_test.Pop()!=array[count-1-i])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(stack_test.Count()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Peek. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Peek(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source stack
|
||||
CStack<int>stack_test(array);
|
||||
//--- check element
|
||||
if(stack_test.Peek()!=array[count-1])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(stack_test.Count()!=count)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_Complex. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_Complex(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source stack
|
||||
CStack<int>stack_test(count);
|
||||
//--- push values
|
||||
for(int i=0; i<count; i++)
|
||||
if(!stack_test.Push(array[i]))
|
||||
return(false);
|
||||
//--- check count
|
||||
if(stack_test.Count()!=count)
|
||||
return(false);
|
||||
//--- check elements
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
if(array[count-1-i]!=stack_test.Pop())
|
||||
return(false);
|
||||
if(count-i-1!=stack_test.Count())
|
||||
return(false);
|
||||
}
|
||||
//--- recheck
|
||||
stack_test.Push(0);
|
||||
if(stack_test.Pop()!=0)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc_TrimExcess. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc_TrimExcess(const int count)
|
||||
{
|
||||
//--- create random array
|
||||
int array[];
|
||||
ArrayResize(array,count);
|
||||
for(int i=0; i<count; i++)
|
||||
array[i]=MathRand();
|
||||
//--- create source stack
|
||||
CStack<int>stack_test(array);
|
||||
//--- trim
|
||||
stack_test.TrimExcess();
|
||||
int removed=stack_test.Pop();
|
||||
stack_test.TrimExcess();
|
||||
//--- check element
|
||||
if(stack_test.Peek()!=array[count-2])
|
||||
return(false);
|
||||
//--- check count
|
||||
if(stack_test.Count()!=count-1)
|
||||
return(false);
|
||||
//--- trim and clear
|
||||
stack_test.TrimExcess();
|
||||
stack_test.Clear();
|
||||
stack_test.TrimExcess();
|
||||
//--- check count
|
||||
if(stack_test.Count()!=0)
|
||||
return(false);
|
||||
//--- add elemnt and trim
|
||||
stack_test.Add(0);
|
||||
stack_test.TrimExcess();
|
||||
//--- check count
|
||||
if(stack_test.Count()!=1)
|
||||
return(false);
|
||||
//--- successful
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestMisc. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool TestMisc(const string test_name)
|
||||
{
|
||||
PrintFormat("%s started",test_name);
|
||||
//--- test 1
|
||||
PrintFormat("%s: Test 1: Validation of Pop method for all element of the stack and check count after.",test_name);
|
||||
if(!TestMisc_Pop(10))
|
||||
return(false);
|
||||
//--- test 2
|
||||
PrintFormat("%s: Test 2: Validation of Peek method for all element of the stack and check count after.",test_name);
|
||||
if(!TestMisc_Peek(10))
|
||||
return(false);
|
||||
//--- test 3
|
||||
PrintFormat("%s: Test 3: Complex validation of Push and Pop methods.",test_name);
|
||||
if(!TestMisc_Complex(10))
|
||||
return(false);
|
||||
//--- test 4
|
||||
PrintFormat("%s: Test 4: Testing TrimExcess method on the stack after filling, clearing and adding elements.",test_name);
|
||||
if(!TestMisc_TrimExcess(10))
|
||||
return(false);
|
||||
//--- successful
|
||||
PrintFormat("%s passed",test_name);
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestStack. |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestStack(int &tests_performed,int &tests_passed)
|
||||
{
|
||||
string test_name="";
|
||||
//--- Constructor functions
|
||||
tests_performed++;
|
||||
test_name="TestConstructor functions test";
|
||||
if(TestConstructor(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
|
||||
//--- AddRange functions
|
||||
tests_performed++;
|
||||
test_name="TestMisc functions test";
|
||||
if(TestMisc(test_name))
|
||||
tests_passed++;
|
||||
else
|
||||
PrintFormat("%s failed",test_name);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
MathSrand(0);
|
||||
string package_name="Generic";
|
||||
PrintFormat("Unit tests for Package %s\n",package_name);
|
||||
//--- initial values
|
||||
int tests_performed=0;
|
||||
int tests_passed=0;
|
||||
//--- test distributions
|
||||
TestStack(tests_performed,tests_passed);
|
||||
//--- print statistics
|
||||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,288 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestStatPrecision.mq5 |
|
||||
//| Copyright 2016-2017, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
|
||||
#include <Math\Stat\Normal.mqh>
|
||||
#include <Math\Stat\Weibull.mqh>
|
||||
#include <Math\Stat\Uniform.mqh>
|
||||
#include <Math\Stat\Logistic.mqh>
|
||||
#include <Math\Stat\Cauchy.mqh>
|
||||
#include <Math\Stat\Exponential.mqh>
|
||||
#include <Math\Stat\Lognormal.mqh>
|
||||
#include <Math\Stat\Poisson.mqh>
|
||||
#include <Math\Stat\Gamma.mqh>
|
||||
#include <Math\Stat\Chisquare.mqh>
|
||||
#include <Math\Stat\NoncentralChisquare.mqh>
|
||||
#include <Math\Stat\Binomial.mqh>
|
||||
#include <Math\Stat\Beta.mqh>
|
||||
#include <Math\Stat\F.mqh>
|
||||
#include <Math\Stat\Geometric.mqh>
|
||||
#include <Math\Stat\T.mqh>
|
||||
#include <Math\Stat\Hypergeometric.mqh>
|
||||
#include <Math\Stat\NegativeBinomial.mqh>
|
||||
#include <Math\Stat\NoncentralBeta.mqh>
|
||||
#include <Math\Stat\NoncentralF.mqh>
|
||||
#include <Math\Stat\NoncentralT.mqh>
|
||||
|
||||
//--- PDF and CDF values calculated with Wolfram Alpha (30 digits)
|
||||
//--- http://www.wolframalpha.com/input/?i=N%5BPDF%5BBetaDistribution%5B2,4%5D,0.5%5D,30%5D
|
||||
const double Wolfram_Beta_PDF = 1.25000000000000000000000000000; // N[PDF[BetaDistribution[2,4],0.5],30]
|
||||
const double Wolfram_Beta_CDF = 0.812500000000000000000000000000; // N[CDF[BetaDistribution[2,4],0.5],30]
|
||||
const double Wolfram_Binomial_PDF = 0.178863050569879740960000000000; // N[PDF[BinomialDistribution[20,0.3],5],30]
|
||||
const double Wolfram_Binomial_CDF = 0.416370829447481383720000000000; // N[CDF[BinomialDistribution[20,0.3],5],30]
|
||||
const double Wolfram_Cauchy_PDF = 0.0783532027529330883785273911988; // N[PDF[CauchyDistribution[2,1],0.25],30]
|
||||
const double Wolfram_Cauchy_CDF = 0.165249340538567909638346176210; // N[CDF[CauchyDistribution[2,1],0.25],30]
|
||||
const double Wolfram_ChiSquare_PDF = 0.389400391535702434122585133489; // N[PDF[ChiSquareDistribution[2],0.5],30]
|
||||
const double Wolfram_ChiSquare_CDF = 0.221199216928595131754829733022; // N[CDF[ChiSquareDistribution[2],0.5],30]
|
||||
const double Wolfram_Exponential_PDF = 0.441248451292297701432446071615; // N[PDF[ExponentialDistribution[1/2],0.25],30]
|
||||
const double Wolfram_Exponential_CDF = 0.117503097415404597135107856771; // N[CDF[ExponentialDistribution[1/2],0.25],30]
|
||||
const double Wolfram_F_PDF = 0.702331961591220850480109739369; // N[PDF[FRatioDistribution[2,4],0.25],30]
|
||||
const double Wolfram_F_CDF = 0.209876543209876543209876543210; // N[CDF[FRatioDistribution[2,4],0.25],30]
|
||||
const double Wolfram_Gamma_PDF = 0.606530659712633423603799534991; // N[PDF[GammaDistribution[1,1],0.5],30]
|
||||
const double Wolfram_Gamma_CDF = 0.393469340287366576396200465009; // N[CDF[GammaDistribution[1,1],0.5],30]
|
||||
const double Wolfram_Geometric_PDF = 0.0504210000000000000000000000000; // N[PDF[GeometricDistribution[0.3],5],30]
|
||||
const double Wolfram_Geometric_CDF = 0.882351000000000000000000000000; // N[CDF[GeometricDistribution[0.3],5],30]
|
||||
const double Wolfram_Hypergeometric_PDF = 0.0366753989045010716837342224339; // N[PDF[HypergeometricDistribution[9,8,20],6],30]
|
||||
const double Wolfram_Hypergeometric_CDF = 0.996784948797332698261490831150; // N[CDF[HypergeometricDistribution[9,8,20],6],30]
|
||||
const double Wolfram_Logistic_PDF = 0.235003712201594489069302695021; // N[PDF[LogisticDistribution[1,1],0.5],30]
|
||||
const double Wolfram_Logistic_CDF = 0.377540668798145435361099434254; // N[CDF[LogisticDistribution[1,1],0.5],30]
|
||||
const double Wolfram_Lognormal_PDF = 2.47498055546993572014793467512E-7; // N[PDF[LognormalDistribution[10,2],0.5],30]
|
||||
const double Wolfram_Lognormal_CDF = 4.48174235017131858935036726113E-8; // N[CDF[LognormalDistribution[10,2],0.5],30]
|
||||
const double Wolfram_NegativeBinomial_PDF = 0.0468750000000000000000000000000; // N[PDF[NegativeBinomialDistribution[2,0.5],5],30]
|
||||
const double Wolfram_NegativeBinomial_CDF = 0.937500000000000000000000000000; // N[CDF[NegativeBinomialDistribution[2,0.5],5],30]
|
||||
const double Wolfram_NoncentralBeta_PDF = 1.83531575828435897166952478333; // N[PDF[NoncentralBetaDistribution[2,4,1],0.25],30]
|
||||
const double Wolfram_NoncentralBeta_CDF = 0.279804451879309969773066407543; // N[CDF[NoncentralBetaDistribution[2,4,1],0.25],30]
|
||||
const double Wolfram_NoncentralChiSquare_PDF = 0.266641691212769080163425079921; // N[PDF[NoncentralChiSquareDistribution[2,1],0.5],30]
|
||||
const double Wolfram_NoncentralChiSquare_CDF = 0.142365913869366361026153686445; // N[CDF[NoncentralChiSquareDistribution[2,1],0.5],30]
|
||||
const double Wolfram_NoncentralF_PDF = 0.354683475208693741397782642610; // N[PDF[NoncentralFRatioDistribution[2,4,2],0.25],30]
|
||||
const double Wolfram_NoncentralF_CDF = 0.0907943467375269920219944143035; // N[CDF[NoncentralFRatioDistribution[2,4,2],0.25],30]
|
||||
const double Wolfram_Normal_PDF = 0.0000133655982673381195940786008171; // N[PDF[NormalDistribution[21,5],0.15],30]
|
||||
const double Wolfram_Normal_CDF = 0.0000152299819479778795518408747262; // N[CDF[NormalDistribution[21,5],0.15],30]
|
||||
const double Wolfram_Poisson_PDF = 2.81323432020839550168137707324E-13; // N[PDF[PoissonDistribution[1],15],30]
|
||||
const double Wolfram_Poisson_CDF = 0.99999999999998132236536831934; // N[CDF[PoissonDistribution[1],15],30]
|
||||
const double Wolfram_Uniform_PDF = 0.00400000000000000000000000000000; // N[PDF[UniformDistribution[0,250],0.125],30]
|
||||
const double Wolfram_Uniform_CDF = 0.000500000000000000000000000000000; // N[CDF[UniformDistribution[0,250],0.125],30]
|
||||
const double Wolfram_Weibull_PDF = 0.0195121858238667121530217146408; // N[PDF[WeibullDistribution[5,1],0.25],30]
|
||||
const double Wolfram_Weibull_CDF = 0.000976085818024337765288210389671; // N[CDF[WeibullDistribution[5,1],0.25],30]
|
||||
const double Wolfram_T_PDF = 0.319904796224811454367412653512; // N[PDF[TDistribution[4],0.51234567890123456],30]
|
||||
const double Wolfram_T_CDF = 0.6822990443550955053632292600646; // N[CDF[TDistribution[4],0.51234567890123456],30]
|
||||
const double Wolfram_NoncentralT_PDF = 4.06507868645014429884902547978E-14; // N[PDF[Noncentral T Distribution[10,8],0.25],30]
|
||||
const double Wolfram_NoncentralT_CDF = 4.81698E-15; // N[CDF[Noncentral T Distribution[10,8],0.25],30]
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| GetCorrectDigits |
|
||||
//+------------------------------------------------------------------+
|
||||
int GetCorrectDigits(const double delta)
|
||||
{
|
||||
double d=MathAbs(delta);
|
||||
//--- check if delta to small
|
||||
if(d<10E-30)
|
||||
return(30);
|
||||
//--- check if delta is large
|
||||
if(d>=1.0)
|
||||
return(0);
|
||||
int correct_digits=0;
|
||||
while(MathAbs(d)<1.0)
|
||||
{
|
||||
d=d*10;
|
||||
correct_digits++;
|
||||
}
|
||||
//---
|
||||
return(correct_digits-1);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| TestPrecision |
|
||||
//+------------------------------------------------------------------+
|
||||
void TestPrecision(const string comment,const double pdf,const double cdf,const double pdf_calculated,const double cdf_calculated)
|
||||
{
|
||||
double delta_pdf=pdf-pdf_calculated;
|
||||
double delta_cdf=cdf-cdf_calculated;
|
||||
//--- print results
|
||||
Print("Testing precision for distribution:",comment);
|
||||
//---- print results
|
||||
PrintFormat("Distribution: %s, Wolfram PDF=%6.30f, PDF_calculated=%6.30f, deltaPDF=%6.30f",comment,pdf,pdf_calculated,delta_pdf);
|
||||
PrintFormat("Distribution: %s, Wolfram CDF=%6.30f, CDF_calculated=%6.30f, deltaCDF=%6.30f",comment,cdf,cdf_calculated,delta_cdf);
|
||||
//--- print correct digits
|
||||
PrintFormat("Distribution: %s PDF correct digits=%d",comment,GetCorrectDigits(delta_pdf));
|
||||
PrintFormat("Distribution: %s CDF correct digits=%d",comment,GetCorrectDigits(delta_cdf));
|
||||
Print("");
|
||||
return;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
int error_code=0;
|
||||
//--- Beta distribution parameters
|
||||
double a=2.0;
|
||||
double b=4.0;
|
||||
double x=0.5;
|
||||
double d_beta = MathProbabilityDensityBeta(x, a, b,error_code);
|
||||
double p_beta = MathCumulativeDistributionBeta(x, a, b,error_code);
|
||||
TestPrecision("Beta",Wolfram_Beta_PDF,Wolfram_Beta_CDF,d_beta,p_beta);
|
||||
|
||||
//--- Binomial distribution parameters
|
||||
x=5;
|
||||
double n=20;
|
||||
double prob=0.3;
|
||||
double d_binomial = MathProbabilityDensityBinomial(x,n,prob,error_code);
|
||||
double p_binomial = MathCumulativeDistributionBinomial(x,n,prob,error_code);
|
||||
TestPrecision("Binomial",Wolfram_Binomial_PDF,Wolfram_Binomial_CDF,d_binomial,p_binomial);
|
||||
|
||||
//--- Cauchy distribution parameters
|
||||
x=0.25;
|
||||
a=2.0; //mean
|
||||
b=1.0; //scale
|
||||
double d_cauchy = MathProbabilityDensityCauchy(x,a,b,error_code);
|
||||
double p_cauchy = MathCumulativeDistributionCauchy(x,a,b,error_code);
|
||||
TestPrecision("Cauchy",Wolfram_Cauchy_PDF,Wolfram_Cauchy_CDF,d_cauchy,p_cauchy);
|
||||
|
||||
//--- ChiSquare distribution parameters
|
||||
double nu=2;
|
||||
x=0.5;
|
||||
double d_chisquare = MathProbabilityDensityChiSquare(x,nu,error_code);
|
||||
double p_chisquare = MathCumulativeDistributionChiSquare(x,nu,error_code);
|
||||
TestPrecision("ChiSquare",Wolfram_ChiSquare_PDF,Wolfram_ChiSquare_CDF,d_chisquare,p_chisquare);
|
||||
|
||||
//--- Exponential distribution parameters
|
||||
x=0.25;
|
||||
double mu=2.0; // scale
|
||||
double d_exp = MathProbabilityDensityExponential(x,mu,error_code);
|
||||
double p_exp = MathCumulativeDistributionExponential(x,mu,error_code);
|
||||
TestPrecision("Exponential",Wolfram_Exponential_PDF,Wolfram_Exponential_CDF,d_exp,p_exp);
|
||||
|
||||
//--- F distribution parameters
|
||||
x=0.25;
|
||||
int nu1=2;
|
||||
int nu2=4;
|
||||
double d_F = MathProbabilityDensityF(x,nu1,nu2,error_code);
|
||||
double p_F = MathCumulativeDistributionF(x,nu1,nu2,error_code);
|
||||
TestPrecision("F",Wolfram_F_PDF,Wolfram_F_CDF,d_F,p_F);
|
||||
|
||||
//--- Gamma distribution parameters
|
||||
x=0.5;
|
||||
a=1.0; // shape
|
||||
b=1.0; // scale
|
||||
double d_gamma = MathProbabilityDensityGamma(x,a,b,error_code);
|
||||
double p_gamma = MathCumulativeDistributionGamma(x,a,b,error_code);
|
||||
TestPrecision("Gamma",Wolfram_Gamma_PDF,Wolfram_Gamma_CDF,d_gamma,p_gamma);
|
||||
|
||||
//--- Geometric distribution parameters
|
||||
x=5;
|
||||
prob=0.3;
|
||||
double d_geometric = MathProbabilityDensityGeometric(x,prob,error_code);
|
||||
double p_geometric = MathCumulativeDistributionGeometric(x,prob,error_code);
|
||||
TestPrecision("Geometric",Wolfram_Geometric_PDF,Wolfram_Geometric_CDF,d_geometric,p_geometric);
|
||||
|
||||
//--- Hypergeometric distribution parameters
|
||||
x=6;
|
||||
double m=20;
|
||||
double k=8;
|
||||
n=9;
|
||||
double d_hypergeometric = MathProbabilityDensityHypergeometric(x,m,k,n,error_code);
|
||||
double p_hypergeometric = MathCumulativeDistributionHypergeometric(x,m,k,n,error_code);
|
||||
TestPrecision("Hypergeometric",Wolfram_Hypergeometric_PDF,Wolfram_Hypergeometric_CDF,d_hypergeometric,p_hypergeometric);
|
||||
|
||||
//--- Logistic distribution parameters
|
||||
x=0.5;
|
||||
mu=1.0; // mean
|
||||
double sigma=1.0; // scale
|
||||
double d_logistic = MathProbabilityDensityLogistic(x,mu,sigma,error_code);
|
||||
double p_logistic = MathCumulativeDistributionLogistic(x,mu,sigma,error_code);
|
||||
TestPrecision("Logistic",Wolfram_Logistic_PDF,Wolfram_Logistic_CDF,d_logistic,p_logistic);
|
||||
|
||||
//--- Lognormal distribution parameters
|
||||
x=0.5;
|
||||
mu=10.0;
|
||||
sigma=2.0;
|
||||
double d_lognormal = MathProbabilityDensityLognormal(x,mu,sigma,error_code);
|
||||
double p_lognormal = MathCumulativeDistributionLognormal(x,mu,sigma,error_code);
|
||||
TestPrecision("Lognormal",Wolfram_Lognormal_PDF,Wolfram_Lognormal_CDF,d_lognormal,p_lognormal);
|
||||
|
||||
//--- Negative Binomial distribution parameters
|
||||
x=5.0;
|
||||
double r=2.0;
|
||||
prob=0.5;
|
||||
double d_negbinomial = MathProbabilityDensityNegativeBinomial(x,r,prob,error_code);
|
||||
double p_negbinomial = MathCumulativeDistributionNegativeBinomial(x,r,prob,error_code);
|
||||
TestPrecision("NegativeBinomial",Wolfram_NegativeBinomial_PDF,Wolfram_NegativeBinomial_CDF,d_negbinomial,p_negbinomial);
|
||||
|
||||
//--- Noncentral Beta distribution parameters
|
||||
x=0.25;
|
||||
a=2.0;
|
||||
b=4.0;
|
||||
double lambda=1;
|
||||
double d_noncentralbeta = MathProbabilityDensityNoncentralBeta(x,a,b,lambda,error_code);
|
||||
double p_noncentralbeta = MathCumulativeDistributionNoncentralBeta(x,a,b,lambda,error_code);
|
||||
TestPrecision("NoncentralBeta",Wolfram_NoncentralBeta_PDF,Wolfram_NoncentralBeta_CDF,d_noncentralbeta,p_noncentralbeta);
|
||||
|
||||
//--- Noncentral ChiSquare distribution parameters
|
||||
x=0.5;
|
||||
nu=2.0;
|
||||
sigma=1.0;
|
||||
double d_nchisquare = MathProbabilityDensityNoncentralChiSquare(x,nu,sigma,error_code);
|
||||
double p_nchisquare = MathCumulativeDistributionNoncentralChiSquare(x,nu,sigma,error_code);
|
||||
TestPrecision("NoncentralChiSquare",Wolfram_NoncentralChiSquare_PDF,Wolfram_NoncentralChiSquare_CDF,d_nchisquare,p_nchisquare);
|
||||
|
||||
//--- Noncentral F distribution parameters
|
||||
x=0.25;
|
||||
nu1=2.0;
|
||||
nu2=4.0;
|
||||
sigma=2.0;
|
||||
double d_noncentralF = MathProbabilityDensityNoncentralF(x,nu1,nu2,sigma,error_code);
|
||||
double p_noncentralF = MathCumulativeDistributionNoncentralF(x,nu1,nu2,sigma,error_code);
|
||||
TestPrecision("NoncentralF",Wolfram_NoncentralF_PDF,Wolfram_NoncentralF_CDF,d_noncentralF,p_noncentralF);
|
||||
|
||||
//--- Normal distribution parameters
|
||||
x=0.15;
|
||||
mu=21.0;
|
||||
sigma=5.0;
|
||||
double d_normal = MathProbabilityDensityNormal(x, mu, sigma,error_code);
|
||||
double p_normal = MathCumulativeDistributionNormal(x, mu, sigma,error_code);
|
||||
TestPrecision("Normal",Wolfram_Normal_PDF,Wolfram_Normal_CDF,d_normal,p_normal);
|
||||
|
||||
//--- Poisson distribution parameters
|
||||
x=15;
|
||||
lambda=1.0;
|
||||
double d_poisson = MathProbabilityDensityPoisson(x,lambda,error_code);
|
||||
double p_poisson = MathCumulativeDistributionPoisson(x,lambda,error_code);
|
||||
TestPrecision("Poisson",Wolfram_Poisson_PDF,Wolfram_Poisson_CDF,d_poisson,p_poisson);
|
||||
|
||||
//--- Uniform distribution parameters
|
||||
x=0.125;
|
||||
a=0.0; // lower
|
||||
b=250.0; // upper
|
||||
double d_uniform = MathProbabilityDensityUniform(x,a,b,error_code);
|
||||
double p_uniform = MathCumulativeDistributionUniform(x,a,b,error_code);
|
||||
TestPrecision("Uniform",Wolfram_Uniform_PDF,Wolfram_Uniform_CDF,d_uniform,p_uniform);
|
||||
|
||||
//--- Weibull distribution parameters
|
||||
x=0.25;
|
||||
a=5.0; // shape
|
||||
b=1.0; // scale
|
||||
double d_weibull = MathProbabilityDensityWeibull(x,a,b,error_code);
|
||||
double p_weibull = MathCumulativeDistributionWeibull(x,a,b,error_code);
|
||||
TestPrecision("Weibull",Wolfram_Weibull_PDF,Wolfram_Weibull_CDF,d_weibull,p_weibull);
|
||||
|
||||
//--- T distribution parameters
|
||||
x=0.51234567890123456;
|
||||
nu=4.0;
|
||||
double d_T = MathProbabilityDensityT(x,nu,error_code);
|
||||
double p_T = MathCumulativeDistributionT(x,nu,error_code);
|
||||
TestPrecision("T",Wolfram_T_PDF,Wolfram_T_CDF,d_T,p_T);
|
||||
|
||||
//--- Noncentral T distribution parameters
|
||||
x=0.25;
|
||||
nu=10.0;
|
||||
double delta=8.0;
|
||||
double d_NT = MathProbabilityDensityNoncentralT(x,nu,delta,error_code);
|
||||
double p_NT = MathCumulativeDistributionNoncentralT(x,nu,delta,error_code);
|
||||
TestPrecision("NoncentralT",Wolfram_NoncentralT_PDF,Wolfram_NoncentralT_CDF,d_NT,p_NT);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user