1. 我们会用到什么模型呢?
) U5 L* H3 S2 s5 U在之前的投票分类器中,我们用到了一个分类模型和一个回归模型。 在回归模型中,我们在用于计算分类时,用预测价格替代预测价格走势(下跌、上涨、不变)。 然而,在这种情况下,我们不能依据分类得到概率分布,而对于所谓的“软投票”这样是不允许的。" u1 k$ g# d% ?/ q
我们已准备了 3 个分类模型。 在“如何在 MQL5 中集成 ONNX 模型的示例”一文中已用到两个模型。 第一个模型(回归)被转换为分类模型。 基于 10 个 OHLC 价格序列进行了培训。 第二个模型是分类模型。 基于 63 个收盘价序列进
2 |! K& ~) e& R//| https://www.mql5.com |4 u1 i" M# e! K! O) M" _3 u, d
//+------------------------------------------------------------------+3 d( u7 D8 u* v% V: D% D5 T! t
//--- price movement prediction' d- R" q. D+ Y5 ~
#define PRICE_UP 0
1 `! H3 C y0 ~9 J$ F4 o* f#define PRICE_SAME 1
! Y M; m2 F5 V/ q( E#define PRICE_DOWN 28 K6 D. ^# m. }* b* T% @, M( o% H
//+------------------------------------------------------------------+
5 P8 K# f" P _//| Base class for models based on trained symbol and period |- v; f: [6 Q7 a9 X- x4 \1 l7 v
//+------------------------------------------------------------------+
7 W# x0 V5 f. |class CModelSymbolPeriod# X i) L. Q% d* }9 M* w/ `
{
2 Y" r+ r8 p) g6 }: j9 Lprotected:
9 k: J: V/ J: e s6 Llong m_handle; // created model session handle
2 d" \" Z- P/ lstring m_symbol; // symbol of trained data
. \: z, X8 [. P0 S4 D4 l3 c% |# l3 PENUM_TIMEFRAMES m_period; // timeframe of trained data
! z/ P0 f7 W% N# h1 pdatetime m_next_bar; // time of next bar (we work at bar begin only)
! ]+ Z, i x! `2 Z3 I4 u Hdouble m_class_delta; // delta to recognize "price the same" in regression models
( [4 b& _7 h& x$ C Mpublic:
/ h6 M* Y% u4 a3 C% ?" J0 J//+------------------------------------------------------------------+
" I a1 j- {0 P( f; l. ]# x6 _//| Constructor |
& Y" l- |* p% f$ }$ d% `//+------------------------------------------------------------------+2 o$ X2 z8 L% r# |5 \
CModelSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period,const double class_delta=0.0001)
3 Y* E% D; x2 m. D0 |* r' x. A{
- B ?& p7 o: [* D7 o, em_handle=INVALID_HANDLE;8 r5 P, R* K- O; G
m_symbol=symbol;
7 M! C/ G' u$ }0 r. i, vm_period=period;
2 Q. x9 P; F2 c$ Gm_next_bar=0;
`+ I6 _: X8 _m_class_delta=class_delta;" @1 W' T- t. n# ~9 p, W% F
}
7 H* d! ~6 V6 a5 ~9 c% Q//+------------------------------------------------------------------+
K/ W! Z5 T/ A z; O1 u//| Destructor |
) K6 `! U! ~0 H//| Check for initialization, create model |+ t" l- N+ o6 [- i
//+------------------------------------------------------------------+
$ I9 i* G" x$ W" K6 `% I4 Ibool CheckInit(const string symbol,const ENUM_TIMEFRAMES period,const uchar& model[])
9 o; W3 |8 D' z1 l( a$ W& q% l{
& `- S- Q& Q2 {' [//--- check symbol, period
+ C! u5 ~7 H! [6 O. a7 qif(symbol!=m_symbol || period!=m_period)& C% Y. w5 i& s6 j0 p( t7 E6 a
{! W% h8 s+ T# v) {# I
PrintFormat("Model must work with %s,%s",m_symbol,EnumToString(m_period));2 D' }+ ?$ u N& \* j' ~
return(false);
+ N! n+ w; s/ N3 Z( I8 O}3 @ o8 C/ m. \2 T' S
//--- create a model from static buffer
& h2 P' d! I0 p: `m_handle=OnnxCreateFromBuffer(model,ONNX_DEFAULT);
# r+ b, \! n+ Sif(m_handle==INVALID_HANDLE)
( y0 P. t: M$ ~4 y9 h{& @1 n2 k+ q8 h% Z
Print("OnnxCreateFromBuffer error ",GetLastError());
. s+ f& {. ~/ K. |0 r- x1 M. ]8 creturn(false);9 F/ t/ t& x1 ~2 ^: e' V" H% w
} r3 k' V) L) q! A, U2 F
//--- ok
" N3 t5 M' }5 D s T: l: w" O" Treturn(true);
( {6 k/ y" @; _: P}
1 l) H- c4 m4 {/ \' G9 z) H* G//+------------------------------------------------------------------+8 p; j$ E8 k- b9 Z6 V) F, C
m_next_bar=TimeCurrent();6 `$ n! U* V6 \. M8 }+ j
m_next_bar-=m_next_bar%PeriodSeconds(m_period);
1 y( h$ [( {& N; x: K4 `m_next_bar+=PeriodSeconds(m_period);
% m8 _8 U( D7 ?7 J. m: r. `//--- work on new day bar; }- l! E+ ?) z8 A) i
return(true);
! I% U- v6 R7 S3 Q}
% y: N! w$ D2 Z) n! J//+------------------------------------------------------------------+6 t* @7 O: D4 E3 l# @
//| virtual stub for PredictPrice (regression model) |* J/ @/ ?2 x5 z" t' h8 q
//+------------------------------------------------------------------+
+ T7 M1 }* p# j6 @6 cvirtual double PredictPrice(void)3 M+ i, ?" K ~% A6 N/ ]7 a$ q
{, s8 X2 h/ N3 S' |+ y7 x
return(DBL_MAX);
! d6 A" ~3 i) P7 `! N) q @}+ c& i8 ]$ ]. i* J
//+------------------------------------------------------------------+
- p- L8 z- [' H4 o//| Predict class (regression -> classification) |
- p4 K7 s; E+ x/ L//+------------------------------------------------------------------++ z2 B" Q5 n& R8 G' T+ G- r
virtual int PredictClass(void)
* u: T0 j# w3 p4 M{# Q' N# N, `& m, L' p" @
double predicted_price=PredictPrice();; B8 Z1 ^3 C' I2 B9 H! P8 P
if(predicted_price==DBL_MAX)
. K& [) `( f; g+ o2 h; Jreturn(-1);
5 ]( d r; Q3 k3 s/ |int predicted_class=-1;5 }! ?( e( E9 P- e; s3 R& y1 s
double last_close=iClose(m_symbol,m_period,1);5 L& }1 j% M' r r4 r2 r* y$ f$ L. b
//--- classify predicted price movement
* O3 u: H1 x- {3 X0 u2 pdouble delta=last_close-predicted_price;% ^0 E2 p6 d) y, ?' f3 L2 N# [
if(fabs(delta)<=m_class_delta)0 n: S- g9 y: R# \, }
predicted_class=PRICE_SAME;. v" b( k7 \) l* D
else; N4 ~7 K3 a4 `* L; {: n9 A
private:% u0 ?& W! u9 {( g2 |
int m_sample_size;6 `+ {9 T4 Z3 m2 C. N5 f3 e
//+------------------------------------------------------------------+/ w+ r1 G. a a$ f3 ?2 R4 {1 F- k
virtual bool Init(const string symbol, const ENUM_TIMEFRAMES period)6 R6 q! h5 C+ F
{
; m6 L. R I* Q//--- check symbol, period, create model6 T' P9 B! q+ c: U8 p
if(!CModelSymbolPeriod::CheckInit(symbol,period,model_eurusd_D1_10_class))
7 q. x3 Q9 X" y{
9 ^, n# @6 M# U8 S8 y/ APrint("model_eurusd_D1_10_class : initialization error");3 Z7 x& B: \$ s% M: Q
return(false);2 o& c( N7 ^4 m$ j+ d# a6 u; N- `
}) b$ d) P* q0 p: \0 D# S
//--- since not all sizes defined in the input tensor we must set them explicitly
9 T1 ?' l7 k+ ^//--- first index - batch size, second index - series size, third index - number of series (OHLC)
7 c) S7 `; w9 p) O Jconst long input_shape[] = {1,m_sample_size,4};
f# P) l( `: `7 M. ]if(!OnnxSetInputShape(m_handle,0,input_shape))
, m7 Z y1 V0 N# y! [3 [{
" K% b& O4 Q1 L# B. g4 T7 GPrint("model_eurusd_D1_10_class : OnnxSetInputShape error ",GetLastError());4 b5 z+ @; b1 v1 @" D6 S0 C
return(false);
' d* j4 _. L% U# v}8 k$ @ E9 ~ Y5 }
//--- since not all sizes defined in the output tensor we must set them explicitly
+ i) z V [+ W% ~! ]+ X$ f2 }//--- first index - batch size, must match the batch size of the input tensor
9 S; u% J) V, n( @( b3 {* @//--- second index - number of classes (up, same or down)# J0 d6 N- c" {1 n
const long output_shape[] = {1,3};4 q @* g6 l/ M! y; m2 y
if(!OnnxSetOutputShape(m_handle,0,output_shape))
/ g. s: H- s' X( B6 y{. m; U& G+ q% V, j2 K% R5 m& V
Print("model_eurusd_D1_10_class : OnnxSetOutputShape error ",GetLastError());1 _0 F' d+ ]3 V$ G, I: o8 ]3 O
return(false);- Y8 X5 c9 E6 w5 \! m0 b q' z1 |% ~
}
$ H: h; a! o% Z% T/ z//--- ok9 y) T, w3 b, j1 ~
return(true);: O9 u) x x+ D3 r
}
1 Q3 ` }/ z# }) X1 O//+------------------------------------------------------------------+0 O* s/ l6 x5 Q y6 E r
//| Predict class |
" k9 x+ l% R5 c; D0 A/ H//+------------------------------------------------------------------+4 D& q' J# g! ~8 T* I0 E4 P& d
virtual int PredictClass(void)+ r+ X% t T$ q) @/ \1 F% t
{ |