我是新手,MQL5
我正在尝试捕捉每根新蜡烛的Open
、High
和Low
的值。Close
现在我TimeFRAME
为每支蜡烛使用一分钟。
我阅读了文档并没有弄清楚我该怎么做。
我唯一的线索是CopyOpen()
功能,但我仍然卡住了。
我是新手,MQL5
我正在尝试捕捉每根新蜡烛的Open
、High
和Low
的值。Close
现在我TimeFRAME
为每支蜡烛使用一分钟。
我阅读了文档并没有弄清楚我该怎么做。
我唯一的线索是CopyOpen()
功能,但我仍然卡住了。
如果您变得太沮丧,这里有一个脚本,它将在出现新蜡烛的第二个时导出选定的图表内容。只需选择您想要的对并将其附加到图表上,您将.csv
在每根新蜡烛上导出一个文件。
//+------------------------------------------------------------------+
#include <stdlib.mqh>
#include <stderror.mqh>
//+------------------------------------------------------------------+
//| Input Parameters Definition |
//+------------------------------------------------------------------+
extern int BarCount = 500;
extern string Pairs = "EURAUD,EURCAD,EURCHF,EURGBP,EURNZD,EURUSD,EURJPY,AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPNZD,GBPUSD,CADCHF,CADJPY,USDCAD,USDCHF,USDJPY,NZDCAD,NZDCHF,NZDJPY,NZDUSD,CHFJPY";
extern string delimiter = ",";
//+------------------------------------------------------------------+
//| Local Parameters Definition |
//+------------------------------------------------------------------+
datetime lastExport[];
string pairs[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//------------------------------------------------------------------
Split(Pairs, pairs, ",");
//------------------------------------------------------------------
if (ArraySize(pairs) == 0 || StringTrimLeft(StringTrimRight(pairs[0])) == "")
{
Alert("Pairs are not entered correctly please check it...");
return (0);
}
//------------------------------------------------------------------
ArrayResize(lastExport, ArraySize(pairs));
ArrayInitialize(lastExport, 0);
//------------------------------------------------------------------
Comment("quote exporter is active :)");
//------------------------------------------------------------------
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//------------------------------------------------------------------
Comment("");
//------------------------------------------------------------------
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//------------------------------------------------------------------
if (ArraySize(pairs) == 0 || StringTrimLeft(StringTrimRight(pairs[0])) == "") return (0);
//------------------------------------------------------------------
BarCount = MathMin(Bars, BarCount);
//------------------------------------------------------------------
for (int j = 0; j < ArraySize(pairs); j++)
{
if (lastExport[j] == Time[0]) continue;
lastExport[j] = Time[0];
if (StringTrimLeft(StringTrimRight(pairs[j])) == "") continue;
if (MarketInfo(pairs[j], MODE_BID) == 0) { Alert("symbol " + pairs[j] + " is not loaded!!!"); continue; }
//------------------------------------------------------------------
string file = pairs[j] + "_" + GetTimeFrameName(0) + ".csv";
int log = FileOpen(file, FILE_CSV|FILE_WRITE, "~");
if (log < 0) { Alert("can not create/overwrite csv file " + file + "!!!"); continue; }
string buffer;
buffer = "Date"+delimiter+"Time"+delimiter+"Open"+delimiter+"High"+delimiter+"Low"+delimiter+"Close"+delimiter+"Volume";
FileWrite(log, buffer);
int digits = MarketInfo(pairs[j], MODE_DIGITS);
for (int i = BarCount; i >= 1; i--)
{
buffer = TimeToStr(Time[i], TIME_DATE)+delimiter+TimeToStr(Time[i], TIME_MINUTES)+delimiter+DoubleToStr(iOpen(pairs[j], 0, i), digits)+delimiter+DoubleToStr(iHigh(pairs[j], 0, i), digits)+delimiter+DoubleToStr(iLow(pairs[j], 0, i), digits)+delimiter+DoubleToStr(iClose(pairs[j], 0, i), digits)+delimiter+DoubleToStr(iVolume(pairs[j], 0, i), 0);
FileWrite(log, buffer);
}
buffer = "0"+delimiter+"0"+delimiter+"0"+delimiter+"0"+delimiter+"0"+delimiter+"0"+delimiter+"0";
FileWrite(log, buffer);
FileClose(log);
}
//------------------------------------------------------------------
return(0);
}
//+------------------------------------------------------------------+
string GetTimeFrameName(int TimeFrame)
{
switch (TimeFrame)
{
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN1");
case 0: return(GetTimeFrameName(Period()));
}
}
//+------------------------------------------------------------------+
void Split(string buffer, string &splitted[], string separator)
{
string value = "";
int index = 0;
ArrayResize(splitted, 0);
if (StringSubstr(buffer, StringLen(buffer) - 1) != separator) buffer = buffer + separator;
for (int i = 0; i < StringLen(buffer); i++)
if (StringSubstr(buffer, i, 1) == separator)
{
ArrayResize(splitted, index + 1);
splitted[index] = value;
index ++;
value = "";
}
else
value = value + StringSubstr(buffer, i, 1);
}
//+------------------------------------------------------------------+
A1:
MQL4/MQL5
Open[]
语法直接在, High[]
, Low[]
, Close[]
,Volume[]
时间序列数组中报告 OHLCV 值。根据经验,这些数组是时间序列的,反向步进索引,因此最近的单元格(当前柱(蜡烛))总是有 cell-index == 0
。“Open[1], High[1], Low[1], Close[1]
当前工具_Symbol
” TimeFRAME
(复杂的?好吧,就在最初的几次阅读中。你会熟悉这个。
如果您的代码不想依赖“当前”隐式上下文,则语法允许使用显式、间接的规范:
/* iVolume( ||| ... )
iTime( ||| ... )
iClose( ||| ... )
iLow( ||| ... )
iHigh( vvv ... ) */
iOpen( aTradingSymbolNameSTRING, // Broker specific names, "DE-30.." may surprise
PERIOD_M1, // explicit reference to use M1 TimeFRAME
1 // a Cell-index [1] last, closed Candle
)
A2:
有一种巧妙的方法可以间接检测新的蜡烛,同样的技巧可以让人们检测到一个时刻,当前一个蜡烛停止演变(值不再改变),因此报告“已经冻结”OHLCV
的值是有意义的在其他任何地方报告。
请记住,“当前” -registers- OHLCV
[0] 总是“热”==在整个“当前”TimeFRAME
蜡烛持续时间期间不断变化,因此必须等到新蜡烛开始(间接意味着“现在-以前" Candle [0] 已结束,因此已将反向步进索引“重新索引”为 [1],即冻结的索引)。
为了检测新蜡烛,监控系统寄存器的变化就足够了int Bars
,resp。一个间接的,上下文感知的,int iBars( ... )
.
人们可能会意识到,有一些“理论”蜡烛不会发生,因此在时间序列数据中不是“可见”/“可访问”的——因此市场在这段时间内不活跃且没有PriceDOMAIN
变化在这样的行政框架时期发生过——对于这样的情况,因为没有价格变化,所以没有QUOTE
,因此这样的蜡烛没有发生,并且在线性计数和数据单元中都“缺失”。因此,第一个下一个QUOTE
到达的蜡烛被画在“旁边”的蜡烛上,该蜡烛主要比“前一个”邻居“更老”(未描绘丢失的蜡烛,因此在处理时应格外小心)。