FORTS 请帮助 - 页 6

 
Serj_Che:
为什么你要在OnCalculate中重复OnInit中的内容?是这样的咒语吗?)

这是简单的复制/粘贴魔法))。

好吧,我通俗地解释给你听。仅仅在内部检查一次数据准备情况是不够的。由于数据是异步生成的(为了不拖累主进程),在init中检查时有可能出现数据错误(取决于许多因素)。

因此,你应该在计算中检查和(或只)检查,直到所有需要的数据都可用时才开始主要的计算--也就是说,在每一个刻度 上检查直到准备好。

 
Dima_S:

这是简单的复制/粘贴魔法))。

好吧,我通俗地解释给你听。仅仅在内部检查一次数据准备情况是不够的。由于数据是异步生成的(以便不拖累主进程),那么,在init中检查时,很可能会出现数据错误(取决于许多因素)。

这就是为什么检查应该在计算中进行,并且(或仅)在所有必要的数据可用之前不要开始主要的计算--也就是说,在每一个tick上检查直到准备好。

这就是我们所讨论的,指标中的OnInit函数 要么是假的,要么是开发者没有做好他们的工作。

复制/粘贴是个好东西,我自己也这么做))。

 

喊了又喊,叫了又叫,但问题还是没有解决!

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//
bool is_failed = false;
datetime start_time;
datetime end_time;
int mix_bars, rts_bars, si_bars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
    start_time = StringToTime( "2015.03.17" );
    end_time = TimeCurrent();
//--- indicator buffers mapping
  mix_bars = GetBars( "MIX-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( mix_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. MIX-6.15 ");
  }
  rts_bars = GetBars( "RTS-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( rts_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. RTS-6.15 ");
  }
  si_bars = GetBars( "Si-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( si_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. Si-6.15 ");
  }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator Get bars function                               |
//+------------------------------------------------------------------+
int GetBars( string symbol, ENUM_TIMEFRAMES period, const datetime start_date, const datetime end_date )
{
  if ( !SymbolInfoInteger( symbol, SYMBOL_SELECT ) )
  {
    ResetLastError();
//---    
    if ( GetLastError() != ERR_MARKET_UNKNOWN_SYMBOL )
    {
      SymbolSelect( symbol, true );
    }
    else
    {
      Print( "GetBars: Неизвестный символ - ", symbol );
      return( 0 );
    }    
  }
//---  
  if ( MQL5InfoInteger( MQL5_PROGRAM_TYPE ) == PROGRAM_INDICATOR && Period() == period && Symbol() == symbol )
  {
    Print( "GetBars: Не пройдена проверка типа программы!" );
    return( 0 );
  }  
//---
  if ( SymbolIsSynchronized( symbol ) )
  {
    return( Bars( symbol, period, start_date, end_date ) );
  }
  else
  {
    long first_date = 0;
    datetime times[1];
//---    
    if ( SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date ) )
    {
      if ( first_date > 0 )
      {
//--- force timeseries build
        CopyTime( symbol, period, datetime( first_date ) + PeriodSeconds( period ), 1, times );
//--- check date
        if ( SeriesInfoInteger( symbol, period, SERIES_FIRSTDATE, first_date ) )
//---        
        if ( first_date > 0 && first_date <= long( start_date ) )
        {
          return( Bars( symbol, period, start_date, end_date ) );
        } 
      }
    }
    Print( "Необходима загрузка истории с сервера!");
  }       
//---  
  return( 0 );
}  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 ( is_failed )
   {
     Print( "Sorry! Get Bars failed." );
   }
   else Print( "Bingo! We done.");
//--- return value of prev_calculated for next call
   return(rates_total);
  }

我还没有写历史下载,但数据在终端中,而且第一次没有从终端中出来!

2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. RTS-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. Si-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Sorry! Get Bars failed.
 
Serj_Che:

好吧,有意思!我也是。

指标在自己的线程中工作,EA在自己的线程中工作。当然,除非是单芯石。

所有的事情都完全按照文件中的规定进行。:)

我画了一个指标和EA进行测试+视频中的结果。

