English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
MQL5'te ONNX modellerinin nasıl bir araya getirileceğine dair bir örnek

MQL5'te ONNX modellerinin nasıl bir araya getirileceğine dair bir örnek

MetaTrader 5Makine öğrenimi | 17 Ocak 2024, 14:48
525 0
MetaQuotes
MetaQuotes

Giriş

İstikrarlı ticaret için, genellikle hem ticareti yapılan enstrümanların hem de ticaret stratejilerinin çeşitlendirilmesi önerilir. Aynı durum makine öğrenimi modelleri için de geçerlidir: karmaşık bir model yerine daha basit birkaç model oluşturmak daha kolaydır. Ancak bu modelleri tek bir ONNX modelinde bir araya getirmek zor olabilir.

Bununla birlikte, birkaç eğitilmiş ONNX modelini tek bir MQL5 programında birleştirmek mümkündür. Bu makalede, oylama sınıflandırıcısı olarak adlandırılan topluluklardan birini ele alacağız. Size böyle bir topluluğu uygulamanın ne kadar kolay olduğunu göstereceğiz.


Proje için modeller

Örneğimiz için iki basit model kullanacağız: bir regresyon fiyat tahmin modeli ve bir sınıflandırma fiyat hareketi tahmin modeli. Modeller arasındaki temel fark, regresyonun niceliği tahmin ederken, sınıflandırmanın sınıfı tahmin etmesidir.

İlk model regresyondur.

2003'ten 2022'nin sonuna kadar EURUSD D1 verileri kullanılarak eğitilmiştir. Eğitim, 10 OHLC fiyatı serisi kullanılarak gerçekleştirilmiştir. Modelin eğitilebilirliğini artırmak için fiyatları normalleştiriyor ve serideki ortalama fiyatı serideki standart sapmaya bölüyoruz. Böylece, bir seriyi ortalaması 0 ve yayılımı 1 olan belirli bir aralığa koyuyoruz, bu da eğitim sırasında yakınsamayı iyileştirir.

Sonuç olarak, model ertesi gün için kapanış fiyatını tahmin etmelidir.

Kod oldukça basittir. Burada yalnızca sunum amacıyla verilmiştir.

# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com

from datetime import datetime
import MetaTrader5 as mt5
import tensorflow as tf
import numpy as np
import pandas as pd
import tf2onnx
from sklearn.model_selection import train_test_split
from tqdm import tqdm
from sys import argv

if not mt5.initialize():
    print("initialize() failed, error code =",mt5.last_error())
    quit()

# we will save generated onnx-file near the our script
data_path=argv[0]
last_index=data_path.rfind("\\")+1
data_path=data_path[0:last_index]
print("data path to save onnx model",data_path)

# input parameters
inp_model_name = "model.eurusd.D1.10.onnx"
inp_history_size = 10
inp_start_date = datetime(2003, 1, 1, 0)
inp_end_date = datetime(2023, 1, 1, 0)

# get data from client terminal
eurusd_rates = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_D1, inp_start_date, inp_end_date)
df = pd.DataFrame(eurusd_rates)


#
# collect dataset subroutine
#
def collect_dataset(df: pd.DataFrame, history_size: int):
    """
    Collect dataset for the following regression problem:
    - input: history_size consecutive H1 bars;
    - output: close price for the next bar.

    :param df: D1 bars for a range of dates
    :param history_size: how many bars should be considered for making a prediction
    :return: features and labels
    """
    n = len(df)
    xs = []
    ys = []
    for i in tqdm(range(n - history_size)):
        w = df.iloc[i: i + history_size + 1]

        x = w[['open', 'high', 'low', 'close']].iloc[:-1].values
        y = w.iloc[-1]['close']
        xs.append(x)
        ys.append(y)

    X = np.array(xs)
    y = np.array(ys)
    return X, y
###


# get prices
X, y = collect_dataset(df, history_size=inp_history_size)

# normalize prices
m = X.mean(axis=1, keepdims=True)
s = X.std(axis=1, keepdims=True)
X_norm = (X - m) / s
y_norm = (y - m[:, 0, 3]) / s[:, 0, 3]

# split data to train and test sets
X_train, X_test, y_train, y_test = train_test_split(X_norm, y_norm, test_size=0.2, random_state=0)

