从一个文件中自动初始化和重新初始化EA

 
任务:在重新初始化后恢复EA环境(位置数据、计数器等),在系统崩溃的情况下重新启动,等等。

解决方案:我们把EA动态变量的每一个变化都保存到一个文件中。在OnInit()过程中,所有这些东西都被加载回文件中。

然而,在以下情况下,变量的过去状态不能从文件中加载。
  • 文件结构已经改变(不同的版本,专家顾问的新构建)。这是基本的检查,没有问题。
  • 上次机器人故障了。比方说,它在停顿时崩溃了,或者挂掉了,或者超过了错误限制,那么文件中可能有一些变量会立即导致错误。这部分是非常容易检查的(要考虑的错误限制,关键错误 记录......),但这不是一个完整的解决方案。
  • 该文件实在是太 "尘封 "了。假设上次的EA是在X天前甚至今天上传的,但其中的信息已经过时了。如何检查 - 软糖知道。

现在我已经这样做了:分析OnDeinit()的原因,如果程序关闭,那么我就删除全局终端(像重新初始化的标志)。

当OnInit()过程中没有这个标志时,我不得不每次都用哑巴消息框问用户 "从文件中恢复变量?"。

这是个愚蠢至极且不方便的方法!


问题:如何使这种解决方案完全自动化?

如何判断一个文件何时不能上传,何时可以下载?

至少要把这个信息箱的调用降到最低。

 

MQL4或MQL5?

如果是MQL5,那么。

在OnInit()检查。

1.职务

if ( PositionSelect(_Symbol) )
{
}
else
{
}

2) 订单。

(如果出了问题,我就直接删除所有的订单,而不检查它们来自哪里。)

//+------------------------------------------------------------------+
//| Expert Remove orders function                                    |
//+------------------------------------------------------------------+
void RemoveOrders()
{
  int orders_total = OrdersTotal();
//---  
  if ( orders_total > 0 )
  {
    for ( int i = ( orders_total - 1 ); i >= 0; i-- )
    {
      ulong temp_order_ticket = OrderGetTicket( i );
      
      if ( OrderSelect( temp_order_ticket ) )
      {
        string temp_symbol = OrderGetString( ORDER_SYMBOL );
        
        if ( ( temp_symbol == sec_symbol ) || ( temp_symbol == _Symbol ) )
        {
          RemoveOldOrder( temp_order_ticket );
        }
      }
    }
  }
}

3.终端的全局变量

  if ( !GlobalVariableCheck( "trans_count" ) )
  {
    datetime a_time = GlobalVariableSet( "trans_count", 0 );
    
    if ( ulong( a_time ) == 0 )
    {
      MessageBox( "Глобальная переменная терминала 'Счётчик транзакций' не создана!", "Ошибка", MB_OK | MB_ICONHAND );
      return( INIT_FAILED );
    }
  }

4.要保存的变量

a) 加载。

//+------------------------------------------------------------------+
//| Expert Load setings function                                     |
//+------------------------------------------------------------------+
void LoadSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    file_handle = FileOpen( file_name, FILE_READ|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      e_high = FileReadLong( file_handle );
      a_profit = FileReadLong( file_handle );
      e_low = FileReadLong( file_handle );
      ord_delta_high = FileReadLong( file_handle );
      ord_delta_low = FileReadLong( file_handle );
      order_delta = FileReadLong( file_handle );
      exit_delta = FileReadLong( file_handle );
      FileClose( file_handle );
    }
  } 
}

b) 保存 ( OnDeInit() )

//+------------------------------------------------------------------+
//| Expert Save settings function                                    |
//+------------------------------------------------------------------+
void SaveSettings()
{
  string file_name = _Symbol + ".dat";
  int file_handle;
  bool file_found = true;
//---  
  if ( FileIsExist( file_name, 0 ) )
  {
    if ( FileDelete( file_name, 0 ) ) file_found = false;
  }
  else
  {
    file_found = false;
  }
//---
  if ( !file_found )
  {
    file_handle = FileOpen( file_name, FILE_WRITE|FILE_BIN );
    
    if ( file_handle != INVALID_HANDLE )
    {
      FileWriteLong( file_handle, e_high );
      FileWriteLong( file_handle, a_profit );
      FileWriteLong( file_handle, e_low );
      FileWriteLong( file_handle, ord_delta_high );
      FileWriteLong( file_handle, ord_delta_low );
      FileWriteLong( file_handle, order_delta );
      FileWriteLong( file_handle, exit_delta );
      FileClose( file_handle );
    }
  } 
}
 
Fry_Антон:
任务:在重新初始化后恢复EA的环境(位置数据、计数器等),在系统故障时重新启动,等等。

相反的问题是,为什么?

我认为,从长远来看,从文件中恢复环境总是自杀性的。重新启动时,你应该总是根据MetaTrader交易环境重新计算你的数据。

 
Fry_Антон:
任务:在重新初始化后恢复EA环境(位置数据、计数器等),在系统故障时重新启动,等等。
重新计算
 
