#_Lib_Kohhen.mq4

Download script
Author: Copyright � 2008, MetaQuotes Software Corp.
#_Lib_Kohhen.mq4

This 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.

11 Views
0 Downloads
0 Favorites
#_Lib_Kohhen.mq4
//+------------------------------------------------------------------+
//|                                                 #_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