# define model
model = tf.keras.Sequential([
    tf.keras.layers.LSTM(64, input_shape=(inp_history_size, 4)),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(1)
])

model.compile(optimizer='adam', loss='mse', metrics=['mae'])

# model training for 50 epochs
lr_reduction = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, min_lr=0.000001)
history = model.fit(X_train, y_train, epochs=50, verbose=2, validation_split=0.15, callbacks=[lr_reduction])

# model evaluation
test_loss, test_mae = model.evaluate(X_test, y_test)
print(f"test_loss={test_loss:.3f}")
print(f"test_mae={test_mae:.3f}")

# save model to onnx
output_path = data_path+inp_model_name
onnx_model = tf2onnx.convert.from_keras(model, output_path=output_path)
print(f"saved model to {output_path}")

# finish
mt5.shutdown()
Regresyon modelimizin yürütüldüğü varsayılırsa, ortaya çıkan tahmin edilen fiyat şu sınıfa dönüştürülmelidir: fiyat düşer, fiyat değişmez, fiyat yükselir. Bu, oylama sınıflandırıcısını düzenlemek için gereklidir.

İkinci model ise sınıflandırma modelidir.

EURUSD D1 üzerinde 2010'dan 2022'nin sonuna kadar eğitilmiştir. Eğitim, 63 Kapanış fiyatı serisi kullanılarak gerçekleştirilmiştir. Çıktıda üç sınıftan biri tanımlanmalıdır: fiyat düşecek, fiyat 10 puan içerisinde kalacak veya fiyat yükselecek. İkinci sınıf nedeniyle modeli 2010'dan bu yana verileri kullanarak eğitmek zorunda kaldık - öncesinde, 2009'da piyasalar 4 basamaklı hassasiyetten 5 basamaklı hassasiyete geçti. Böylece, bir eski puan on yeni puan haline geldi.

Önceki modelde olduğu gibi, fiyat normalleştirilmiştir. Normalleştirme de aynıdır: serideki ortalama fiyattan sapmayı serideki standart sapmaya böleriz. Bu modelin fikri "Keras'ta MLP ile finansal zaman serisi tahmini" (Rusça) makalesinde açıklanmıştır. Bu model de sadece sunum amaçlı tasarlanmıştır.

# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
#
# Classification model
# 0,0,1 - predict price down
# 0,1,0 - predict price same
# 1,0,0 - predict price up
#

from datetime import datetime
import MetaTrader5 as mt5
import tensorflow as tf
import numpy as np
import pandas as pd
import tf2onnx
from sklearn.model_selection import train_test_split
from tqdm import tqdm
from keras.models import Sequential
from keras.layers import Dense, Activation,Dropout, BatchNormalization, LeakyReLU
from keras.optimizers import SGD
from keras import regularizers
from sys import argv

# initialize MetaTrader 5 client terminal
if not mt5.initialize():
    print("initialize() failed, error code =",mt5.last_error())
    quit()

# we will save the generated onnx-file near the our script
data_path=argv[0]
last_index=data_path.rfind("\\")+1
data_path=data_path[0:last_index]
print("data path to save onnx model",data_path)

# input parameters
inp_model_name = "model.eurusd.D1.63.onnx"
inp_history_size = 63
inp_start_date = datetime(2010, 1, 1, 0)
inp_end_date = datetime(2023, 1, 1, 0)

# get data from the client terminal
eurusd_rates = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_D1, inp_start_date, inp_end_date)
df = pd.DataFrame(eurusd_rates)


#
# collect dataset subroutine
#
def collect_dataset(df: pd.DataFrame, history_size: int):
    """
    Collect dataset for the following regression problem:
    - input: history_size consecutive H1 bars;
    - output: close price for the next bar.

    :param df: H1 bars for a range of dates
    :param history_size: how many bars should be considered for making a prediction
    :return: features and labels
    """
    n = len(df)
    xs = []
    ys = []
    for i in tqdm(range(n - history_size)):
        w = df.iloc[i: i + history_size + 1]
        x = w[['close']].iloc[:-1].values

        delta = x[-1] - w.iloc[-1]['close']
        if np.abs(delta)<=0.0001:
           y = 0, 1, 0
        else:
           if delta<0:
              y = 1, 0, 0
           else:
              y = 0, 0, 1

        xs.append(x)
        ys.append(y)

    X = np.array(xs)
    Y = np.array(ys)
    return X, Y
