私募

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz

期货量化交易软件:赫兹量化中开发回放系统新的类

[复制链接]
发表于 2024-3-31 08:33:07 | 显示全部楼层 |阅读模式
概述5 H# n5 r3 \9 [8 e! A
在上一篇文章“开发回放系统 — 市场模拟(第 15 部分):模拟器(V)的诞生 - 随机游走” 中,我们开发了一种获取随机数据的方法。 这样做是为了确保与结果的完全适配。 但即便该系统确有能力遵循一种合理的方式模拟跳价,它依旧缺乏某些信息,不管是来自模拟器,还是来自回放系统本身。 真相在于我们需要实现的一些事情非常复杂,特别是从系统构建的角度。 故此,我们需要进行一些更改,从而至少可获得更佳的模型,且在接下来的步骤中不会迷失方向。7 ~5 @3 V8 j8 v+ O
信任我,如果您发现随机游走具有挑战性,那只是因为您尚未见识到、或者不知道需要开发什么,才能令模拟/回放达到最佳体验。 最具挑战性的层面之一是,我们必须至少知晓有关资产模拟或回放的基础知识。 在当前开发阶段,我不费心主动解决一些问题,因为有更实用的途径可以做到这一点。
/ w6 u# L8 H. a& K7 Q) ?如果您仔细研究过上一篇文章,您会注意到诸如 EXCEL 这样的程序可用于创建可能的市场场景。 但我们也能采用来自其它资产的信息,并将它们组合起来创建更复杂的模拟。 这令创建一个全自动寻找有关资产自身缺失信息的系统变得困难。 我们还有一个小问题。 因此,在这里我们将剪切和派发 C_Replay.mqh 头文件的内容,从而简化维护和改进。 我不喜欢操控一个超大型的类,这对我来说似乎很不方便。 原因在于,许多情况下代码难以完全优化。 由此,出于易用起见,我们将从两方面更改,即我们把 C_Replay 类的内容分散到若干个类之中,与此同时实现最相关的部分。
/ B1 s/ Q  {4 v/ i- I以新的类系统实现服务7 j( z- t9 u- O/ H8 h
尽管前几篇文章中讨论的代码通常很少更改,但这个新实现包含了一个新模型。 对于那些没有深厚编程知识的人来说,这个模型更易于扩展,也更易于理解,因为所连接元素的方式更简单。 我们无需阅读冗长且累人的函数。 有些细节也许看似有点奇怪,但怪异的是,它们令代码更加安全、稳定、且结构合理。 其中一个细节是指针的用法与 C++ 或传统 C 语言中的不同。 不过,该行为与这些语言非常相似。
  z+ T4 t0 {, U7 T  s9 c) i指针的运用令我们能够做到原本不可能的事情。 尽管 C++ 中引入的许多特色在 MQL5 中不可用,但以最简单的形式使用指针的朴素事实令我们能以更灵活、更愉快的方式实现建模,至少在编程和语法方面如此。( Z4 G- h  `& A* ~7 }) h
故而,当前版本中的新服务文件现在如下所示:
" G9 F5 D0 y+ z( h0 s#property service9 }; N" \0 ~6 }4 J( l
#property icon "\\Images\\Market Replay\\Icon.ico"8 Z3 @' {4 _  F0 c4 }/ m
#property copyright "Daniel Jose"
9 C+ A8 }! u) c5 ^. v#property version   "1.16"3 x7 D/ T; r$ `* }+ b2 ?( B" ~9 [/ y
#property description "Replay-simulation system for MT5."
2 |0 h- [% U. Y8 T2 v#property description "It is independent from the Market Replay."
- H& o4 K. ?4 T' v! v1 Z/ H#property description "For details see the article:": ~0 e9 }( R6 l+ S/ i) |8 Y: a
#property link "https://www.mql5.com/ru/articles/11095". T% s) ^. n' B( T% i& f7 j
//+------------------------------------------------------------------+
: H5 ~2 s* e( z3 N6 f& a6 e3 b#define def_Dependence  "\\Indicators\\Market Replay.ex5"
8 |, X1 i7 l0 x! ]! G4 c/ J#resource def_Dependence
8 D4 O6 V8 }$ g$ `+ w5 f) T//+------------------------------------------------------------------+
2 T7 h1 ]; _, O* U# C7 }: G; O1 g#include <Market Replay\C_Replay.mqh>
6 ~" j7 F$ @9 F5 I6 w# ?8 n: P. D//+------------------------------------------------------------------+5 W6 O/ T- i0 l4 B0 T: i
input string            user00 = "Config.txt";  //"Replay" config file.
- M1 o/ U; I# k; W( e- iinput ENUM_TIMEFRAMES   user01 = PERIOD_M1;     //Initial timeframe for the chart.) w7 B: d& m# |, Z: M# M& e  N. j
input bool              user02 = true;          //Visual bar construction.
" R0 [/ y/ U1 [9 _& iinput bool              user03 = true;          //Visualize creation metrics.
- R! d$ M) w# `5 [3 K6 Z5 v( e0 m0 S//+------------------------------------------------------------------++ d* \3 E3 \7 w' J" S1 L; Y
void OnStart()
, Z; O* y3 _+ r3 y{) X# u9 T8 O# W: e
C_Replay        *pReplay;
; Y" o7 c& T2 P9 ~* XpReplay = new C_Replay(user00);$ p0 q6 g, d* L2 y! \( Y
if (pReplay.ViewReplay(user01))
$ U2 z/ V% q6 u# _- b& L{5 z0 B! C* D0 E, r& ]) d
Print("Permission received. The replay service can now be used...");+ J* ^5 S0 P8 Y1 q( M& x# _& z
while (pReplay.LoopEventOnTime(user02, user03));3 Q! i, {' @' x% L
}7 C1 r- k' W5 ^9 ~( C8 p' [
delete pReplay;& u# z: D) a' x$ C4 s) ?
}% N4 U) z. ^1 f+ [: C5 O7 J' h
//+------------------------------------------------------------------+' R; K2 E9 F$ d/ T3 n
看似没有经历任何重大变化,但实际上一切都完全不同。 对于最终用户而言,它保持不变,并具有与以前版本完全相同的行为。 但对于平台而言,尤其是对于操作系统,生成的可执行文件看起来会有所不同,且具有不同的行为。 原因在于我们所用的类并非当作变量,而是当作指向内存的指针。 这就是为什么整个系统的行为完全不同。 如果您仔细编程,比之仅把类当作变量,类的这种用法更加安全和稳定。 尽管它们展现出相同的行为,但它们在内存使用方面会有所不同。
6 \! C2 S* t! s# J' m. f4 X现在,由于类被当作指针来用,我们就要排除一些东西,并开始用到其它东西。 第一件事就是,该类始终要显式开启和关闭。 这是使用 new 和 delete 操作符完成的。 当我们使用 “new” 操符创建类实例时,我们必须始终调用类的构造函数。 它们从不返回任何值,如此我们就并不能直接检查返回值。 我们只好在另一个时间做这件事。 同样的事情当使用 “delete” 操作符时也会发生,并且将调用类的析构函数。 与类的构造函数一样,析构函数也从不返回任何值。 但与构造函数不同的是,析构函数不接收任何参数。$ i9 L" `4 u) Q4 ]
我们必须始终以这种方式进行:我们用 “new” 操作符创建一个类实例,并用 “delete” 操作符销毁该类实例。 这就是我们仅有的真正要做的工作。 剩下的则由操作系统完成:它在特定的内存区域中为程序分配足够的内存以便运行,令其尽可能安全地贯穿整个存在期。 但对于那些习惯于在 C++/C 中使用指针的人来说,这里存在着危险:我们所说的是注入符。 在 C++ 和 C 中,每当我们引用指针时,我们都会用到非常特殊注入符。 通常我们使用箭头(->)。 对于 C++/C 程序员,这意味着用的是指针。 但我们也可以使用不同的注入符,在我的代码中访问指针时就能见到。
( O0 Q% q; [" Y! f此外,当然,还要用到变量名称,通常以字母 “p” 或 “ptr” 等组合开头(尽管这并非一个严格的规则,故不必强求)。 虽然上面和下面代码中所示的两种注入符 MQL5 都接受,但我个人发现在实际代码里采用正确声明的指针更易于阅读。 因此,在我们的代码中,注入符将如下所示,这要致谢我对 C++/C 语言的了解:2 r' E: S9 e& Q
void OnStart()- K, o" z+ ~  B3 g; S, |
{0 E( c  w7 t" P6 \( h% o- d
C_Replay        *pReplay;
; r+ Q- c5 w) G( t/ [/ ]pReplay = new C_Replay(user00);% X2 s" k4 E( i8 `2 f& [& Y5 a
if ((*pReplay).ViewReplay(user01))  o% W, _) E3 X5 F( U' G6 l' ~
{
( l3 P2 ?% l" l5 y1 mPrint("Permission received. The replay service can now be used...");% I( r  e* p8 x  M& C
while ((*pReplay).LoopEventOnTime(user02, user03));3 \# N2 N! g* k: g( x/ ~3 b
}
1 n) w4 Z/ t( V$ k1 Q4 J! S) x9 ndelete pReplay;* g& t/ C1 `4 a2 Y  q4 \& h( @* ]. R
}$ q8 o6 `  }6 B. v" D, k9 [" y
实际上,还有与编写代码相关的额外工作。 但是作为一个拥有多年经验的 C++/C 程序员,当我查看上面所示的代码时,我很轻易就明白它是引用指针。 由于 MQL5 的理解方式与 C++/C 相同,故我明白注入符这样用没有问题。 每当我们看到含有如上所示注入符的代码时,您不必担心,因为它就只是一个指针。
http://www.simu001.cn/x287862x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Archiver| ( 桂ICP备12001440号-3 )|网站地图

GMT+8, 2024-5-1 14:12 , Processed in 0.362400 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表