私募

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

期货量化软件:赫兹量化中锁定指标

[复制链接]
发表于 2024-4-4 08:08:25 | 显示全部楼层 |阅读模式
概述$ e4 d+ {% m# h2 a- P
在上一篇文章我们曾做过一些修正和调整。 不过,依旧还有错误,如该文所附的视频所示。
, h$ Z$ q. M9 K在本文中,我们将亲眼见证如何修复此错误。 虽然表面上看这似乎很简单,但我们需要遵循若干个步骤。 这个过程将是奇妙和有趣的。 我们的目标是令指标专门应用于特定的图表和品种。 即使用户尝试,他们也无法将指标应用于另外的图表,或在一个会话中多次打开它。
% r6 \& A5 d9 }1 x! V. z我鼓励您继续阅读,因为内容承诺非常实用。; C- @" \, q! x1 B+ Q* j0 M3 G
将指标锁定在特定品种上。
( O0 o% _. T6 i2 K第一步是将控制指标链接到进行市场回放的品种。 这一步虽然看起来很简单,但对于开发我们的主要任务是必要的。 我们来看看指标代码在上下文中会是什么样子:
: C/ u9 @' q* Q4 _/ l9 E#property copyright "Daniel Jose"
2 V1 o1 k! l+ o0 ]0 L#property indicator_chart_window- z, K4 K. |6 S( g! @
#property indicator_plots 01 d( y+ ?0 s/ v8 f, J0 g
//+------------------------------------------------------------------+
" w& p/ J2 W. p( g% _' V' a#include <Market Replay\C_Controls.mqh>
" c( ?- K, z6 y  d3 l//+------------------------------------------------------------------+/ x8 _4 n: m" l
C_Controls      Control;. q  q( r) X: X2 A
//+------------------------------------------------------------------+/ y7 O% ?3 B% n9 @. n
int OnInit()
4 k1 H" m0 r% \6 }' H{
3 L0 _, h5 i% F9 b; qu_Interprocess Info;: \6 A' q( Y9 z4 b7 U* }
IndicatorSetString(INDICATOR_SHORTNAME, def_ShortName);5 v  D- K4 c9 |3 i; s
if (_Symbol != def_SymbolReplay)
0 k+ P9 p! R% Q8 T! p# P3 F{
' [  ^% g! p. D$ c! pChartIndicatorDelete(ChartID(), 0, def_ShortName);! W# U1 t  ?1 }+ A8 o4 p  p4 X
return INIT_FAILED;9 c, h2 _0 a6 o9 w0 T
}: A& C% |9 |; a
if (GlobalVariableCheck(def_GlobalVariableReplay)) Info.Value = GlobalVariableGet(def_GlobalVariableReplay); else Info.Value = 0;" b& b; o+ [/ W8 U" T
Control.Init(Info.s_Infos.isPlay);
& o( d% J; J# areturn INIT_SUCCEEDED;
: v8 `; {+ W/ ~- V4 b, C}2 M/ }4 ]( O* z, m
//+------------------------------------------------------------------+
" a6 T6 f  ?; b' vint OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
  H" S: f. f! v{
6 D) q; `) ^/ d/ o$ [, v) mreturn rates_total;, n, V  R- O8 p; P) n/ _
}4 W! [  F, e+ Y3 X. Z1 {' T& [
//+------------------------------------------------------------------+) T' L5 W0 K" ~$ u& Y9 F+ V, r
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)8 `; H* Y( d4 O' L: e& G: ^7 d" p
{: o- j! ^9 ~2 K) T) x* @$ `
Control.DispatchMessage(id, lparam, dparam, sparam);0 \3 T9 h2 B7 X; d3 P
}
( c1 }6 j7 G: \* Q9 h' X$ Y% j//+------------------------------------------------------------------+
- ~8 G0 |9 ]4 @! [void OnDeinit(const int reason): Q) e; N4 ]+ Y% U5 W
{3 h: n4 t+ f. S( }0 s3 E
switch (reason)# L% \; G: F4 X
{& S7 H$ v1 Q8 T6 Q  G- g
case REASON_REMOVE:% `1 G( r5 t4 ?
case REASON_CHARTCLOSE:0 O, _- k* U% I- ^
if (_Symbol != def_SymbolReplay) break;
- [) \. q8 S; K6 K) z  iGlobalVariableDel(def_GlobalVariableReplay);
; u+ ]- n; `6 q! \) H' L6 @2 n5 IChartClose(ChartID());- K6 N$ ], |% s2 y
break;
6 ~* f0 _3 x" G  z}
( @5 o3 m* ]. A' t9 L6 p7 a% C}% j" }6 |9 ]1 W) M: N6 T
//+------------------------------------------------------------------+4 k! l4 H  @0 N- E
我们首先检查针对的品种是否要进行市场回放。 如果不是这种情况,指标将自动关闭。 请注意,知道指标的名称很重要。 因此,初始化期间执行的第一个函数调用我们的指标,这令我们能够轻松删除它。
8 S: k" S" K+ A* B6 B  J7 s+ g+ Y现在重要的一点是:当您将其从图表中删除时,MetaTrader 5 会生成 DeInit 事件。 此事件触发 OnDeInit 函数,而标记为 REASON_REMOVE 的事件表示从图表中删除指标。 这是因为该品种与指标设计绑定的品种不同。 如果我们不重新检查并阻止代码运行,品种图表将关闭。 不过,幸亏我们的检查,它将保持开放状态。
4 u8 Q9 [% p2 s2 q' Z  d( @% q" e如果指标代码与上一篇文章中提供的代码不同,请不要感到惊讶:上一篇文章重点在于其它改进和修复。 不过,在编写了文章和代码,并录制了本文随附的视频后,我意识到尽管其中一个问题已解决,但另一个问题仍未被发现。 这就是为什么我不得不修改代码。
7 Y% f* n8 e7 G& I" z7 p, s尽管进行了修改,但我们不会在此处详述所做的全部修改。 必须删除很大一部分,因为它对于此处讨论的锁定方面无效。 因此,上面的代码与以前的代码有很大差别。 不过,我相信上一篇文章中讲演的知识在某些时候可能对某些人有用。 我保存了那篇文章,以表明有时我们都会犯错误,但我们依旧应该努力把事情做好。* d( C! E6 ?& m" I& C" ^7 E7 U
因此,我们来建立第一个锁定步骤,即确保控制指标仅存在于市场回放品种的图表上。 然而,该衡量值并不会阻止向同一图表或不同图表添加多个指标,因此必须进行调整。$ ]5 S* E; f; g2 J5 y
我们应该避免在同一图表上多次使用指标。
. R% a: }! r% p, f, G我们已经解决了一个问题,现在我们来应对另一个问题。 这里有各种解决方案,这取决于我们真正想要和愿意做什么。 就个人而言,我没有看到这个问题的理想和最终解决方案。 不过,我将尝试提出一种方式,读者能感到熟悉和理解。 最重要的是,该解决方案将完全基于 MQL5。 我甚至考虑过使用外部编码的可能性,但最终决定使用纯 MQL5。 诉诸外部编码,并利用 DLL 进行锁定的想法很诱人,但这太容易了。- ^9 d) n3 o; l3 _0 x3 ?: c
我认为在诉诸外部 DLL 来填补 MQL5 语言无法胜任的空白之前,我们在 MQL5 中还有很多东西需要学习。 这将提供一个在使用外部代码时看起来“更干净”的解决方案。 只是,这并无助于更好地理解 MQL5。 此外,这可能会强化 MetaTrader 5 是一个受限平台的误解。 对平台的误解和效力利用不足助长了这种误解。
/ i0 |6 q/ G0 V& P; k: t为了应用我们提议的解决方案,您不得不进行一些修改,并撤回其它更改。 第一步是更改 InterProcess.mqh 头文件,令其拥有以下结构:2 Y8 l% b: k& S' G$ B
#property copyright "Daniel Jose"* ~! O/ S0 {, z( s2 R7 v
//+------------------------------------------------------------------+
! L; ?- x1 Y4 ]! b: q#define def_GlobalVariableReplay        "Replay Infos"
9 p" Z* ]; C/ O& }& O! v#define def_GlobalVariableIdGraphics    "Replay ID"
9 Q1 j; W. G0 g2 T0 B( c. h: `#define def_SymbolReplay                "RePlay"
- _' ]" E4 }  u1 f#define def_MaxPosSlider                400& b1 y7 k$ \' k/ D$ b
#define def_ShortName                   "Market Replay"
9 [. B7 S+ q! J$ _9 M//+------------------------------------------------------------------+
7 C. [, |% {$ y( G. u+ qunion u_Interprocess
% I9 Y% E$ U6 j1 ]: S{' e5 [* e; Y, s' t$ P% [
union u_0
9 Z' f) O" q- Q2 E" Q{) x. x1 U9 q  s1 ~4 B. W' k
double  df_Value;
5 A9 d; [) e/ m5 D0 ?6 @- c! F5 Olong    IdGraphic;
# S9 u$ H$ [. A  C1 a4 `}u_Value;. H- M; B8 O; ^9 q9 J5 O
struct st_0; J9 k' Z- K9 e' R7 w( v
{
1 |; Q( q- r. K' V6 Hbool    isPlay;: g5 \+ s3 ~/ T8 m1 ]+ {
int     iPosShift;
6 {" G8 _5 h3 l, n9 h4 b}s_Infos;
0 G+ S% J8 w$ ]* y};. i% Z  {( F/ A/ V& h& P# [
//+------------------------------------------------------------------+4 J+ _# ~2 ^1 Q/ e6 {' F$ u' W
对于许多不熟悉编程的人来说,这似乎有点奇怪,但令人惊讶的是,上述结构仅占用 8 字节的内存。 您也许已经注意到,从上一篇文章的结构中删除了一个变量。 原因是我们将不再使用这种锁定方法。 我们将采取一种不同的方式,稍微复杂一些,但对于把控制指标限定于单个图表方面则有效得多。 这将是一个非常具体和明确的回放服务。
' [, |7 l' b; ], t注意: 如果 MetaTrader 5 平台和 MQL5 语言的开发人员为该服务提供了向特定图表添加指标的能力,或者允许该服务在图表上调用和执行脚本,那将会很有趣。 使用脚本,我们可以将指标添加到特定图表当中,但目前服务无法做到这一点。我们可以打开图表,但不能向其内添加指标。 当尝试执行此动作时,即使我们使用 MQL5 函数,也始终显示错误消息。 在撰写本文时,MetaTrader 5 版本为 build 3280。  F& \& f5 y6 \9 O' ?4 G. f% `# {! M
重要提示:在撰写本章的这个阶段,这是一个更高级的阶段,由此我才能够实现这一点。 不过,当我撰写这篇文章时,我找不到任何可以帮助解决这个问题的参考资料。 因此,请关注这个回放/模拟系列,看看我是如何想出解决方案的。
3 X* w- ~5 h7 ?& p- V* x, y8 c在这种关联境况下,通过运行下面的脚本,我们就能够打开指标,并将其添加到图表之中:
' j# ^4 D* L+ V1 i0 F! M' S//+------------------------------------------------------------------+1 M0 l' D8 F$ h9 r
//| Script program start function                                    |3 {' A. n8 ^( ?" d+ c+ _
//+------------------------------------------------------------------+& N- |; t+ b8 Y4 }
void OnStart()( L* J& k) F7 y# W1 ~
{& N+ f+ _8 K* ?$ h
ENUM_TIMEFRAMES time = PERIOD_D1;
9 A: P8 `# f" p% c5 n) P* p# ?2 rstring szSymbol = "EURUSD";
, f4 s  I$ q6 Y5 R  _long id = ChartOpen(szSymbol, time);
. [, c$ l+ Y  d: T; @ChartRedraw(id);
1 x, k6 n' o0 v# @0 G- G5 QChartIndicatorAdd(id, 0, iCustom(szSymbol, time, "Media Movel.ex5"));8 A  E( A5 O) |1 e
}, k8 c( S& m$ n, p2 x- L* H0 p* h+ g* k
然而,如果我们将相同的脚本转换为服务,我们就不会得到相同的结果。
http://www.simu001.cn/x288003x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-21 10:29 , Processed in 1.490780 second(s), 32 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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