StockSharp
349 строк · 11.9 Кб
1#region S# License2/******************************************************************************************
3NOTICE!!! This program and source code is owned and licensed by
4StockSharp, LLC, www.stocksharp.com
5Viewing or use of this code requires your acceptance of the license
6agreement found at https://github.com/StockSharp/StockSharp/blob/master/LICENSE
7Removal of this comment is a violation of the license agreement.
8
9Project: StockSharp.BusinessEntities.BusinessEntities
10File: UnitHelper.cs
11Created: 2015, 11, 11, 2:32 PM
12
13Copyright 2010 by StockSharp, LLC
14*******************************************************************************************/
15#endregion S# License16namespace StockSharp.BusinessEntities17{
18using System;19using System.Collections.Generic;20using System.Linq;21using System.Reflection;22
23using Ecng.Common;24using Ecng.Reflection;25
26using StockSharp.Localization;27using StockSharp.Messages;28
29/// <summary>30/// Extension class for <see cref="BusinessEntities"/>.31/// </summary>32public static class EntitiesExtensions33{34/// <summary>35/// To create from <see cref="int"/> the pips values.36/// </summary>37/// <param name="value"><see cref="int"/> value.</param>38/// <param name="security">The instrument from which information about the price increment is taken.</param>39/// <returns>Pips.</returns>40public static Unit Pips(this int value, Security security)41{42return Pips((decimal)value, security);43}44
45/// <summary>46/// To create from <see cref="double"/> the pips values.47/// </summary>48/// <param name="value"><see cref="double"/> value.</param>49/// <param name="security">The instrument from which information about the price increment is taken.</param>50/// <returns>Pips.</returns>51public static Unit Pips(this double value, Security security)52{53return Pips((decimal)value, security);54}55
56/// <summary>57/// To create from <see cref="decimal"/> the pips values.58/// </summary>59/// <param name="value"><see cref="decimal"/> value.</param>60/// <param name="security">The instrument from which information about the price increment is taken.</param>61/// <returns>Pips.</returns>62public static Unit Pips(this decimal value, Security security)63{64if (security == null)65throw new ArgumentNullException(nameof(security));66
67return new Unit(value, UnitTypes.Step, type => GetTypeValue(security, type));68}69
70/// <summary>71/// To create from <see cref="int"/> the points values.72/// </summary>73/// <param name="value"><see cref="int"/> value.</param>74/// <param name="security">The instrument from which information about the price increment cost is taken.</param>75/// <returns>Points.</returns>76public static Unit Points(this int value, Security security)77{78return Points((decimal)value, security);79}80
81/// <summary>82/// To create from <see cref="double"/> the points values.83/// </summary>84/// <param name="value"><see cref="double"/> value.</param>85/// <param name="security">The instrument from which information about the price increment cost is taken.</param>86/// <returns>Points.</returns>87public static Unit Points(this double value, Security security)88{89return Points((decimal)value, security);90}91
92/// <summary>93/// To create from <see cref="decimal"/> the points values.94/// </summary>95/// <param name="value"><see cref="decimal"/> value.</param>96/// <param name="security">The instrument from which information about the price increment cost is taken.</param>97/// <returns>Points.</returns>98public static Unit Points(this decimal value, Security security)99{100if (security == null)101throw new ArgumentNullException(nameof(security));102
103return new Unit(value, UnitTypes.Point, type => GetTypeValue(security, type));104}105
106/// <summary>107/// Convert string to <see cref="Unit"/>.108/// </summary>109/// <param name="str">String value of <see cref="Unit"/>.</param>110/// <param name="throwIfNull">Throw <see cref="ArgumentNullException"/> if the specified string is empty.</param>111/// <param name="security">Information about the instrument. Required when using <see cref="UnitTypes.Point"/> и <see cref="UnitTypes.Step"/>.</param>112/// <returns>Object <see cref="Unit"/>.</returns>113public static Unit ToUnit2(this string str, bool throwIfNull = true, Security security = null)114{115return str.ToUnit(throwIfNull, t => GetTypeValue(security, t));116}117
118/// <summary>119/// Cast the value to another type.120/// </summary>121/// <param name="unit">Source unit.</param>122/// <param name="destinationType">Destination value type.</param>123/// <param name="security">Information about the instrument. Required when using <see cref="UnitTypes.Point"/> и <see cref="UnitTypes.Step"/>.</param>124/// <returns>Converted value.</returns>125public static Unit Convert(this Unit unit, UnitTypes destinationType, Security security)126{127return unit.Convert(destinationType, type => GetTypeValue(security, type));128}129
130internal static decimal ShrinkPrice(this Security security, decimal price)131{132if (security == null)133throw new ArgumentNullException(nameof(security));134
135if (security.PriceStep == null)136throw new ArgumentException(LocalizedStrings.PriceStepNotSpecified, nameof(security));137
138return price.Round(security.PriceStep ?? 1m, security.Decimals ?? 0);139}140
141/// <summary>142/// To set the <see cref="Unit.GetTypeValue"/> property for the value.143/// </summary>144/// <param name="unit">Unit.</param>145/// <param name="security">Security.</param>146/// <returns>Unit.</returns>147public static Unit SetSecurity(this Unit unit, Security security)148{149if (unit is null)150throw new ArgumentNullException(nameof(unit));151
152unit.GetTypeValue = type => GetTypeValue(security, type);153
154return unit;155}156
157private static decimal? GetTypeValue(Security security, UnitTypes type)158{159switch (type)160{161case UnitTypes.Point:162if (security == null)163throw new ArgumentNullException(nameof(security));164
165return security.StepPrice;166case UnitTypes.Step:167if (security == null)168throw new ArgumentNullException(nameof(security));169
170return security.PriceStep;171default:172throw new ArgumentOutOfRangeException(nameof(type), type, LocalizedStrings.InvalidValue);173}174}175
176/// <summary>177/// Reregister the order.178/// </summary>179/// <param name="provider">The transactional provider.</param>180/// <param name="order">Order.</param>181/// <param name="clone">Changes.</param>182public static void ReRegisterOrderEx(this ITransactionProvider provider, Order order, Order clone)183{184if (provider is null)185throw new ArgumentNullException(nameof(provider));186
187if (provider.IsOrderReplaceable(order) == true)188{189if (provider.IsOrderEditable(order) == true)190provider.EditOrder(order, clone);191else192provider.ReRegisterOrder(order, clone);193}194else195{196provider.CancelOrder(order);197provider.RegisterOrder(clone);198}199}200
201/// <summary>202/// To create copy of the order for re-registration.203/// </summary>204/// <param name="oldOrder">The original order.</param>205/// <param name="newPrice">Price of the new order.</param>206/// <param name="newVolume">Volume of the new order.</param>207/// <returns>New order.</returns>208public static Order ReRegisterClone(this Order oldOrder, decimal? newPrice = null, decimal? newVolume = null)209{210if (oldOrder == null)211throw new ArgumentNullException(nameof(oldOrder));212
213return new Order214{215Portfolio = oldOrder.Portfolio,216Side = oldOrder.Side,217TimeInForce = oldOrder.TimeInForce,218Security = oldOrder.Security,219Type = oldOrder.Type,220Price = newPrice ?? oldOrder.Price,221Volume = newVolume ?? oldOrder.Volume,222ExpiryDate = oldOrder.ExpiryDate,223VisibleVolume = oldOrder.VisibleVolume,224BrokerCode = oldOrder.BrokerCode,225ClientCode = oldOrder.ClientCode,226Condition = oldOrder.Condition?.TypedClone(),227IsManual = oldOrder.IsManual,228IsMarketMaker = oldOrder.IsMarketMaker,229IsMargin = oldOrder.IsMargin,230MinVolume = oldOrder.MinVolume,231PositionEffect = oldOrder.PositionEffect,232PostOnly = oldOrder.PostOnly,233StrategyId = oldOrder.StrategyId,234Leverage = oldOrder.Leverage,235};236}237
238/// <summary>239/// Reregister the order.240/// </summary>241/// <param name="provider">The transactional provider.</param>242/// <param name="oldOrder">Changing order.</param>243/// <param name="price">Price of the new order.</param>244/// <param name="volume">Volume of the new order.</param>245/// <returns>New order.</returns>246public static Order ReRegisterOrder(this ITransactionProvider provider, Order oldOrder, decimal price, decimal volume)247{248if (provider == null)249throw new ArgumentNullException(nameof(provider));250
251var newOrder = oldOrder.ReRegisterClone(price, volume);252provider.ReRegisterOrder(oldOrder, newOrder);253return newOrder;254}255
256/// <summary>257/// Get portfolio identifier.258/// </summary>259/// <param name="portfolio">Portfolio.</param>260/// <returns>Portfolio identifier.</returns>261[Obsolete("Use Portfolio.Name property.")]262public static string GetUniqueId(this Portfolio portfolio)263{264if (portfolio == null)265throw new ArgumentNullException(nameof(portfolio));266
267return /*portfolio.InternalId?.To<string>() ?? */portfolio.Name;268}269
270/// <summary>271/// To get the instrument by the identifier.272/// </summary>273/// <param name="provider">The provider of information about instruments.</param>274/// <param name="id">Security ID.</param>275/// <returns>The got instrument. If there is no instrument by given criteria, <see langword="null" /> is returned.</returns>276public static Security LookupByStringId(this ISecurityProvider provider, string id)277{278return provider.LookupById(id.ToSecurityId());279}280
281private const BindingFlags _publicStatic = BindingFlags.Public | BindingFlags.Static;282
283/// <summary>284/// To get a list of exchanges.285/// </summary>286/// <returns>Exchanges.</returns>287public static IEnumerable<Exchange> EnumerateExchanges()288=> typeof(Exchange)289.GetMembers<PropertyInfo>(_publicStatic, typeof(Exchange))290.Select(prop => (Exchange)prop.GetValue(null, null));291
292/// <summary>293/// To get a list of boards.294/// </summary>295/// <returns>Boards.</returns>296public static IEnumerable<ExchangeBoard> EnumerateExchangeBoards()297=> typeof(ExchangeBoard)298.GetMembers<PropertyInfo>(_publicStatic, typeof(ExchangeBoard))299.Select(prop => (ExchangeBoard)prop.GetValue(null, null));300
301/// <summary>302/// To convert the message into tick trade.303/// </summary>304/// <param name="message">Message.</param>305/// <param name="security">Security.</param>306/// <returns>Tick trade.</returns>307[Obsolete("Use ITickTradeMessage.")]308public static Trade ToTrade(this ExecutionMessage message, Security security)309{310if (security == null)311throw new ArgumentNullException(nameof(security));312
313return message.ToTrade(new Trade { Security = security });314}315
316/// <summary>317/// To convert the message into tick trade.318/// </summary>319/// <param name="message">Message.</param>320/// <param name="trade">Tick trade.</param>321/// <returns>Tick trade.</returns>322[Obsolete("Use ITickTradeMessage.")]323public static Trade ToTrade(this ExecutionMessage message, Trade trade)324{325if (message == null)326throw new ArgumentNullException(nameof(message));327
328trade.Id = message.TradeId;329trade.StringId = message.TradeStringId;330trade.Price = message.TradePrice ?? 0;331trade.Volume = message.TradeVolume ?? 0;332trade.Status = message.TradeStatus;333trade.IsSystem = message.IsSystem;334trade.ServerTime = message.ServerTime;335trade.LocalTime = message.LocalTime;336trade.OpenInterest = message.OpenInterest;337trade.OriginSide = message.OriginSide;338trade.IsUpTick = message.IsUpTick;339trade.Currency = message.Currency;340trade.SeqNum = message.SeqNum;341trade.BuildFrom = message.BuildFrom;342trade.Yield = message.Yield;343trade.OrderBuyId = message.OrderBuyId;344trade.OrderSellId = message.OrderSellId;345
346return trade;347}348}349}