#_Lib_Kohhen.mq4
Download scriptThis script implements a specialized artificial intelligence system based on a Kohonen Map (also known as a Self-Organizing Map). In simple terms, it is a type of neural network designed to take complex, multi-dimensional data and organize it into a simplified, two-dimensional map. It "learns" by moving its internal neurons to match the patterns it sees in the market data.
Here is a breakdown of the logic used by this system:
1. The Neural Architecture
The script creates a grid of virtual "neurons." Each neuron is connected to several inputs via "synapses," which have specific weights. Think of these weights as the neuron's "preferences"—they determine how much importance a neuron gives to specific pieces of information (like price, volume, or other indicators).
2. The Learning Process
The system follows a specific cycle to learn from market behavior:
- Propagation: When new data enters the system, every neuron calculates its response. It combines the input data with its current weights to produce an output.
- Competition (Best Matching Unit): The script identifies which neuron responded most strongly and "closely" to the current market state. This specific neuron is considered the winner for that specific moment in time.
- Adjustment: The system then updates the weights of the winning neuron and its immediate neighbors. It nudges their weights to be slightly more similar to the current data. Over time, this causes neurons in a specific area of the grid to become "specialists" in recognizing specific market conditions.
3. Key Mechanisms
To make the learning effective and stable, the script uses several sophisticated logic gates:
- Inhibition: This prevents a single neuron from becoming too dominant or "over-learning" a pattern too quickly. If a neuron becomes too active, it enters an inhibited state where it is temporarily silenced, allowing other neurons a chance to participate in the learning process.
- Accreditation & Distance: The script manages how much of the map is updated at once. Depending on the settings, it can either update a broad "neighborhood" of neurons or use a mathematical decay (based on distance) to ensure that only the neurons closest to the winning neuron are adjusted.
- Normalization: To prevent the numbers within the system from growing infinitely large (which would cause the logic to break), the script periodically scales the weights back into a manageable range.
4. Visualization
The script includes a built-in visualizer. It converts the mathematical "activity" of the neural network into a color spectrum (a rainbow map). This allows a user to see the map on their screen: different colors represent different market states, and the shifting colors show how the network is evolving as it "perceives" new data.
Summary for the User
Essentially, this script acts like a pattern recognizer. Instead of using rigid "if/then" rules, it learns the "shape" of the market. As it processes data, it organizes itself into a visual map where similar market behaviors are grouped together in the same area of the grid.
//+------------------------------------------------------------------+
//| #_Lib_Kohhen.mq4 |
//| Copyright © 2008, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#property library
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
#define MAXDISTANCE 100000000000
#define RAND_MAX 32767
static double InFreshold=0.0;
static double MaxDistance=MAXDISTANCE;
static int Accreditation=0;
static double LearnRate=0.25;
static int Inhibition=0;
static int MAX_INP; //×èñëî âõîäîâ â ñåòü
static int MAX_NEURON; //×èñëî íåéðîíîâ â ñåòè
double delta[]; //îáó÷åíèå
double inhibitory[]; //Òîðìîæåíèå íåéðîíà
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
static int dx=0,dy=0; //Ðàçìåð êàðòû
int imax; //Íåéðîí ïîáåäèòåëü
int nx =0,ny=0; //Åãî êîîðäèíàòû
void SetSizeNet(int inp, int neur)
{
MAX_INP =inp;
MAX_NEURON = neur;
ArrayResize(delta,MAX_NEURON);
ArrayResize(inhibitory,MAX_NEURON);
for(int i=0;i<MAX_NEURON;i++)inhibitory[i]=0;
}
void SetShowDim(int _DX, int _DY){dx=_DX; dy=_DY;}
// çàäàåì íà÷àëüíîå óñëîâèå äëÿ ÃÑ×
void srand(){MathSrand(TimeLocal());}
//
double SetLearnRateUL(double lr){double a;a=LearnRate;LearnRate=lr;return (a);}
// èñïîëüçóåì ãàóññèàí äëÿ îïðåäåëåíèÿ ôîðìû
// îáëàñòè îáó÷åíèÿ è ýôôåêòèâíîñòè âîçäåéñòâèÿ
void SetAccreditationUL(int ac){ Accreditation=ac;}
// ÷èñëî öèêëîâ íà êîòîðûå íåéðîí òîðìîçèòñÿ
// ïîñëå âîçáóæäåíèÿ
void SetInhibitionUL(int in){Inhibition=in;}
// ïîðîã âîçáóæäåíèÿ, èíèöèèðóþùèé òîðìîæåíèå
double SetInhibitionFreshold(double f){double a;a=InFreshold;InFreshold=f; return (a);}
//
double SetMaxDistanceUL(double md){double a;a=MaxDistance;if(md<1.0) Accreditation=0;MaxDistance=md;return (a);}
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
//Çàïîëíÿåì âåñà ñëó÷àéíûìè âåëè÷èíàìè
void LayerUL_Randomize(double & n[][],double range)
{
int i,j;
double p=0.0001;
for( i=0; i<MAX_NEURON;i++ )
{ for( j=0; j<MAX_INP;j++ )
{
n[i][j] =( p+ range*MathRand()/RAND_MAX);
}
}
}
//íîðìàëèçóåì âåñà
void NormalizeSynapses(double & n[][])
{
double s=0;
int i,j;
for(i=0;i<MAX_NEURON;i++)
{
for(j=0;j<MAX_INP;j++)
s+=n[i][j]*n[i][j];
s=MathSqrt(s);
if(s !=0 )
for(j=0;j<MAX_INP;j++)n[i][j]/=s;
}
}
//Íîðìàëèçàöèÿ ìàññèâà çíà÷åíèå
void Normalize(double & mv[])
{
int Size=ArrayRange(mv,0);
double s=0.;
for(int i=0;i<Size;i++)
s+=(mv[i]+0.5)*(mv[i]+0.5);
s=MathSqrt(s);
if(s != 0)
for(i=0;i<Size;i++)
mv[i]=(mv[i]+0.5)/s-0.5;
}
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
//Ðàñ÷åò ñëîÿ Êðõõåíà
void LayerUL_Propagate(double inputs[],double &n[][],double &axon[])
{
int i,j;
int cx, cy;
double fmax, f;
for(i=0;i<MAX_NEURON;i++)
{
//neurons[i].Propagate();
double state=0.;
for( j=0;j<MAX_INP;j++)
{
state+=(inputs[j])*(n[i][j]);
}
//"Ýêñïîíåíòà áîëåå òåðïèìà ê ïàðàìåòðàì ïðåâûøàþùèì +1;-1 ñ òàíãåíñîì êàê âñåãà âñå ïå÷àëüíî :(
axon[i]=2.0 / (1.0 + MathExp(-state)) - 1;//MathTan(state);
if(Inhibition !=0)
{
if(axon[i]>InFreshold) // âîçáóæäåíèå
{
if(inhibitory[i]<=0) // ïîêà íå çàòîðìîæåí
inhibitory[i]=axon[i]*Inhibition/0.5; // òîðìîçèì
}
// ïîñòåïåííîå âîññòàíîâëåíèå âîçìîæíîñòè âîçáóæäàòüñÿ
if(inhibitory[i]>0) inhibitory[i]--;
}
}
fmax=MAXDISTANCE;
imax=-1;
for(i=0;i<MAX_NEURON;i++)
{
//
double s=0.0;
for(j=0;j<MAX_INP;j++)
s+=MathAbs(inputs[j]-n[i][j]);
delta[i]=s;
//
//f=neurons[i].CountDistance();
f = s;
if(f<fmax)
{
fmax=f;
imax=i;
}
}
//Ìîæíî è òàê çäåëàòü
//imax = ArrayMaximum(axon); //Íàõîäèì íåéðîí ìàêñèìàëüíî îòêëèêíóâøèéñÿ íà ñèãíàë
if(imax==-1){return (false);}
ny=imax/dx; // âû÷èñëåíèå êîîðäèíàò X & Y
nx=imax%dx;
for(i=0;i<MAX_NEURON;i++) delta[i] = 0; //ïîäãîòàâëèâàåì ê ðàáîòå
if(0==Accreditation) //neurons[imax].delta = 1;
{
for(cx=MathMax(nx-MathRound(MaxDistance),0); cx<MathMin(nx+MathRound(MaxDistance+1),dx);cx++)
{
if(dy > 0)
{
for(cy=MathMax(ny-MathRound(MaxDistance),0);cy<MathMin(ny+MathRound(MaxDistance+1),dy);cy++)
{
// íåéðîí â çîíå îáó÷åíèÿ
delta[cy*dx+cx] = 1;
//neurons[cy*dx+cx].delta = 1;
}
}
else
{
delta[cx] = 1;
//neurons[cx].delta = 1;
}
}
}
else //if(Accreditation)
{
for(i=0;i<MAX_NEURON;i++)
{
int y=i/dx;
int x=i%dx;
if(MathAbs(MaxDistance)>=1.0)
{
delta[i] = MathExp(-MathSqrt((nx-x)*(nx-x)+(ny-y)*(ny-y))/MaxDistance);
//neurons[i].delta = exp(-sqrt((nx-x)*(nx-x)+(ny-y)*(ny-y))/MaxDistance);
}
else
Accreditation=0;
//Accreditation = 1;
}
}
// OutSkreenKoh(10,260,delta,"S3");
// Print("minD = ",imax," nx=",nx," ny=",ny);
return (true);
}
//Êîððåêöèÿ îøèáêè
void LayerUL_Learn(double inputs[],double &n[][])
{
int i,j,k;
if(Accreditation==0)
{
for(i=0;i<MAX_NEURON;i++)
{
// ïî íåéðîíàì
if(delta[i] == 0) continue;
// ïî ñèíàïñàì
for(k=0;k<MAX_INP;k++)
{
n[i][k]+=LearnRate*(inputs[k] - n[i][k]);
//layers[j]->neurons[i].synapses[k]+=LearnRate* (layers[j-1]->neurons[k].axon - layers[j]->neurons[i].synapses[k]);
}
}
}
else
{
for(i=0;i<MAX_NEURON;i++)
{
// ïî íåéðîíàì
// çàòîðìîæåííûå ïðîïóñêàåì
if(Inhibition > 0 && inhibitory[i]>0) continue;
// ïî ñèíàïñàì
for(k=0;k<MAX_INP;k++)
{
n[i][k]+=LearnRate * delta[i] * (inputs[k] - n[i][k]);
//layers[j]->neurons[i].synapses[k]+=LearnRate *layers[j]->neurons[i].delta *(layers[j-1]->neurons[k].axon - layers[j]->neurons[i].synapses[k]);
}
}
}
}
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ//
int N=200; //×èñëî öâåòîâ â ïàëèòðå
int rainbow[10000]; //òóò õðàíèòñÿ ðàäóãà
int nRainbow; //÷èñëî öâåòîâ ðàäóãè
int GetRGB(int r, int g, int b)
{//ñòðîèò öâåò ïî êîìïîíåíòàì r, g, b
return (256*(256*b + g) + r);
}
int GetRainbowColor(int c)
{//Âûáèðàåò èç ðàäóãè îòìàñøòàáèðîâàííûé öâåò
double k=nRainbow/N;
int n=c*k;
return (rainbow[n]);
}
int BuildRainbow()
{//ñòðîèò ðàäóãó, âîçâðàùàÿ ÷èñëî öâåòîâ
//âîçìîæíî Âû ïðèäóìàåòå áîëåå âûðàçèòåëüíóþ ïàëèòðó :)
int r=255, g=0, b=0;
int n=0;
while(g !=255)
{
rainbow[n]=GetRGB(r, g, b);
g++; n++;
}
while(r !=0)
{
rainbow[n]=GetRGB(r, g, b);
r--; n++;
}
while(b !=255)
{
rainbow[n]=GetRGB(r, g, b);
b++; n++;
}
while(g !=0)
{
rainbow[n]=GetRGB(r, g, b);
g--; n++;
}
while(r !=255)
{
rainbow[n]=GetRGB(r, g, b);
r++; n++;
}
nRainbow = n;
return (n);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int ObjectMakeLabel( string n,string text, int xoff, int yoff ,color text_color) {
ObjectCreate( n, OBJ_LABEL, 0, 0, 0 );
ObjectSet( n, OBJPROP_CORNER, text_color );
ObjectSet( n, OBJPROP_XDISTANCE, xoff );
ObjectSet( n, OBJPROP_YDISTANCE, yoff );
ObjectSet( n, OBJPROP_BACK, true );
ObjectSetText( n,text, 4, "Webdings", text_color );
}
//âûâîäèì ñîäåðæèìîå êàðòû íà ýêðàí â êîîðäèíàòó ïðàâîãî âåðõíåãî óãëà Sx, Sy
void OutScreenKoh(int x,int y,double arr[],string Marcer)
{
int i=0, j=0;
int k=0;
for(j=0;j<dy;j++)
for(i=0;i<dx;i++)
{
int nc =(arr[k]+1) * 100;
if(nc <0 ) nc = 0;
int col = GetRainbowColor(nc);
ObjectDelete(Marcer+"X"+DoubleToStr(i ,0 )+"Y"+DoubleToStr(j ,0 ));
string str="0";
string text= StringSetChar(str, 0,103);
ObjectMakeLabel( Marcer+"X"+DoubleToStr(i ,0 )+"Y"+DoubleToStr(j ,0 ),text, x+i*4, y+j*4, col);
k++;
}
}
Comments