Нейронная сеть из Statistica 10

 

Statistica 10 сформировала простенькую нейросеть и сохранила в файл SANN_C_Code_Spreadsheet1-1.c. Вот код:

//Analysis Type - TS_Reg 
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>


double Spreadsheet1_1_MLP_12_2_1_input_hidden_weights[2][12]=
{
 {1.21155309799961e-001, 1.54407987165188e-001, 1.28487022704017e-001, -8.16446569295661e-002, -1.53581013840496e-001, -1.82694747151451e-001, -3.96125797407203e-001, -5.87657182524898e-001, -6.47192679551735e-001, -8.52757899901614e-001, -1.16232590905976e+000, -1.21567055938552e+000 },
 {1.47651682941213e-001, -6.18102798396527e-001, -4.05364346133979e-001, 8.63443328151275e-002, 1.97105443920401e-001, 2.74604161379845e-001, 4.07923116256085e-001, -8.04615481865259e-001, 1.73631332467316e-001, -2.35263573099311e-001, -8.79521255073543e-001, -1.81487133364026e+000 } 
};

double Spreadsheet1_1_MLP_12_2_1_hidden_bias[2]={ 1.18791537300970e+000, 1.47961211953680e+000 };

double Spreadsheet1_1_MLP_12_2_1_hidden_output_wts[1][2]=
{
 {-8.05165951448064e-002, -1.17487671693641e+000 }
};

double Spreadsheet1_1_MLP_12_2_1_output_bias[1]={ 8.32491783166062e-002 };

double Spreadsheet1_1_MLP_12_2_1_max_input[1]={ 1.09270000000000e+000 };

double Spreadsheet1_1_MLP_12_2_1_min_input[1]={ 1.08750000000000e+000 };

double Spreadsheet1_1_MLP_12_2_1_max_target[1]={ 1.09270000000000e+000 };

double Spreadsheet1_1_MLP_12_2_1_min_target[1]={ 1.08750000000000e+000 };

double Spreadsheet1_1_MLP_12_2_1_input[12];
double Spreadsheet1_1_MLP_12_2_1_hidden[2];
double Spreadsheet1_1_MLP_12_2_1_output[1];

double Spreadsheet1_1_MLP_12_2_1_MeanInputs[1]={ 1.09075333333333e+000 };

void Spreadsheet1_1_MLP_12_2_1_ScaleInputs(double* input, double minimum, double maximum, int nContTargets, int steps)
{
 double delta;
 long i,j;
 for(i=0; i<nContTargets; i++)
 {
        delta = (maximum-minimum)/(Spreadsheet1_1_MLP_12_2_1_max_input[i]-Spreadsheet1_1_MLP_12_2_1_min_input[i]);
   for(j=0; j<steps; j++)
        input[i+j*nContTargets] = minimum - delta*Spreadsheet1_1_MLP_12_2_1_min_input[i]+ delta*input[i+j*nContTargets];
 }
}

void Spreadsheet1_1_MLP_12_2_1_UnscaleTargets(double* output, double minimum, double maximum, int size)
{
  double delta;
  long i;
  for(i=0; i<size; i++)
  {
    delta = (maximum-minimum)/(Spreadsheet1_1_MLP_12_2_1_max_target[i]-Spreadsheet1_1_MLP_12_2_1_min_target[i]);
    output[i] = (output[i] - minimum + delta*Spreadsheet1_1_MLP_12_2_1_min_target[i])/delta;
   }
}

void Spreadsheet1_1_MLP_12_2_1_ComputeFeedForwardSignals(double* MAT_INOUT,double* V_IN,double* V_OUT, double* V_BIAS,int size1,int size2,int layer)
{
  int row,col;
  for(row=0;row < size2; row++) 
    {
      V_OUT[row]=0.0;
      for(col=0;col<size1;col++)V_OUT[row]+=(*(MAT_INOUT+(row*size1)+col)*V_IN[col]);
      V_OUT[row]+=V_BIAS[row];
      if(layer==0) V_OUT[row] = exp(V_OUT[row]);
      if(layer==1) V_OUT[row] = exp(V_OUT[row]);
   }
}

