私募

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

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

[复制链接]
发表于 2024-4-4 08:08:25 | 显示全部楼层 |阅读模式
概述% T( q% U$ R% K3 H
在上一篇文章我们曾做过一些修正和调整。 不过,依旧还有错误,如该文所附的视频所示。2 F+ F/ u) \% Q8 _( v$ P
在本文中,我们将亲眼见证如何修复此错误。 虽然表面上看这似乎很简单,但我们需要遵循若干个步骤。 这个过程将是奇妙和有趣的。 我们的目标是令指标专门应用于特定的图表和品种。 即使用户尝试,他们也无法将指标应用于另外的图表,或在一个会话中多次打开它。, p- A! {* a% {/ |" ^
我鼓励您继续阅读,因为内容承诺非常实用。& P1 ]  S) q( H, i! R
将指标锁定在特定品种上。
5 V; X) T0 _; U( J9 o; }/ R% ~第一步是将控制指标链接到进行市场回放的品种。 这一步虽然看起来很简单,但对于开发我们的主要任务是必要的。 我们来看看指标代码在上下文中会是什么样子:9 N- K' g& J& j% p0 c9 j4 [
#property copyright "Daniel Jose", V- X5 Q3 P" g) L8 d8 O  z' |6 A! I
#property indicator_chart_window/ q3 ?/ k* v6 G( r& `
#property indicator_plots 0) U+ H$ k# A0 J9 t5 d1 a* A0 @
//+------------------------------------------------------------------++ i( H. \) s' _4 \& S5 U/ w# l
#include <Market Replay\C_Controls.mqh>
& S7 _7 k% ^' R) R6 k7 i+ M//+------------------------------------------------------------------+! |4 e  r4 f8 C/ ?# z
C_Controls      Control;  |" ~8 T: b4 Q! o0 ^: H
//+------------------------------------------------------------------+; ^3 q4 k* r) _
int OnInit()
: z# t2 |$ \1 p8 Z, V  H{* g4 A  s) k& |3 V' v
u_Interprocess Info;( {* R& ?" |+ b% J
IndicatorSetString(INDICATOR_SHORTNAME, def_ShortName);' D7 i4 A( M/ l
if (_Symbol != def_SymbolReplay)3 Q, Z' t8 [( I& E' u
{$ i9 T8 Y: I$ U+ G! F
ChartIndicatorDelete(ChartID(), 0, def_ShortName);
  X+ {& \2 x4 l& M5 Z7 preturn INIT_FAILED;
( v/ g) {& Y2 v5 o: J}* _" @0 I" r! u& P
if (GlobalVariableCheck(def_GlobalVariableReplay)) Info.Value = GlobalVariableGet(def_GlobalVariableReplay); else Info.Value = 0;
* s0 C4 g4 d9 L: k$ GControl.Init(Info.s_Infos.isPlay);6 V5 M7 {! L1 q2 h, O2 f( M* D% n
return INIT_SUCCEEDED;
- c7 F" L9 B: ^' N' ~}
+ n) \" P& o5 I) F//+------------------------------------------------------------------+
- {1 [5 ^  [+ Z! a+ O' F0 vint OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
" s& W  e: n  y! ~{8 |: E0 o8 V% \4 |. T8 [
return rates_total;
! ?6 R2 [6 [2 z( S8 M: b}2 N2 q' A7 u- U5 ?* a2 d
//+------------------------------------------------------------------+
* w, E, D8 d8 ?6 l- \void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
( x' f- ?! v3 O3 \; t" `$ V! G{
% C& s# H8 B9 {2 f- cControl.DispatchMessage(id, lparam, dparam, sparam);5 {/ g' H7 D# O
}* I4 v: S8 w! }& ^! J& t
//+------------------------------------------------------------------+: \1 i/ D( K, z! z5 h* H$ \
void OnDeinit(const int reason)& C: {( o1 J; m
{
7 [4 U- b1 f$ b3 n4 b0 dswitch (reason)
: G8 ^  y" Y( }' d: k) G{
9 P! m  L$ O2 I( q6 _9 M: N  Icase REASON_REMOVE:+ B- N8 G+ T$ Q6 H( z' U" J- t9 S
case REASON_CHARTCLOSE:2 J+ m9 \' @) @; a5 r
if (_Symbol != def_SymbolReplay) break;
" O/ C$ J- c$ s& ZGlobalVariableDel(def_GlobalVariableReplay);4 g" B0 B8 ~7 o( ~' t) A
ChartClose(ChartID());' Z1 N) `' p5 j" R- }0 f/ @) v
break;, |  {9 Q5 l- ^0 [( |) k
}
( p$ C4 z/ ]. d1 F4 J/ N1 |}9 Q6 g; j% K* q
//+------------------------------------------------------------------+& b3 v. m; e1 ?" E' e: V7 \
我们首先检查针对的品种是否要进行市场回放。 如果不是这种情况,指标将自动关闭。 请注意,知道指标的名称很重要。 因此,初始化期间执行的第一个函数调用我们的指标,这令我们能够轻松删除它。
1 V8 F2 R* Q6 O现在重要的一点是:当您将其从图表中删除时,MetaTrader 5 会生成 DeInit 事件。 此事件触发 OnDeInit 函数,而标记为 REASON_REMOVE 的事件表示从图表中删除指标。 这是因为该品种与指标设计绑定的品种不同。 如果我们不重新检查并阻止代码运行,品种图表将关闭。 不过,幸亏我们的检查,它将保持开放状态。
& M% G5 j+ o5 u) A( r如果指标代码与上一篇文章中提供的代码不同,请不要感到惊讶:上一篇文章重点在于其它改进和修复。 不过,在编写了文章和代码,并录制了本文随附的视频后,我意识到尽管其中一个问题已解决,但另一个问题仍未被发现。 这就是为什么我不得不修改代码。
3 P3 ?' Q8 n: q, V5 T6 Z尽管进行了修改,但我们不会在此处详述所做的全部修改。 必须删除很大一部分,因为它对于此处讨论的锁定方面无效。 因此,上面的代码与以前的代码有很大差别。 不过,我相信上一篇文章中讲演的知识在某些时候可能对某些人有用。 我保存了那篇文章,以表明有时我们都会犯错误,但我们依旧应该努力把事情做好。
# a, `* [# C9 F- s, ?因此,我们来建立第一个锁定步骤,即确保控制指标仅存在于市场回放品种的图表上。 然而,该衡量值并不会阻止向同一图表或不同图表添加多个指标,因此必须进行调整。2 M2 `; v6 p% w+ |5 S
我们应该避免在同一图表上多次使用指标。8 u7 q" v3 L9 `3 M+ b% n  ^
我们已经解决了一个问题,现在我们来应对另一个问题。 这里有各种解决方案,这取决于我们真正想要和愿意做什么。 就个人而言,我没有看到这个问题的理想和最终解决方案。 不过,我将尝试提出一种方式,读者能感到熟悉和理解。 最重要的是,该解决方案将完全基于 MQL5。 我甚至考虑过使用外部编码的可能性,但最终决定使用纯 MQL5。 诉诸外部编码,并利用 DLL 进行锁定的想法很诱人,但这太容易了。; _$ l; w; R6 Q4 x7 _: g
我认为在诉诸外部 DLL 来填补 MQL5 语言无法胜任的空白之前,我们在 MQL5 中还有很多东西需要学习。 这将提供一个在使用外部代码时看起来“更干净”的解决方案。 只是,这并无助于更好地理解 MQL5。 此外,这可能会强化 MetaTrader 5 是一个受限平台的误解。 对平台的误解和效力利用不足助长了这种误解。' O3 J. ]0 _! L& F) J
为了应用我们提议的解决方案,您不得不进行一些修改,并撤回其它更改。 第一步是更改 InterProcess.mqh 头文件,令其拥有以下结构:2 p7 `( C0 b- y7 P  s
#property copyright "Daniel Jose"
3 A' W' W+ {% s//+------------------------------------------------------------------+
+ e7 V5 g) m9 W- C" v6 m1 D#define def_GlobalVariableReplay        "Replay Infos"
+ S9 t3 i$ w( C#define def_GlobalVariableIdGraphics    "Replay ID"
  E1 I* b3 L) t- F#define def_SymbolReplay                "RePlay"* {: M" W$ R! X/ }
#define def_MaxPosSlider                400
: V/ s  d  Y3 P5 R#define def_ShortName                   "Market Replay"
5 U* j' X+ w1 O  _( y6 Q! h//+------------------------------------------------------------------+
: _1 H, Y" |( x3 R1 yunion u_Interprocess
3 H; f5 a6 i3 Y{
. ?& p+ _, P5 c* T+ R5 Junion u_0" B2 M9 W0 f6 b% e, O+ o
{. t4 x/ [" M& U  I3 U* O9 c1 l
double  df_Value;$ M, R! @$ p- `
long    IdGraphic;
' I5 Z+ f7 a" t/ `}u_Value;
, F) l! s: u: s6 n9 ~1 Wstruct st_0& \, N* q# Y! _; {* G9 O8 \
{# {& h; H7 L. o0 p5 z9 y
bool    isPlay;
; F; x: W' g& ^int     iPosShift;
* @4 ]6 {+ m/ n0 J- x9 i) ?}s_Infos;' m+ B2 |8 j; }2 C* U$ F9 y: t
};
, t6 L* B) v/ r/ {' Z1 {1 b//+------------------------------------------------------------------++ r4 x7 d) }/ \& I8 D# l
对于许多不熟悉编程的人来说,这似乎有点奇怪,但令人惊讶的是,上述结构仅占用 8 字节的内存。 您也许已经注意到,从上一篇文章的结构中删除了一个变量。 原因是我们将不再使用这种锁定方法。 我们将采取一种不同的方式,稍微复杂一些,但对于把控制指标限定于单个图表方面则有效得多。 这将是一个非常具体和明确的回放服务。
: n! N1 _; M$ f7 p注意: 如果 MetaTrader 5 平台和 MQL5 语言的开发人员为该服务提供了向特定图表添加指标的能力,或者允许该服务在图表上调用和执行脚本,那将会很有趣。 使用脚本,我们可以将指标添加到特定图表当中,但目前服务无法做到这一点。我们可以打开图表,但不能向其内添加指标。 当尝试执行此动作时,即使我们使用 MQL5 函数,也始终显示错误消息。 在撰写本文时,MetaTrader 5 版本为 build 3280。
! s5 V: p% ^+ }/ G重要提示:在撰写本章的这个阶段,这是一个更高级的阶段,由此我才能够实现这一点。 不过,当我撰写这篇文章时,我找不到任何可以帮助解决这个问题的参考资料。 因此,请关注这个回放/模拟系列,看看我是如何想出解决方案的。" A% z( t2 L& Z
在这种关联境况下,通过运行下面的脚本,我们就能够打开指标,并将其添加到图表之中:# `! O+ {1 z8 o9 h3 @, |3 }+ L
//+------------------------------------------------------------------+- p2 w5 c  z9 {# A
//| Script program start function                                    |
) I1 V+ Y5 [' D8 P; I3 V//+------------------------------------------------------------------+
% D0 I2 j) G6 I7 g! ^void OnStart()2 r: d7 h; p. b9 E4 B# b: Y
{) w2 r4 u) m, D) F1 d9 T
ENUM_TIMEFRAMES time = PERIOD_D1;
4 N1 v3 D7 x% h+ Y( `; _6 ]3 F* ^4 R2 \string szSymbol = "EURUSD";
: ~  P, q( ?  G3 w6 s6 Dlong id = ChartOpen(szSymbol, time);
0 h) v$ j8 c9 TChartRedraw(id);
5 @9 c/ a2 _+ `9 H1 [: WChartIndicatorAdd(id, 0, iCustom(szSymbol, time, "Media Movel.ex5"));
1 e- [4 m* ~5 V2 f8 Z# E}
$ p' P! M8 \$ z/ y然而,如果我们将相同的脚本转换为服务,我们就不会得到相同的结果。
http://www.simu001.cn/x288003x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-26 05:07 , Processed in 0.374273 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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