###


# get prices
X, Y = collect_dataset(df, history_size=inp_history_size)

# normalize prices
m = X.mean(axis=1, keepdims=True)
s = X.std(axis=1, keepdims=True)
X_norm = (X - m) / s

# split data to train and test sets
X_train, X_test, Y_train, Y_test = train_test_split(X_norm, Y, test_size=0.1, random_state=0)

# define model
model = Sequential()
model.add(Dense(64, input_dim=inp_history_size, activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.3))
model.add(Dense(16, activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(3))
model.add(Activation('softmax'))

opt = SGD(learning_rate=0.01, momentum=0.9)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])

# model training for 300 epochs
lr_reduction = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.9, patience=5, min_lr=0.00001)
history = model.fit(X_train, Y_train, epochs=300, validation_data=(X_test, Y_test), shuffle = True, batch_size=128, verbose=2, callbacks=[lr_reduction])

# model evaluation
test_loss, test_accuracy = model.evaluate(X_test, Y_test)
print(f"test_loss={test_loss:.3f}")
print(f"test_accuracy={test_accuracy:.3f}")

# save model to onnx
output_path = data_path+inp_model_name
onnx_model = tf2onnx.convert.from_keras(model, output_path=output_path)
print(f"saved model to {output_path}")

# finish
mt5.shutdown()
Modeller 2022 sonuna kadar verilerle eğitilmiş, böylece strateji sınayıcıda çalışmalarını göstermek için süre bırakılmıştır.


MQL5 Uzman Danışmanında bir ONNX modelleri topluluğu

Aşağıda, model topluluklarının olanaklarını göstermek için basit bir Uzman Danışman bulunmaktadır. MQL5'te ONNX modellerini kullanmanın ana ilkeleri bir önceki makalenin ikinci bölümünde açıklanmıştı.

İleri bildiriler ve tanımlar

#include <Trade\Trade.mqh>

input double InpLots = 1.0;              // Lots amount to open position

#resource "Python/model.eurusd.D1.10.onnx" as uchar ExtModel1[]
#resource "Python/model.eurusd.D1.63.onnx" as uchar ExtModel2[]

#define SAMPLE_SIZE1 10
#define SAMPLE_SIZE2 63

long     ExtHandle1=INVALID_HANDLE;
long     ExtHandle2=INVALID_HANDLE;
int      ExtPredictedClass1=-1;
int      ExtPredictedClass2=-1;
int      ExtPredictedClass=-1;
datetime ExtNextBar=0;
CTrade   ExtTrade;

//--- price movement prediction
#define PRICE_UP   0
#define PRICE_SAME 1
#define PRICE_DOWN 2

OnInit fonksiyonu

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(_Symbol!="EURUSD" || _Period!=PERIOD_D1)
     {
      Print("model must work with EURUSD,D1");
      return(INIT_FAILED);
     }

//--- create first model from static buffer
   ExtHandle1=OnnxCreateFromBuffer(ExtModel1,ONNX_DEFAULT);
   if(ExtHandle1==INVALID_HANDLE)
     {
      Print("First model OnnxCreateFromBuffer error ",GetLastError());
      return(INIT_FAILED);
     }
//--- since not all sizes defined in the input tensor we must set them explicitly
//--- first index - batch size, second index - series size, third index - number of series (OHLC)
   const long input_shape1[] = {1,SAMPLE_SIZE1,4};
   if(!OnnxSetInputShape(ExtHandle1,0,input_shape1))
     {
      Print("First model OnnxSetInputShape error ",GetLastError());
      return(INIT_FAILED);
     }
   
//--- since not all sizes defined in the output tensor we must set them explicitly
//--- first index - batch size, must match the batch size of the input tensor
//--- second index - number of predicted prices (we only predict Close)
   const long output_shape1[] = {1,1};
   if(!OnnxSetOutputShape(ExtHandle1,0,output_shape1))
     {
      Print("First model OnnxSetOutputShape error ",GetLastError());
      return(INIT_FAILED);
     }

