用 MQL 编写的用户界面图库 - 页 68

 
hini #:

MQL5 实现了策略的逻辑,WinForms 只需按几个按钮、控制 EA 内部的一些变量和显示一些信息,即可改变策略的逻辑。

为了保持代码的简洁,策略和界面代码是分开的。

从技术上讲,无论是在功能(许多功能即将推出)还是在界面构建速度方面,任何 WinForms 都无法与我在 MQL 环境中的 解决方案相媲美。使用 KIB 代码模板可以比使用可视化编辑器更快地创建界面。此外,我还计划在构造函数中添加抓取和移动窗口内元素的功能,以便快速定位。这一点现在已经很容易做到了。除此之外,根据大众用户的可理解性和可访问性标准,我的解决方案是领先的。你不需要懂得 C# 和面向对象编程,也不需要插入 DLL。此外,我还在本主题中提供了用户所需的详细教程信息。每个人都可以自己寻找和发明连接 WinForms 的方法。

作为一个人,您有权发表自己的个人意见和喜好。但我必须提醒您,这个主题是关于用 MQL 编写的生成器和引擎的。 因此,在技术上无理反对的情况下讨论其他开发环境的接口是不合适的,尽管这并不禁止。我们不反对 MT5 和其他平台,就像我们不反对 ME 和 VS 一样。

在 MT5 平台上,构造函数引擎的基本 版本完成后,WinForms 不再 解决算法交易任务的手段,但总会有人选择自己的原创方式。

我认为这个话题已经讨论完毕,不会再回应进一步的质疑。

 

由于合并了这些主题,审议顺序如下: 14:

对参数边界实施交错保护:

  • 编写控制用户预设边界内设置的逻辑,并在违反边界时创建警告系统。
  • 警告 1:用户收到的信号是负责设置的部分元素的颜色发生变化。(让我们 将文本、底座、框架和滑动 条的颜色与数值边界联系起来)。
  • 警告 2:打开一个对话框,其中包含风险提示和返回原始设置的建议。(让我们测试一下在点击 "取消 " 按钮时恢复到先前设置的实际能力。)
  • 警告 3:打开一个警告窗口,阻止对设置的进一步更改,并提示免责声明,需要用户手动确认。(检查警告窗口出现时窗口和元素的阻塞情况。)


15.让我们详细看看新的 API 文件打印输出。

//----------------------------------------------------------------------------------------------------


接下来,我将收集发现的错误和缺陷,并为下一个版本列出任务清单。

 
让我着迷的是在 MQL 环境中的实施以及实施的完整性。因此,我在等待开发。我相信很多人都在等待。
 
Edgar Akhmadeev #:
让我着迷的是在 MQL 环境中的实施以及实施的完整性。因此,我在等待开发。我相信很多人都在等待。
谢谢,我也希望如此。开发工作正在实时进行)。
 

彼得,这个项目 到底在哪里?

那里有一些东西的资源库(在我看来,这很难被称为源代码 和文档

 
Maxim Kuznetsov 项目 到底在哪里?

那里有一些东西的资源库(在我看来很难称之为源代码 和文档

你为什么要找它,找来找去,就是找不到)))。项目在分支页面上,还有安装说明。我不会告诉你具体的页面,请向后滚动。

下一个版本将在 kodobase 上发布。如果你愿意,可以再等等。
 

增加了以编程方式更改元素框架颜色并将其与参数值关联的功能。这是一个信息丰富的实用指标,有助于快速了解输入值的风险等级。它既实用又清晰。此外,在超出设定限值时,会出现警告窗口。

举几个例子:


明天我们将通过示例和代码进行详细介绍。

 
让我们从新的一页开始。
 

在继续讨论实施交错参数边界保护和用户警告之前,我们应该先提一下与之直接相关的另一个话题。即参数预设

我先从众所周知的问题说起:大多数 MQL 程序都有输入 类变量。它们在全局级别声明,并在一个设置窗口中可见。该窗口在程序开始时出现,如果需要,用户可以在窗口内更改 "外部 "变量的初始值。但在此之前,用户需要在程序内部初始化外部变量。问题在于,程序预设值并不是万能的,因此有一类变量需要在每次启动时进行设置。众所周知,在程序执行过程中手动访问外部变量是不可能的,需要重新启动。有了图形界面,这种必要性就不复存在了。程序设置可以在运行时打开。

不过,仍然需要在程序开始时设置程序参数的初始值

