ENUM_TIMEFRAMES array_timeframes[]=
{
PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
};
int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
for(int i=0; i<total; i++){
string symbol_name=SymbolName(i,true);
for(int j=0; j<total_tf; j++){
if(IsNewBar(symbol_name,array_timeframes[j])){
Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
}
}
}
像这样的东西(MQL5的代码)。
intOnInit()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательноEventSetMillisecondTimer(100);
return(INIT_SUCCEEDED);
}
voidOnDeinit(constint reason)
{
EventKillTimer();
}
voidOnTimer()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательно// различные варианты проверки новых баровif(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента"); // режим вывода информацииif(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF"); // режим вывода информации
}
voidOnTick()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательно// различные варианты проверки новых баровif(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF"); // режим вывода информации
}
//+---------------------------------------------------------------------------------------------------+//| Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка" |//| два режима работы: |//| - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar(); |//| - режим вывода информации, out=true |//| tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации) |//| Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации) |//+---------------------------------------------------------------------------------------------------+bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="")
{
staticconstENUM_TIMEFRAMES TF[22]=
{
PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
};
staticbool newbar[];
staticlong acb[]; // array of current barsstaticint N_Sym=0;
if(Sym=="") Sym=Symbol();
int total=SymbolsTotal(true);
int n_cur=-1;
for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
if(out && N_Sym>0) // если режим вывода информации
{
int curtf=0;
while(TF[curtf]!=tf) curtf++;
return (newbar[n_cur*22+curtf]);
}
// режим сбора информацииif (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
for(int j=0,j1=0; j<total; j++,j1+=22)
for(int i=0;i<22;i++)
{
long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
if(acb[j1+i]<CurBars) // пришел новый бар
{
//if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+" "+EnumToString(TF[i]));
acb[j1+i]=CurBars;
newbar[j1+i]=true;
}
else
{
newbar[j1+i]=false;
if(i==1) for(;i<22;i++) newbar[j1+i]=false; // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
}
}
return(false);
}
线性、非线性...你是不是又在谈论编程中的歌剧?
没办法。
好的。你的解决方案只对蜱虫有效。我的是定时器。你认为我用酒吧出场的计时方法是否有缺点。好的。让它像这样。我将在设置一个新的条形标志之前,增加一个检查报价是否到达的功能。我将为该函数添加另一个参数--一个符号。用户将选择他们想要接收新的酒吧事件的符号,并将其发送到该函数。该函数将检查该符号的最后一次引用的时间。然后我们将比较酒吧正式出现的时间和报价的时间,并设置事件标志。
我刚刚开始学习这个科目,但我没有看到任何困难。
关于交易、自动交易系统和策略测试的论坛
Mt4结束支持。
Artyom Trishkin, 2017.09.10 22:27
我知道如何获得报价 :)
在一个多币种的程序中--在一个定时器中的右侧符号的循环 中。而新条形图(物理的,而不是虚拟的--错误的--和你一样)的开启 是由最后一次报价的时间控制的,并将该时间与零条形图符号的时间 相比较。
而你,则是在随机制作--一个可能不存在的虚拟酒吧。你在周末没有他们,但你应该有他们--这是最简单的事情,可以作为一个例子。
而且,你看,你是唯一一个不会这样做的人。我们其余的人以正确和可靠的方式行事。但是,这当然只是你自己的事。
我想告诉你怎么做才是正确的,并展示在解决同样的任务时,用OOP编写的简单性和用程序式编写的复杂曲折性之间的巨大差异。
但你可能知道得更多,而且不需要它。我不敢看起来像我知道更多的东西。对不起。
没问题。对冲以节省字符串操作的比较,好吧,如果客户是个疯子,会同时对所有字符进行交易。
但似乎没有其他地方可以保存操作和内存--一切都很简单。
void OnTimer(){
Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }
//+------------------------------------------------------------------+
uint Sp_Adler32(string line){
ulong s1 = 1;
ulong s2 = 0;
uint buflength=StringLen(line);
uchar char_array[];
ArrayResize(char_array, buflength,0);
StringToCharArray(line, char_array, 0, -1, CP_ACP);
for (uint n=0; n<buflength; n++){
s1 = (s1 + char_array[n]) % 65521;
s2 = (s2 + s1) % 65521;}
return ((s2 << 16) + s1);}
//+------------------------------------------------------------------+
bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){
static datetime st_time[];
static uint st_id[];
//---- set
datetime new_time = iTime(symb, tf, 0); if(new_time==0) return(false);
uint new_id = Sp_Adler32(StringConcatenate(symb,EnumToString(tf)));
datetime old_time = 0;
uint old_id = 0;
//---- find
int size = ArraySize(st_time);
for(int i=0; i<size; i++){
if(st_id[i]!=new_id) continue;
old_id = st_id [i];
old_time = st_time[i];
break;}
//----add new element
if(old_time==0){
ArrayResize(st_time, size+1); st_time[size]=new_time;
ArrayResize(st_id, size+1); st_id [size]=new_id; }
//----
return(old_time>0 && old_time<new_time);}
到目前为止,这似乎是结构上最合理的代码。 有一个对新符号和tf的检查,它没有检查所有的东西,而只是检查你需要的东西,没有多余的操作,这意味着它应该运行得很快。
最好的问候。
P.S. 这里唯一可以添加的小东西是将数组st_time和st_id合并为一个结构,因为它们是相互关联的,这将减少代码中数组递增的操作。
我有一个目标,让他的程序化风格的代码最终像这样在一个循环中工作。
像这样的东西(MQL5的代码)。
但我还是要说--我是OOP的拥护者。
只是一个非常不幸的例子,说明程序化编程中不能做什么。
这不是在EA中调用一个函数,而是在写通用接口(处理程序)。
你有1000个任务要写机器人;事实上,每个任务都包括
1获得信号的功能,以打开
2.订单开放的功能
3、订单跟踪的功能
4) 接收信号关闭订单的功能。
等等。
这些功能对每个机器人来说都是不同的,但它们在1000个项目中都是重复的。 因此,你可以将这些功能组合成通用模块,并根据任务,调用正确的模块。
好吧,如果你有这些功能,你不需要做任何其他事情。函数的输入参数是接口。每一个额外的复杂性都会增加可能的错误数量,并增加程序员的工作时间。
类似这样的东西(MQL5的代码)。
但我重申--我是OOP的支持者。
这真的是一个不幸的例子,说明程序化编程中不能做什么。
原则上有这样一个例子吗?即使不是你的?我有深深的怀疑。在21世纪初,我不再计算我所写的调试和工作的代码行数,因为它超过了一百万--它变得无趣了。而且我从来没有遇到过必须自己创建班级的情况,尽管我的任务种类和规模都非常多样化。当需要为几个人并行工作时,我不得不使用过程型变量,但不再是了。为什么这么说?
顺便问一下,为什么你说程序化编程是对OOP的一种替代?有一些语言没有OOP,原则上是非程序化的(SQL),甚至还有一个语言发展的方向--函数式编程https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5:"一些概念和范式是函数式编程所特有的,与命令式编程(包括面向对象的编程)大多是陌生的","函数式程序的另一个优点是,它们为自动化 提供了大量机会事实证明,OOP阻止了计算的自动平行化。这现在应该被认为是一个非常严重的缺点,观点不适合OOP。
原则上,是否有这样的例子?即使不是你的?我有深深的怀疑。
我认为很可能找不到这样的例子。我个人认为,OOP的主要优点是更方便地对大型项目 进行编程,并为将来使用你的开发成果提供方便的机制。这一点以前在这里已经正确地说过很多次了。
已经讨论过,单一的界面根本不适用于任何计算任务的编程......。把漂亮的东西放在接口的形式中,纯粹是一种表面程序,它只适用于已经准备好的代码,而且也妨碍了对代码的进一步支持和完善......
没有。这不是 "完全不适用",而是 "使用它们没有意义"。
接口不是 "适用于现成代码的纯粹的表面程序"。
恰恰相反,接口是系统架构的核心。这是设计 开始的地方。接口根本不会 "妨碍支持和返工",而是通过明确划定可允许的边界来帮助他们。如果没有接口,就很容易越过这些界限,在不打算修改的地方进行修改,导致难以计算的错误。
任何复杂的系统(不仅是在编程方面)都始于其各部分之间相互作用的基本原则的发展。然而,在编程中,由于最初的任务通常非常小,他们的方向相反。首先写出各部分,然后将它们组合成一个整体,经常会遇到各部分相互不兼容的情况--顺便说一下,这就解释了 "能够获得所有可用的变量 "的愿望。
除了isNewBar()函数根本就不应该存在外,其他都没问题。有趣的是,在这样一件小事上有这么多的舞蹈。
这只是一个变量,它被简单地与条形图的时间相比较;如果所有的情况都是成功的,那么这个变量就被分配到最后的新条形图 的时间。否则,对所有案件只分配一次尝试。
除了isNewBar()函数根本就不应该存在外,其他都没问题。有趣的是,在这样一件小事上有这么多的舞蹈。
这只是一个变量,它被简单地与条形图的时间相比较;如果所有的情况都成功了,那么这个变量就被分配到最后的新条形图 的时间。否则,对所有案件只分配一次尝试。
+1