English 中文 Español Deutsch 日本語
preview
Анализ нескольких символов с помощью Python и MQL5 (Часть II): Анализ главных компонентов для оптимизации портфеля

Анализ нескольких символов с помощью Python и MQL5 (Часть II): Анализ главных компонентов для оптимизации портфеля

MetaTrader 5Примеры |
255 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

Управление общим риском, которому подвержен портфель, является достаточно сложной задачей, с которой сталкиваются все члены торгового сообщества. Как можно всесторонне проанализировать и принять решение о целесообразном распределении активов в современном мире постоянно расширяющихся рынков, учитывая огромный выбор инвестиционных возможностей, предлагаемых современному инвестору? В предыдущей статье я продемонстрировал, как можно максимизировать общую доходность портфеля с помощью SciPy. Сегодня я сосредоточусь на том, как контролировать риск/дисперсию любого портфеля. Существует множество возможных моделей, которые мы можем использовать для контроля риска нашего портфеля. Мы можем использовать популярный инструмент статистики — анализ главных компонентов (Principal Components Analysis, PCA) — для эффективного управления общей дисперсией нашего портфеля.

Для членов нашего сообщества, желающих продавать советников, эта статья продемонстрирует, как добиться бесперебойной работы для ваших конечных пользователей. Наше торговое приложение будет гибким и надежным одновременно. Я покажу вам, как создавать торговые приложения, которые позволят вашим клиентам легко переключаться между режимами торговли с высоким, средним и низким риском. При этом алгоритм PCA выполнит наиболее трудоемкую работу для ваших конечных пользователей в фоновом режиме.


Обзор методологии

В этой статье мы будем управлять портфелем из 10 криптовалют. Криптовалюты — это цифровые активы, которые существуют в особом типе сети, известном как сеть блокчейн. Технология блокчейн — это протокол безопасности, который делает практически невозможным совершение мошеннических транзакций любым участником сети. Таким образом, учитывая мощь базовой сети, одним из первых популярных применений технологии блокчейн стала цифровая валюта. Однако эти цифровые активы печально известны своей высокой волатильностью, и инвесторам может быть сложно адекватно управлять уровнем риска при инвестировании в криптоактивы. К счастью, мы можем использовать статистические методы, такие как PCA, чтобы управлять общим объемом дисперсии, которому мы готовы подвергаться при инвестировании в криптовалюты.

Анализ главных компонентов — это метод из раздела многомерной статистики, называемого факторным анализом. PCA нашел применение во многих областях: от анализа изображений до машинного обучения. В анализе изображений PCA обычно используется для таких задач, как сжатие данных, тогда как в машинном обучении он чаще всего применяется для снижения размерности.

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

Второй главный компонент будет ортогонален первому. Это означает, что они полностью некоррелированы, одновременно максимизируя общую дисперсию набора данных. Этот паттерн действует до тех пор, пока мы не создадим достаточно компонентов для учета всей дисперсии в исходном наборе данных.

Я продемонстрирую вам, как каждый основной компонент по отдельности сопоставляется с дискретными уровнями риска, которые мы можем использовать в качестве настроек для наших торговых приложений. Это поможет вам разумно управлять настройками рисков за считанные минуты.


Начало работы

Наглядная демонстрация работы алгоритма будет весьма полезна читателям, которые, возможно, сталкиваются с этим алгоритмом впервые. Я возьму логотип MQL5 на рис. 1 и сначала преобразую его в черно-белый вид. Этот черно-белый фильтр облегчит нам применение и визуальное наблюдение за тем, как алгоритм PCA действует на наши данные.

Рис. 1. Мы используем логотип MQL5, чтобы продемонстрировать работу алгоритма PCA

Теперь, когда у нас есть изображение, с которым можно работать, давайте загрузим наши библиотеки Python.

#Let's go
import pandas as pd
import numpy  as np
import MetaTrader5 as mt5
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from skimage import io, color

Считаем изображение и преобразуем его в черно-белый вид.

# Load and preprocess the image
image = io.imread('mql5.png')  # Replace with your image path
image_gray = image_gray = color.rgb2gray(image)   # Convert to grayscale