如果我们使用的是图形界面 ,那么 声明输入 类型的变量 没有意义了 因为我们不再需要标准设置窗口 但本质是一样的。我们必须为控件参数设置初始值,而不是输入 变量

在程序初始化时,我们应该调用一些函数,为我们自己的窗口而 不是标准窗口设置初始值。 作为一种选择,这可以在 KIB 构建器中完成,在界面构建阶段设置V_CURRENT 值或开/关 状态等,但现在可以通过编程初始化元素。现在可以将构造函数和程序中的元素初始化结合起来。

因此,我们需要一个从OnInit() 调用的特殊函数来完成这项工作。

该函数的具体功能

  • 在程序开始时打开所需的窗口。
  • 在目标控件中设置值。

将调用什么函数?

我想称之为Initialize(),但任何人都可以提出自己的变体。

重要的 是,这个函数必须出现在任何界面的智能交易系统中。它可以与智能交易系统 OnTick() 函数或指标的OnCalculate() 函数相比较。理解这一点很重要


函数将返回什么值?

函数为void 类型 无需返回值。调用时,它将打开必要的窗口,初始化元素参数,并可能预设一些属性。基本上就是这样。理论上,你可以在其中设置初始参数边界,但我认为值控制将在一个单独的函数中实现,该函数在元素事件发生时从 API 文件和计时器中调用。我可能会在下一个版本中写入控制调用的打印输出。

*重要的是要考虑到,目前界面智能顾问的概念刚刚形成,还有许多发现有待我们去探索。


下面以当前的演示项目为例,说明界面智能交易系统的初始化功能:

