私募

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

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

[复制链接]
发表于 2024-4-4 08:08:25 | 显示全部楼层 |阅读模式
概述
6 G& z$ F: e" Z- c在上一篇文章我们曾做过一些修正和调整。 不过,依旧还有错误,如该文所附的视频所示。
9 n; u. @4 T. t" q6 ~/ o: C; b1 k在本文中,我们将亲眼见证如何修复此错误。 虽然表面上看这似乎很简单,但我们需要遵循若干个步骤。 这个过程将是奇妙和有趣的。 我们的目标是令指标专门应用于特定的图表和品种。 即使用户尝试,他们也无法将指标应用于另外的图表,或在一个会话中多次打开它。
2 H# C2 b" Y4 X  Y0 R) I我鼓励您继续阅读,因为内容承诺非常实用。
0 c1 Q# P' g0 n) q) k将指标锁定在特定品种上。
; O, _/ D7 c( }. B' m第一步是将控制指标链接到进行市场回放的品种。 这一步虽然看起来很简单,但对于开发我们的主要任务是必要的。 我们来看看指标代码在上下文中会是什么样子:
: G1 @( L6 e- h8 m7 V9 P#property copyright "Daniel Jose"
& H) Z9 J3 L  h7 d) r% s#property indicator_chart_window
" ]1 d' u  D4 N7 \#property indicator_plots 0
* @! f6 ]. {; K0 l8 h//+------------------------------------------------------------------+" Q* U! ~- G, n8 R* N
#include <Market Replay\C_Controls.mqh>
3 q# \# c2 n* Y( ^//+------------------------------------------------------------------+! d* P* ~- |1 x# H. R3 S# M
C_Controls      Control;; r7 g) u7 y; n2 j4 C, r. _/ o
//+------------------------------------------------------------------+
! \$ U5 `. @& F( ^int OnInit()* J0 U$ F3 ^% U. E
{
, x- z" @2 A1 K: ru_Interprocess Info;
6 ~) y/ T) X; s9 m# J; i/ h, NIndicatorSetString(INDICATOR_SHORTNAME, def_ShortName);
, Q3 e& K: M# u  n4 Sif (_Symbol != def_SymbolReplay)( }6 I8 @: z% R
{
9 W6 a8 ^3 g# ]  YChartIndicatorDelete(ChartID(), 0, def_ShortName);
6 _! G$ e8 Y7 X- ]2 N9 Preturn INIT_FAILED;
: d/ m3 N. N& m- ~2 R0 C}
1 s6 U7 X* T$ d* nif (GlobalVariableCheck(def_GlobalVariableReplay)) Info.Value = GlobalVariableGet(def_GlobalVariableReplay); else Info.Value = 0;
2 P$ p! w; W" cControl.Init(Info.s_Infos.isPlay);; t9 @; V: B9 K" [6 \
return INIT_SUCCEEDED;
! o( Q9 E1 h0 g! \% E}
! A! k3 T1 J2 ~* u//+------------------------------------------------------------------+
; m7 o, u4 k' h( n, fint OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
" N1 Z8 r3 P: u{& X1 M' d. L4 r( ]  ?
return rates_total;+ |( I1 ~0 f) c( ]0 ~6 Q
}
! s# |' Q" d1 H: s) j: F//+------------------------------------------------------------------+$ y1 G3 w# b6 K$ E
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)5 R1 _. s; @7 F. g
{9 j3 z  R4 h- G+ Z5 A5 _" P
Control.DispatchMessage(id, lparam, dparam, sparam);, E$ I  G2 J& c* C. F9 t# D
}
/ U* q3 s7 f" I# h  @//+------------------------------------------------------------------+$ M! c- l1 \& F1 F& T8 r
void OnDeinit(const int reason)4 d$ d) O, U- @( L; T4 n' U3 ~
{, k7 M/ u( ~# e& @: }" D
switch (reason), T% [+ Y- n# c6 n9 z: ?6 b/ T, r1 [9 N
{
! \0 `) P) I, U' bcase REASON_REMOVE:
! @4 B# i, V2 V# Acase REASON_CHARTCLOSE:
: W8 H: r+ L5 Dif (_Symbol != def_SymbolReplay) break;3 Z' N& [3 O* B' V' a5 R1 d/ D! J( @
GlobalVariableDel(def_GlobalVariableReplay);
0 B: K" N* @+ R0 M! o! F! `* RChartClose(ChartID());8 T6 Y8 ?4 m$ p8 I6 @( v$ M( p
break;! v% X4 S( R1 e7 T
}
+ I# _% |4 i5 a7 D}3 A' ?8 Q4 }6 B+ M! S
//+------------------------------------------------------------------+
- `) m7 F; L& c) H9 A我们首先检查针对的品种是否要进行市场回放。 如果不是这种情况,指标将自动关闭。 请注意,知道指标的名称很重要。 因此,初始化期间执行的第一个函数调用我们的指标,这令我们能够轻松删除它。3 N( v1 {) P1 D9 s# f# c. p- H
现在重要的一点是:当您将其从图表中删除时,MetaTrader 5 会生成 DeInit 事件。 此事件触发 OnDeInit 函数,而标记为 REASON_REMOVE 的事件表示从图表中删除指标。 这是因为该品种与指标设计绑定的品种不同。 如果我们不重新检查并阻止代码运行,品种图表将关闭。 不过,幸亏我们的检查,它将保持开放状态。5 o1 x. O* i+ o1 w7 W3 v4 l
如果指标代码与上一篇文章中提供的代码不同,请不要感到惊讶:上一篇文章重点在于其它改进和修复。 不过,在编写了文章和代码,并录制了本文随附的视频后,我意识到尽管其中一个问题已解决,但另一个问题仍未被发现。 这就是为什么我不得不修改代码。
; l0 ]) ^9 |* e: f7 G/ p3 P尽管进行了修改,但我们不会在此处详述所做的全部修改。 必须删除很大一部分,因为它对于此处讨论的锁定方面无效。 因此,上面的代码与以前的代码有很大差别。 不过,我相信上一篇文章中讲演的知识在某些时候可能对某些人有用。 我保存了那篇文章,以表明有时我们都会犯错误,但我们依旧应该努力把事情做好。, R; ?) r4 S: L0 M
因此,我们来建立第一个锁定步骤,即确保控制指标仅存在于市场回放品种的图表上。 然而,该衡量值并不会阻止向同一图表或不同图表添加多个指标,因此必须进行调整。) a( y! @9 z; {; t6 ?6 {! A- D0 M
我们应该避免在同一图表上多次使用指标。) t2 V' z# U- O: w
我们已经解决了一个问题,现在我们来应对另一个问题。 这里有各种解决方案,这取决于我们真正想要和愿意做什么。 就个人而言,我没有看到这个问题的理想和最终解决方案。 不过,我将尝试提出一种方式,读者能感到熟悉和理解。 最重要的是,该解决方案将完全基于 MQL5。 我甚至考虑过使用外部编码的可能性,但最终决定使用纯 MQL5。 诉诸外部编码,并利用 DLL 进行锁定的想法很诱人,但这太容易了。
! T& `; d2 k# a5 d% n5 ~我认为在诉诸外部 DLL 来填补 MQL5 语言无法胜任的空白之前,我们在 MQL5 中还有很多东西需要学习。 这将提供一个在使用外部代码时看起来“更干净”的解决方案。 只是,这并无助于更好地理解 MQL5。 此外,这可能会强化 MetaTrader 5 是一个受限平台的误解。 对平台的误解和效力利用不足助长了这种误解。
! o/ ]  ^- ?7 \为了应用我们提议的解决方案,您不得不进行一些修改,并撤回其它更改。 第一步是更改 InterProcess.mqh 头文件,令其拥有以下结构:
; }" N7 B, F. W4 t! ~+ Q! e#property copyright "Daniel Jose"
  L1 K% r' }3 a% V//+------------------------------------------------------------------+  u4 T/ y: T& r% ?
