代码拉取完成,页面将自动刷新
同步操作将从 yu3a/StockSharp 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#region S# License
/******************************************************************************************
NOTICE!!! This program and source code is owned and licensed by
StockSharp, LLC, www.stocksharp.com
Viewing or use of this code requires your acceptance of the license
agreement found at https://github.com/StockSharp/StockSharp/blob/master/LICENSE
Removal of this comment is a violation of the license agreement.
Project: StockSharp.Algo.Algo
File: BasketPortfolio.cs
Created: 2015, 11, 11, 2:32 PM
Copyright 2010 by StockSharp, LLC
*******************************************************************************************/
#endregion S# License
namespace StockSharp.Algo
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Ecng.Common;
using Ecng.Collections;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// Basket portfolio.
/// </summary>
public abstract class BasketPortfolio : Portfolio
{
/// <summary>
/// Portfolios from which this basket is created.
/// </summary>
[Browsable(false)]
public abstract IEnumerable<Portfolio> InnerPortfolios { get; }
/// <summary>
/// Positions from which this basket is created.
/// </summary>
[Browsable(false)]
public abstract IEnumerable<BasketPosition> InnerPositions { get; }
}
/// <summary>
/// Portfolios basket based on the weights <see cref="WeightedPortfolio.Weights"/>.
/// </summary>
public class WeightedPortfolio : BasketPortfolio
{
private sealed class WeightsDictionary : CachedSynchronizedDictionary<Portfolio, decimal>
{
private sealed class WeightedPosition : BasketPosition
{
public WeightedPosition(WeightedPortfolio portfolio, IEnumerable<Position> innerPositions)
{
_innerPositions = innerPositions ?? throw new ArgumentNullException(nameof(innerPositions));
decimal? beginValue = null;
decimal? currentValue = null;
decimal? blockedValue = null;
foreach (var position in _innerPositions)
{
var mult = portfolio.Weights[position.Portfolio];
if (beginValue == null)
beginValue = mult * position.BeginValue;
else
beginValue += mult * position.BeginValue;
if (currentValue == null)
currentValue = mult * position.CurrentValue;
else
currentValue += mult * position.CurrentValue;
if (blockedValue == null)
blockedValue = mult * position.BlockedValue;
else
blockedValue += mult * position.BlockedValue;
}
BeginValue = beginValue;
BlockedValue = blockedValue;
CurrentValue = currentValue;
}
private readonly IEnumerable<Position> _innerPositions;
public override IEnumerable<Position> InnerPositions => _innerPositions;
}
private readonly WeightedPortfolio _parent;
private readonly IConnector _connector;
public WeightsDictionary(WeightedPortfolio parent, IConnector connector)
{
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
_connector = connector;
}
public IEnumerable<BasketPosition> Positions
{
get
{
return CachedKeys
.SelectMany(pf => _connector.Positions.Where(pos => pos.Portfolio == pf))
.GroupBy(pos => pos.Security)
.Select(g => new WeightedPosition(_parent, g));
}
}
public override void Add(Portfolio key, decimal value)
{
base.Add(key, value);
((INotifyPropertyChanged)key).PropertyChanged += OnPortfolioChanged;
RefreshName();
}
public override bool Remove(Portfolio key)
{
if (base.Remove(key))
{
((INotifyPropertyChanged)key).PropertyChanged -= OnPortfolioChanged;
RefreshName();
return true;
}
return false;
}
public override void Clear()
{
foreach (var portfolio in CachedKeys)
Remove(portfolio);
}
private void OnPortfolioChanged(object sender, PropertyChangedEventArgs e)
{
RefreshParent();
}
private void RefreshName()
{
_parent.Name = CachedPairs.Select(p => $"{p.Value}*{p.Key}").JoinCommaSpace();
RefreshParent();
}
private void RefreshParent()
{
var currencyType = _parent.Currency;
var beginValue = 0m.ToCurrency(currencyType ?? CurrencyTypes.USD);
var currentValue = 0m.ToCurrency(currencyType ?? CurrencyTypes.USD);
var leverage = 0m.ToCurrency(currencyType ?? CurrencyTypes.USD);
var commission = 0m.ToCurrency(currencyType ?? CurrencyTypes.USD);
foreach (var pair in CachedPairs)
{
var portfolio = pair.Key;
var weight = (Currency)pair.Value;
beginValue += Multiple(beginValue, weight, portfolio.BeginValue);
currentValue += Multiple(currentValue, weight, portfolio.CurrentValue);
leverage += Multiple(leverage, weight, portfolio.Leverage);
commission += Multiple(commission, weight, portfolio.Commission);
}
_parent.BeginValue = beginValue.Value;
_parent.CurrentValue = currentValue.Value;
_parent.Leverage = leverage.Value / Count;
_parent.Commission = commission.Value;
}
private static Currency Multiple(Currency currency, Currency weight, Currency part)
{
if (currency == null)
throw new ArgumentNullException(nameof(currency));
if (part == null)
throw new ArgumentNullException(nameof(part));
if (currency.Type != part.Type)
part = part.Convert(currency.Type);
return currency * weight * part;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="WeightedPortfolio"/>.
/// </summary>
/// <param name="connector">The connection of interaction with trade systems.</param>
public WeightedPortfolio(IConnector connector)
{
_weights = new WeightsDictionary(this, connector);
}
private readonly WeightsDictionary _weights;
/// <summary>
/// Instruments and their weighting coefficients in the basket.
/// </summary>
public SynchronizedDictionary<Portfolio, decimal> Weights => _weights;
/// <summary>
/// Portfolios from which this basket is created.
/// </summary>
public override IEnumerable<Portfolio> InnerPortfolios => _weights.CachedKeys;
/// <summary>
/// Positions from which this basket is created.
/// </summary>
public override IEnumerable<BasketPosition> InnerPositions => _weights.Positions;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。