void Spreadsheet1_1_MLP_12_2_1_RunNeuralNet_TS_Reg () 
{
  Spreadsheet1_1_MLP_12_2_1_ComputeFeedForwardSignals((double*)Spreadsheet1_1_MLP_12_2_1_input_hidden_weights,Spreadsheet1_1_MLP_12_2_1_input,Spreadsheet1_1_MLP_12_2_1_hidden,Spreadsheet1_1_MLP_12_2_1_hidden_bias,12, 2,0);
  Spreadsheet1_1_MLP_12_2_1_ComputeFeedForwardSignals((double*)Spreadsheet1_1_MLP_12_2_1_hidden_output_wts,Spreadsheet1_1_MLP_12_2_1_hidden,Spreadsheet1_1_MLP_12_2_1_output,Spreadsheet1_1_MLP_12_2_1_output_bias,2, 1,1);
}

int main()
{
  int i=0;
  int keyin=1;
  int stepcntr;
  int inputindex;
  int nsteps;
  while(1)
  {
        stepcntr=1;
        inputindex=0;
    for(nsteps=0;nsteps<12;nsteps++)
    {
     printf("\n%s%d\n","Enter Input values for Step ",stepcntr++);
     printf("%s%d%s","Input-",inputindex+1,": ");
     scanf("%lg",&Spreadsheet1_1_MLP_12_2_1_input[inputindex]);
     //Substitution of missing continuous variables
     if(Spreadsheet1_1_MLP_12_2_1_input[inputindex] == -9999)
          Spreadsheet1_1_MLP_12_2_1_input[inputindex]=Spreadsheet1_1_MLP_12_2_1_MeanInputs[0];
     inputindex++;
    }
    Spreadsheet1_1_MLP_12_2_1_ScaleInputs(Spreadsheet1_1_MLP_12_2_1_input,0,1,1,12);
        Spreadsheet1_1_MLP_12_2_1_RunNeuralNet_TS_Reg();
        Spreadsheet1_1_MLP_12_2_1_UnscaleTargets(Spreadsheet1_1_MLP_12_2_1_output,0,1,1);
        printf("\n%s%.14e","Predicted Output of Var1 = ",Spreadsheet1_1_MLP_12_2_1_output[0]);
        printf("\n\n%s\n","Press any key to make another prediction or enter 0 to quit the program.");
        keyin=getch();
        if(keyin==48)break;
  }
        return 0;
}



Как теперь прикрутить этот код к индикатору или советнику?