#define def_GlobalVariableReplay        "Replay Infos"; O* l1 T9 d+ J- e2 c! z5 M
#define def_GlobalVariableIdGraphics    "Replay ID"
/ ~4 T6 a/ c9 D  g#define def_SymbolReplay                "RePlay"! t7 U" W- P( a" L" D
#define def_MaxPosSlider                400
6 q: ]  h. U9 D$ N#define def_ShortName                   "Market Replay"
9 X' ]: y% f0 b7 Y# Q9 Z' ^  w//+------------------------------------------------------------------+
4 e& j3 G, M% hunion u_Interprocess4 \/ j% S8 b1 N8 w6 ]
{
9 S, \6 k/ ~/ T5 dunion u_0! B" y1 @: d- ~9 G$ K
{0 }' f* W* n& b, u+ Y. j. l
double  df_Value;+ R8 a5 }! f8 o& W1 b7 b( i) K
long    IdGraphic;
; X/ Y' X2 w% M0 B7 R- M}u_Value;
- k/ {+ H6 e8 G6 F9 }' n1 Q5 }struct st_0! Y; w6 e. [& e
{) M( {+ Y7 a' k7 b4 g, N4 b
bool    isPlay;" K" o2 Q! w! W! U" ?1 z1 v
int     iPosShift;/ c% E! t" w' B, _7 m
}s_Infos;
2 f- v; B" U. a) W! H2 q( ~};
3 @/ f: w  w: Y4 C- Y//+------------------------------------------------------------------++ N7 C9 F0 w, H: o
对于许多不熟悉编程的人来说,这似乎有点奇怪,但令人惊讶的是,上述结构仅占用 8 字节的内存。 您也许已经注意到,从上一篇文章的结构中删除了一个变量。 原因是我们将不再使用这种锁定方法。 我们将采取一种不同的方式,稍微复杂一些,但对于把控制指标限定于单个图表方面则有效得多。 这将是一个非常具体和明确的回放服务。* ?& ~; u1 A4 D# z5 M: a0 e
注意: 如果 MetaTrader 5 平台和 MQL5 语言的开发人员为该服务提供了向特定图表添加指标的能力,或者允许该服务在图表上调用和执行脚本,那将会很有趣。 使用脚本,我们可以将指标添加到特定图表当中,但目前服务无法做到这一点。我们可以打开图表,但不能向其内添加指标。 当尝试执行此动作时,即使我们使用 MQL5 函数,也始终显示错误消息。 在撰写本文时,MetaTrader 5 版本为 build 3280。! ]9 C6 ]$ x; a* u: @, D; h
重要提示:在撰写本章的这个阶段,这是一个更高级的阶段,由此我才能够实现这一点。 不过,当我撰写这篇文章时,我找不到任何可以帮助解决这个问题的参考资料。 因此,请关注这个回放/模拟系列,看看我是如何想出解决方案的。
& G  D2 Y' M3 w* V, ]% Y& z1 L在这种关联境况下,通过运行下面的脚本,我们就能够打开指标,并将其添加到图表之中:
- U1 M+ K* ?- R3 C//+------------------------------------------------------------------+; {1 K/ ]' T0 A& `' I2 ^! e
//| Script program start function                                    |$ Z  z4 Z4 W* F$ l  X) W
//+------------------------------------------------------------------+# W( I9 R1 ~/ E2 a: O- u
void OnStart()8 q9 v5 P( `/ o8 E+ u
{
; ^8 {1 a: _& ~/ C1 r' nENUM_TIMEFRAMES time = PERIOD_D1;
0 W. {' ~1 h! ^& j# M1 J/ istring szSymbol = "EURUSD";
& m. X$ W4 t0 v2 t5 ?long id = ChartOpen(szSymbol, time);
0 V# B4 O$ H* h. C5 @" rChartRedraw(id);
; `& r3 @$ X4 OChartIndicatorAdd(id, 0, iCustom(szSymbol, time, "Media Movel.ex5"));
5 t9 v: Q( @) t' @# q/ k}0 ^4 Q3 c. q% _5 o5 Q
然而,如果我们将相同的脚本转换为服务,我们就不会得到相同的结果。
http://www.simu001.cn/x288003x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-13 13:02 , Processed in 6.996909 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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