股票量化:赫兹量化中自动优化器的逻辑部分与图形绑定

ViewModel 类与图形层的交互

如前所述,ViewModel 是应用程序的图形部分与软件逻辑实现之间的连接器。 它是程序图形表述,其实现应用程序逻辑调用,并针对应用程序逻辑部分的回调在图形上做出反应。 相应地,来自 ViewModel 部分的公开属性对应于应用程序图形部分中的每个可编辑字段。 这些属性可以是 getter(只读),在这种情况下不能在图形中更改;也可以是 setter,如此即可覆盖隐藏在此属性后面的对象。 在前面的部分里,我们已经详细研究过数据绑定技术。 故此,我在这里仅提供一些示例。 

文本字段是通过可读写权限的属性进行连接。 举例,考虑一个字段,该字段指示正在执行优化的资产名称。 该字段的 XAML 标记极其简单。

 

<TextBox Width="100"          IsEnabled="{Binding EnableMainTogles, UpdateSourceTrigger=PropertyChanged}"          Text="{Binding AssetName}"/>

除了设置文本窗口的宽度外,它还含有字段 IsEnabled 和 Text。 第一个设置该字段是否可编辑。 如果将其设置为 true,则该字段可编辑。 如果为 false,则该字段被锁定。 “Text” 字段包含在此字段中输入的文本。 然后,每个结构都有一对花括号。 其内容设置对象与特定公共属性的连接,而属性来自在 “Binding” 参数之后指定的 ViewModel 类。

后还可以跟一定数量的参数。 例如,UpdateSourceTrigger 参数指示此应用程序的图形部分的更新方法。 在我们的示例中使用的值(PropertyChanged)表示,仅当触发 ViewModel 类中的 OnPropertyChanged 事件时,图形部分才会更新,并且在 “Binding” 参数之后指定传递的名称(在本例中为 “EnableMainTogles”) 。

如果 “Text” 参数并未与字符串绑定,而是绑定 double 型参数,则此字段中仅允许数字。 如果绑定到 int 类型,则只允许整数型。 换言之,此实现能够依据需求设置输入值的类型。

在 ViewModel 部分里,字段显示如下:

IsEnabled 参数:

 

/// <summary> /// If the switch = false, then the most important fields are not available /// </summary> public bool EnableMainTogles { get; private set; } = true;

以及 Text 参数:

 

/// <summary> /// Name of the asset selected for tests / optimization /// </summary> public string AssetName { get; set; }

如您所见,它们两个都即可写入也可读取数据。 仅有的区别在于 EnableMainTogles 属性仅提供来自 AutoOptimiserVM 类的写入访问权限(即,来自其自身),因此无法从外部对其进行编辑。

如果我们研究任何数据集合,譬如举例来说,前向验证优化结果列表,则它所对应的属性包含数值列表。 我们来研究一个含前向验证结果的表格:

 

<ListView ItemsSource="{Binding ForwardOptimisations}"           SelectedIndex="{Binding SelectedForwardItem}"           v:ListViewExtention.DoubleClickCommand="{Binding StartTestForward}">     <ListView.View>         <GridView>             <GridViewColumn Header="Date From"                             DisplayMemberBinding="{Binding From}"/>             <GridViewColumn Header="Date Till"                             DisplayMemberBinding="{Binding Till}"/>             <GridViewColumn Header="Payoff"                             DisplayMemberBinding="{Binding Payoff}"/>             <GridViewColumn Header="Profit pactor"                             DisplayMemberBinding="{Binding ProfitFactor}"/>             <GridViewColumn Header="Average Profit Factor"                             DisplayMemberBinding="{Binding AverageProfitFactor}"/>             <GridViewColumn Header="Recovery factor"                             DisplayMemberBinding="{Binding RecoveryFactor}"/>             <GridViewColumn Header="Average Recovery Factor"                             DisplayMemberBinding="{Binding AverageRecoveryFactor}"/>             <GridViewColumn Header="PL"                             DisplayMemberBinding="{Binding PL}"/>             <GridViewColumn Header="DD"                             DisplayMemberBinding="{Binding DD}"/>             <GridViewColumn Header="Altman Z score"                             DisplayMemberBinding="{Binding AltmanZScore}"/>             <GridViewColumn Header="Total trades"                             DisplayMemberBinding="{Binding TotalTrades}"/>             <GridViewColumn Header="VaR 90"                             DisplayMemberBinding="{Binding VaR90}"/>             <GridViewColumn Header="VaR 95"                             DisplayMemberBinding="{Binding VaR95}"/>             <GridViewColumn Header="VaR 99"                             DisplayMemberBinding="{Binding VaR99}"/>             <GridViewColumn Header="Mx"                             DisplayMemberBinding="{Binding Mx}"/>             <GridViewColumn Header="Std"                             DisplayMemberBinding="{Binding Std}"/>         </GridView>     </ListView.View> </ListView>