dll только начал осваивать и ничего не понятно. Пожалуйста, объясните, а то никак(

 
Или кроме dll есть еще способы?
 
Murat Ishakov:

Наверное как-то так :

1. установить Visual Studio, можно взять бесплатную версию - https://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx

2. открыть ее после установки и создать там проект, как показано здесь - https://www.mql5.com/ru/articles/18

3. в основной исполняемій файл засунуть код. которій сгенерила Статистика

4. те функции, которые вызываются в main пометить как внешение - extern "C" __declspec(dllexport), опять же, как здесь - https://www.mql5.com/ru/articles/18

5. скомпилировать этот проект в DLL, опять же, как здесь - https://www.mql5.com/ru/articles/18

6. поместить DLL в папку Libraries, опять же, как здесь - https://www.mql5.com/ru/articles/18

7. подключить DLL в индикаторе или советнике и вызвать функции, помеченные внешними, опять же, как здесь - https://www.mql5.com/ru/articles/18

Если же вы спрашиваете, как пользоваться нейросетью, то врядли вам кто подскажет, по крайней мере не на этом форуме, надо искать более специализированные, именно по нейросетям.

Или даже воспользоваться готовыми поделками других участников MQL5 без забивания головы возней с DLL - кликни меня.

 
Murat Ishakov:

Statistica 10 сформировала простенькую нейросеть и сохранила в файл SANN_C_Code_Spreadsheet1-1.c. Вот код:



Как теперь прикрутить этот код к индикатору или советнику?

dll только начал осваивать и ничего не понятно. Пожалуйста, объясните, а то никак(

А зачем тут dll? Вам сгенерирован полностью автономный исходник на C++. С поправкой на стандартные библиотеки, упомянутые в инклудах, это можно откомпилить как mql после небольших правок.
 
Stanislav Korotky:
А зачем тут dll? Вам сгенерирован полностью автономный исходник на C++. С поправкой на стандартные библиотеки, упомянутые в инклудах, это можно откомпилить как mql после небольших правок.
А как правильно передать в функцию все элементы массива? Маленький бы примерчик...
 
Murat Ishakov:
А как правильно передать в функцию все элементы массива? Маленький бы примерчик...
Ну тут по-любому прийдется ввод/вывод данных переделывать, если хочется чтобы приямо внутри индюка данные из котировок попадали в массив Spreadsheet1_1_MLP_12_2_1_input, а выход выводился на чарт из Spreadsheet1_1_MLP_12_2_1_output.
 
Stanislav Korotky:
Ну тут по-любому прийдется ввод/вывод данных переделывать, если хочется чтобы приямо внутри индюка данные из котировок попадали в массив Spreadsheet1_1_MLP_12_2_1_input, а выход выводился на чарт из Spreadsheet1_1_MLP_12_2_1_output.
Нет, а вообще заинтересовало, как в любую пользовательскую функцию передать все элементы массива? Это как бы общий вопрос
 
Нет, не надо, разобрался с массивами)
 
Stanislav Korotky:
А зачем тут dll? Вам сгенерирован полностью автономный исходник на C++. С поправкой на стандартные библиотеки, упомянутые в инклудах, это можно откомпилить как mql после небольших правок.
Потихоньку получается, но что за вызов функции getch () в самом конце? Чем заменить?
 
Murat Ishakov:
Потихоньку получается, но что за вызов функции getch () в самом конце? Чем заменить?
Ожидание нажатия клавиши с получением ее кода.
 

Итак, вот код в dll:

// NCDLL.cpp: определяет экспортированные функции для приложения DLL.
//

#include "stdafx.h"
#include <cmath>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>


double a1[2][12]=
{
 {1.21155309799961e-001, 1.54407987165188e-001, 1.28487022704017e-001, -8.16446569295661e-002, -1.53581013840496e-001, -1.82694747151451e-001, -3.96125797407203e-001, -5.87657182524898e-001, -6.47192679551735e-001, -8.52757899901614e-001, -1.16232590905976e+000, -1.21567055938552e+000 },
 {1.47651682941213e-001, -6.18102798396527e-001, -4.05364346133979e-001, 8.63443328151275e-002, 1.97105443920401e-001, 2.74604161379845e-001, 4.07923116256085e-001, -8.04615481865259e-001, 1.73631332467316e-001, -2.35263573099311e-001, -8.79521255073543e-001, -1.81487133364026e+000 } 
};

double a2[2]={ 1.18791537300970e+000, 1.47961211953680e+000 };

double a3[1][2]=
{
 {-8.05165951448064e-002, -1.17487671693641e+000 }
};


double a4[1]={ 8.32491783166062e-002 };

double a5[1]={ 1.09270000000000e+000 };

double a6[1]={ 1.08750000000000e+000 };

double a7[1]={ 1.09270000000000e+000 };

double a8[1]={ 1.08750000000000e+000 };




double Vhod[12];
double Sloi[2];
double Vyhod[1];


double a9[1]={ 1.09075333333333e+000 };




_DLLAPI void __stdcall F1  (double* inp, double minimum, double maximum, int nContTargets, int steps)
{
 double delta;
 long i,j;
 for(i=0; i<nContTargets; i++)
 {
        delta = (maximum-minimum)/(a5[i]-a6[i]);
   for(j=0; j<steps; j++)
        inp[i+j*nContTargets] = minimum - delta*a6[i]+ delta*inp[i+j*nContTargets];
 }
}




_DLLAPI void __stdcall F2(double* output, double minimum, double maximum, int size)
{
  double delta;
  long i;
  for(i=0; i<size; i++)
  {
    delta = (maximum-minimum)/(a7[i]-a8[i]);
    output[i] = (output[i] - minimum + delta*a8[i])/delta;
   }
}


_DLLAPI void __stdcall F3(double* MAT_INOUT,double* V_IN,double* V_OUT, double* V_BIAS,int size1,int size2,int layer)
{
  int row,col;
  for(row=0;row < size2; row++) 
    {
      V_OUT[row]=0.0;
      for(col=0;col<size1;col++)V_OUT[row]+=(*(MAT_INOUT+(row*size1)+col)*V_IN[col]);
      V_OUT[row]+=V_BIAS[row];
      if(layer==0) V_OUT[row] = exp(V_OUT[row]);
      if(layer==1) V_OUT[row] = exp(V_OUT[row]);
   }
}




_DLLAPI void __stdcall F4 () 
{
  F3((double*)a1,Vhod,Sloi,a2,12, 2,0);
  F3((double*)a3,Sloi,Vyhod,a4,2, 1,1);
}



int main()
{
 
}


_DLLAPI double __stdcall NC(double *CL)
  {
          for (int w=0; w<12; ++w){
          

                  Vhod [w]=CL [w];

          }

      int i=0;
  int keyin=1;
  int stepcntr;
  int inputindex;
  int nsteps;
  while(1)
  {
        stepcntr=1;
        inputindex=0;
    for(nsteps=0;nsteps<12;nsteps++)
    {
     printf("\n%s%d\n","Enter Input values for Step ",stepcntr++);
     printf("%s%d%s","Input-",inputindex+1,": ");
     scanf("%lg",&Vhod[inputindex]);
     //Substitution of missing continuous variables
     if(Vhod[inputindex] == -9999)
          Vhod[inputindex]=a9[0];
     inputindex++;
    }
    F1(Vhod,0,1,1,12);
        F4();
        F2(Vyhod,0,1,1);
        printf("\n%s%.14e","Predicted Output of Var1 = ",Vyhod[0]);
        printf("\n\n%s\n","Press any key to make another prediction or enter 0 to quit the program.");
        keyin=getch();
        if(keyin==48)break;
  }
        return (Vyhod[0]);
  }

 А вот - в mql4:

 

//+------------------------------------------------------------------+
//|                                                Prognoz_close.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot CL
#property indicator_label1  "CL"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters

#import "NCDLL.dll"
 double NC(double &CL []);
 void F1  (double &inp, double minimum, double maximum, int nContTargets, int steps);
 void F2(double &output, double minimum, double maximum, int size);
 void F3(double &MAT_INOUT,double &V_IN,double &V_OUT, double &V_BIAS,int size1,int size2,int layer);
 void F4 ();
#import 


input int Max=2;

//--- indicator buffers
double         CLBuffer[];



//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CLBuffer);

   SetIndexArrow(0,108);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   double CL[12],PR_CL;

   for(int i=0; i<Max; i++)
     {
      PR_CL=0;
      int b=0;
       

      for(int a=i; a<=i+11; a++)
        {
         CL[b]=Close[a];
         b++;
         
        }

      PR_CL=NC (CL);
      
      if (i<5) Alert (PR_CL);
      
      CLBuffer[i]=PR_CL;
      
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

 Но в результате выводит не прогнозное значение Close, а 1.#INF. Где может ошибка?

Если что, прошу строго не судить, это моя первая DLL)

Причина обращения: