MT4 Series array

这篇博客探讨了MT4平台中时间序列的概念,详细介绍了Time[]系列数组的使用,包括其元素如何以反向索引存储,从当前条目(索引0)到最旧条目(索引 Bars-1)。内容还涵盖了动态数组、静态分布数组、内存分配操作,以及如何通过ArraySetAsSeries()改变数组索引方向。同时,讨论了在指标中接收价格数据、异步访问、数据存储以及确保终端和服务器数据同步的方法。

时间序列

datetime Time[]


Series array that contains open time of each bar of the current chart. Data like datetime represent time, in seconds, that has passed since 00:00 a.m. of 1 January, 1970.

Series array elements are indexed in the reverse order, i.e., from the last one to the first one. The current bar which is the last in the array is indexed as 0. the oldest bar, the first in the chart, is indexed as Bars-1.


Access to Timeseries and Indicator Data

dynamic arrays

An indicator buffer is a dynamic array of type double, whose size is managed by the client terminals

statically distributed arrays

operations of memory allocations

indexing direction in Arrays, Buffers and Timeseries

The default indexing of all arrays and indicator buffers is left to right. The index of the first element is always equal to zero.

changing the indexing direction: ArraySetAsSeries()

Receiving Price Data in indicators

asynchronous access

Organizing Data Access

Receiving data from a trade server

packed blocks of minute bars

Storing intermediate data

unpack

Synchronization of the terminal data and server data

Obtaining data on a necessary timeframe out of intermediate data

Symbol Properties

MarketInfo(_Symbol, MODE_DIGITS);

SymbolInfoInteger(_Symbol, );

SymbolInfoDouble();

SymbolInfoString();