//--- create second model from static buffer
   ExtHandle2=OnnxCreateFromBuffer(ExtModel2,ONNX_DEFAULT);
   if(ExtHandle2==INVALID_HANDLE)
     {
      Print("Second model OnnxCreateFromBuffer error ",GetLastError());
      return(INIT_FAILED);
     }
  
//--- since not all sizes defined in the input tensor we must set them explicitly
//--- first index - batch size, second index - series size
   const long input_shape2[] = {1,SAMPLE_SIZE2};
   if(!OnnxSetInputShape(ExtHandle2,0,input_shape2))
     {
      Print("Second model OnnxSetInputShape error ",GetLastError());
      return(INIT_FAILED);
     }

//--- since not all sizes defined in the output tensor we must set them explicitly
//--- first index - batch size, must match the batch size of the input tensor
//--- second index - number of classes (up, same or down)
   const long output_shape2[] = {1,3};
   if(!OnnxSetOutputShape(ExtHandle2,0,output_shape2))
     {
      Print("Second model OnnxSetOutputShape error ",GetLastError());
      return(INIT_FAILED);
     }
//--- ok
   return(INIT_SUCCEEDED);
  }

Sadece EURUSD, D1 ile çalıştıracağız. Bunun nedeni, modeller günlük fiyatlar kullanılarak eğitilirken bizim mevcut sembol zaman diliminin verilerini kullanmamızdır.

Modeller Uzman Danışmana kaynak olarak dahil edilmiştir.

Girdi ve çıktı veri şekillerini açıkça tanımlamak önemlidir.

OnTick fonksiyonu

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check new bar
   if(TimeCurrent()<ExtNextBar)
      return;
//--- set next bar time
   ExtNextBar=TimeCurrent();
   ExtNextBar-=ExtNextBar%PeriodSeconds();
   ExtNextBar+=PeriodSeconds();

//--- predict price movement
   Predict();
//--- check trading according to prediction
   if(ExtPredictedClass>=0)
      if(PositionSelect(_Symbol))
         CheckForClose();
      else
         CheckForOpen();
  }

Tüm ticaret işlemleri yalnızca günün başında gerçekleştirilir.

Tahmin fonksiyonu

//+------------------------------------------------------------------+
//| Voting classification                                            |
//+------------------------------------------------------------------+
void Predict(void)
  {
//--- evaluate first model
   ExtPredictedClass1=PredictPrice(ExtHandle1,SAMPLE_SIZE1);
//--- evaluate second model
   ExtPredictedClass2=PredictPriceMovement(ExtHandle2,SAMPLE_SIZE2);
//--- vote
   if(ExtPredictedClass1==ExtPredictedClass2)
      ExtPredictedClass=ExtPredictedClass1;
   else
      ExtPredictedClass=-1;
  }

Her iki model de aynı sınıfı aldığında bir sınıf seçilmiş olarak kabul edilir. Bu bir oy çokluğudur. Ve toplulukta sadece iki model olduğu için, oy çokluğu "oy birliği" anlamına gelir.

Önceki 10 OHLC fiyatından gün Kapanış fiyatı tahmini

//+------------------------------------------------------------------+
//| Predict next price (first model)                                 |
//+------------------------------------------------------------------+
int PredictPrice(const long handle,const int sample_size)
  {
   static matrixf input_data(sample_size,4);    // matrix for prepared input data
   static vectorf output_data(1);               // vector to get result
   static matrix  mm(sample_size,4);            // matrix of horizontal vectors Mean
   static matrix  ms(sample_size,4);            // matrix of horizontal vectors Std
   static matrix  x_norm(sample_size,4);        // matrix for prices normalize

//--- prepare input data
   matrix rates;
//--- request last bars
   if(!rates.CopyRates(_Symbol,_Period,COPY_RATES_OHLC,1,sample_size))
      return(-1);
//--- get series Mean
   vector m=rates.Mean(1);
//--- get series Std
   vector s=rates.Std(1);
//--- prepare matrices for prices normalization
   for(int i=0; i<sample_size; i++)
     {
      mm.Row(m,i);
      ms.Row(s,i);
     }
//--- the input of the model must be a set of vertical OHLC vectors
   x_norm=rates.Transpose();
//--- normalize prices
   x_norm-=mm;
   x_norm/=ms;

//--- run the inference
   input_data.Assign(x_norm);
   if(!OnnxRun(handle,ONNX_NO_CONVERSION,input_data,output_data))
      return(-1);
//--- denormalize the price from the output value
   double predicted=output_data[0]*s[3]+m[3];
//--- classify predicted price movement
   int    predicted_class=-1;
   double delta=rates[3][sample_size-1]-predicted;
   if(fabs(delta)<=0.0001)
      predicted_class=PRICE_SAME;
   else
     {
      if(delta<0)
         predicted_class=PRICE_UP;
      else
         predicted_class=PRICE_DOWN;

     }

   return(predicted_class);
  }