1) 首先,我在图表上绘制了一个专家顾问,OnTick函数运行了20秒。

其结果是,图表继续工作,并按其应有的方式显示一切。该图表也如预期的那样工作。

2) 然后我们在图表上应用具有OnCalculate 功能的指标,持续20秒。

结果是--聊天挂起。同时,下一个具有不同时期的相同符号的聊天也被暂停。玻璃继续像它应该的那样工作。在该功能发挥作用后,一切都会恢复正常。

3)视频中没有 - 但如果你把指标扔在一个聊天室里(设置为60秒),而把专家扔在另一个聊天室里 - 专家不开始工作,直到另一个聊天室的指标出现故障!这是不可能的。

我已经单独附上了视频--在我的浏览器中速度很慢。

 
MigVRN:

一切都像文件中说的那样发生。:)

勾画了一个指标和一个专家顾问,用于检查+视频上的结果。

1) 首先,我把它投到专家顾问的图表上,该图表内部有OnTick函数,工作时间为20秒。

其结果是,图表继续工作,并按其应有的方式显示一切。该图表也如预期的那样工作。

2) 然后我们在图表上应用具有OnCalculate 功能的指标,持续20秒。

结果是--聊天挂起。同时,下一个具有不同时期的相同符号的聊天也被暂停。玻璃继续像它应该的那样工作。在该功能发挥作用后,一切都会恢复正常。

3) 视频中没有显示 - 但如果你在一个聊天室中投下一个指标(设置为60秒),而在另一个聊天室中投下一个EA - EA不会开始工作,直到指标在另一个聊天室中出现故障!这是不可能的。

另外附上视频--我的浏览器很慢。

谢谢,我拿不到视频看,我会研究的。

 

如果你在从指标工作时试图从交易环境中获取数据,甚至不要试图在OnInit()中设置查询。进行查询并在OnCalculate()中检查响应。当从另一个符号或另一个时间段接收数据时,几乎可以保证即使在OnCalculate中,你也无法成功接收到第一次的数据。这就是为什么你应该检查数值的返回。如果没有获得任何数值,在OnCalculate()中尝试在下一个tick上获得数据。


另外,看到servicedesk的回应已经很有意思了--提供的代码。

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

FORTS 请帮助

alexvd, 2015.03.26 15:48

Servisdesk已经给了你源代码。试着把你最后的代码放到Test()函数中。

已经有了运动的兴趣--作者一直在写自己的代码,而忽略了服务台的代码?

 
barabashkakvn:

如果你在从指标工作时试图从交易环境中获取数据,甚至不要试图在OnInit()中设置查询。进行查询并在OnCalculate()中检查响应。当从另一个符号或另一个时间段接收数据时,几乎可以保证即使在OnCalculate中,你也无法成功接收到第一次的数据。这就是为什么你应该检查数值的返回。如果没有收到任何数值,在OnCalculate()中尝试在下一个tick上接收数据。

+++等等,直到最后。也就是说,如果没有数据--返回。
 
MigVRN:
+++等等,直到最后。即:如果没有数据,则返回。
这取决于你想要查询的内容。而要进行多少次查询,完全取决于代码编写者的偏好。
 
barabashkakvn:
这取决于要查询什么。以及多少次查询--这完全取决于代码编写者的偏好。

你明白

如果终端中存在数据,那么函数

SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date )

不应该返回FALSE?

P/S的SD代码也从第一次开始就不工作了!

 

再来一次。

从帮助。

系列信息Integer

返回有关历史数据状态的信息。该函数有2种变体。

第二种变体。

bool  SeriesInfoInteger(
   string                     symbol_name,     // имя символа
   ENUM_TIMEFRAMES            timeframe,       // период
   ENUM_SERIES_INFO_INTEGER   prop_id,         // идентификатор свойства
   long&                      long_var         // переменная для получения информации
   );

series_terminal_firstdate。

根据客户终端的符号,在历史上的第一个日期,不分时期

日期时间

如果终端中有数据,该函数不应该返回false!!!。

无论你从哪里打电话给它!