四目观天下

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

期货量化软件:赫兹量化如何利用 MQL5 创建自定义指标Heiken

[复制链接]
发表于 2024-4-9 08:32:19 | 显示全部楼层 |阅读模式
概述6 M* D/ F# a" O: w
我们都需要读取图表,任何可以帮助完成此任务的工具都会受到欢迎。 在有助于读取图表的工具之中,指标计算可基于价格、交易量、其它技术指标、或它们的组合,而在交易世界中存在众多新奇的思路。 我们在交易终端中内置了很多现成的指标,如果我们需要添加一些功能以便能适应我们的交易风格,我们会发现这有一些挑战,因为也许无法更改它,除此之外,我们也许无法在交易终端中的内置指标里找到期望的指标。4 n0 J4 d2 t  h8 {- X! F8 l8 Z
赫兹量化交易软件$ U4 d0 v1 l) [- i* \
自定义指标和 Heiken Ashi 定义
) D% u# k7 q) }6 z在这一部分中,我们将更详细地学习自定义指标和 Heiken Ashi 指标。 正如我在上一章节的概述中提到的,自定义指标是用户利用 MQL5 编程语言创建的技术分析工具。 它可以在 MetaTrader 5 中用来分析和明晰市场走势,并有助于做出明智的投资决策。 有许多实用的内置技术指标,但有时我们需要根据一些额外和特定的数学、统计或技术概念来分析和理解市场的行为,而这些概念在内置指标中不存在,或者没有指标可以完成任务。 那么,在这种情况下,我们必须自己创建指标 — 这是 MetaTrader 5 平台的功能之一,因为它可以帮助我们创建自己的分析或交易工具,从而满足我们的特定偏好和目标。赫兹量化交易软件
  Y  j5 f4 f* v- D% z1 J4 F# V简单的 Heiken Ashi 指标( Q3 u3 O5 H! ^4 \
