1. 我们会用到什么模型呢?+ f4 ~0 E7 B1 `2 | N7 ~- H7 L0 m- j
在之前的投票分类器中,我们用到了一个分类模型和一个回归模型。 在回归模型中,我们在用于计算分类时,用预测价格替代预测价格走势(下跌、上涨、不变)。 然而,在这种情况下,我们不能依据分类得到概率分布,而对于所谓的“软投票”这样是不允许的。
4 J9 }/ A' n7 s# P0 a4 k我们已准备了 3 个分类模型。 在“如何在 MQL5 中集成 ONNX 模型的示例”一文中已用到两个模型。 第一个模型(回归)被转换为分类模型。 基于 10 个 OHLC 价格序列进行了培训。 第二个模型是分类模型。 基于 63 个收盘价序列进
4 A6 U" P* J7 [5 K//| https://www.mql5.com |. Y: d. X2 `- p
//+------------------------------------------------------------------+. d0 B7 I" n) f3 j) G
//--- price movement prediction
: `6 l. B2 n! l$ V/ `& H#define PRICE_UP 0
4 k' p2 E9 A3 G9 r, e# |#define PRICE_SAME 1) X0 q9 r+ z& u7 S, ]
#define PRICE_DOWN 2
. q9 X! P* t j//+------------------------------------------------------------------+
+ y/ a9 J6 K4 y//| Base class for models based on trained symbol and period |- s5 r9 d& K3 p% C! g) F
//+------------------------------------------------------------------+" p+ c7 ?* x+ M
class CModelSymbolPeriod
8 e. ~6 w! p: C. c. P{
* {, }/ w1 q3 wprotected:
9 e- J" d+ j( f0 j. F& dlong m_handle; // created model session handle& \/ f3 o$ P( w8 Y, R- ^/ h
string m_symbol; // symbol of trained data: X% V! W7 ~- Z; l1 w
ENUM_TIMEFRAMES m_period; // timeframe of trained data
% s5 |; W \+ k! z' ]7 E7 Tdatetime m_next_bar; // time of next bar (we work at bar begin only)* q( t9 D1 h* X) N
double m_class_delta; // delta to recognize "price the same" in regression models( O0 @* ~+ m+ u/ R" h6 G |
public:
~: }. N5 X1 k' W( E//+------------------------------------------------------------------+5 c+ ^) h' i) `$ ~
//| Constructor | j7 _. D C" Z
//+------------------------------------------------------------------+
3 b+ M2 b: Z4 dCModelSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period,const double class_delta=0.0001)& M, S! ^% r* ?$ O3 g' m
{+ W2 E4 P% j7 J' d0 q n! M
m_handle=INVALID_HANDLE;' Y% p* P% _* B% S, D
m_symbol=symbol;0 h: F+ m4 Q. i/ F
m_period=period;
0 N) P8 N; j! mm_next_bar=0;
' D9 i4 x0 @; p4 |' z! Z( @m_class_delta=class_delta;& D6 r' `. g/ H, T
}
: K5 G' y0 j3 K/ |//+------------------------------------------------------------------+
3 @. E+ `6 `0 c+ `: X f- F) g# ^//| Destructor |
[, O7 Q1 i# L# l7 {//| Check for initialization, create model |
@- v$ y. v6 p5 c; d9 F. [//+------------------------------------------------------------------+: T1 R' r! f" k; `
bool CheckInit(const string symbol,const ENUM_TIMEFRAMES period,const uchar& model[])
9 [, J# k7 G, P{% |1 \7 U4 t$ `6 U0 X% u
//--- check symbol, period s, w8 P. Z! Q e! _
if(symbol!=m_symbol || period!=m_period)
" Z3 O& S1 H, J% U8 N4 Z{2 K# m! [9 o) F* X3 G4 k
PrintFormat("Model must work with %s,%s",m_symbol,EnumToString(m_period));
Y% P! U. a' p9 A7 G: k* a1 a% wreturn(false);8 k# Q5 I$ x8 c
}
* W2 q0 S, C& {% e2 _! X( Q# f* {//--- create a model from static buffer
# ^6 }/ @) _3 y0 cm_handle=OnnxCreateFromBuffer(model,ONNX_DEFAULT);# T3 f% |' b+ @
if(m_handle==INVALID_HANDLE)' `, f' k2 Z" f
{% `. b! d- `1 P$ F7 g
Print("OnnxCreateFromBuffer error ",GetLastError());+ R8 X5 O: i: ]
return(false);) X4 x( }2 U( {9 A
}
* o; n4 d- n: z/ \6 p. J//--- ok
5 k7 b; k3 W+ h5 j. |return(true);$ `4 x! { g ?3 u5 G) l
}
- d$ F& _' y3 @//+------------------------------------------------------------------+
1 ^9 F% Y) z& r* B; Om_next_bar=TimeCurrent();7 |% D: k" }8 \7 v ]9 ~+ J: {9 q
m_next_bar-=m_next_bar%PeriodSeconds(m_period);8 \" D% T0 g' ]" F+ R4 Z" K) l d
m_next_bar+=PeriodSeconds(m_period);
0 H2 a2 p0 D; x8 P//--- work on new day bar
7 \8 q. r8 ^, V7 Y0 E8 d4 }return(true);0 |: V6 l4 x3 U' [
}9 C& a) M: n- v0 @& M- n
//+------------------------------------------------------------------+ H! k+ u4 _' M, b3 @2 C
//| virtual stub for PredictPrice (regression model) |
5 @; b" y! x+ W( f3 \; p- K* A//+------------------------------------------------------------------+& } d* ~2 N* Q! H8 K) i: o
virtual double PredictPrice(void). J) }$ k& G; z6 o/ d8 ^
{( I' d$ E! K% Q; j: U
return(DBL_MAX);/ C1 x) U# Q3 d) ]9 T
}
2 \% e' {+ e! F U//+------------------------------------------------------------------+1 M6 e. I* b/ R& ~/ U
//| Predict class (regression -> classification) |
; Q8 v) s7 C( }5 {//+------------------------------------------------------------------+( |1 @' n0 n* g& u
virtual int PredictClass(void)
# \' c, Q" Y) K( W: g{. r4 o1 q0 P; u# |5 L* T
double predicted_price=PredictPrice();/ M: B9 g. \7 j1 Z2 ?
if(predicted_price==DBL_MAX)
4 Q$ t5 C6 C k/ Yreturn(-1);- e# h: S9 U8 a
int predicted_class=-1;
7 K5 e- a$ z1 x$ h$ Rdouble last_close=iClose(m_symbol,m_period,1);
+ O7 K$ _4 T0 b' \* C0 n//--- classify predicted price movement) v- d8 Y# C$ G9 H
double delta=last_close-predicted_price;
7 X$ O4 B# y' R4 v9 eif(fabs(delta)<=m_class_delta)
' ?4 g* N3 O0 b4 d+ ]1 tpredicted_class=PRICE_SAME;9 `! _ ?) H! c, D9 M5 P* y+ b X! E
else; o* ~! |: u; Q# t* v' I' B+ k
private:
+ [) I/ P2 b: I6 mint m_sample_size;4 n# K: `1 i) j+ P- n1 Q
//+------------------------------------------------------------------+, M" g2 h/ n7 K
virtual bool Init(const string symbol, const ENUM_TIMEFRAMES period)! O* a9 w& e1 j" @0 m
{/ Q3 ~3 Z' W6 {4 Q, `
//--- check symbol, period, create model. ^4 f# o \' h, `2 P6 P
if(!CModelSymbolPeriod::CheckInit(symbol,period,model_eurusd_D1_10_class))8 p# j5 G9 y- W1 x% e0 [
{) K1 ]$ N9 M7 `( X9 D$ ^. J
Print("model_eurusd_D1_10_class : initialization error");
. b1 [8 C4 w8 s) ^- G0 c5 e' p8 Ireturn(false);
0 ]( O% P# x* {7 {! ^) o}) }9 ~9 p5 W l% D- I
//--- since not all sizes defined in the input tensor we must set them explicitly
2 G* V: c7 c) W5 |( k F( o//--- first index - batch size, second index - series size, third index - number of series (OHLC)
; u) Z$ z1 G2 N% D# A8 x$ \; B' Wconst long input_shape[] = {1,m_sample_size,4};
# A4 G% A {& q: I5 y3 `if(!OnnxSetInputShape(m_handle,0,input_shape))( N* l- Y' T: u) X# [
{6 ]/ L/ [6 j3 c$ N* a0 W
Print("model_eurusd_D1_10_class : OnnxSetInputShape error ",GetLastError());- z- K+ k7 t6 |, \1 `! D1 ~: h
return(false);
9 s Y! \8 r# t7 e}
. R) v W: ?% T/ ]: v//--- since not all sizes defined in the output tensor we must set them explicitly% R- a( J$ Q1 _2 K9 G
//--- first index - batch size, must match the batch size of the input tensor. o" k& H! P8 R0 V
//--- second index - number of classes (up, same or down)- N0 _+ V! V' C0 q, E, O; t+ }
const long output_shape[] = {1,3};
+ f$ l% G! i& W5 Jif(!OnnxSetOutputShape(m_handle,0,output_shape))
$ m* Q U3 T: a$ M{6 _$ Q: H+ }5 [4 x7 B
Print("model_eurusd_D1_10_class : OnnxSetOutputShape error ",GetLastError());- G& C3 Z6 |5 N- P! f0 f3 s9 |" Q
return(false);: ?1 k- ]) ~) q3 l5 S
}9 }. d8 K4 C7 n/ p# j
//--- ok8 N$ a, O* U9 ^4 U! N+ e
return(true);* _" x& b# h% t& _
}
# V# \/ s3 G+ }; r/ F//+------------------------------------------------------------------+1 o, f" r( E3 r" l# b, y$ F( o @ \
//| Predict class |
% g4 z; b0 ?- M4 E" p//+------------------------------------------------------------------+" i% _; X6 d" i. w! P7 W8 ?
virtual int PredictClass(void). ?4 q2 X3 S( y0 g9 q
{ |