L1Trend/Scripts/L1TrendRandomWalk.mq5

153 lines
4.8 KiB
MQL5
Raw Permalink Normal View History

//+------------------------------------------------------------------+
//| 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);
}