Сведем изображение к двум измерениям и применим PCA, ориентируясь на 5 различных уровней компонентов. Исходное изображение находится слева на рис. 2. Первый главный компонент максимизирует дисперсию входных данных. Как мы видим на изображении 1 Components, общая структура исходного изображения в некоторой степени сохранилась. Хотя текст "MQL5" в центре изображения больше не читается, мы можем обоснованно заключить из изображения, что на черном фоне присутствует белая структура в середине.

При использовании 5 главных компонентов текст на изображении становится разборчивым. Однако мелкие детали, такие как светло-серые значки, стилизованные под фон, теряются и требуют восстановления дополнительных компонентов.

Это упражнение должно дать вам интуитивное понимание того, что алгоритм PCA пытается создать компактные и некоррелированные представления исходных входных данных. Эта задача решается путем создания последовательных линейных комбинаций входных данных, которые максимизируют дисперсию входных данных.

# Flatten the image
h, w = image_gray.shape
image_flattened = image_gray.reshape(h, w)

# Apply PCA with different numbers of components
n_components_list = [1,5,20,50,100]  # Number of components to keep

fig, axes = plt.subplots(1, len(n_components_list) + 1, figsize=(20, 10))
axes[0].imshow(image_gray, cmap='gray')
axes[0].set_title("Original Image")
axes[0].axis('off')

for i, n_components in enumerate(n_components_list):
        # Initialize PCA and transform the flattened image
        pca = PCA(n_components=n_components)
        pca.fit(image_flattened)
    
        # Transform and inverse transform the image
        transformed_image = pca.transform(image_flattened)
        reconstructed_image = pca.inverse_transform(transformed_image).reshape(h, w)
    
        # Plot the reconstructed image
        axes[i + 1].imshow(reconstructed_image, cmap='gray')
        axes[i + 1].set_title(f"{n_components} Components")
        axes[i + 1].axis('off')

plt.tight_layout()
plt.show()

Рис. 2. Первые 2 главных компонента логотипа MQL5

Рис. 3. Последние 3 главных компонента логотипа MQL5

Вместо изображения нас больше интересует максимизация или минимизация дисперсии портфеля. Мы можем добиться этого, передав набор данных, содержащий доходность каждого актива в портфеле, в наш алгоритм PCA.


Получение рыночных данных

Для начала нужно убедиться, что наш терминал MetaTrader 5 запущен.

mt5.initialize()
True

Теперь перечислим все активы, которые будут в нашем портфеле.

#List of cryptocurrencies we wish to invest
crypto = [
                "BCHUSD", #BitcoinCash
                "EOSUSD", #EOS
                "BTCUSD", #Bitcoin
                "ETHUSD", #Etherum
                "ADAUSD", #Cardano
                "XRPUSD", #Ripple
                "UNIUSD", #Monero
                "DOGUSD", #Dogecoin
                "LTCUSD", #Litecoin
                "SOLUSD"  #Solana
]

Мы хотим получить ежедневные рыночные данные за 6 лет.

fetch = 365 * 6

Наша модель будет делать прогнозы на 30 дней вперед.

look_ahead = 30

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

data = pd.DataFrame(columns=crypto,index=range(fetch))

Получим рыночные котировки для каждого из символов в нашем списке.

for i in range(0,len(crypto)):
        data[crypto[i]]         = pd.DataFrame(mt5.copy_rates_from_pos(crypto[i],mt5.TIMEFRAME_M1,0,fetch)).loc[:,"close"]

Посмотрим на наши рыночные данные.

data

Рис. 4. Визуализация некоторых собранных нами рыночных данных, фиксирующих 6-летние исторические цены ряда криптовалют


Разведочный анализ данных

Торговля криптовалютами может быть сложной задачей, поскольку они очень волатильны. Рис. 5 помогает нам увидеть эффективность корзины из 10 криптовалют за 6-летний период с 2018 по 2024 год. Разница между активами меняется, и человеку может быть сложно ее рассчитать или эффективно использовать.

data_plotting = data.iloc[:,:]/data.iloc[0,:]
sns.lineplot(data_plotting)

Рис. 5. Эффективность 10 различных криптовалют, в которые мы могли бы инвестировать

Риск, привносимый в наш портфель каждой криптовалютой, можно визуализировать как скользящее стандартное отклонение доходности каждого символа. На рис. 6 видно, что периоды высокой волатильности, по-видимому, группируются вместе. Однако некоторые рынки демонстрируют более волатильное поведение, чем другие.

