153 lines
No EOL
4.8 KiB
MQL5
153 lines
No EOL
4.8 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| L1TrendRandomWalk.mq5 |
|
|
//| Copyright 2000-2026, MetaQuotes Ltd. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2000-2026, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
//---
|
|
#include <Graphics\Graphic.mqh>
|
|
//---
|
|
uint32_t ExtSeed = 1;
|
|
//--- buffer
|
|
vector<double> ExtBuffer;
|
|
double ExtLastValue = 0.0;
|
|
int ExtHead = 0;
|
|
bool ExtReady = false;
|
|
//+------------------------------------------------------------------+
|
|
//| Init |
|
|
//+------------------------------------------------------------------+
|
|
void BMInit(uint32_t size)
|
|
{
|
|
MathSrand(ExtSeed);
|
|
ExtBuffer.Resize(size);
|
|
ExtLastValue = 0.0;
|
|
for(uint32_t i = 0; i < size; i++)
|
|
{
|
|
ExtLastValue += (MathRand() / 32767.0 - 0.5);
|
|
ExtBuffer[i] = ExtLastValue;
|
|
}
|
|
ExtHead = 0;
|
|
ExtReady = true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Add N new points |
|
|
//+------------------------------------------------------------------+
|
|
void BMNext(int n_points)
|
|
{
|
|
if(!ExtReady)
|
|
return;
|
|
int size = (int)ExtBuffer.Size();
|
|
for(int k=0; k<n_points; k++)
|
|
{
|
|
ExtLastValue += (MathRand() / 32767.0 - 0.5);
|
|
ExtBuffer[ExtHead] = ExtLastValue;
|
|
ExtHead++;
|
|
if(ExtHead >= size)
|
|
ExtHead = 0;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Get ordered data |
|
|
//+------------------------------------------------------------------+
|
|
bool BMGet(double &out[])
|
|
{
|
|
if(!ExtReady)
|
|
return(false);
|
|
|
|
int size = (int)ExtBuffer.Size();
|
|
|
|
if(ArrayResize(out, size) != (int)size)
|
|
return(false);
|
|
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
int idx = (ExtHead + i) % size;
|
|
out[i] = ExtBuffer[idx];
|
|
}
|
|
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| L1Trend from existing data |
|
|
//+------------------------------------------------------------------+
|
|
bool L1Trend(double &result[], const double &src[], int size, double lambda)
|
|
{
|
|
vector<double> v;
|
|
v.Resize(size);
|
|
|
|
for(int i=0; i<size; i++)
|
|
v[i] = src[i];
|
|
|
|
vector<double> vres;
|
|
if(!v.L1TrendFilter(lambda, true, vres))
|
|
return(false);
|
|
|
|
if(ArrayResize(result,(int)vres.Size()) != (int)vres.Size())
|
|
return(false);
|
|
|
|
for(int i=0; i<(int)vres.Size(); i++)
|
|
result[i]=vres[i];
|
|
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TestRun |
|
|
//+------------------------------------------------------------------+
|
|
bool TestRun(int data_count)
|
|
{
|
|
//--- init or continue
|
|
if(!ExtReady || ExtBuffer.Size() != data_count)
|
|
BMInit(data_count);
|
|
else
|
|
BMNext(10); // add new values
|
|
//--- graphic
|
|
CGraphic graphic;
|
|
long chart = 0;
|
|
string name = "Random walk";
|
|
if(ObjectFind(chart,name)<0)
|
|
graphic.Create(chart,name,0,0,0,1000,600);
|
|
else
|
|
graphic.Attach(chart,name);
|
|
//---
|
|
graphic.BackgroundMain("L1Trend filtering (random walk) with different lambda ");
|
|
graphic.BackgroundMainSize(16);
|
|
graphic.HistoryNameWidth(60);
|
|
graphic.HistoryColor(ColorToARGB(clrGray,255));
|
|
graphic.XAxis().AutoScale(false);
|
|
graphic.XAxis().Min(0);
|
|
graphic.XAxis().Max(data_count);
|
|
//--- X
|
|
double x[];
|
|
ArrayResize(x, data_count);
|
|
for(int i=0; i<data_count; i++)
|
|
x[i] = i;
|
|
//--- data
|
|
double y[];
|
|
if(!BMGet(y))
|
|
return(false);
|
|
|
|
graphic.CurveAdd(x, y, CURVE_LINES, "Data").LinesWidth(1);
|
|
//--- filters
|
|
const double lambda_factors[] = {1.0,0.8,0.5,0.2,0.1,0.01,0.001};
|
|
for(int i=0; i<ArraySize(lambda_factors); i++)
|
|
{
|
|
double yt[];
|
|
if(L1Trend(yt, y, data_count, lambda_factors[i]))
|
|
graphic.CurveAdd(x, yt, CURVE_LINES, "λ=" + DoubleToString(lambda_factors[i],4)).LinesWidth(3);
|
|
}
|
|
//--- draw
|
|
graphic.CurvePlotAll();
|
|
graphic.Update();
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| OnStart |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
for(int n=0; !IsStopped(); n++, Sleep(1))
|
|
TestRun(1000);
|
|
} |