在这一部分中,我们将创建一个用在 MetaTrader 5 上的简单 Heiken Ashi 指标。 该指标应持续检查价格(开盘价、最高价、最低价和收盘价),并执行数学计算,以从而成 haOpen、haHigh、haLow 和 haClose 等数值。 根据计算结果,指标应依据数值在图表上绘制不同颜色的烛条:如果烛条方向看涨,则为蓝色,如果为看跌,则为红色。 烛条应作为子窗口显示在传统图表下方的单独窗口之中。赫兹量化交易软件* B3 `( |& j$ B( `5 e2 L5 M
我们来查看创建此自定义指标需要完成的所有步骤。+ B- L' B9 Z) @) \
通过 #property 和标识符值指定附加参数来确定指标设置,如下所示:
* U3 U/ ^8 g- B+ J" U(indicator_separate_window) 在单独的窗口中显示指标。
6 B0 E; o6 _$ F4 y! N" V(indicator_buffers) 确定指标计算的缓冲区数量。, G4 Q: i$ V. l+ s
(indicator_plots) 确定指标中图形序列的数量。 图形系列是在创建自定义指标时可用的绘图样式。
: Q1 N# w, w/ r/ F& V1 S" t% U(indicator_typeN) 要根据 (ENUM_DRAW_TYPE) 的值确定图形绘图的类型,N 是我们在最后一个参数中确定的图形序列的数量,它从 1 开始。. `1 U2 S, L. R7 \
(indicator_colorN) 确定 N 的颜色,N 也是我们之前确定的图形序列的数量,它从 1 开始。
' p7 Y5 ^4 P! r: m9 ~3 Q(indicator_widthN) 还要确定 N 或图形序列的宽度。9 ^0 h0 g" s+ k% |7 x* x
(indicator_labelN) 确定图形序列 N 的标签设置。, Q9 E% @9 C0 r, T, x3 V
#property indicator_separate_window
$ T. |1 E/ C1 z; c1 ~  g( y  [#property indicator_buffers 5
/ b% Z8 O4 }6 `#property indicator_plots   1
" j7 G$ a0 j- i$ A( \6 e0 V#property indicator_type1   DRAW_COLOR_CANDLES
$ D  q8 ~9 s/ v. T9 E* Q: W#property indicator_color1  clrBlue, clrRed
4 T: A. w; X( m, Z; B#property indicator_width1  2% \. R7 j) J( r, l1 I
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
; y) A7 M, r3 T) p% |- T为指标的五个缓冲区(haOpen、haHigh、haLow、haClose、haColor)创建五个数组,均为双精度类型。
! p' A1 B3 r1 G% [: tdouble haOpen[];
: U2 f7 `1 ?; l: B8 u5 t0 `double haHigh[];
5 q7 i: D! G$ R3 ?double haLow[];2 Z* o6 K; {9 }5 }- G6 C
double haClose[];3 X. |0 i% s5 G9 ^
double haColor[];
8 ]5 W1 T1 L" @+ I  J3 J: @, F在 OnInit() 中,此函数初始化正在运行的指标。
; k" B: h1 @: M! \int OnInit()6 a4 b2 }7 {( T
调用(SetIndexBuffer)函数为双精度类型的一维动态数组的指标缓冲区进行排序。赫兹量化交易软件
0 Z7 F, r- m, U. Q4 H/ M! i( P其参数为:
3 Q- j& K, _7 u( e& t: Lindex: 指标缓冲区从 0 开始的编号,此数字必须小于在参数 (indicator_buffers) 中确定的声明值。- [' s; G* X. I0 ~8 N' `2 h. b
buffer[]: 在我们的自定义指标中声明的数组。7 t9 H8 D( o. {# ?2 A2 `8 p, e
data_type: 我们需要在指标数组中存储的数据类型。2 q. A: v' b+ M5 f7 s7 }
SetIndexBuffer(0,haOpen,INDICATOR_DATA);3 M) e; S( B2 q2 B4 z+ f4 q- G
SetIndexBuffer(1,haHigh,INDICATOR_DATA);" ?' R, s. ~6 S8 R5 G8 c9 ~
SetIndexBuffer(2,haLow,INDICATOR_DATA);
3 ^+ E3 n: T  @( g* ~' o% YSetIndexBuffer(3,haClose,INDICATOR_DATA);- j1 w; A( ^2 b) R7 q$ \% U5 X
SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);
6 C% G0 j, I+ |1 ~通过调用(IndicatorSetInteger)函数和调用变体,设置相应指标属性的值,其中我们指定了属性标识符。 其参数为:
. |, `) t, z; l8 m1 N4 C# ^% Tprop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_INTEGER)之一的属性的标识符,我们将指定(INDICATOR_DIGITS)。
- F5 q0 Q- r! ]$ h7 Fprop_value: 属性的值,我们将指定(_Digits)。
( y! q& \# h1 wIndicatorSetInteger(INDICATOR_DIGITS,_Digits);8 M7 A; e$ \+ |7 S  ]
调用变体设置相应字符串类型属性的值,我们还在其中指定属性标识符。 其参数为:& ?. |) \1 L, ?6 ~/ Y
prop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_STRING)之一的属性标识符,我们将指定 (INDICATOR_SHORTNAME)为指标设置短名称。
" f9 ?2 T' |9 R% hprop_value: 属性的值,我们将指定(“Simple Heiken Ashi”)。- G/ O& t3 O4 A: ~
IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");4 m8 b2 M, s9 B& W% P
调用(PlotIndexSetDouble)函数设置相应指标的对应双精度类型属性值。 其参数为:. h; D; `1 d' D* a+ g& e/ r8 o
plot_index: 图形绘图的索引,我们将指定 0。
- F9 }5 {3 m& Rprop_id:(ENUM_PLOT_PROPERTY_DOUBLE)值之一,对于无绘图,它是(PLOT_EMPTY_VALUE)。- @/ m4 y: h& S; I% n
prop_value: 属性值。) n# O& K# `2 N
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);5 J7 o2 D3 B2 A3 R
然后返回(INIT_SUCCEEDED)作为 OnInit() 函数的一部分,终止它,并返回初始化成功。8 w# I4 p2 u, G3 Q5 W: O& t# I. |# v; f: W
return(INIT_SUCCEEDED);  w+ q; [/ y6 j, x( d. i& q' `) H
在指标中调用的 OnCalculate 函数内部,赫兹量化交易软件3 z; c) s  B% M) {6 B5 H; h
基于当前时间帧的时间序列进行计算,其处理的价格数据随着计算类型而变化。
# l( X8 ^8 u. v  Fint OnCalculate(const int rates_total,* b& r; \% ~  K
const int prev_calculated,7 d# T. N& Q% h- a! N. B
const datetime &time[],, u- O  r! f0 f
const double &open[],
7 c3 d' O# c: ~' [6 o" J& ], hconst double &high[],( Z$ b, a( k8 ^, K/ z
const double &low[],' P2 Y3 T# w/ C2 j- T
const double &close[],
0 X9 |5 N4 u/ g/ \1 Zconst long &tick_volume[],# C" H0 |1 `: A/ a6 ^* I
const long &volume[],
) M: }- N$ e; r6 r/ k2 }5 Kconst int &spread[])* g' ^- }3 U% {
创建一个整数型 “start” 变量,我们稍后将为其赋值:
: h. Y" b+ R" }- O, Lint start;
: D  ~2 D% ~+ U4 _7 f+ @使用 'if' 语句返回索引值(最低价、最高价、开盘价和收盘价),如果 prev_calculated 等于 0,则 start 值 = 1;或把返回的值(prev_calculated-1)分配给 start:. y  v. L7 V# ~& ~& v  M
if(prev_calculated==0)% g7 u9 c& x1 c+ @
{
7 C5 `$ b! S* m* k+ ohaLow[0]=low[0];7 W7 ~1 [2 g1 k# k- g! U9 t
haHigh[0]=high[0];
! j2 Q- J& a* @4 m( ?haOpen[0]=open[0];
$ K* v( T/ c8 F8 nhaClose[0]=close[0];
) \% Z) R' }* u5 D# |  ?start=1;
% ~* Y; F4 z& u5 @9 h; _1 D8 |}/ y2 Y9 a. `/ _' F& |0 A
else4 d& g) A; E, n+ d1 n" y
start=prev_calculated-1;4 ^4 b$ z! f# e
在主循环的 “for” 主体里进行计算,“for” 运算符由三个表达式和可执行运算符组成。
( @. y# g. {( R' U1 y/ W这三个表达式将是:
7 p- I9 h( O3 O1 O: mi=start: 对应起始位置。# G4 p  f4 l7 j" w7 l+ r  v
i<rates_total && !IsStopped(): 完成循环的条件。 IsStopped() 检查指标的强制关闭。7 @. s6 G, y% S8 `2 D( w" G
i++: 加 1 作为新的 i。
& v% \9 j: N+ x8 a- ^我们每次在循环过程中需要执行的操作:9 \0 V. u/ X7 |
计算四个双精度变量- S6 x3 h8 o/ d8 }+ O/ \2 S
haOpenVal: 对应 Heiken Ashi 开盘价。+ s$ r% a- B1 c5 ^8 n. A* J
haCloseVal: 对应 Heiken Ashi 收盘价。
6 Q3 E, K1 G1 X0 I: R- Y7 ohaHighVal: 对应 Heiken Ashi 最高价。3 \+ b% b  g0 t# p$ A1 l! H
haLowVal: 对应 Heiken Ashi 最低价。0 y3 |. z$ I, \) s
在上一步中分配的计算值与以下内容相同
$ ]2 K3 n( a; x1 [4 u/ xhaLow=haLowVal
6 B& {4 e; F2 o4 P8 QhaHigh=haHighVal
! ^; P, P7 V' e$ b) {2 u% OhaOpen=haOpenVal! m' R: D2 y7 }
haClose=haCloseVal
, y. s" }: ^% D, o: D检查 Heiken Ashi 的开盘价是否低于收盘价,我们需要指标绘制蓝色蜡烛;如若不是,我们需要把它绘制为红色烛条。
' E, N9 z" U& \8 lfor(int i=start; i<rates_total && !IsStopped(); i++)
& j2 m8 s/ E- C{
; S' Z! H4 Q" T0 gdouble haOpenVal =(haOpen[i-1]+haClose[i-1])/2;
; v/ f5 t' w2 X! `: |. @! cdouble haCloseVal=(open+high+low+close)/4;
: Y; k6 c* L6 a; W7 Udouble haHighVal =MathMax(high,MathMax(haOpenVal,haCloseVal));7 \- x8 U+ ]4 a2 r2 ], a; q
double haLowVal  =MathMin(low,MathMin(haOpenVal,haCloseVal));
1 S2 \. J5 p$ bhaLow=haLowVal;
6 J; G8 m- N8 O: y4 Y9 T! Q) QhaHigh=haHighVal;; j' p) ^- F) z& D) V
haOpen=haOpenVal;, I, u( ]- \( }/ O
haClose=haCloseVal;
0 Y1 ?2 e0 x( G" ^//--- set candle color0 G- K  ~5 J, N& ?# ]0 S
if(haOpenVal<haCloseVal)
; n0 u* e- s' ]haColor=0.0;- L: m, g' f/ a, s
else
5 J, V& ?* S/ N5 GhaColor=1.0;0 z* e- v3 W! K
}
8 P5 w( E; [9 ~1 J: C% U终止函数,并返回(rates_total)作为下一次调用的 prev_calculated。) I7 b. m0 c& S# g& T3 k
return(rates_total);
+ u/ |) z* B% _- L然后我们编译代码,并确保没有错误。 以下是一个模块中的完整代码:
' ~7 I+ M' i; D: A$ n( a* c, y% Q1 c//+------------------------------------------------------------------++ Q6 k; ?& e6 Q2 J/ E
//|                                             simpleHeikenAshi.mq5 |
& c; f+ ]- D" ?+ q0 F" ~/ g//|                                  Copyright 2023, MetaQuotes Ltd. |/ ~- z5 e1 c1 f4 I7 E# p5 T6 g5 w
//|                                             https://www.mql5.com |
$ g* ^  |+ ]1 j8 A; q//+------------------------------------------------------------------+7 N5 q3 H3 ~  D
#property copyright "Copyright 2023, MetaQuotes Ltd."% g- w- m9 d5 }% F& m/ P3 S( c% L
#property link      "https://www.mql5.com"
6 d* ?2 g! ~3 [5 ]8 ]5 ~#property version   "1.00"  m7 s: u4 e& ]0 O6 J" T
#property indicator_separate_window% ?- h8 K3 |5 k/ ]
#property indicator_buffers 5
0 c3 z& X, P9 c#property indicator_plots   1
/ t: H4 q2 W4 k# R. Q#property indicator_type1   DRAW_COLOR_CANDLES
6 B4 N9 f/ z1 A3 l5 |& A, a#property indicator_color1  clrBlue, clrRed
6 L7 K$ z. V" U1 q; s/ n* U#property indicator_width1  2" B6 R* s: k3 i  E7 f
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
; e) ]$ Q; L' ^double haOpen[];
4 [0 P6 T3 E0 Ndouble haHigh[];
& z1 e4 t) M$ R- Ydouble haLow[];
! I( d" f( E6 k: y2 _double haClose[];( j1 O) l6 I$ c' t. ?3 f
double haColor[];
7 b: q( t. o7 Q* X; \) _; \% y; \int OnInit()( Y4 g: t- R# L3 y
{6 e: S" I  ?! D' \7 i8 Z6 k
SetIndexBuffer(0,haOpen,INDICATOR_DATA);
6 c# s+ R4 L* L7 \* FSetIndexBuffer(1,haHigh,INDICATOR_DATA);
0 D) L/ j+ D% ESetIndexBuffer(2,haLow,INDICATOR_DATA);' s5 A( H2 g7 V& _8 V0 u  h  O
SetIndexBuffer(3,haClose,INDICATOR_DATA);* ^. C0 x) Y1 p* y* }: `9 E# F# d
SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);4 T, ]( j: o2 A: X- u
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
& W1 |+ H; l. w) Y% S$ t! A: ?IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");
' m, d. s* R( [0 sPlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);) D2 R  K' [" @7 X: @* ~# A7 O
return(INIT_SUCCEEDED);
- z  W$ h% W0 u1 J}: a* b' T  B( \, e5 ~# l
int OnCalculate(const int rates_total,
0 v4 J' ?/ H) N! x1 xconst int prev_calculated,
$ W9 B4 t7 Z9 l  C8 A2 F! U0 V+ b7 aconst datetime &time[],
4 X! u: P( w  Q- A3 Q4 |const double &open[],/ X- @* l+ ?" e  W0 E
const double &high[],
9 u0 e7 ~$ A- l- s3 pconst double &low[],
* S* ]& b5 @3 vconst double &close[],% b" h  p8 ~) F5 I5 L3 \% ]
const long &tick_volume[],
; _3 W; y" s1 N% K! v# ?. Tconst long &volume[],
http://www.simu001.cn/x288178x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-16 13:43 , Processed in 1.922415 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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