plt.plot(data_plotting.iloc[:,0].rolling(14).std())
plt.plot(data_plotting.iloc[:,1].rolling(14).std())
plt.plot(data_plotting.iloc[:,2].rolling(14).std())
plt.plot(data_plotting.iloc[:,3].rolling(14).std())
plt.plot(data_plotting.iloc[:,4].rolling(14).std())
plt.plot(data_plotting.iloc[:,5].rolling(14).std())
plt.plot(data_plotting.iloc[:,6].rolling(14).std())
plt.plot(data_plotting.iloc[:,7].rolling(14).std())
plt.plot(data_plotting.iloc[:,8].rolling(14).std())
plt.plot(data_plotting.iloc[:,9].rolling(14).std())
plt.legend(crypto)
plt.title("The Risk Associated With Each of our Cryptocurrencies")
plt.xlabel("Time")
plt.ylabel("Standard Deviation") 

Рис. 6. Стандартное отклонение каждой криптовалюты в нашем портфеле

Алгоритм PCA поможет нам намеренно минимизировать или максимизировать нашу подверженность общей дисперсии портфеля, визуализированного на рис. 6. Попытка вручную решить, какие активы максимизируют дисперсию нашего портфеля, учитывая, что в нем 10 активов, может оказаться для человека невыполнимой задачей без посторонней помощи.

При анализе активов одного и того же класса вполне ожидаемо наличие сильной корреляции. Особый интерес представляют уровни корреляции между:
  1. EOSUSD и XRPUSD
  2. DOGUSD и BCHUSD

Эти пары демонстрируют практически идеальный уровень корреляции на протяжении 6 лет ежедневных рыночных котировок. Возможно, эту взаимосвязь наша модель может эффективно использовать и ее стоит изучить в разных условиях.
#Correlation analysis
sns.heatmap(data.corr(),annot=True)

Рис. 7: Визуализация уровней корреляции в нашем портфеле из 10 криптовалют

Рассчитаем изменение уровня цен за 2 недели.

#Calculate the change over 2 weeks
data = data.diff(14).dropna().reset_index(drop=True)

Теперь установим масштабировщик.

scaler = RobustScaler()
scaled_data = pd.DataFrame(scaler.fit_transform(data), columns=data.columns)

Подберем объект PCA из scikit learn на основе наших ежедневных рыночных доходов.

pca = PCA()
pca.fit(scaled_data)

Давайте теперь проанализируем первый главный компонент. Знак коэффициента указывает нам, следует ли нам занимать длинные или короткие позиции на каждом рынке. Положительные коэффициенты говорят нам о необходимости покупки, а отрицательные — о необходимости продажи. Поэтому, чтобы максимизировать дисперсию нашего портфеля, алгоритм PCA предлагает открывать короткие позиции на всех выбранных нами рынках.

Для трейдеров, которые хотят построить стратегии скальпинга, использование этого первого главного компонента — правильное решение.

#High risk strategy
pca.components_[0]
array([-0.31760842, -0.32146743, -0.35867192, -0.35797826, -0.28276975, -0.36658864, -0.2954465 , -0.19875535, -0.32278201, -0.30604428])

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

Разделим компонент на его норму L1. Норма L1 (L1 Norm) представляет собой сумму абсолютных значений компонента. Разделив каждый показатель основной нагрузки на их общую сумму, мы узнаем оптимальные пропорции, которые следует выделить каждому активу, чтобы максимизировать дисперсию нашего портфеля.

Рассчитав долю каждой криптовалюты в компоненте, мы можем умножить коэффициент распределения активов на количество позиций, которые мы хотим открыть, чтобы получить приблизительное значение того, сколько позиций нам следует открыть на каждом рынке. Мы рассчитали сумму, чтобы доказать, что общая сумма позиций составит 100, если умножить коэффициент распределения активов на 100.

#High risk asset allocations can be estimated from the first principal component
high_risk_asset_allocation = pca.components_[0] / np.linalg.norm(pca.components_[0],1)
np.sum(high_risk_asset_allocation * 100)
-100

Например, если мы хотим открыть 10 позиций, следуя высокорисковой стратегии, наш основной компонент предполагает, что мы продаем 1 позицию в BCHUSD (Bitcoin Cash). Десятичную часть коэффициента можно интерпретировать как позицию немного меньшего размера лота. Однако для точного учета этого фактора в нашем портфеле может потребоваться значительное количество времени. Возможно, проще будет положиться на целую часть распределения.

