四目观天下

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

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

[复制链接]
发表于 2024-4-9 08:32:19 | 显示全部楼层 |阅读模式
概述: p' z5 F5 p# [. j" D* n. x* s# y# Y6 T
我们都需要读取图表,任何可以帮助完成此任务的工具都会受到欢迎。 在有助于读取图表的工具之中,指标计算可基于价格、交易量、其它技术指标、或它们的组合,而在交易世界中存在众多新奇的思路。 我们在交易终端中内置了很多现成的指标,如果我们需要添加一些功能以便能适应我们的交易风格,我们会发现这有一些挑战,因为也许无法更改它,除此之外,我们也许无法在交易终端中的内置指标里找到期望的指标。
5 r& Z7 X$ i! U赫兹量化交易软件. T1 G" Z5 x- T& O% O' N3 T; v
自定义指标和 Heiken Ashi 定义/ ~# s0 }; q/ a7 C
在这一部分中,我们将更详细地学习自定义指标和 Heiken Ashi 指标。 正如我在上一章节的概述中提到的,自定义指标是用户利用 MQL5 编程语言创建的技术分析工具。 它可以在 MetaTrader 5 中用来分析和明晰市场走势,并有助于做出明智的投资决策。 有许多实用的内置技术指标,但有时我们需要根据一些额外和特定的数学、统计或技术概念来分析和理解市场的行为,而这些概念在内置指标中不存在,或者没有指标可以完成任务。 那么,在这种情况下,我们必须自己创建指标 — 这是 MetaTrader 5 平台的功能之一,因为它可以帮助我们创建自己的分析或交易工具,从而满足我们的特定偏好和目标。赫兹量化交易软件# V8 g0 B6 p5 |6 f$ X0 U7 W
简单的 Heiken Ashi 指标
; e+ Q$ I0 j  N7 ]* B! w在这一部分中,我们将创建一个用在 MetaTrader 5 上的简单 Heiken Ashi 指标。 该指标应持续检查价格(开盘价、最高价、最低价和收盘价),并执行数学计算,以从而成 haOpen、haHigh、haLow 和 haClose 等数值。 根据计算结果,指标应依据数值在图表上绘制不同颜色的烛条:如果烛条方向看涨,则为蓝色,如果为看跌,则为红色。 烛条应作为子窗口显示在传统图表下方的单独窗口之中。赫兹量化交易软件& b8 D$ d# Q* E4 ]5 w3 d8 [
我们来查看创建此自定义指标需要完成的所有步骤。
* {; g- x* B  \8 }  }1 K* @% o% n通过 #property 和标识符值指定附加参数来确定指标设置,如下所示:4 G5 a( |6 o$ v
(indicator_separate_window) 在单独的窗口中显示指标。, k; N5 k! k+ c+ F" q! g8 S1 ]
(indicator_buffers) 确定指标计算的缓冲区数量。
: R$ b3 ]4 H8 |* t4 n( p) y  ?4 Q(indicator_plots) 确定指标中图形序列的数量。 图形系列是在创建自定义指标时可用的绘图样式。
  B1 W8 k2 c7 P% u* W(indicator_typeN) 要根据 (ENUM_DRAW_TYPE) 的值确定图形绘图的类型,N 是我们在最后一个参数中确定的图形序列的数量,它从 1 开始。. }: }% T% }" H, X/ U/ X" X