Girdi verileri, modeli eğitirken uygulanan kurallara uygun olarak hazırlanmalıdır. Model yürütüldükten sonra, elde edilen değer tekrar fiyata dönüştürülür. Sınıf, serideki son Kapanış fiyatı ile ortaya çıkan fiyat arasındaki farka göre hesaplanır.

Fiyat hareketi tahmini, 63 günlük Kapanış fiyatından oluşan bir seriye dayanmaktadır:

//+------------------------------------------------------------------+
//| Predict price movement (second model)                            |
//+------------------------------------------------------------------+
int PredictPriceMovement(const long handle,const int sample_size)
  {
   static vectorf input_data(sample_size);    // vector for prepared input data
   static vectorf output_data(3);             // vector to get result

//--- request last bars
   if(!input_data.CopyRates(_Symbol,_Period,COPY_RATES_CLOSE,1,sample_size))
      return(-1);
//--- get series Mean
   float m=input_data.Mean();
//--- get series Std
   float s=input_data.Std();
//--- normalize prices
   input_data-=m;
   input_data/=s;

//--- run the inference
   if(!OnnxRun(handle,ONNX_NO_CONVERSION,input_data,output_data))
      return(-1);
//--- evaluate prediction
   return(int(output_data.ArgMax()));
  }

Fiyatlar, ilk modelde olduğu gibi aynı kurallar kullanılarak normalleştirilir. Ancak bu sefer kod daha kompakttır çünkü girdi bir matris değil bir vektördür. Sınıf, üç olasılığın maksimum değerine göre seçilir.

Ticaret stratejisi basittir. Ticaret işlemleri her günün başında gerçekleştirilir. Eğer tahmin "fiyat yükselecek" ise satın alırız; "fiyat düşecek" ise satarız.

//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   ENUM_ORDER_TYPE signal=WRONG_VALUE;
//--- check signals
   if(ExtPredictedClass==PRICE_DOWN)
      signal=ORDER_TYPE_SELL;    // sell condition
   else
     {
      if(ExtPredictedClass==PRICE_UP)
         signal=ORDER_TYPE_BUY;  // buy condition
     }

//--- open position if possible according to signal
   if(signal!=WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
      ExtTrade.PositionOpen(_Symbol,signal,InpLots,
                            SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                            0,0);
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   bool bsignal=false;
//--- position already selected before
   long type=PositionGetInteger(POSITION_TYPE);
//--- check signals
   if(type==POSITION_TYPE_BUY && ExtPredictedClass==PRICE_DOWN)
      bsignal=true;
   if(type==POSITION_TYPE_SELL && ExtPredictedClass==PRICE_UP)
      bsignal=true;

//--- close position if possible
   if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
     {
      ExtTrade.PositionClose(_Symbol,3);
      //--- open opposite
      CheckForOpen();
     }
  }


Modelimizi 2023 yılı başına kadar olan verilerle eğittik. Öyleyse, test aralığını yılın başından itibaren ayarlayalım.

Test ayarları

İşte yıl başından bu yana olan verilere dayanan test sonucu.

Uzman Danışman test sonuçları


Her bir model için test sonuçlarını bilmek ilginç olacaktır.

Bunu yapmak için Uzman Danışman kaynak kodunu aşağıdaki gibi değiştirelim:

enum EnModels
  {
   USE_FIRST_MODEL,    // Use first model only
   USE_SECOND_MODEL,   // Use second model only
   USE_BOTH_MODELS     // Use both models
  };
input EnModels InpModels = USE_BOTH_MODELS;  // Models using
input double   InpLots   = 1.0;              // Lots amount to open position

...

