四目观天下

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

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

[复制链接]
发表于 2024-4-9 08:32:19 | 显示全部楼层 |阅读模式
概述
; u. Z& U$ `5 B0 L* X( t; c我们都需要读取图表,任何可以帮助完成此任务的工具都会受到欢迎。 在有助于读取图表的工具之中,指标计算可基于价格、交易量、其它技术指标、或它们的组合,而在交易世界中存在众多新奇的思路。 我们在交易终端中内置了很多现成的指标,如果我们需要添加一些功能以便能适应我们的交易风格,我们会发现这有一些挑战,因为也许无法更改它,除此之外,我们也许无法在交易终端中的内置指标里找到期望的指标。2 ?0 }8 `5 v  o# ^  i$ Y  j, O; M
赫兹量化交易软件9 }9 \8 O  z0 F9 }
自定义指标和 Heiken Ashi 定义
4 g7 E8 x& \, ^3 ]在这一部分中,我们将更详细地学习自定义指标和 Heiken Ashi 指标。 正如我在上一章节的概述中提到的,自定义指标是用户利用 MQL5 编程语言创建的技术分析工具。 它可以在 MetaTrader 5 中用来分析和明晰市场走势,并有助于做出明智的投资决策。 有许多实用的内置技术指标,但有时我们需要根据一些额外和特定的数学、统计或技术概念来分析和理解市场的行为,而这些概念在内置指标中不存在,或者没有指标可以完成任务。 那么,在这种情况下,我们必须自己创建指标 — 这是 MetaTrader 5 平台的功能之一,因为它可以帮助我们创建自己的分析或交易工具,从而满足我们的特定偏好和目标。赫兹量化交易软件6 F' o+ S# r' e# @2 h
简单的 Heiken Ashi 指标
# t2 ]  l8 [( \# T) {) y在这一部分中,我们将创建一个用在 MetaTrader 5 上的简单 Heiken Ashi 指标。 该指标应持续检查价格(开盘价、最高价、最低价和收盘价),并执行数学计算,以从而成 haOpen、haHigh、haLow 和 haClose 等数值。 根据计算结果,指标应依据数值在图表上绘制不同颜色的烛条:如果烛条方向看涨,则为蓝色,如果为看跌,则为红色。 烛条应作为子窗口显示在传统图表下方的单独窗口之中。赫兹量化交易软件) [4 @2 u* ]* F; `9 J2 ^/ ~4 O! P5 A
我们来查看创建此自定义指标需要完成的所有步骤。
# f6 A7 j5 q$ s. e) o通过 #property 和标识符值指定附加参数来确定指标设置,如下所示:3 B, {8 ~, G6 P$ D, S) [) z
(indicator_separate_window) 在单独的窗口中显示指标。
# [; e" F, @- O* O$ F* S(indicator_buffers) 确定指标计算的缓冲区数量。2 _( W! E( D" ^& `7 ]6 @
(indicator_plots) 确定指标中图形序列的数量。 图形系列是在创建自定义指标时可用的绘图样式。! l! q" i! {7 a
(indicator_typeN) 要根据 (ENUM_DRAW_TYPE) 的值确定图形绘图的类型,N 是我们在最后一个参数中确定的图形序列的数量,它从 1 开始。
! U# P. `4 o2 u" o( ~(indicator_colorN) 确定 N 的颜色,N 也是我们之前确定的图形序列的数量,它从 1 开始。
  B5 M6 e1 @+ g3 ^( S(indicator_widthN) 还要确定 N 或图形序列的宽度。; v, w/ T- y% F# v( ?1 q) Y
(indicator_labelN) 确定图形序列 N 的标签设置。
& w  n7 ]: ~" W6 C( R. ?#property indicator_separate_window
7 ~0 ?2 S& x: Z$ z#property indicator_buffers 5
- F1 v# [. O/ P9 D- S, N+ T#property indicator_plots   1' e& U( }1 x5 K# [
#property indicator_type1   DRAW_COLOR_CANDLES
1 p% [5 c3 P6 c0 M: g3 ^3 Q8 N- G#property indicator_color1  clrBlue, clrRed
) _, g7 b( O% I: M, G5 ^#property indicator_width1  26 u" c7 h2 C0 p; G3 j- o
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"7 Y0 L. o$ }$ \. o+ Y
为指标的五个缓冲区(haOpen、haHigh、haLow、haClose、haColor)创建五个数组,均为双精度类型。
0 Q+ c- L9 e5 L. ^7 v3 f8 P/ Xdouble haOpen[];
' P. m$ J& F8 E8 [% @double haHigh[];. h" D4 p9 {- ^  l5 Q
double haLow[];( R3 G, o; }* }$ x# k, z
double haClose[];
) l- Q8 u, ^& |! [double haColor[];
# [( `, r  s- _6 w在 OnInit() 中,此函数初始化正在运行的指标。
% {, N: t4 R- e/ \+ nint OnInit()
. u! {( q  T7 O调用(SetIndexBuffer)函数为双精度类型的一维动态数组的指标缓冲区进行排序。赫兹量化交易软件2 j  K# i# T+ }5 A
其参数为:
. B7 ^% N$ K3 Y$ X& ^$ |index: 指标缓冲区从 0 开始的编号,此数字必须小于在参数 (indicator_buffers) 中确定的声明值。
9 X+ ^+ p5 a0 |( e- tbuffer[]: 在我们的自定义指标中声明的数组。- g6 q. ~# J; P/ b. M9 ?& q& j
data_type: 我们需要在指标数组中存储的数据类型。
4 w2 U9 x5 ?8 k1 \SetIndexBuffer(0,haOpen,INDICATOR_DATA);
, z! {1 A/ Y9 ~9 i5 D, zSetIndexBuffer(1,haHigh,INDICATOR_DATA);
: q$ o: n7 _! T1 g. V# YSetIndexBuffer(2,haLow,INDICATOR_DATA);) Z% Q7 Q/ Y+ b/ y
SetIndexBuffer(3,haClose,INDICATOR_DATA);
5 Z3 o. ^7 `4 ASetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);$ C: H' B2 m# F$ G) b
通过调用(IndicatorSetInteger)函数和调用变体,设置相应指标属性的值,其中我们指定了属性标识符。 其参数为:
# f! N- ^; ~3 H/ j# t. ~+ eprop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_INTEGER)之一的属性的标识符,我们将指定(INDICATOR_DIGITS)。
1 Q; E& b: ^" {' l8 _0 Q! Tprop_value: 属性的值,我们将指定(_Digits)。
0 _5 s5 o1 Q9 q! I$ s' a' k( KIndicatorSetInteger(INDICATOR_DIGITS,_Digits);
! Z  C  w. |2 x0 m' G调用变体设置相应字符串类型属性的值,我们还在其中指定属性标识符。 其参数为:
6 R6 O' @+ X! @prop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_STRING)之一的属性标识符,我们将指定 (INDICATOR_SHORTNAME)为指标设置短名称。
8 {( y  p4 f" \1 K# Zprop_value: 属性的值,我们将指定(“Simple Heiken Ashi”)。
4 O" l; n7 d% W' sIndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");
8 ]' x8 G9 O7 e. S* l调用(PlotIndexSetDouble)函数设置相应指标的对应双精度类型属性值。 其参数为:
  O, Z; e' I* A3 p" [plot_index: 图形绘图的索引,我们将指定 0。
3 c, d) g5 t" O7 rprop_id:(ENUM_PLOT_PROPERTY_DOUBLE)值之一,对于无绘图,它是(PLOT_EMPTY_VALUE)。
2 F7 N' @- H6 Dprop_value: 属性值。
3 P0 G: _" r! \5 ]! K' u3 fPlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
: G- j# q* |8 Y  ~9 ]' h) v然后返回(INIT_SUCCEEDED)作为 OnInit() 函数的一部分,终止它,并返回初始化成功。
! ]1 b& s' u+ k0 `: C( }7 Sreturn(INIT_SUCCEEDED);
8 e! v4 f" x! ?+ m# m' r在指标中调用的 OnCalculate 函数内部,赫兹量化交易软件
3 I  G# [" Y% o# m- n) U基于当前时间帧的时间序列进行计算,其处理的价格数据随着计算类型而变化。) ~2 C9 J" F" ]5 v2 a' \; V) ^
int OnCalculate(const int rates_total,7 p- e8 H7 \8 ]2 c2 P& `
const int prev_calculated,- j4 ~2 p$ U. k5 i2 B8 u) @) [
const datetime &time[]," l6 J/ k+ l; o- C% y1 H& f
const double &open[],' ]& S5 T  q) V. j5 y9 G
const double &high[],
9 s! Y  e( l( G0 nconst double &low[],
! F* x# F( V+ B2 V; t: vconst double &close[],2 R  }; C) B, h6 J
const long &tick_volume[],
8 X! G6 {2 z/ f0 ~5 gconst long &volume[],
; o( h" y2 o& k* _# a: \const int &spread[])
0 D& F& J8 }8 V+ h3 P创建一个整数型 “start” 变量,我们稍后将为其赋值:+ z" H" i6 w; I! f+ M! b3 @# A
int start;% y, s& z6 e6 J5 `4 ~3 ~
使用 'if' 语句返回索引值(最低价、最高价、开盘价和收盘价),如果 prev_calculated 等于 0,则 start 值 = 1;或把返回的值(prev_calculated-1)分配给 start:, q2 \8 n2 u+ C( S8 R
if(prev_calculated==0)3 U5 V% X0 [" M+ R
{0 E0 s" t4 z; j3 Q9 S; U; j
haLow[0]=low[0];4 \; s( T# ~5 j8 v( r1 ^1 J1 o
haHigh[0]=high[0];
' l) u. d9 y# {5 XhaOpen[0]=open[0];( [) x* @8 Q; D3 l' v0 n- N
haClose[0]=close[0];* z7 ?& D9 }# l/ g1 K
start=1;$ t7 J/ g4 f# U3 u% q! [7 `
}
& Q& i- |: B9 C" N8 D+ w$ Eelse& c3 ~% g6 b0 E# R
start=prev_calculated-1;9 D; K% m; ~7 x# H$ A1 w* g$ V
在主循环的 “for” 主体里进行计算,“for” 运算符由三个表达式和可执行运算符组成。: k9 v# ~9 n& I+ d+ W7 P* y
这三个表达式将是:- g2 W5 {: @9 ?
i=start: 对应起始位置。4 }2 O+ w$ G1 q1 l
i<rates_total && !IsStopped(): 完成循环的条件。 IsStopped() 检查指标的强制关闭。+ U+ f: G6 \* F5 n
i++: 加 1 作为新的 i。3 i0 h1 h$ P- x  [+ d
我们每次在循环过程中需要执行的操作:8 Y  I0 ~' R+ g+ h! f
计算四个双精度变量5 j4 T8 q* V; g. z( P
haOpenVal: 对应 Heiken Ashi 开盘价。
5 ~5 q' `3 E7 f- o! J7 ?  f5 L( RhaCloseVal: 对应 Heiken Ashi 收盘价。& x) y9 {6 I; Q1 [* a& }7 l* I
haHighVal: 对应 Heiken Ashi 最高价。
# d+ H  J* i* q% ~7 m( JhaLowVal: 对应 Heiken Ashi 最低价。
% N4 e, N) l& d% ]( G! C, {在上一步中分配的计算值与以下内容相同0 i8 X! H: ]4 B, z' S6 k# Q
haLow=haLowVal
3 v/ a* k( s) ~; `& ?; z4 P7 QhaHigh=haHighVal
8 v9 H* ]6 Q  }1 |haOpen=haOpenVal
* a) P0 e: L; L. YhaClose=haCloseVal
; A$ {1 u7 y4 X; u检查 Heiken Ashi 的开盘价是否低于收盘价,我们需要指标绘制蓝色蜡烛;如若不是,我们需要把它绘制为红色烛条。
, _) R1 ^8 {- O7 Z' sfor(int i=start; i<rates_total && !IsStopped(); i++)2 G# c4 g, f8 t0 m! B2 @3 w
{- ^; R  S0 d4 C3 u6 @( ]  i
double haOpenVal =(haOpen[i-1]+haClose[i-1])/2;4 L8 n! t7 b5 T( _' D9 r. Y
double haCloseVal=(open+high+low+close)/4;
% \8 C* Z! V( V" v9 C5 udouble haHighVal =MathMax(high,MathMax(haOpenVal,haCloseVal));; s! y. a) n+ k  b& g" C( B' w3 f
double haLowVal  =MathMin(low,MathMin(haOpenVal,haCloseVal));# _" l4 \/ V/ x+ R- p* M% l
haLow=haLowVal;
8 g3 W* l* r/ L5 r/ m* C" r$ B7 {haHigh=haHighVal;
0 u+ ~: c6 O1 }6 R9 JhaOpen=haOpenVal;
$ G1 T" o$ i* i& L, s- O) m' ChaClose=haCloseVal;
% J4 w& E( m% ~& U9 S& M//--- set candle color  j5 ]) k9 N7 o9 n8 k
if(haOpenVal<haCloseVal)
& U6 D4 |2 _( @haColor=0.0;# B" d- N* S- l
else% v9 j3 f+ M, s5 s: I5 Y* y) E
haColor=1.0;
% l) z# e, b/ c$ r}
, F6 |1 l: s- J* J$ s; ]终止函数,并返回(rates_total)作为下一次调用的 prev_calculated。8 Z# d  k. ^: s
return(rates_total);9 s5 f3 P+ ?$ B
然后我们编译代码,并确保没有错误。 以下是一个模块中的完整代码:
$ ~( U$ H/ [5 H//+------------------------------------------------------------------+) Z. D. X7 U' W5 `: t
//|                                             simpleHeikenAshi.mq5 |8 ~" T% s# p/ z7 X/ k8 @0 [
//|                                  Copyright 2023, MetaQuotes Ltd. |# Q" G  ]9 `) a4 }( W: ^
//|                                             https://www.mql5.com |0 }- E1 z6 E7 Z! y
//+------------------------------------------------------------------+) h6 p' Y% |$ C6 N$ K# x
#property copyright "Copyright 2023, MetaQuotes Ltd."
% @, ~7 O/ |7 f& V* P#property link      "https://www.mql5.com"& S( y% V+ ~- ~4 j6 w
#property version   "1.00"" J; Q) w- @8 M2 I: ]2 `
#property indicator_separate_window
0 a6 r7 v& O$ F) o: U- i- S+ b#property indicator_buffers 50 B" V& f0 w+ _% V2 f- e0 }% K, V
#property indicator_plots   1
( x* _- U( f# S% W#property indicator_type1   DRAW_COLOR_CANDLES0 R+ x4 v/ U% R  s! \' u9 ?/ N) p# B
#property indicator_color1  clrBlue, clrRed; L0 v; N# H3 Y8 o3 _+ ]+ d
#property indicator_width1  28 ?  f* M( x* m9 ?/ J! M
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
* h: B* W$ D) U& l9 y. L* [double haOpen[];
6 j4 p5 t- B- U3 e" Idouble haHigh[];
" c9 G; h' o9 R9 l2 X( P/ ]double haLow[];
- M& Z8 t+ \' v% O" U; i& f6 Rdouble haClose[];9 k0 G/ z& J6 O/ S& ^& {( v0 ]
double haColor[];3 @2 ~) I& Z  s& x5 a! f
int OnInit()$ g( w$ t* q' q
{
  d. K5 {7 }6 O0 v: _/ e* c2 DSetIndexBuffer(0,haOpen,INDICATOR_DATA);
& h" s: K+ A5 B' bSetIndexBuffer(1,haHigh,INDICATOR_DATA);
! r/ v# p: `* r- {- d2 D6 ISetIndexBuffer(2,haLow,INDICATOR_DATA);
+ I7 A: H- F3 x4 xSetIndexBuffer(3,haClose,INDICATOR_DATA);
) ~. R1 T( M) x% p+ @/ BSetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);4 v; _, P2 F( C: D4 p# M
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);& L- f' D) d' N0 F  ]& c/ M3 a! Y& q
IndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");% e/ q  z1 [0 [# V' E* r( |" U, b! i
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
+ |1 z5 ~1 b" q1 D9 c6 Y8 Kreturn(INIT_SUCCEEDED);
" k- s& i' l0 U; ^. M) Q$ {3 u}; z; w! l0 F$ ^- t. A2 A. ]
int OnCalculate(const int rates_total,' @4 T- a% N4 q
const int prev_calculated,; n7 L, d. {9 Y) z, M) ^- c; @" `" r
const datetime &time[],* m  D2 `- P8 ^% v* @9 b
const double &open[],: }! s2 G% O2 }' p9 A
const double &high[],
2 c: V, l. t/ n; vconst double &low[],
+ o4 c. ]7 W/ ^( ?const double &close[],
8 A" z+ A9 C% t; N  E- i# Cconst long &tick_volume[],% _5 \1 D2 I# Z+ ?$ o+ l! g( U
const long &volume[],
http://www.simu001.cn/x288178x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-29 17:35 , Processed in 0.827945 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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