high_risk_asset_allocation * 10
array([-1.01533565, -1.02767219, -1.1466081 , -1.14439061, -0.90396285,-1.17191639, -0.94448806, -0.63538425, -1.03187466, -0.97836721])

Теперь перейдем к главным компонентам среднего риска.

#Mid risk strategy
pca.components_[len(crypto)//2]
array([-0.00530455,  0.16374242,  0.03976866, -0.19508115,  0.75650629,0.08559565, -0.51882352, -0.15840483, -0.23524968,  0.06543203])

И, наконец, наши главные компоненты с низким уровнем риска в целом предполагают совершенно иную торговую стратегию.

#Low risk strategy
pca.components_[len(crypto)-1]
array([-0.03520096,  0.37157999, -0.41562007,  0.74700647, -0.06764155,-0.15451366, -0.28321595, -0.01342945, -0.09973515, -0.10555529])

Давайте сохраним эти основные компоненты в текстовом файле, чтобы мы могли использовать полученные результаты в нашем торговом приложении MetaTrader 5.

np.savetxt("LOW RISK COMPONENTS.txt",pca.components_[len(crypto)-1])
np.savetxt("MID RISK COMPONENTS.txt",pca.components_[len(crypto)//2])
np.savetxt("HIGH RISK COMPONENTS.txt",pca.components_[0])


Реализация средствами MQL5

Теперь мы готовы приступить к внедрению нашего торгового приложения для MetaTrader 5.

Наше приложение будет стремиться следовать результатам оптимального распределения активов. Мы будем открывать только одну сделку на каждом рынке в соответствии с текущими пользовательскими настройками риска. Торговое приложение будет рассчитывать время входа, используя скользящую среднюю и стохастический осциллятор.

Если главный компонент предполагает, что нам следует открывать длинные позиции на рынке, мы будем ждать, пока уровни цен поднимутся выше значения скользящей средней на этом рынке, а стохастический осциллятор поднимется выше 50. Как только оба условия будут выполнены, мы займем длинную позицию и соответствующим образом установим уровни тейк-профита и стоп-лосса с использованием ATR. Мы надеемся, что такой выбор времени выхода на рынок со временем даст нам более стабильные и последовательные сигналы для входа.

Для начала мы определим пользовательский перечислитель, который предоставит конечному пользователю контроль над параметрами риска нашего торгового приложения.

//+------------------------------------------------------------------+
//|                               PCA For Portfolio Optimization.mq5 |
//|                                        Gamuchirai Zororo Ndawana |
//|                          https://www.mql5.com/en/gamuchiraindawa |
//+------------------------------------------------------------------+
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com/en/gamuchiraindawa"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Custom enumerations                                              |
//+------------------------------------------------------------------+
enum risk_level
  {
   High=0,
   Mid=1,
   Low=2
  };

Загружаем нужные нам библиотеки.

//+------------------------------------------------------------------+
//| Libraries                                                        |
//+------------------------------------------------------------------+
#include  <Trade\Trade.mqh>
CTrade Trade;

Определим постоянные значения.

//+------------------------------------------------------------------+
//| Constants values                                                 |
//+------------------------------------------------------------------+
const double high_risk_components[] = {#include "HIGH RISK COMPONENTS.txt"};
const double mid_risk_components[]  = {#include "MID RISK COMPONENTS.txt"};
const double low_risk_components[]  = {#include "LOW RISK COMPONENTS.txt"};
const string crypto[]               = {"BCHUSD","EOSUSD","BTCUSD","ETHUSD","ADAUSD","XRPUSD","UNIUSD","DOGUSD","LTCUSD","SOLUSD"};

Наши глобальные переменные, которые мы будем использовать во всей нашей программе.

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
double current_risk_settings[];
double vol,bid,ask;
int    atr_handler;
int    stoch_handler;
int    ma_handler;
double atr_reading[],ma_reading[],stoch_reading[];

Мы позволим конечному пользователю динамически контролировать настройки риска торгового счета и желаемый размер лота.

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input group "Risk Levels"
input risk_level user_risk = High; //Which risk level should we use?

input group "Money Management"
input int lot_multiple     = 1;    //How big should out lot size be?

При загрузке нашего торгового приложения мы сначала загрузим наши главные компоненты в соответствии с выбранной пользователем настройкой риска. Все это за нас сделает функция "настройки".

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Setup our market data
   setup();

//---
   return(INIT_SUCCEEDED);
  }

Если мы больше не используем советник, освободим ненужные ресурсы.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Release the indicators
   IndicatorRelease(atr_handler);
   IndicatorRelease(ma_handler);
   IndicatorRelease(stoch_handler);
  }

Наконец, всякий раз, когда мы получаем обновленные цены, будем поддерживать портфель из одной позиции на каждом рынке криптовалют. Позиция, которую мы займем, будет определяться выбранными пользователем настройками риска. В зависимости от уровня риска нам может потребоваться занять позицию на покупку или продажу, чтобы контролировать дисперсию в портфеле.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Ensure we always have 10 positions
   if(PositionsTotal() < 10)
     {
      //--- Let's see which market we aren't in
      for(int i = 0; i < 10; i++)
        {
         //--- Check if we can now enter that market
         if(!PositionSelect(crypto[i]))
           {
            check_setup(i);
           }
        }
     }
  }

Функция настройки определит, какой параметр риска выбрал конечный пользователь, а затем загрузит соответствующий главный компонент.

//+------------------------------------------------------------------+
//| Setup our market data                                            |
//+------------------------------------------------------------------+
void setup(void)
  {
//--- First let us define the current risk settings
   switch(user_risk)
     {
      //--- The user selected high risk
      case 0:
        {
         ArrayCopy(current_risk_settings,high_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in high risk mode");
         break;
        }
      //--- The user selected mid risk
      case 1:
        {
         ArrayCopy(current_risk_settings,mid_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in mid risk mode");
         break;
        }
      //--- The user selected low risk
      //--- Low risk is also the default setting for safety!
      default:
        {
         ArrayCopy(current_risk_settings,low_risk_components,0,0,WHOLE_ARRAY);
         Comment("EA in low risk mode");
         break;
        }
     }
  }

Поскольку мы активно торгуем 10 различными символами, нам нужна функция, отвечающая за получение рыночных данных, связанных с каждым символом. Функция update, определенная ниже, выполнит эту задачу за нас. Всякий раз, когда вызывается функция, она загружает в память текущую цену bid и ask, а также показания других технических индикаторов, которые рассчитываются на основе указанного рынка. После того, как мы использовали данные и решили, какое действие предпринять, функция загрузит в память рыночные данные следующего символа.

//+------------------------------------------------------------------+
//| Update our system varaibles                                      |
//+------------------------------------------------------------------+
void update(string market)
  {
//--- Get current prices
   bid = SymbolInfoDouble(market,SYMBOL_BID);
   ask = SymbolInfoDouble(market,SYMBOL_ASK);
//--- Get current technical readings
   atr_handler   = iATR(market,PERIOD_CURRENT,14);
   stoch_handler = iStochastic(market,PERIOD_CURRENT,5,3,3,MODE_EMA,STO_CLOSECLOSE);
   ma_handler    = iMA(market,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE);
//--- Copy buffer
   CopyBuffer(atr_handler,0,0,1,atr_reading);
   CopyBuffer(ma_handler,0,0,1,ma_reading);
   CopyBuffer(stoch_handler,0,0,1,stoch_reading);
//---
  }

Наконец, нам нужна функция, которая будет проверять, можем ли мы открыть позицию, соответствующую текущим настройкам риска, указанным пользователем. В противном случае, если мы не сможем этого сделать, мы дадим конечному пользователю содержательное объяснение, почему мы не можем открыть позицию на этом рынке.

//+------------------------------------------------------------------+
//| Open a position if we can                                        |
//+------------------------------------------------------------------+
void check_setup(int idx)
  {
//--- The function takes the index of the symbol as its only parameter
//--- It will look up the principal component loading of the symbol to determine whether it should buy or sell
   update(crypto[idx]);
   vol = lot_multiple * SymbolInfoDouble(crypto[idx],SYMBOL_VOLUME_MIN);

   if(current_risk_settings[idx] > 0)
     {
      if((iClose(crypto[idx],PERIOD_D1,0) > ma_reading[0]) && (stoch_reading[0] > 50))
        {
         Comment("Analyzing: ",crypto[idx],"\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: Buy");
         Trade.Buy(vol,crypto[idx],ask,(ask - (atr_reading[0] * 3)),(ask + (atr_reading[0] * 3)),"PCA Risk Optimization");
         return;
        }
      else
        {
         Comment("Waiting for an oppurtunity to BUY: ",crypto[idx]);
        }
     }

   else
      if(current_risk_settings[idx] < 0)
        {

         if((iClose(crypto[idx],PERIOD_D1,0) < ma_reading[0]) && (stoch_reading[0] < 50))
           {
            Comment("Analyzing: ",crypto[idx],"\nClose: ","\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: Sell");
            Trade.Sell(vol,crypto[idx],bid,(bid + (atr_reading[0] * 3)),(bid - (atr_reading[0] * 3)),"PCA Risk Optimization");
            return;
           }

         else
           {
            Comment("Waiting for an oppurtunity to SELL: ",crypto[idx]);
            return;
           }
        }
   Comment("Analyzing: ",crypto[idx],"\nMA: ",ma_reading[0],"\nStoch: ",stoch_reading[0],"\nAction: None");
   return;
  };
//+------------------------------------------------------------------+

Рис. 8. Просмотр нашего советника в MetaTrader 5

Рис. 9. Настройка параметров риска нашего торгового приложения

Рис. 10. Наше торговое приложение тестируется в реальном времени на реальных рыночных данных



Заключение

PCA обычно рассматривается как довольно сложная тема из-за математической нотации, необходимой для изучения этой концепции. Надеюсь, эта статья показала вам, как использовать PCA простым и понятным способом, который вы можете начать применять уже сегодня, даже если вы новичок в этой теме.

Управление рисками при распределении вашего портфеля — непростая задача. Математические инструменты и модели — лучший способ измерения и управления рисками, которым вы подвергаетесь на финансовых рынках. Особенно, когда количество рынков, на которых вы хотите работать, увеличивается.

Независимо от того, сколько у нас символов — 10 или 100, PCA всегда покажет нам, какие комбинации максимизируют риск портфеля, а какие — минимизируют.

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/16273

Разработка передовых торговых систем (ПТС): Реализация Order Blocks в индикаторе Разработка передовых торговых систем (ПТС): Реализация Order Blocks в индикаторе
В этой статье мы узнаем, как создать индикатор, который обнаруживает, рисует и предупреждает о смягчении ордер-блоков (ОВ). Также мы подробно рассмотрим, как идентифицировать эти блоки на графике, устанавливать точные предупреждения и визуализировать их положение с помощью прямоугольников, чтобы лучше понять поведение цены. Данный индикатор станет ключевым инструментом для тех, кто следует концепциям Smart Money Concepts и методологии Inner Circle Trader.
Создание торговой панели администратора на MQL5 (Часть VI): Мультифункциональный интерфейс (I) Создание торговой панели администратора на MQL5 (Часть VI): Мультифункциональный интерфейс (I)
Роль администратора выходит за рамки простого общения в Telegram; он также может заниматься различными видами контроля, включая управление ордерами, отслеживание позиций и настройку интерфейса. В этой статье мы поделимся практическими советами по расширению нашей программы для поддержки множества функций в MQL5. Это обновление направлено на преодоление ограничений текущей панели администратора, которая в первую очередь сосредоточена на общении.
Поэтапный отбор признаков на MQL5 Поэтапный отбор признаков на MQL5
В этой статье мы представляем модифицированную версию поэтапного отбора признаков, реализованную в MQL5. Настоящий подход основан на методах, описанных Тимоти Мастерсом (Timothy Masters) в работе "Современных алгоритмах интеллектуального анализа данных на C++" и "CUDA C".
Оптимизация на основе биогеографии — Biogeography-Based Optimization (BBO) Оптимизация на основе биогеографии — Biogeography-Based Optimization (BBO)
Оптимизация на основе биогеографии (BBO) — элегантный метод глобальной оптимизации, вдохновленный природными процессами миграции видов между островами архипелагов. В основе алгоритма лежит простая, но мощная идея: решения с высоким качеством активно делятся своими характеристиками, решения низкого качества активно заимствуют новые черты, создавая естественный поток информации от лучших решений к худшим. Уникальный адаптивный оператор мутации, обеспечивает превосходный баланс между исследованием и эксплуатацией, BBO демонстрирует высокую эффективность на различных задачах.