//+------------------------------------------------------------------+
//| Voting classification                                            |
//+------------------------------------------------------------------+
void Predict(void)
  {
//--- evaluate first model
   if(InpModels==USE_BOTH_MODELS || InpModels==USE_FIRST_MODEL)
      ExtPredictedClass1=PredictPrice(ExtHandle1,SAMPLE_SIZE1);
//--- evaluate second model
   if(InpModels==USE_BOTH_MODELS || InpModels==USE_SECOND_MODEL)
      ExtPredictedClass2=PredictPriceMovement(ExtHandle2,SAMPLE_SIZE2);

//--- check predictions
   switch(InpModels)
     {
      case USE_FIRST_MODEL :
         ExtPredictedClass=ExtPredictedClass1;
         break;
      case USE_SECOND_MODEL :
         ExtPredictedClass=ExtPredictedClass2;
         break;
      case USE_BOTH_MODELS :
         if(ExtPredictedClass1==ExtPredictedClass2)
            ExtPredictedClass=ExtPredictedClass1;
         else
            ExtPredictedClass=-1;
     }
  }

"Yalnızca ilk modeli kullan" parametresini etkinleştirelim:

Yalnızca ilk modeli kullanmak için Uzman Danışman ayarları

İlk model test sonuçları

İlk model test sonuçları


Şimdi ikinci modeli test edelim. İşte ikinci model test sonuçları.

İkinci model test sonuçları

İkinci modelin ilkinden çok daha güçlü olduğu ortaya çıktı. Sonuçlar, zayıf modellerin bir araya getirilmesi gerektiği teorisini doğrulamaktadır. Ancak, bu makale topluluk oluşturma teorisi ile değil, pratik uygulama ile ilgiliydi.

Önemli not: Makalede kullanılan modellerin yalnızca MQL5 dilini kullanarak ONNX modelleriyle nasıl çalışılacağını göstermek için sunulduğunu lütfen unutmayın. Uzman Danışman, gerçek hesaplarda ticaret yapmak için tasarlanmamıştır.



Sonuç

İki ONNX modelinden oluşan bir topluluğun çok basit ama açıklayıcı bir örneğini sunduk. Aynı anda kullanılan model sayısı sınırlıdır ve 256 modeli geçemez. Bununla birlikte, ikiden fazla modelin kullanılması bile Uzman Danışman programlamasına farklı bir yaklaşım gerektirecektir, yani nesne yönelimli programlama gerektirecektir.

Ama bu başka bir makalenin konusu.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/12433

Ekli dosyalar |
MQL5.zip (105.08 KB)
MQL5'te matrisler ve vektörler: Aktivasyon fonksiyonları MQL5'te matrisler ve vektörler: Aktivasyon fonksiyonları
Burada makine öğreniminin sadece bir yönünü - aktivasyon fonksiyonlarını - açıklayacağız. Yapay sinir ağlarında, bir nöron aktivasyon fonksiyonu, bir girdi sinyalinin veya bir dizi girdi sinyalinin değerlerine dayalı olarak bir çıktı sinyali değerini hesaplar. Sürecin iç işleyişini derinlemesine inceleyeceğiz.
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 25): Sistemin sağlamlığını artırma (II) Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 25): Sistemin sağlamlığını artırma (II)
Bu makalede, Uzman Danışmanın performansına yönelik son adımı atacağız. Bu yüzden uzun bir okumaya hazırlıklı olun. Uzman Danışmanımızı sağlam hale getirmek için, öncelikle ticaret sisteminin bir parçası olmayan her şeyi koddan kaldıracağız.
ONNX modellerini sınıflara sarma ONNX modellerini sınıflara sarma
Nesne yönelimli programlama, okunması ve değiştirilmesi kolay olan daha kompakt bir kod oluşturulmasını sağlar. Burada üç ONNX modeli için örneğe bir göz atacağız.
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 24): Sistemin sağlamlığını artırma (I) Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 24): Sistemin sağlamlığını artırma (I)
Bu makalede, daha istikrarlı ve güvenli bir kullanım sağlamak için sistemi daha sağlam hale getireceğiz. İstenilen sağlamlığı elde etmenin yollarından biri, kodu mümkün olduğunca yeniden kullanmaya çalışmak ve böylece farklı durumlarda sürekli olarak test edilmesini sağlamaktır. Ancak bu, yöntemlerden yalnızca bir tanesidir. Bir diğeri ise OOP kullanmaktır.