持仓图表

OptionPositionChart 图形组件是一个显示与标的资产相关的持仓及期权“希腊值”的图表。

以下是 SampleOptionQuoting 示例,其中使用了该图表。示例的源代码可以在 Samples/06_Strategies/09_LiveOptionsQuoting 文件夹中找到。

期权波动率微笑

SampleOptionQuoting 示例

  1. 在 XAML 代码中,添加 OptionPositionChart 元素,并将其命名为 PosChart

    <Window x:Class="OptionCalculator.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:loc="clr-namespace:StockSharp.Localization;assembly=StockSharp.Localization"
            xmlns:xaml="http://schemas.stocksharp.com/xaml"
            Title="{x:Static loc:LocalizedStrings.XamlStr396}" Height="400" Width="1030">
        <Grid Margin="5,5,5,5">
    
         .........................................................
    
         <xaml:OptionPositionChart x:Name="PosChart" Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="6" />
     </Grid>
    </Window>
    
    
  2. 在 C# 代码中,创建一个连接并订阅必要的事件。

    ...                 
    public readonly Connector Connector = new Connector();
    ...                 
    // 订阅连接成功事件
    Connector.Connected += () =>
    {
     // 更新界面标签
     this.GuiAsync(() => ChangeConnectStatus(true));
    };
    // 订阅断开连接事件
    Connector.Disconnected += () =>
    {
     // 更新界面标签
     this.GuiAsync(() => ChangeConnectStatus(false));
    };
    // 订阅连接错误事件
    Connector.ConnectionError += error => this.GuiAsync(() =>
    {
     // 更新界面标签
     ChangeConnectStatus(false);
     MessageBox.Show(this, error.ToString(), LocalizedStrings.ErrorConnection);
    });
    // 填充标的资产列表
    Connector.SecurityReceived += (sub, security) =>
    {
     if (security.Type == SecurityTypes.Future)
     	_assets.Add(security);
    };
    Connector.Level1Received += (sub, security) =>
    {
     if (_model.UnderlyingAsset == security || _model.UnderlyingAsset.Id == security.UnderlyingSecurityId)
     	_isDirty = true;
    };
    // 订阅 tick 价格并更新资产价格
    Connector.TickTradeReceived += (sub, trade) =>
    {
     if (_model.UnderlyingAsset == trade.Security || _model.UnderlyingAsset.Id == trade.Security.UnderlyingSecurityId)
     	_isDirty = true;
    };
    Connector.NewPosition += position => this.GuiAsync(() =>
    {
     var asset = SelectedAsset;
     if (asset == null)
     	return;
     var assetPos = position.Security == asset;
     var newPos = position.Security.UnderlyingSecurityId == asset.Id;
     if (!assetPos && !newPos)
     	return;
     RefreshChart();
    });
    Connector.PositionChanged += position => this.GuiAsync(() =>
    {
     if ((PosChart.AssetPosition != null && PosChart.AssetPosition == position) || PosChart.Positions.Cache.Contains(position))
     	RefreshChart();
    });
    try
    {
     if (File.Exists(_settingsFile))
     	Connector.Load(new JsonSerializer<SettingsStorage>().Deserialize(_settingsFile));
    }
    ...
    
  3. 连接时,设置初始控制设置:

    1. 正在重置 OptionPositionChart.Model 控件的模型;
    2. 使用初始值重新绘制图表 OptionPositionChart.Refresh(System.Nullable<System.Decimal> assetPrice, System.Nullable<System.DateTimeOffset> currentTime, System.Nullable<System.DateTimeOffset> expiryDate );
    3. 为市场数据和工具指定消息提供者。
    private void ConnectClick(object sender, RoutedEventArgs e)
    {
     if (!_isConnected)
     {
     	ConnectBtn.IsEnabled = false;
    ...
     	PosChart.Model = null;
    ...
     	PosChart.MarketDataProvider = Connector;
     	PosChart.SecurityProvider = Connector;
     	PosChart.PositionProvider = Connector;
     	Connector.Connect();
     }
     else
     	Connector.Disconnect();
    }
    
  4. 在接收工具时,我们将基础资产添加到清单中。

    Connector.SecurityReceived += (sub, security) =>
    {
     if (security.Type == SecurityTypes.Future)
     	_assets.Add(security);
    };
    
  5. 在更改基础工具或期权的 Level1,或者获得新的交易时,我们会设置 _isDirty 标志。这允许在定时器事件中调用 RefreshChart 方法(见下文)(代码省略)来重新绘制图表。这样我们就可以控制重绘的频率。

    Connector.Level1Received += (sub, security) =>
    {
     if (_model.UnderlyingAsset == security || _model.UnderlyingAsset.Id == security.UnderlyingSecurityId)
     	_isDirty = true;
    };
    Connector.TickTradeReceived += (sub, trade) =>
    {
     if (_model.UnderlyingAsset == trade.Security || _model.UnderlyingAsset.Id == trade.Security.UnderlyingSecurityId)
     	_isDirty = true;
    };
    
  6. 在新位置发生事件处理程序中,我们调用RefreshChart来重绘图表。

    Connector.NewPosition += position => this.GuiAsync(() =>
    {
     var asset = SelectedAsset;
     if (asset == null)
     	return;
     var assetPos = position.Security == asset;
     var newPos = position.Security.UnderlyingSecurityId == asset.Id;
     if (!assetPos && !newPos)
     	return;
     RefreshChart();
    });
    Connector.PositionChanged += position => this.GuiAsync(() =>
    {
     if ((PosChart.AssetPosition != null && PosChart.AssetPosition == position) || PosChart.Positions.Cache.Contains(position))
     	RefreshChart();
    });
    
  7. 此方法会重绘图表:

    private void RefreshChart()
    {
     var asset = SelectedAsset;
     var trade = asset.LastTrade;
     if (trade != null)
     	PosChart.Refresh(trade.Price);
    }
    

推荐内容

波动性交易