(indicator_colorN) 确定 N 的颜色,N 也是我们之前确定的图形序列的数量,它从 1 开始。
. k+ ~  g. B8 o. I(indicator_widthN) 还要确定 N 或图形序列的宽度。* y7 ~8 M' d* O, T6 C6 `0 K
(indicator_labelN) 确定图形序列 N 的标签设置。
4 h6 J) o; M3 @#property indicator_separate_window% T4 f  b7 m3 j- ]# X5 F
#property indicator_buffers 5
2 m" ^; G; W& M  _1 c#property indicator_plots   1: \2 B" v/ _2 V8 r* |
#property indicator_type1   DRAW_COLOR_CANDLES
, u0 U2 q' T' v- ^) @#property indicator_color1  clrBlue, clrRed# k7 x1 V: ?% E
#property indicator_width1  29 O, [$ }) N: E7 r! I/ s
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
! L; E2 @% \, A为指标的五个缓冲区(haOpen、haHigh、haLow、haClose、haColor)创建五个数组,均为双精度类型。8 ~3 ^7 s) d7 V! l. v
double haOpen[];% m5 Q! t! K3 _3 @0 C' e
double haHigh[];: {" {5 A* D7 R, N6 G4 A# ]
double haLow[];
; j5 U9 {- z1 E, D% }; Vdouble haClose[];8 T1 \' O$ S% W; r
double haColor[];
9 [6 z5 N! u3 G# u5 L8 b2 O在 OnInit() 中,此函数初始化正在运行的指标。" x0 d% B' e" R; N4 I4 K& D
int OnInit()3 L' o& D; l% [7 Q0 o
调用(SetIndexBuffer)函数为双精度类型的一维动态数组的指标缓冲区进行排序。赫兹量化交易软件
) F0 o9 ^4 k9 @# d其参数为:1 [, {7 m* C) ]# d! S
index: 指标缓冲区从 0 开始的编号,此数字必须小于在参数 (indicator_buffers) 中确定的声明值。' t8 l$ d2 q, ^" _* @- C2 ?
buffer[]: 在我们的自定义指标中声明的数组。2 M7 X- e% B3 x5 h
data_type: 我们需要在指标数组中存储的数据类型。
; b5 H$ S& @0 E' aSetIndexBuffer(0,haOpen,INDICATOR_DATA);# P3 G: Z& N8 m
SetIndexBuffer(1,haHigh,INDICATOR_DATA);5 }* `: }" `5 e. ^$ K
SetIndexBuffer(2,haLow,INDICATOR_DATA);
" b* @* [: v3 ?/ o" X/ u$ dSetIndexBuffer(3,haClose,INDICATOR_DATA);
( F, j1 E5 G. ~" N3 s7 [SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);
0 ]0 A2 D# Q: M$ H- H: _通过调用(IndicatorSetInteger)函数和调用变体,设置相应指标属性的值,其中我们指定了属性标识符。 其参数为:
. r3 F- w9 q" F! ^# U3 B# Vprop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_INTEGER)之一的属性的标识符,我们将指定(INDICATOR_DIGITS)。3 I- U9 O, i! b" h
prop_value: 属性的值,我们将指定(_Digits)。
( V6 \+ T# w5 W% h4 ~: GIndicatorSetInteger(INDICATOR_DIGITS,_Digits);6 l2 T# Z" p6 v# h5 e+ H
调用变体设置相应字符串类型属性的值,我们还在其中指定属性标识符。 其参数为:
8 a8 H) W& `% |% b4 m$ |- k- A4 Vprop_id: 可以是(ENUM_CUSTOMIND_PROPERTY_STRING)之一的属性标识符,我们将指定 (INDICATOR_SHORTNAME)为指标设置短名称。
1 A; Z, p+ _- a4 l( C& Qprop_value: 属性的值,我们将指定(“Simple Heiken Ashi”)。
) G+ ]3 m3 K" K% ?0 t7 oIndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");
/ B4 d' q9 t2 W4 s% ~' X调用(PlotIndexSetDouble)函数设置相应指标的对应双精度类型属性值。 其参数为:
% ^4 Q1 L( {: @" o% tplot_index: 图形绘图的索引,我们将指定 0。
6 D# ]. |5 n% Q2 E) z( J8 Zprop_id:(ENUM_PLOT_PROPERTY_DOUBLE)值之一,对于无绘图,它是(PLOT_EMPTY_VALUE)。% n" N2 n, E5 o& B9 v$ }. O1 G& s! ~
prop_value: 属性值。
& y' W0 s! _3 Z. N/ LPlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
) C" Q' s4 K6 w$ o; u/ v# n8 x然后返回(INIT_SUCCEEDED)作为 OnInit() 函数的一部分,终止它,并返回初始化成功。' b$ o" y) z; l$ Y0 ?2 _8 ^
return(INIT_SUCCEEDED);/ i9 f) s( j+ y! O6 b* Z, P
在指标中调用的 OnCalculate 函数内部,赫兹量化交易软件
7 b$ \6 Z6 |7 ?4 f, O基于当前时间帧的时间序列进行计算,其处理的价格数据随着计算类型而变化。
& c; V+ P& M9 {3 y1 Aint OnCalculate(const int rates_total,
  @6 c% s9 Y3 n/ J: oconst int prev_calculated,4 y" e; N, c1 ?+ k6 ^* d
const datetime &time[],
* M/ m- z7 ~# R" Pconst double &open[],* ~7 a2 m4 p# Y9 t8 M: L
const double &high[],6 ]2 J8 c8 f, }) n
const double &low[],8 n3 H3 u8 p0 a' r
const double &close[],4 r  T: h4 f- W; A! l% [" D
const long &tick_volume[],
( [+ t0 ?0 `$ Jconst long &volume[],. M* ?3 J+ _5 M5 z" C* V& y
const int &spread[])
6 y6 E% i. e# u1 f/ R/ L# s7 z创建一个整数型 “start” 变量,我们稍后将为其赋值:
8 {, V; H- Z7 Y$ ~int start;$ C/ z8 D$ y% U* |
使用 'if' 语句返回索引值(最低价、最高价、开盘价和收盘价),如果 prev_calculated 等于 0,则 start 值 = 1;或把返回的值(prev_calculated-1)分配给 start:
5 ]/ `' j& h* B' e4 c7 P- V7 \if(prev_calculated==0)
/ v% `- A( _, g3 X3 v! y5 e/ j0 M{
; a& Z2 L- `; X1 q2 uhaLow[0]=low[0];
" T+ @9 Z) G8 v- q4 v5 ihaHigh[0]=high[0];
/ a" w  j+ Q& ?, @  @8 q: E: r* F% qhaOpen[0]=open[0];
  o5 Z; H/ j2 ^- fhaClose[0]=close[0];
# @4 [' t7 v5 h. X  |2 Z# r6 V3 Qstart=1;4 m: g/ `  N& T8 v; H+ {
}
) {0 w+ D2 K# p- f& yelse  V+ V4 w' ?6 C  V3 ^! X
start=prev_calculated-1;
7 b% c( F1 R7 l在主循环的 “for” 主体里进行计算,“for” 运算符由三个表达式和可执行运算符组成。
' Y, |9 `3 d/ x这三个表达式将是:8 ]" |7 @5 T- P8 x9 i
i=start: 对应起始位置。; i& U' @- |; |8 g, l- O) g
i<rates_total && !IsStopped(): 完成循环的条件。 IsStopped() 检查指标的强制关闭。; A) Y4 _& e; f
i++: 加 1 作为新的 i。( U& R; C+ \; Y
我们每次在循环过程中需要执行的操作:" @, H1 u  ]* ^$ v$ Q' c
计算四个双精度变量
1 \& d" i6 @" L" l+ E7 ZhaOpenVal: 对应 Heiken Ashi 开盘价。
" o& v: |6 p. z) OhaCloseVal: 对应 Heiken Ashi 收盘价。$ [& L& R0 {: V4 }4 c
haHighVal: 对应 Heiken Ashi 最高价。& T0 r& P, ?; R* `* a4 c
haLowVal: 对应 Heiken Ashi 最低价。6 c) w" N5 @3 U% \& Q7 z
在上一步中分配的计算值与以下内容相同5 O; V) _2 G" K. I% y
haLow=haLowVal
# ?1 t/ I- ^& @haHigh=haHighVal
* Y$ b- g* T; f- AhaOpen=haOpenVal
+ Z( M) {* a8 \& W' \+ _haClose=haCloseVal+ a+ T0 g0 V) L% U2 g& X, C. O
检查 Heiken Ashi 的开盘价是否低于收盘价,我们需要指标绘制蓝色蜡烛;如若不是,我们需要把它绘制为红色烛条。8 G# S/ w2 T" E* Y- I
for(int i=start; i<rates_total && !IsStopped(); i++)
: P4 _# F. m: C0 p# \{. J$ x! A/ z, v) t3 ~1 Y9 B
double haOpenVal =(haOpen[i-1]+haClose[i-1])/2;
# C: A& |/ @4 ]. {* Q# D! B9 s$ K0 B9 bdouble haCloseVal=(open+high+low+close)/4;
) d$ ]$ d6 U- A$ g. zdouble haHighVal =MathMax(high,MathMax(haOpenVal,haCloseVal));
( W( G8 Y5 c% ]. r' l1 c& Hdouble haLowVal  =MathMin(low,MathMin(haOpenVal,haCloseVal));9 r. }8 h* e4 X/ E0 B, I% ?* O
haLow=haLowVal;
( `2 `6 L" D6 z+ k( shaHigh=haHighVal;- k5 m: O) E0 p0 H) R8 Z
haOpen=haOpenVal;4 n; _& k, \9 k2 W7 b+ Z
haClose=haCloseVal;$ F8 N' d. ^0 b: P
//--- set candle color% K! _9 h' d- M. [
if(haOpenVal<haCloseVal)$ j$ d; L0 G0 x1 H. t* ]
haColor=0.0;
7 ?. Z  F8 N4 V- T9 Z$ delse1 r# g8 H* |6 L0 c5 d# k8 v/ O
haColor=1.0;$ c  o2 f( c/ M! L+ C' y8 P' Q5 q
}
6 ]- p8 B) m% D" v$ @. T终止函数,并返回(rates_total)作为下一次调用的 prev_calculated。7 F% u2 {; `' s# u, y& n2 @
return(rates_total);* k) X7 T9 W7 {' x
然后我们编译代码,并确保没有错误。 以下是一个模块中的完整代码:
  j4 s; u; G9 \- h$ l9 l//+------------------------------------------------------------------+
, Y) L8 u- w0 ^( ]' \6 Q; A//|                                             simpleHeikenAshi.mq5 |
) O0 q; o/ R2 @8 s0 k/ K' U//|                                  Copyright 2023, MetaQuotes Ltd. |  [1 a- `8 [2 X, m7 g6 {1 `1 s3 l
//|                                             https://www.mql5.com |
; M6 A) B/ N! {//+------------------------------------------------------------------+# U" Q9 ^0 I5 @3 L# `
#property copyright "Copyright 2023, MetaQuotes Ltd."
1 {4 J! g# x) [! ~& Q8 l: Q#property link      "https://www.mql5.com"( H5 I# X! U. {. P/ x6 d
#property version   "1.00"
% X+ w% x3 K# u2 o#property indicator_separate_window
9 i! P3 r& P0 h7 t$ r7 s, h#property indicator_buffers 5/ e7 ]3 y* @# ^+ v8 j
#property indicator_plots   12 h% W1 D( K8 ?- O, o" y  ~1 ?1 B
#property indicator_type1   DRAW_COLOR_CANDLES
- d' \$ Q- o7 f2 K! O#property indicator_color1  clrBlue, clrRed
) X5 X! ?/ }: a9 s#property indicator_width1  2
4 d' a8 n* U# m* b7 I( ?" ]0 Z' B#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"1 {* P- k9 r  ?
double haOpen[];- d0 X. u9 N# ~- e; x
double haHigh[];& b" Z- u0 B* d5 c
double haLow[];
5 i2 _4 V9 Z/ h& g! ]1 ^! ddouble haClose[];3 y0 q. x  Q. H  n/ F; Y
double haColor[];
0 O* [* A" a0 B- Eint OnInit()
- z! _3 o" _( |2 `) o{
5 H6 `* [1 V# d% S. YSetIndexBuffer(0,haOpen,INDICATOR_DATA);
7 h4 y& M9 _% B! b- FSetIndexBuffer(1,haHigh,INDICATOR_DATA);9 T9 |' \$ R5 |4 Q- I: x+ ~6 N
SetIndexBuffer(2,haLow,INDICATOR_DATA);
4 G- {+ t0 [- KSetIndexBuffer(3,haClose,INDICATOR_DATA);. x! b4 y9 a8 Y/ A8 s
SetIndexBuffer(4,haColor,INDICATOR_COLOR_INDEX);
6 B& ]# E. ]* O  D- aIndicatorSetInteger(INDICATOR_DIGITS,_Digits);
, _) C" I" ^- sIndicatorSetString(INDICATOR_SHORTNAME,"Simple Heiken Ashi");- l3 C0 J9 k% o
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
! W( K( Y  U+ d" Freturn(INIT_SUCCEEDED);
; V* D+ y% P" U2 c( ?; t}
* s. W, V1 e+ J+ @2 Oint OnCalculate(const int rates_total,( @+ o& q8 n3 B, R
const int prev_calculated,& C# S" F3 O) g$ P
const datetime &time[],
0 E9 ]5 t1 {2 ^* econst double &open[],2 i3 T% [' }0 T# k7 H9 v) P$ y
const double &high[],
- a( \' C% Z, N- G, i! r- P7 }const double &low[],
0 p) L( C6 C# ]2 sconst double &close[],
# \) C3 R3 D' \2 M$ X# rconst long &tick_volume[],) j8 `. x- S) C) g" R
const long &volume[],
http://www.simu001.cn/x288178x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-3 20:42 , Processed in 4.916208 second(s), 32 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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