NN_in_Trading/Experts/Unsupervised/AssocRules/assocrules_pca.mq5
2026-06-05 22:00:59 +03:00

344 lines
No EOL
24 KiB
MQL5
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+------------------------------------------------------------------+
//| pca_net.mq5 |
//| Copyright 2022, DNG |
//| https://www.mql5.com/ru/users/dng |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, DNG"
#property link "https://www.mql5.com/ru/users/dng"
#property version "1.00"
//+------------------------------------------------------------------+
//| Includes |
//+------------------------------------------------------------------+
#include "AssocRules.mqh"
#include "..\\PCA\\pca.mqh"
#include <Trade\SymbolInfo.mqh>
#include <Indicators\Oscilators.mqh>
//---
#define FileName Symb.Name()+"_"+EnumToString((ENUM_TIMEFRAMES)Period())+"_"+StringSubstr(__FILE__,0,StringFind(__FILE__,".",0))
#define CSV __FILE__+".csv"
//---
enum ENUM_SIGNAL
{
Sell = -1,
Undefine = 0,
Buy = 1
};
//+------------------------------------------------------------------+
//| input parameters |
//+------------------------------------------------------------------+
input int StudyPeriod = 15; //Study period, years
/*input*/ uint HistoryBars = 20; //Depth of history
ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;
//---
input group "---- RSI ----"
input int RSIPeriod = 14; //Period
input ENUM_APPLIED_PRICE RSIPrice = PRICE_CLOSE; //Applied price
//---
input group "---- CCI ----"
input int CCIPeriod = 14; //Period
input ENUM_APPLIED_PRICE CCIPrice = PRICE_TYPICAL; //Applied price
//---
input group "---- ATR ----"
input int ATRPeriod = 14; //Period
//---
input group "---- MACD ----"
input int FastPeriod = 12; //Fast
input int SlowPeriod = 26; //Slow
input int SignalPeriod = 9; //Signal
input ENUM_APPLIED_PRICE MACDPrice = PRICE_CLOSE; //Applied price
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CSymbolInfo *Symb;
MqlRates Rates[];
CArrayDouble *TempData;
CiRSI *RSI;
CiCCI *CCI;
CiATR *ATR;
CiMACD *MACD;
CAssocRules *Rules;
CPCA *PCA;
//---
double dError;
double dUndefine;
double dForecast;
double dPrevSignal;
datetime dtStudied;
bool bEventStudy;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
Symb = new CSymbolInfo();
if(CheckPointer(Symb) == POINTER_INVALID || !Symb.Name(_Symbol))
return INIT_FAILED;
Symb.Refresh();
//---
RSI = new CiRSI();
if(CheckPointer(RSI) == POINTER_INVALID || !RSI.Create(Symb.Name(), TimeFrame, RSIPeriod, RSIPrice))
return INIT_FAILED;
//---
CCI = new CiCCI();
if(CheckPointer(CCI) == POINTER_INVALID || !CCI.Create(Symb.Name(), TimeFrame, CCIPeriod, CCIPrice))
return INIT_FAILED;
//---
ATR = new CiATR();
if(CheckPointer(ATR) == POINTER_INVALID || !ATR.Create(Symb.Name(), TimeFrame, ATRPeriod))
return INIT_FAILED;
//---
MACD = new CiMACD();
if(CheckPointer(MACD) == POINTER_INVALID || !MACD.Create(Symb.Name(), TimeFrame, FastPeriod, SlowPeriod, SignalPeriod, MACDPrice))
return INIT_FAILED;
//---
Rules = new CAssocRules();
if(!Rules)
return INIT_FAILED;
//---
PCA = new CPCA();
if(CheckPointer(PCA) == POINTER_INVALID)
return INIT_FAILED;
int handl = FileOpen("pca.net", FILE_READ | FILE_BIN);
if(handl == INVALID_HANDLE)
return INIT_FAILED;
if(!PCA.Load(handl))
{
FileClose(handl);
return INVALID_HANDLE;
}
FileClose(handl);
//---
bEventStudy = EventChartCustom(ChartID(), 1, 0, 0, "Init");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
if(CheckPointer(Symb) != POINTER_INVALID)
delete Symb;
//---
if(CheckPointer(RSI) != POINTER_INVALID)
delete RSI;
//---
if(CheckPointer(CCI) != POINTER_INVALID)
delete CCI;
//---
if(CheckPointer(ATR) != POINTER_INVALID)
delete ATR;
//---
if(CheckPointer(MACD) != POINTER_INVALID)
delete MACD;
//---
if(CheckPointer(Rules) != POINTER_INVALID)
delete Rules;
//---
if(CheckPointer(PCA) != POINTER_INVALID)
delete PCA;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
if(!bEventStudy && (dPrevSignal == -2 || dtStudied < SeriesInfoInteger(Symb.Name(), TimeFrame, SERIES_LASTBAR_DATE)))
bEventStudy = EventChartCustom(ChartID(), 1, (long)0, 0, "New Bar");
//---
}
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
//---
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//---
if(id == 1001)
{
Train(lparam);
bEventStudy = false;
OnTick();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Train(datetime StartTrainBar = 0)
{
//---
MqlDateTime start_time;
TimeCurrent(start_time);
start_time.year -= StudyPeriod;
if(start_time.year <= 0)
start_time.year = 1900;
datetime st_time = StructToTime(start_time);
//---
int bars = CopyRates(Symb.Name(), TimeFrame, st_time, TimeCurrent(), Rates);
if(!RSI.BufferResize(bars) || !CCI.BufferResize(bars) || !ATR.BufferResize(bars) || !MACD.BufferResize(bars))
{
ExpertRemove();
return;
}
if(!ArraySetAsSeries(Rates, true))
{
ExpertRemove();
return;
}
//---
RSI.Refresh();
CCI.Refresh();
ATR.Refresh();
MACD.Refresh();
//---
int total = bars - (int)HistoryBars - 1;
matrixf fractals;
matrixf data;
if(!data.Init(total, 8 * HistoryBars) ||
!fractals.Init(total, 3))
{
ExpertRemove();
return;
}
//---
for(int i = 0; (i < total && !IsStopped()); i++)
{
Comment(StringFormat("Create data: %d of %d", i, total));
for(int b = 0; b < (int)HistoryBars; b++)
{
int bar = i + b;
int shift = b * 8;
double open = Rates[bar].open;
data[i, shift] = (float)(open - Rates[bar].low);
data[i, shift + 1] = (float)(Rates[bar].high - open);
data[i, shift + 2] = (float)(Rates[bar].close - open);
data[i, shift + 3] = (float)RSI.GetData(MAIN_LINE, bar);
data[i, shift + 4] = (float)CCI.GetData(MAIN_LINE, bar);
data[i, shift + 5] = (float)ATR.GetData(MAIN_LINE, bar);
data[i, shift + 6] = (float)MACD.GetData(MAIN_LINE, bar);
data[i, shift + 7] = (float)MACD.GetData(SIGNAL_LINE, bar);
}
int bar = i + 1;
fractals[i, 0] = (float)(Rates[bar - 1].high <= Rates[bar].high && Rates[bar + 1].high < Rates[bar].high);
fractals[i, 1] = (float)(Rates[bar - 1].low >= Rates[bar].low && Rates[bar + 1].low > Rates[bar].low);
fractals[i, 2] = (float)((fractals[i, 0] + fractals[i, 1]) == 0);
}
if(IsStopped())
{
ExpertRemove();
return;
}
//---
data=PCA.ReduceM(data);
//---
ulong array[] = {300};
matrixf ar_data[], ar_fractals[];
data.Hsplit(array, ar_data);
fractals.Hsplit(array, ar_fractals);
//---
Rules.CreateRules(ar_data[1], ar_fractals[1].Col(0), ar_fractals[1].Col(1), 5, 0.05f, 0.50f);
float buy_prob, sell_prob;
for(ulong i = 0; i < ar_data[0].Rows(); i++)
{
if(!Rules.Probability(ar_data[0].Row(i), buy_prob, sell_prob))
return;
if(DoubleToSignal(buy_prob - sell_prob) == Undefine)
DeleteObject(Rates[i].time);
else
DrawObject(Rates[i].time, (buy_prob - sell_prob), Rates[i].high, Rates[i].low);
}
Comment("");
//---
ExpertRemove();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
ENUM_SIGNAL DoubleToSignal(double value)
{
value = NormalizeDouble(value, 1);
if(MathAbs(value) > 1 || MathAbs(value) <= 0)
return Undefine;
if(value > 0)
return Buy;
else
return Sell;
//---
return Undefine;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DrawObject(datetime time, double signal, double high, double low)
{
double price = 0;
int arrow = 0;
color clr = 0;
ENUM_ARROW_ANCHOR anch = ANCHOR_BOTTOM;
switch(DoubleToSignal(signal))
{
case Buy:
price = low;
arrow = 217;
clr = clrBlue;
anch = ANCHOR_TOP;
break;
case Sell:
price = high;
arrow = 218;
clr = clrRed;
anch = ANCHOR_BOTTOM;
break;
}
if(price == 0 || arrow == 0)
return;
//---
string name = TimeToString(time);
if(ObjectFind(0, name) < 0)
{
ResetLastError();
if(!ObjectCreate(0, name, OBJ_ARROW, 0, time, 0))
{
printf("Error of creating object %d", GetLastError());
return;
}
}
//---
ObjectSetDouble(0, name, OBJPROP_PRICE, price);
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, arrow);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, anch);
ObjectSetString(0, name, OBJPROP_TOOLTIP, EnumToString(DoubleToSignal(signal)) + " " + DoubleToString(signal, 5));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DeleteObject(datetime time)
{
string name = TimeToString(time);
if(ObjectFind(0, name) >= 0)
ObjectDelete(0, name);
}
//+------------------------------------------------------------------+