Mt4结束支持。 - 页 27

 
Реter Konow:
线性、非线性...你是不是又在谈论编程中的歌剧?

没办法。

 
Реter Konow:

好的。你的解决方案只对蜱虫有效。我的是定时器。你认为我用酒吧出场的计时方法是否有缺点。好的。让它像这样。我将在设置一个新的条形标志之前,增加一个检查报价是否到达的功能。我将为该函数添加另一个参数--一个符号。用户将选择他们想要接收新的酒吧事件的符号,并将其发送到该函数。该函数将检查该符号的最后一次引用的时间。然后我们将比较酒吧正式出现的时间和报价的时间,并设置事件标志。

我刚刚开始学习这个科目,但我没有看到任何困难。

关于交易、自动交易系统和策略测试的论坛

Mt4结束支持。

Artyom Trishkin, 2017.09.10 22:27

我知道如何获得报价 :)

在一个多币种的程序中--在一个定时器中的右侧符号的循环。而新条形图(物理的,而不是虚拟的--错误的--和你一样)的开启 是由最后一次报价的时间控制的,并将该时间与零条形图符号的时间 相比较。

而你,则是在随机制作--一个可能不存在的虚拟酒吧。你在周末没有他们,但你应该有他们--这是最简单的事情,可以作为一个例子。

而且,你看,你是唯一一个不会这样做的人。我们其余的人以正确和可靠的方式行事。但是,这当然只是你自己的事。

我想告诉你怎么做才是正确的,并展示在解决同样的任务时,用OOP编写的简单性和用程序式编写的复杂曲折性之间的巨大差异。

但你可能知道得更多,而且不需要它。我不敢看起来像我知道更多的东西。对不起。


 
Galina Bobro:

没问题。对冲以节省字符串操作的比较,好吧,如果客户是个疯子,会同时对所有字符进行交易。

但似乎没有其他地方可以保存操作和内存--一切都很简单。

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合并为一个结构,因为它们是相互关联的,这将减少代码中数组递增的操作。

 
Artyom Trishkin:

我有一个目标,让他的程序化风格的代码最终像这样在一个循环中工作。

 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的代码)。

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   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");     // режим вывода информации
  }

void OnTick()
  {
   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="") 
  {
   static const ENUM_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
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int 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);
  }

但我还是要说--我是OOP的拥护者。
只是一个非常不幸的例子,说明程序化编程中不能做什么。

 
Andrey Kisselyov:
这不是在EA中调用一个函数,而是在写通用接口(处理程序)。

你有1000个任务要写机器人;事实上,每个任务都包括
1获得信号的功能,以打开
2.订单开放的功能
3、订单跟踪的功能
4) 接收信号关闭订单的功能。
等等。
这些功能对每个机器人来说都是不同的,但它们在1000个项目中都是重复的。 因此,你可以将这些功能组合成通用模块,并根据任务,调用正确的模块。

好吧,如果你有这些功能,你不需要做任何其他事情。函数的输入参数是接口。每一个额外的复杂性都会增加可能的错误数量,并增加程序员的工作时间。

 
Nikolai Semko:

类似这样的东西(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。

 
Vladimir:

原则上,是否有这样的例子?即使不是你的?我有深深的怀疑。


我认为很可能找不到这样的例子。我个人认为,OOP的主要优点是更方便地对大型项目 进行编程,并为将来使用你的开发成果提供方便的机制。这一点以前在这里已经正确地说过很多次了。

 
Andrei:

已经讨论过,单一的界面根本不适用于任何计算任务的编程......。把漂亮的东西放在接口的形式中,纯粹是一种表面程序,它只适用于已经准备好的代码,而且也妨碍了对代码的进一步支持和完善......

没有。这不是 "完全不适用",而是 "使用它们没有意义"。

接口不是 "适用于现成代码的纯粹的表面程序"。

恰恰相反,接口是系统架构的核心。这是设计 开始的地方。接口根本不会 "妨碍支持和返工",而是通过明确划定可允许的边界来帮助他们。如果没有接口,就很容易越过这些界限,在不打算修改的地方进行修改,导致难以计算的错误。

任何复杂的系统(不仅是在编程方面)都始于其各部分之间相互作用的基本原则的发展。然而,在编程中,由于最初的任务通常非常小,他们的方向相反。首先写出各部分,然后将它们组合成一个整体,经常会遇到各部分相互不兼容的情况--顺便说一下,这就解释了 "能够获得所有可用的变量 "的愿望。

 

除了isNewBar()函数根本就不应该存在外,其他都没问题。有趣的是,在这样一件小事上有这么多的舞蹈。

这只是一个变量,它被简单地与条形图的时间相比较;如果所有的情况都是成功的,那么这个变量就被分配到最后的新条形图 的时间。否则,对所有案件只分配一次尝试。

 
Dmitry Fedoseev:

除了isNewBar()函数根本就不应该存在外,其他都没问题。有趣的是,在这样一件小事上有这么多的舞蹈。

这只是一个变量,它被简单地与条形图的时间相比较;如果所有的情况都成功了,那么这个变量就被分配到最后的新条形图 的时间。否则,对所有案件只分配一次尝试。


+1