boss/Scripts/BOSS/BOSSNoiseSweep.mq5
2026-07-13 16:05:51 +00:00

128 lines
4.4 KiB
MQL5

//+------------------------------------------------------------------+
//| BOSSNoiseSweep.mq5|
//| MMQ — Muhammad Minhas Qamar |
//| www.mql5.com/en/articles/23491 |
//+------------------------------------------------------------------+
#property copyright "MMQ — Muhammad Minhas Qamar"
#property link "https://www.mql5.com/en/articles/23491"
#property description "Sweeps the retained-coefficient count against a rising noise level on a trend-vs-range task and prints an accuracy grid."
#property version "1.00"
#property strict
#include <BOSS\BOSS.mqh>
input int Alphabet = 4;
input int Window = 24;
input int SeriesLen = 240;
//+------------------------------------------------------------------+
//| Trending shape: drift plus a small oscillation and noise. |
//+------------------------------------------------------------------+
void MakeTrend(double &out[],int len,double noise)
{
ArrayResize(out,len);
for(int i=0;i<len;i++)
out[i]=0.02*i+0.5*MathSin(2.0*M_PI*i/Window)+noise*(MathRand()/32767.0-0.5);
}
//+------------------------------------------------------------------+
//| Ranging shape: clean oscillation about a flat mean plus noise. |
//+------------------------------------------------------------------+
void MakeRange(double &out[],int len,double noise)
{
ArrayResize(out,len);
for(int i=0;i<len;i++)
out[i]=MathSin(2.0*M_PI*i/Window)+noise*(MathRand()/32767.0-0.5);
}
//+------------------------------------------------------------------+
//| Build a broad window pool (both shapes) for MCB fitting. |
//+------------------------------------------------------------------+
void BuildWindows(double &windows[],int &count,int win,double noise)
{
int per=150;
count=per*2;
ArrayResize(windows,count*win);
double s[];
int idx=0;
for(int r=0;r<per;r++)
{
MakeTrend(s,win,noise);
for(int i=0;i<win;i++)
windows[idx*win+i]=s[i];
idx++;
MakeRange(s,win,noise);
for(int i=0;i<win;i++)
windows[idx*win+i]=s[i];
idx++;
}
}
//+------------------------------------------------------------------+
//| Accuracy of a trend/range classifier at a given query noise. |
//| Trains one clean prototype per class, then classifies fresh |
//| noisy series of both shapes and returns overall accuracy. |
//+------------------------------------------------------------------+
double AccuracyAt(int word_len,double train_noise,double query_noise)
{
double windows[];
int nwin;
BuildWindows(windows,nwin,Window,train_noise);
CBossClassifier clf;
if(!clf.Build(word_len,Alphabet,windows,nwin,Window))
return -1.0;
double s[];
MakeTrend(s,SeriesLen,train_noise);
clf.AddExample(s,SeriesLen,"trend");
MakeRange(s,SeriesLen,train_noise);
clf.AddExample(s,SeriesLen,"range");
int correct=0, trials=40, total=0;
double bd;
for(int t=0;t<trials;t++)
{
MakeTrend(s,SeriesLen,query_noise);
if(clf.Classify(s,SeriesLen,bd)=="trend")
correct++;
total++;
MakeRange(s,SeriesLen,query_noise);
if(clf.Classify(s,SeriesLen,bd)=="range")
correct++;
total++;
}
return 100.0*correct/total;
}
//+------------------------------------------------------------------+
//| Print the WordLen x noise accuracy grid. |
//+------------------------------------------------------------------+
void OnStart()
{
MathSrand(20260712);
int wls[3] = {2,3,4};
double noises[5]= {0.1,0.3,0.5,1.0,1.5};
//--- header row
string hdr=" WordLen |";
for(int n=0;n<5;n++)
hdr+=StringFormat(" noise=%.1f",noises[n]);
Print("=== BOSS accuracy: retained coefficients vs query noise ===");
Print(" (trained at low noise 0.07; trend-vs-range; chance = 50%)");
Print(hdr);
for(int w=0;w<3;w++)
{
string row=StringFormat(" %2d (%dL) |",wls[w],wls[w]*2);
for(int n=0;n<5;n++)
{
double acc=AccuracyAt(wls[w],0.07,noises[n]);
row+=StringFormat(" %5.0f%%",acc);
}
Print(row);
}
Print("=== sweep complete ===");
}
//+------------------------------------------------------------------+