1.函数调用: 2:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int _OnInit()
  {
   //------------------------------------------------
   //Initializing program interface:
   //------------------------------------------------
   Initialize();
   //------------------------------------------------


2. 函数执行:

void Initialize()   
{
   //------------------------------------------------
   //Opening the windows:
   //------------------------------------------------
   //1. "Main Parameters". 

    w_14_Main_Parameters();
   //------------------------------------------------

   //------------------------------------------------
   //2. "Input parameters".

   w_10_Input_parameters();
   //------------------------------------------------

   //------------------------------------------------
   //3. "Setting example 1"

   w_6_Settings_example_1();
   //------------------------------------------------


  //------------------------------------------------
  //Initializing the elements:
  //------------------------------------------------
  
   w6_d_p5_S_EDIT_Spin_the_value(55);

   w6_i_p3_H_SLIDER_Roll_the_value(55);

   w14_i_p3_V_SLIDER_Vertical_slider(55);

   w14_s_p4_EDIT_Max("100");

   w14_s_p4_EDIT_Min("0");

   w14_s_p4_EDIT_Selected("55");

   w15_i_p2_P_BAR_P1(55);

   w15_s_p4_VALUE_V1("55");
  //------------------------------------------------
}


到目前为止,我看到的函数结构如下。一个非常简单的函数。它打开窗口并将所需值发送给元素参数。有可能在某些地方改变元素的初始化和窗口的打开,因为打开窗口后将立即显示元素的所需值,而无需额外重绘。不过,这些都是次要的。


接下来我们进入正题:实现对参数的逐步保护

 

实现对参数边界的分步保护:

  • 1.编写控制预设边界设置的逻辑,并创建警告系统。
  • 2. 2.第一个警告:用户会收到一个信号,即负责设置的部分元素的颜色发生变化。(让我们 将文本、底座、框架和滑动 条的颜色 数值边界联系起来)。
  • 3. 3. 第二次警告:打开一个对话框,其中包含风险提示和返回原始设置的建议。(让我们测试一下点击 "取消 " 按钮后是否可以返回到以前的设置)。
  • 第三次 警告:打开一个警告窗口,阻止进一步更改设置并要求用户手动确认。(让我们检查警告窗口出现时窗口和元素的阻塞情况)。

//------------------------------------------------------------------------------------------------------------

编写在预设范围内控制设置的逻辑,并创建警告系统:

  • 实现的第一部分 是设置所选元素参数的初始值并打开所需的窗口。为此,我们将编写Initialise() 函数,并在 _OnInit() 函数中调用该函数。
  • 实现的第二部分--让我们打开 API 文件并编写元素连接 对于公共链中的每个元素,我们将编写调用并将值传递给其他目标元素。例如:在带按钮的字段发生事件时,我们将调用水平滑块并将值传递给它。然后,当事件发生在滑块情况下时,我们将其传递回带按钮的字段,并传递给垂直滑块。而垂直滑块则将数值传递给自身附近的输入栏和进度条窗口....。总之,在这个链中有七个主要元素在多个方向上传递数值。它们是设置示例 1" 包含"旋转数值""滚动数值"元素,"主要参数" 包含"V_SLIDER"、"选定" 字段和"百分比" 元素,"处理数据. .. "包含" 数值"" P_BAR"元素
  • 第三部分: 测试连接。
  • 第四部分: 编写一个参数控制函数,其条件名称为:void Risk_management_group_1()。该函数的任务是向用户发出信号,告知用户该组元素中 的危险值已接近极限,并在超出允许范围时发出警告。该函数将接受来自相关元素的值,并将它们通过条件中的设置过滤器。我们将通过适当风险等级的文本和框架颜色变化来实施警告,并将其发送给链中的所有元素。同时,我们还将调用阻塞窗口,不允许用户在没有额外确认的情况下继续操作。
  • 第五部分: 测试功能的工作情况。

//-----------------------------------------------------------------------------

让我们继续

1. 设置所选元素参数的初始值,并打开必要的窗口。为此,让我们编写Initialise() 函数 ,并 _OnInit() 函数中调用它。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int _OnInit()
  {
   //------------------------------------------------
   //Initializing program interface:
   //------------------------------------------------
   Initialize();
   //------------------------------------------------
void Initialize()   
{
   //------------------------------------------------
   //Opening the windows:
   //------------------------------------------------
   //1. "Main Parameters". 
    w_14_Main_Parameters();

   //2. "Input parameters".
   w_10_Input_parameters();

   //3. "Setting example 1"
   w_6_Settings_example_1();

   //------------------------------------------------
  //Initializing the elements:
  //------------------------------------------------
   w6_d_p5_S_EDIT_Spin_the_value(55);
   w6_i_p3_H_SLIDER_Roll_the_value(55);
   w14_i_p3_V_SLIDER_Vertical_slider(55);
   w14_s_p4_EDIT_Max("100");
   w14_s_p4_EDIT_Min("0");
   w14_s_p4_EDIT_Selected("55");
   w15_i_p2_P_BAR_P1(55);
   w15_s_p4_VALUE_V1("55");
  //------------------------------------------------
}

结果:打开所需窗口并为目标元素 设置初始值


2.打开 API 文件并写入元素连接 每个元素的情况下,写入调用并将值传递给链中的其他目标元素

case Settings_example_1___Spin_the_value:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when the value is set?
               //------------------------------------------------------------------------------------------------------
               //Min value:  NOT SET  |   Max value:  NOT SET  |   V_step:  1.7  |   Default value:  468.99  |  Digits: 3
               //------------------------------------------------------------------------------------------------------
               w6_i_p3_H_SLIDER_Roll_the_value((int)value);

               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
case Settings_example_1___Roll_the_value:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when the slider's handle is moved?
               //------------------------------------------------------------------------------------------------------
               //Min value:  0  |   Max value:  100  |   V_step:  1  |   Default value:  55  |  Digits: Integer value
               //------------------------------------------------------------------------------------------------------
               //Transferring the value:
               w14_i_p3_V_SLIDER_Vertical_slider((int)value);

               w6_d_p5_S_EDIT_Spin_the_value((double)value);
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
case Main_Parameters___Vertical_slider:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when the slider's handle is moved?
               //------------------------------------------------------------------------------------------------------
               //Min value:  0  |   Max value:  100  |   V_step:  1  |   Default value:  50  |  Digits: Integer value
               //------------------------------------------------------------------------------------------------------
               {
                //----------------------------------------------------- 
                //Transferring value to other destinations:
                //----------------------------------------------------- 
                w14_s_p4_EDIT_Percent(value);
                //-----------------------------------------------------
                w14_s_p4_EDIT_Selected(value);
                //-----------------------------------------------------
                w15_i_p2_P_BAR_P1((int)value);
                //-----------------------------------------------------
                w15_s_p4_VALUE_V1(value);
                //-----------------------------------------------------
                w6_i_p3_H_SLIDER_Roll_the_value((int)value);
                //-----------------------------------------------------
                w6_d_p5_S_EDIT_Spin_the_value((double)value);
                //-----------------------------------------------------
                w8_s_p4_CELL_Account_balance__Value(value);
                //------------------------------------------------------------------------------------------------------
                //Your comment:
                //------------------------------------------------------------------------------------------------------
               }
               break;


3.3. 测试连接:

结果:元素值按预期连接



4.编写一个函数来控制元素组的参数:void Risk_management_group_1()

void Risk_management_group_1(string value)
{
 uint Color = 0;
 //--------------------
 static uint This_color;
 static bool User_warned, Last_warning;
 //------------------------------------------------------------
 //Setting limit colors:
 //------------------------------------------------------------
 if((int)value < 25)                      Color = clrLightGreen;
 //------------------------------------------------------------
 if((int)value >= 25 && (int)value < 50)  Color = clrLimeGreen;
 //------------------------------------------------------------
 if((int)value >= 50 && (int)value < 70)  Color = clrGreen;
 //------------------------------------------------------------
 if((int)value >= 70 && (int)value < 85)  Color = clrDarkGreen;
 //------------------------------------------------------------
 if((int)value >= 85 && (int)value < 90)  Color = clrBrown;
 //------------------------------------------------------------
 if((int)value >= 90 && (int)value < 95)  Color = C'170,0,0';
 //------------------------------------------------------------
 if((int)value >= 95 && (int)value <=100) Color = clrRed;
 //------------------------------------------------------------  

 //------------------------------------------------------------ 
 //Changing colors when the limits are passed:
 //------------------------------------------------------------
 if(This_color != Color)
   {
    w14_s_p4_EDIT_Percent((string)Color, p4_COLOR_base); 
    //-----------------------------------------------------
    w14_s_p4_EDIT_Selected((string)Color, p4_COLOR_base); 
    //-----------------------------------------------------
    w15_i_p2_P_BAR_P1(Color, p2_COLOR_bar);
    w15_i_p2_P_BAR_P1(Color, p2_COLOR_frame);
    w15_s_p4_VALUE_V1((string)Color, p4_COLOR_frame);
                   
    w8_s_p4_CELL_Account_balance__Value((string)Color, p4_COLOR_text);
    w8_s_p4_CELL_Account_balance__Value((string)Color, p4_COLOR_frame);
    //-----------------------------------------------------
    w14_i_p3_V_SLIDER_Vertical_slider(Color,p3_COLOR_bar);
    //-----------------------------------------------------
    w15_s_p4_VALUE_V1((string)Color, p4_COLOR_text);
    //-----------------------------------------------------
    w6_i_p3_H_SLIDER_Roll_the_value(Color,p3_COLOR_bar);
    //-----------------------------------------------------
    w6_d_p5_S_EDIT_Spin_the_value((double)Color, p5_COLOR_text);
    //-----------------------------------------------------
    w6_d_p5_S_EDIT_Spin_the_value((double)Color, p5_COLOR_frame);
    //-----------------------------------------------------
    w14_i_p1_BUTTON_BUY_OFF(Color, p1_N_COLOR_frame);
    w14_i_p1_BUTTON_BUY_OFF(Color, p1_A_COLOR_frame);
    //-----------------------------------------------------
    w14_i_p1_BUTTON_SELL_OFF(Color, p1_N_COLOR_frame);
    w14_i_p1_BUTTON_SELL_OFF(Color, p1_A_COLOR_frame);
    //-----------------------------------------------------
    w7_s_p4_EDIT_Comment_1(Color, p4_COLOR_frame);
    //-----------------------------------------------------
    This_color = Color;
    //-----------------------------------------------------
   }   
 //-----------------------------------------------------
 //Opening warning window 1:
 //-----------------------------------------------------
 if((int)value >= 85 && (int)value < 95 && !User_warned)
   { 
    //---------------------------------
    //Opening dialog window:
    //---------------------------------
    w_13_Risky_managment(); 
    //---------------------------------
    //Setting flag of warning 1:
    //---------------------------------
    User_warned = true;
    //---------------------------------
   }
 //-----------------------------------------------------
 if((int)value < 85)User_warned = false;
 //-----------------------------------------------------
 //Opening warning window 2:
 //-----------------------------------------------------
 if((int)value >= 96 && !Last_warning)
   { 
    //---------------------------------
    //Calling blocking window:
    //---------------------------------
    w_17_Last_warning();
    //---------------------------------
    //Setting flag of warning 2:
    //---------------------------------
    Last_warning = true;
    //---------------------------------
   }
 //-----------------------------------------------------
 if((int)value < 95)Last_warning = false;                
 //-----------------------------------------------------                 
}

在 _OnInit() 函数中调用 Risk_management_group_1() 函数:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int _OnInit()
  {
   //------------------------------------------------
   //Initializing program interface:
   //------------------------------------------------
   Initialize();
   //----------------------------------------------------------
   //Checking default value of the parameters in the group:  
   //----------------------------------------------------------
   Risk_management_group_1();
   //----------------------------------------------------------