#property copyright "Converted from WenHua Finance Indicator" #property link "" #property version "1.00" #property description "TR1-based Trend Indicator with HH/LL Bands" #property indicator_chart_window #property indicator_buffers 11 #property indicator_plots 2 #property indicator_label1 "WWW" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_width1 3 #property indicator_label2 "WWW1" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_width2 3 // 输入参数 input int EMA_Period = 2; // TR的EMA周期 input int Lookback = 144; // 高低点回溯周期 input double Multiplier = 1.25; // TR乘数 // 指标缓冲区 double TR1Buffer[]; double TRBuffer[]; double MEDIANBuffer[]; double HHBuffer[]; double LLBuffer[]; double WBuffer[]; double BBXBuffer[]; double SSXBuffer[]; double WWBuffer[]; double WWWBuffer[]; // 红色线 (W<0) double WWW1Buffer[]; // 蓝色线 (W>0) // 临时存储数组 double cond1Array[]; double cond2Array[]; double barslast1Array[]; double barslast2Array[]; double barslastNegArray[]; double barslastPosArray[]; int OnInit() { // 设置指标缓冲区 SetIndexBuffer(0, WWWBuffer, INDICATOR_DATA); SetIndexBuffer(1, WWW1Buffer, INDICATOR_DATA); SetIndexBuffer(2, TR1Buffer, INDICATOR_CALCULATIONS); SetIndexBuffer(3, TRBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(4, MEDIANBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(5, HHBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(6, LLBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(7, WBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(8, BBXBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(9, SSXBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(10, WWBuffer, INDICATOR_CALCULATIONS); // 设置绘图属性 PlotIndexSetString(0, PLOT_LABEL, "WWW (Down)"); PlotIndexSetString(1, PLOT_LABEL, "WWW1 (Up)"); // 设置指标在实时K线显示 PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, Lookback); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, Lookback); // 初始化空值 ArrayInitialize(WWWBuffer, EMPTY_VALUE); ArrayInitialize(WWW1Buffer, EMPTY_VALUE); return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // 检查最小数据量 if (rates_total < Lookback) return(0); // 设置数组方向 ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(TR1Buffer, true); ArraySetAsSeries(TRBuffer, true); ArraySetAsSeries(MEDIANBuffer, true); ArraySetAsSeries(HHBuffer, true); ArraySetAsSeries(LLBuffer, true); ArraySetAsSeries(WBuffer, true); ArraySetAsSeries(BBXBuffer, true); ArraySetAsSeries(SSXBuffer, true); ArraySetAsSeries(WWBuffer, true); ArraySetAsSeries(WWWBuffer, true); ArraySetAsSeries(WWW1Buffer, true); // 调整数组大小 ArrayResize(cond1Array, rates_total); ArrayResize(cond2Array, rates_total); ArrayResize(barslast1Array, rates_total); ArrayResize(barslast2Array, rates_total); ArrayResize(barslastNegArray, rates_total); ArrayResize(barslastPosArray, rates_total); // 修复1:确保所有数组初始化 ArrayInitialize(cond1Array, 0); ArrayInitialize(cond2Array, 0); ArrayInitialize(barslast1Array, -1); ArrayInitialize(barslast2Array, -1); ArrayInitialize(barslastNegArray, -1); ArrayInitialize(barslastPosArray, -1); // 修复2:正确设置计算起点(包含所有K线) int start = (prev_calculated < Lookback) ? Lookback : prev_calculated - 1; if (start < Lookback) start = Lookback; if (start < 1) start = 1; for (int i = start; i < rates_total; i++) { // 1. 计算TR1 if (i == 0) { TR1Buffer[i] = high[i] - low[i]; } else { double d1 = high[i] - low[i]; double d2 = MathAbs(close[i-1] - high[i]); double d3 = MathAbs(close[i-1] - low[i]); TR1Buffer[i] = MathMax(MathMax(d1, d2), d3); } // 2. 计算TR (EMA) if (i == 0) { TRBuffer[i] = TR1Buffer[i]; } else { TRBuffer[i] = (2.0/(EMA_Period+1)) * TR1Buffer[i] + (1 - 2.0/(EMA_Period+1)) * TRBuffer[i-1]; } // 3. 计算中值和上下轨 MEDIANBuffer[i] = (high[i] + low[i]) / 2.0; HHBuffer[i] = MEDIANBuffer[i] + TRBuffer[i] * Multiplier; LLBuffer[i] = MEDIANBuffer[i] - TRBuffer[i] * Multiplier; // 4. 计算144周期高低点 int startIdx = MathMax(i - Lookback + 1, 0); int count = i - startIdx + 1; double highestHigh = high[ArrayMaximum(high, startIdx, count)]; double lowestLow = low[ArrayMinimum(low, startIdx, count)]; // 5. 条件判断 cond1Array[i] = (HHBuffer[i] >= highestHigh) ? 1 : 0; cond2Array[i] = (lowestLow >= LLBuffer[i]) ? 1 : 0; // 6. 计算BARSLAST(条件) // 使用更高效的查找方法 int lastCond1 = -1; for (int j = i; j >= 0; j--) { if (cond1Array[j] == 1) { lastCond1 = j; break; } } barslast1Array[i] = (lastCond1 != -1) ? (i - lastCond1) : -1; int lastCond2 = -1; for (int j = i; j >= 0; j--) { if (cond2Array[j] == 1) { lastCond2 = j; break; } } barslast2Array[i] = (lastCond2 != -1) ? (i - lastCond2) : -1; // 7. 计算W值 if (barslast1Array[i] != -1 && barslast2Array[i] != -1) { WBuffer[i] = barslast1Array[i] - barslast2Array[i]; } else { WBuffer[i] = 0; } // 8. 计算BARSLAST(W<0)和BARSLAST(W>0) int lastNeg = -1; for (int j = i; j >= 0; j--) { if (WBuffer[j] < 0) { lastNeg = j; break; } } barslastNegArray[i] = (lastNeg != -1) ? (i - lastNeg) : -1; int lastPos = -1; for (int j = i; j >= 0; j--) { if (WBuffer[j] > 0) { lastPos = j; break; } } barslastPosArray[i] = (lastPos != -1) ? (i - lastPos) : -1; // 9. 计算BBX和SSX if (barslastNegArray[i] != -1) { int bbStart = i - barslastNegArray[i]; int bbCount = barslastNegArray[i] + 1; BBXBuffer[i] = low[ArrayMinimum(low, bbStart, bbCount)]; } else { BBXBuffer[i] = EMPTY_VALUE; } if (barslastPosArray[i] != -1) { int ssStart = i - barslastPosArray[i]; int ssCount = barslastPosArray[i] + 1; SSXBuffer[i] = high[ArrayMaximum(high, ssStart, ssCount)]; } else { SSXBuffer[i] = EMPTY_VALUE; } // 10. 计算WW if (WBuffer[i] > 0) { WWBuffer[i] = BBXBuffer[i]; } else if (WBuffer[i] < 0) { WWBuffer[i] = SSXBuffer[i]; } else { WWBuffer[i] = close[i]; } // 11. 计算最终输出(修复3:确保实时K线显示) WWWBuffer[i] = (WBuffer[i] < 0) ? WWBuffer[i] : EMPTY_VALUE; WWW1Buffer[i] = (WBuffer[i] > 0) ? WWBuffer[i] : EMPTY_VALUE; } // 修复4:确保实时K线有值 if (rates_total > 1) { int lastIndex = rates_total - 1; if (WWWBuffer[lastIndex] == EMPTY_VALUE && WWW1Buffer[lastIndex] == EMPTY_VALUE) { WWWBuffer[lastIndex] = WWBuffer[lastIndex]; WWW1Buffer[lastIndex] = WWBuffer[lastIndex]; } } return(rates_total); } 以上代码还是没有完全在MT5主图上显示出来,还缺失一部分
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值