从标记中可以看出,ListView 类型表是表格类本身的引用。 接下来是创建网格,即会在其中存储数据,和数据列。 提到所创建的类引用,我指的是 ListView 类。 这种看似简单的 XAML 标记代表了一种相当复杂,且经过深思熟虑的机制,该机制允许利用标记语言描述类,并操控类对象。 我们与 AutoOptimiserVM 类关联的所有字段都是这些类的属性。 在上面的表格示例中,我们处理了三个类:

  • ListView — System.Windows.Controls.ListView.
  • GridView — System.Windows.Controls.GridView,它是从 System.Windows.Controls.ViewBase 派生的,因此可用作 ListView 类 View 属性的初始化类。
  • GridViewColumn — System.Windows.Controls.GridViewColumn.

ListView 类的 ItemsSource属性代表由表格构成的元素集合。 将此属性与 ViewModel 的集合连接后,我们为 Window 类提供了一种 DataContext,该 DataContext 要在表格中操作。 由于我们正在谈论一个表格,因此代表集合的表格必须由含有每个表格公开属性的类构成。 将 ItemsSource 属性与 ViewModel 的属性绑定在一起之后,该属性表示一个带有数据的表格,我们可以将每列与给定表格中的所需列值进行绑定。 此外,该表格还含有 SelectedIndex 属性和 ViewModel 中的 SelectedForwardItem 属性的连接。 ViewModel 需要知道用户在此表格中所选择的行。

在 ViewModel 部分中,与表格呈现绑定的属性实现如下:

 

/// <summary> /// Selected forward tests /// </summary> public ObservableCollection<ReportItem> ForwardOptimisations { get; } = new ObservableCollection<ReportItem>();

C# 标准库中的 ObservableCollection 类是一个对象,用于通知图形有关修改的信息。 这是因为该类已经含所提到的事件,并在每次更新其元素列表时都会调用它。 至于其余的,它是标准的数据集合。

SelectedForwardItem 属性执行若干角色:它在所选表格行上存储数据,并作为行选择回调。

 

/// <summary> /// Selected forward pass /// </summary> private int _selectedForwardItem; public int SelectedForwardItem {     get => _selectedForwardItem;     set     {         _selectedForwardItem = value;         if (value > -1)         {             FillInBotParams(model.ForwardOptimisations[value]);             FillInDailyPL(model.ForwardOptimisations[value]);             FillInMaxPLDD(model.ForwardOptimisations[value]);         }     } } 

由于该属性用作回调,因此(在我们的示例中)期望针对所设置的数值做出特别反应,故此 setter 必须包含此反应的实现,并作为函数。 由此,属性值存储在私密变量中。 若要从该变量接收数值,我们可从取值器(getter)直接访问它。 若要设置一个值,在赋值器(setter)中将数值存储在 "value" 变量里。'value' 变量没有题标,在 C# 语言里作为设置数值的特定别名。 如果 “value” 大于-1,则在“结果”选项卡中填充其他相关表格,这些表格会根据所选行进行更新。 这些表格包含交易机器人参数,平均利润,交易日的亏损,以及盈亏的最高/最低值。 需要在 “if” 条件下执行检查,如果因为所选表项索引为 -1,则意味着表格为空,因此不需要填充相关表格。 AutoOptimiserVM 类代码中提供了调用方法的实现。

此处是类的实现,优化结果也含有说明行。

 

/// <summary> /// Class - a wrapper for a report item (for a graphical interval) /// </summary> class ReportItem {     /// <summary>     /// Constructor     /// </summary>     /// <param name="item">Item</param>     public ReportItem(OptimisationResult item)     {         result = item;     }     /// <summary>     /// Report item     /// </summary>     private readonly OptimisationResult result;     public DateTime From => result.report.DateBorders.From;     public DateTime Till => result.report.DateBorders.Till;     public double SortBy => result.SortBy;     public double Payoff => result.report.OptimisationCoefficients.Payoff;     public double ProfitFactor => result.report.OptimisationCoefficients.ProfitFactor;     public double AverageProfitFactor => result.report.OptimisationCoefficients.AverageProfitFactor;     public double RecoveryFactor => result.report.OptimisationCoefficients.RecoveryFactor;     public double AverageRecoveryFactor => result.report.OptimisationCoefficients.AverageRecoveryFactor;     public double PL => result.report.OptimisationCoefficients.PL;     public double DD => result.report.OptimisationCoefficients.DD;     public double AltmanZScore => result.report.OptimisationCoefficients.AltmanZScore;     public int TotalTrades => result.report.OptimisationCoefficients.TotalTrades;     public double VaR90 => result.report.OptimisationCoefficients.VaR.Q_90;     public double VaR95 => result.report.OptimisationCoefficients.VaR.Q_95;     public double VaR99 => result.report.OptimisationCoefficients.VaR.Q_99;     public double Mx => result.report.OptimisationCoefficients.VaR.Mx;     public double Std => result.report.OptimisationCoefficients.VaR.Std; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值