#_LinRegres_Neuro_GA
Download scriptThis script is a sophisticated technical analysis tool designed to predict market trends and calculate potential profits by combining three distinct mathematical concepts: Linear Regression, Artificial Neural Networks, and Genetic Algorithms.
Instead of relying on simple price movements, the logic follows a multi-layered approach to "learn" and identify high-probability trading signals. Here is a breakdown of how that logic works:
1. Data Input (Linear Regression)
The script begins by analyzing historical price data using linear regression. It calculates the "slope" (the rate of change) of the price over various periods. Rather than just looking at the raw price, it looks at the curvature and direction of these slopes to determine if the market is accelerating, decelerating, or moving in a specific trend.
2. Pattern Recognition (Neural Network)
The data gathered from the linear regression is fed into a "Neural Network." In non-technical terms, this is a mathematical model that mimics how biological brains process information.
- It takes multiple inputs simultaneously.
- It processes them through different layers of "neurons" to identify hidden patterns that a human eye might miss.
- The output of this network is a specific signal value that represents the strength and direction of the market trend.
3. Smoothing & Filtering (T3MA)
To prevent the system from reacting to "noise" (small, insignificant price flickers), the raw signal from the neural network is passed through a smoothing filter (referred to as T3). This ensures that only significant, sustained movements trigger a potential trade, filtering out the erratic jumps common in volatile markets.
4. Optimization (Genetic Algorithm)
This is the "intelligence" of the script. Rather than using fixed settings chosen by a human, the script uses a Genetic Algorithm to find the best possible parameters for itself. It works like biological evolution:
- Population: It creates a large group of different "individuals" (sets of trading parameters).
- Fitness: It tests each individual against historical data to see which ones would have made the most profit.
- Evolution: It takes the "winners" (the most profitable parameters) and "breeds" them together, introducing small random changes (mutations).
- Iteration: It repeats this process many times over several generations until it arrives at a set of parameters that perform optimally.
5. Execution & Reporting
Once the Genetic Algorithm finds the best performing "DNA" for the trading strategy:
- It saves these optimal settings to a local file.
- The indicator then uses these saved settings to calculate real-time signals on your chart.
- It identifies specific Buy and Sell points based on the neural network's output and the smoothed trend.
- It calculates the cumulative profit of those trades in real-time, displaying it directly on your screen.
Summary for the User
In short, this script is a self-optimizing system. It uses a "biological" approach to evolution to test thousands of different mathematical combinations, identifies the most profitable ones using a neural network inspired by brain structures, and then applies those findings to provide you with smoothed trend signals and profit tracking.
//+------------------------------------------------------------------+
//| LinRegres_Neuro_GA.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, klot."
#property link "klot@mail.ru"
//------
#define MAXPOP 200 // ìàêñèìàëüíîå êîëè÷åñòâî îñîáåé â ïîïóëÿöèè
#define MAXWITCH 18 // êîëè÷åñòâî îïòèìèçèðóåìûõ ïàðàìåòðîâ
//-------
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Aqua
#property indicator_level1 0.0
#property indicator_level2 1.0
#property indicator_level3 -1.0
//---- indicator parameters
//----
extern int barn = 130; // ÷èñëî áàðîâ äëÿ îïòèìèçàöèè ÒÑ ïî èñòîðèè
//extern double th= 1.0; // ïîðîã äëÿ òîðãîâîé ñèñòåìû
//---- indicator buffers
double profits[];
double signal[];
//-------------
extern bool Optimize=false;
static datetime New_Time=0;
static int Nosob=-1;
//-------------
double ww[13];
//-----
double fitness[MAXPOP];
//-----
double population[MAXPOP][MAXWITCH]; // Population
//+------------------------------------------------------------------+
//| Ôóíêöèÿ âîçâðàùàåò õðîìîñîìó (gene[]) îñîáè (int p) |
//+------------------------------------------------------------------+
void GetGene(int p, double &gene[])
{
for(int j=0; j<MAXWITCH; j++) gene[j]=population[p][j];
return;
}
//+------------------------------------------------------------------+
//| Îñíîâíàÿ ôóíêöèÿ îïòèìèçàöèè âîçâðàùàåò èíäåêñ íàèáîëåå |
//| ïðèñïîñîáëåííîé îñîáè |
//+------------------------------------------------------------------+
int Solve() {
int osob = -1;
double fit=-1;
// Generate initial population.
MathSrand(TimeLocal());
//--- Ãåíåðèðóåñòÿ íà÷àëüíàÿ ïîïóëÿöèÿ -------------
for(int i=0; i<MAXPOP; i++) {
for (int j=0; j<MAXWITCH; j++) {
if (j<13 ) population[i][j]=(MathRand() % 401)/100.0-2.0;
if (j==13 ) population[i][j]=(MathRand() % 100)/100.0;
if (j>13 ) population[i][j]=(MathRand() % 70)+3;
}
}
//---
int iterations = 0; // Keep record of the iterations.
int TotalIterations = 0;
double Bestfit=-1;
int Bestosob=-1;
//+-- Öèêë ýâîëþöèè ------------------------------------+
//| Åñëè â òå÷åíèè 20 ïîêîëåíèé óëó÷øåíèÿ íå ïðîèñõîäÿò +
//| Îïòèìèçàöèÿ çàâåðøàåòñÿ +
//+-----------------------------------------------------+
while ( (iterations<20) ) {
//---
osob=CreateFitnesses(fit);
//--- Ñáðàñûâàåì ñ÷åò÷èê êàæäûé ðàç åñëè ïðîèñõîäèò èçìåíåíèå ----
if( (osob!=Bestosob) || (fit>Bestfit) ) {
//---
iterations=0;
Bestfit=fit;
Bestosob=osob;
//Print("Îñîáü ¹ ",osob," TotalIterations = ",TotalIterations);
}
//---
CreateNewPopulation(Bestosob);
//---
iterations++;
TotalIterations++;
}
//---
Print("TotalIterations = ",TotalIterations, " Ëó÷øàÿ îñîáú ¹ ",Bestosob," fit = ",Bestfit);
return (Bestosob);
}
//+------------------------------------------------------------------+
//| Ôóíêöèÿ âîçâðàùàåò èíäåêñ ë÷øåé îñîáè |
//| è ñðåäíþþ ïðèáûëü ïî âñåé ïîïóëÿöèè (double &avgfit) |
//+------------------------------------------------------------------+
int CreateFitnesses(double &avgfit) {
//---
double gene[];
double www[];
double th=0;
int p1,p2,p3,p4;
double max=0;
int maxFitnessIndex=-1;
ArrayResize(gene,MAXWITCH);
ArrayResize(www,13);
//---
avgfit=0;
for(int i=0;i<MAXPOP;i++) {
//---
GetGene(i,gene);
ArrayCopy(www,gene,0,0,13);
th=gene[13];
p1=gene[14];
p2=gene[15];
p3=gene[16];
p4=gene[17];
fitness[i]=TStrategy1(www,th,p1,p2,p3,p4,true);
//---
if (fitness[i]>max ) {
max=fitness[i];
maxFitnessIndex=i;
}
avgfit += fitness[i];
}
avgfit=avgfit/MAXPOP;
//---
return(maxFitnessIndex);
}
//+------------------------------------------------------------------+
//| Ôóíêöèÿ ñîçäàåò íîâóþ ïîïóëÿöèþ ïóòåì ñêðåùèâàíèÿ |
//| âñåõ îñîáåé â ïîïóëÿöèè ñ íàèáîëåå ëó÷øåé |
//+------------------------------------------------------------------+
void CreateNewPopulation(int osob) {
//---
int i=0,j=0;
int crossover=0;
int mutate=0;
double xromosoma[];
ArrayResize(xromosoma,MAXWITCH);
//--- Õðîìîñîìà ýëèòíîé îñîáè --------
GetGene(osob,xromosoma);
//---
MathSrand(TimeLocal()+MathRand());
//---
for( i=0; i<MAXPOP; i++ ) {
//---
if ( i==osob ) { // Èñêëþ÷àåì ñêðåùèâàíèå ñàìó ñ ñîáîé
continue;
}
//---- ×àñòü îñîáåé â ïîïóëÿöèè ïîäâåðãàþòñÿ ìóòàöèÿì -----
mutate=(MathRand() % 101);
//----
if( mutate > 40 ) {
//---- Ðàñ÷èòûâàåì êàêèå ãåíû ýëèòíîé îñîáè áóäóò ïåðåäàíû ïîòîìêàì -----
crossover = (MathRand() % MAXWITCH);
//----
if ( crossover<MAXWITCH/2.0 ) {
//---- Îïëîäîòâîðåíèå -----
for( j=crossover; j<MAXWITCH; j++ ) {
population[i][j]=xromosoma[j];
}
} else {
for( j=0; j<crossover; j++ ) {
population[i][j]=xromosoma[j];
}
}
//---
} else { //---Èíà÷å ïðîèñõîäèò ìóòàöèÿ
for( j=0; j<MAXWITCH; j++ ) {
if (j<13 ) population[i][j]=(MathRand() % 401)/100.0-2.0;
if (j==13 ) population[i][j]=(MathRand() % 100)/100.0;
if (j>13 ) population[i][j]=(MathRand() % 70)+3;
}
}
}
//---
return;
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(2);
//---- drawing settings
SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
SetIndexBuffer(1,profits);
SetIndexBuffer(0,signal);
SetIndexEmptyValue(0,0.0);
//---- indicator short name
IndicatorShortName("LinRegres_Neuro_GA("+barn+")");
//---- initialization done
//-------
MathSrand(TimeLocal());
for(int i=0; i<13; i++) ww[i]=(MathRand() % 401)/100.0-2.0;
//-------
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
//------
double th=0;
double gene[];
int p1=0,p2=0,p3=0,p4=0;
ArrayResize(gene,MAXWITCH);
//---
int nbar=iBarShift(Symbol(),PERIOD_MN1,Time[0]);
//---
if( Optimize==true && New_Time!=iTime(Symbol(),PERIOD_MN1,nbar) ) {
//----
Nosob=Solve();
//----
if( Nosob!=-1 )GetGene(Nosob,gene);
//----
WriteFileNeuro(gene);
//----
New_Time=iTime(Symbol(),PERIOD_MN1,nbar);
}
//---
if (ReadFileNeuro(gene) ) {
//---
ArrayCopy(ww,gene,0,0,13);
th=gene[13];
p1=gene[14];
p2=gene[15];
p3=gene[16];
p4=gene[17];
}
double profit=TStrategy1(ww,th,p1,p2,p3,p4,false);
//}
Comment("Îáùàÿ ïðèáûëü= ",profit," Ëó÷øàÿ îñîáú ¹ ",Nosob," th = ",th," p1 = ",p1," p2 = ",p2," p3 = ",p3," p4 = ",p4);
//-----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool ReadFileNeuro(double& www[])
{
int handle;
string Fname="LinReres_NeuroWich.dat";
int N=ArraySize(www);
handle=FileOpen(Fname, FILE_BIN|FILE_READ);
if(handle>0) {
FileReadArray(handle,www,0,N);
FileClose(handle);
return (true);
} else
return (false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void WriteFileNeuro(double www[])
{
int handle;
//-----
int N=ArraySize(www);
string Fname="LinReres_NeuroWich.dat";
//-------
handle=FileOpen(Fname,FILE_BIN|FILE_WRITE);
if(handle>0) {
FileWriteArray(handle,www,0,N);
//-------
FileFlush(handle);
FileClose(handle);
}
return;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TStrategy1(double wa[],double trh,int p1,int p2,int p3,int p4, int fOpt=false)
{
int shift,k=0;
string name="Signal";
double in[];
int lastbuy=0,lastsell=0,trend=0;
double profit,profit0;
double spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
double Buy[],Sell[];
ArrayResize(in,4);
ArrayResize(Buy,barn);
ArrayResize(Sell,barn);
ArrayInitialize(Buy,0.0);
ArrayInitialize(Sell,0.0);
//--------------T3 ñãëàæèâàíèå---------------------------------+
double e1, e2, e3, e4, e5, e6, c1, c2, c3, c4, w1, w2, b2, b3;
double n,t3,b;
//----
n=6.0;
b=0.75;
//-----
b2=b*b;
b3=b2*b;
c1=-b3;
c2=(3.0*(b2+b3));
c3=-3.0*(2.0*b2+b+b3);
c4=(1.0+3.0*b+b3+3*b2);
//------
if (n<1) n=1;
n = 1.0+0.5*(n-1);
w1 = 2.0/(n+1);
w2 = 1.0-w1;
//-------------------------------------------------------------+*/
//-------------------------------------------------------------
if(!fOpt) for(shift=barn; shift>=0; shift--) ObjectDelete(name+shift);
profit=0;
profit0=0;
for(shift=barn; shift>=0; shift--) {
//-----Âõîäû ñåòè ----
in[0]=LinRegresSlope2(p1,shift+1);
in[1]=LinRegresSlope2(p2,shift+1);
in[2]=LinRegresSlope2(p3,shift+1);
in[3]=LinRegresSlope2(p4,shift+1);
//----- Âûõîä ñåòè -------------
signal[shift] = neuronet1(wa,in);
//----- T3 ñãëàæèâàíèå --------
e1 = w1*signal[shift] + w2*e1;
e2 = w1*e1 + w2*e2;
e3 = w1*e2 + w2*e3;
e4 = w1*e3 + w2*e4;
e5 = w1*e4 + w2*e5;
e6 = w1*e5 + w2*e6;
//-----
t3=c1*e6+c2*e5+c3*e4+c4*e3;
signal[shift]=t3;///------*/
//-------------------------------------------------------------+
//| Ñèãíàëû |
//-------------------------------------------------------------+
if( signal[shift]>signal[shift+1] && signal[shift+2]>signal[shift+1]
&& signal[shift+1]<-trh && trend!=1 ) {
Buy[shift]=Close[shift]+spread;
trend=1;
lastbuy=shift;
if(!fOpt){
ObjectCreate(name+shift,OBJ_ARROW,0,Time[shift],Buy[shift]);
ObjectSet(name+shift,OBJPROP_ARROWCODE,225);
}
k++;
}
//------
if( signal[shift]<signal[shift+1] && signal[shift+2]<signal[shift+1]
&& signal[shift+1]>trh && trend!=-1 ) {
Sell[shift]=Close[shift]-spread;
trend=-1;
lastsell=shift;
if(!fOpt){
ObjectCreate(name+shift,OBJ_ARROW,0,Time[shift],Sell[shift]);
ObjectSet(name+shift,OBJPROP_ARROWCODE,226);
}
k++;
}
//------Ïîäñ÷åò ïðîôèòà-------------
if( k>1 && ((Buy[shift]!=0 && Sell[lastsell]!=0) ||
(Buy[lastbuy]!=0 && Sell[shift]!=0)) ) {
//-------
profit+=(Sell[lastsell]-Buy[lastbuy])/Point;
}
//------
profits[shift]=profit;
}
//------Ïîäñ÷åò ïðîôèòà òåêóùåé ñäåëêè -------------
profit0=0;
if( lastbuy<lastsell && lastbuy>0 ) profit0=(Close[0]-Buy[lastbuy])/Point;
if( lastsell<lastbuy && lastsell>0 ) profit0=(Sell[lastsell]-Close[0])/Point;
//-----------------------+
return(profit+profit0);
}
//+------------------------------------------------------------------+
//| 2-õ ñëîéíàÿ íåéðîñåòü èç 3-õ íåéðîíîâ |
//| ïåðâûé ñëîé - äâà íåéðîíà |
//| âòîðîé ñëîé - îäèí íåéðîí |
//| âåñà W[0], W[N+1], W[2*N+2] - çàäàþò ñìåùåíèå íåéðîíîâ |
//| N - ÷èñëî âõîäîâ |
//| ×èñëî ïîäñòðàèâàåìûõ âåñîâ ðàñ÷èòûâàåòñÿ êàê N*2+2+3 |
//+------------------------------------------------------------------+
double neuronet1(double W[],double x[])
{
int i;
int N=ArraySize(x);
if(ArraySize(W)!=N*2+5) {
Print("Îøèáêà! Ðàçìåð ìàññèâà âåñîâ äîëæåí áûòü = ",N*2+5);
return(0);
}
double sum=0.0;
double Out1=0.0, Out2=0.0;
//---Neuron 1 ----------------+
sum=W[0];
//---
for(i=1; i<=N; i++) {
sum+=W[i]*x[i-1];
}
Out1=MathArctan(sum);//th(sum);
//---Neuron 2 ----------------+
sum=W[N+1];
//---
for(i=N+2; i<=2*N+1; i++) {
sum+=W[i]*x[i-(N+2)];
}
Out2=MathArctan(sum);//th(sum);
//---Neuron 3 ----------------+
return(MathArctan(Out1*W[2*N+3]+Out2*W[2*N+4]+W[2*N+2]));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LinRegresSlope2(int length, int shift)
{
int m_pos[2];
m_pos[0]=shift;
m_pos[1]=shift+length;
int n=m_pos[1]-m_pos[0]+1;
//---- calculate price values
double value=Close[m_pos[0]];
double a,b,c;
double sumy=value;
double sumx=0.0;
double sumxy=0.0;
double sumx2=0.0;
for(int i=1; i<n; i++)
{
value=Close[m_pos[0]+i];
sumy+=value;
sumxy+=value*i;
sumx+=i;
sumx2+=i*i;
}
c=sumx2*n-sumx*sumx;
if(c==0.0) c=0.000001;
b=(sumxy*n-sumx*sumy)/c;
a=(sumy-sumx*b)/n;
//m_value[0]=a;
//m_value[Extlength]=a+b*n;
//return(th(3000*(a -(a+b*n))/n));
return(MathArctan(10000*(a -(a+b*n))/n));
}
/*
double Normalize(int PeriodNorm, int i)
{
double ma=iMA(NULL,0,PeriodNorm,0,MODE_SMA,PRICE_CLOSE,i);
double dev=1.5*iStdDev(NULL,0,PeriodNorm,0,MODE_SMA,PRICE_CLOSE,i);
if(dev==0) dev=0.000001;
//-----
return((Close[i]-ma)/dev);
}*/
/*//+-----------------------------------------------------------------+
//| Ãèïåðáîëè÷åñêèé òàíãåíñ |
//+-----------------------------------------------------------------+
double th(double x)
{
double x_=MathExp(x);
double _x=MathExp(-x);
//-----
double a=(x_+_x);
double b=(x_-_x);
if( a==0) a=0.00000001;
return(b/a);
}*/
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
ObjectsDeleteAll();
//----
return(0);
}
Comments