Vasiliy Sokolov:

相反的问题是,为什么?

我认为,从长远来看,从文件中恢复环境总是自杀性的。在重新启动时,你应该始终根据MetaTrader交易环境重新计算你的数据。

期货市场的特点。

不是所有的东西都可以重新计算的。当然,我从环境中更新我所能做的,但是......。那么,这里有一个例子。

在清算头寸和订单被关闭/打开时。终端锁定交易并删除当天的订单(在取消之前,订单会被经纪人禁止)。我必须创建新的订单。

而且我需要开仓的 初始价格,设置仓位和订单的初始时间。

因此,我必须对这种参数进行自己的核算。

还有每秒/分钟/小时/天的请求的计数器,非致命错误行动的计数器,等等等等。

我很乐意放弃这个文件!如果它是真实的。=(

有一种情况是这样的:终端崩溃了(今天的构建是稳定的,之前一直是这样的,并不是说永远只有稳定版)。

终端崩溃后:快速重启和自动运行--从文件中恢复,一切正常。

工作非常稳定,因为我总是将初始化文件保存在OnTrade()事件中(有一两秒钟的计时器,不至于折磨磁盘)。


所以对我来说,这个问题很有意义:如何不从一个过时的或危险的文件中加载变量?

 
Михаил:

MQL4或MQL5?

如果是MQL5,那么。

在OnInit()检查。

1.职务

2) 订单。

(如果出了问题,我就直接删除所有的订单,而不检查它们来自哪里。)

3.终端的全局变量

4.要保存的变量

a) 加载。

b) 保存 ( OnDeInit() )

几乎是这样做的。但我把文件保存到OnTrade(),有一个定时器。

我还有一大堆不同的符号和其他变量,而且代码在不断变化,所以一个一个地存储它们非常不方便。

我创建了一个基本的结构,容纳了我需要的所有文件(除了一些字符串值)。

我用一个字母来命名,所以代码相当短(b.volume几乎和volume一样)。而且,用操作符=一次性保存整个结构也很方便。

 
Fry_Антон:

...

问题:如何使这种解决方案完全自动化?

...

一个根本不同的EA编程方法。

 
Dmitry Fedoseev:

一个根本不同的EA编程方法。

把答案扩展为合理有用的想法,我将对你表示感谢。

什么是EA代码变成 "更好 "的基本原则?

 
Fry_Антон:

把答案扩展为合理有用的想法,我将不胜感激。

使EA代码 "更好 "的基本原则是什么?

这里已经写过了--重新计算一切。即用命令分析情况。一些数据是存储在文件中,还是以其他方式(也许是在全局变量 中),并不具有根本重要性。主要的一点是,如果需要一些数据,它被储存在绑定的订单票中,在这种情况下,不存在数据过期的问题--我们有订单--我们有数据,没有订单--我们没有数据。可能有数据不与特定的订单挂钩,但我们必须考虑每一种情况,这是一个可解决的问题。

清理确实是最复杂的问题。但这不是一个长期数据存储(或其过时)的问题,我们可以将数据存储在专家顾问的简单变量中(有点冒险,但只是5分钟)。这里的困难是以后如何处理它。我们可以为每个订单创建一组全局终端变量,并在其中存储开盘价。然后,当未标记的订单出现时(或在新的一天开始时),我们在历史中查看最新的已关闭的订单,根据那些可以使用的特征(例如,批次)进行匹配,并将已关闭的订单中的所有全局变量重置为新的订单。

 

安东!

你对这个问题太 "激动 "了。

很明显,你想在紧急情况后适当恢复专家的工作。

情况。我一开始也是绞尽脑汁。

但后来决定,这种情况极为罕见

(从我自己半年一次的MT5真实交易的经验来看),所以我决定这并不值得

来 "打扰 "已下的订单,只是 "钉 "住秋天后存在的一切。

在秋天之前已经下了命令,如果这些命令已经被执行,那么什么也做不了,如果

如果它们还在 "闲逛",那么杀了它们并根据交易情况重新设置,你就不会有任何损失!"。

那么剩下的就是位置了--无论它是否存在

至于从文件中写入/读取变量。

我有 "热"(工作期间)的变量变化在我的EA,所以我

我把它们写入文件并从文件中读取,这样专家顾问就会在新的开始时采用 "热 "设置。

你为自己创造的问题

想一想吧!

P/S MT5不是MT4,在MT4中,订单是非常重要的!

在MT5中,你必须以位置为导向,而不是以订单为导向。

 
Fry_Антон:

把答案扩展为合理有用的想法,我将不胜感激。

使EA代码 "更好 "的基本原则是什么?

已私下回答。

Z.I. 你的例子是不成立的。堡垒上没有这样的问题。当然,你可以编造任何问题,然后在很长一段时间内试图解决它。但为什么要解决它,因为不编造它更容易?