StockSharp
779 строк · 16.6 Кб
1#region S# License
2/******************************************************************************************
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: Position.cs
11Created: 2015, 11, 11, 2:32 PM
12
13Copyright 2010 by StockSharp, LLC
14*******************************************************************************************/
15#endregion S# License
16namespace StockSharp.BusinessEntities
17{
18using System;
19using System.ComponentModel;
20using System.ComponentModel.DataAnnotations;
21using System.Runtime.Serialization;
22using System.Xml.Serialization;
23
24using Ecng.Common;
25using Ecng.ComponentModel;
26
27using StockSharp.Messages;
28using StockSharp.Localization;
29
30/// <summary>
31/// The position by the instrument.
32/// </summary>
33[Serializable]
34[DataContract]
35[Display(
36ResourceType = typeof(LocalizedStrings),
37Name = LocalizedStrings.PositionKey,
38Description = LocalizedStrings.PositionDescKey)]
39public class Position : NotifiableObject, ILocalTimeMessage, IServerTimeMessage
40{
41DateTimeOffset IServerTimeMessage.ServerTime
42{
43get => LastChangeTime;
44set => LastChangeTime = value;
45}
46
47/// <summary>
48/// Initializes a new instance of the <see cref="Position"/>.
49/// </summary>
50public Position()
51{
52}
53
54private decimal? _beginValue;
55
56/// <summary>
57/// Position size at the beginning of the trading session.
58/// </summary>
59[DataMember]
60[Display(
61ResourceType = typeof(LocalizedStrings),
62Name = LocalizedStrings.BeginValueKey,
63Description = LocalizedStrings.PosBeginValueKey,
64GroupName = LocalizedStrings.StatisticsKey)]
65//[Nullable]
66[Browsable(false)]
67public decimal? BeginValue
68{
69get => _beginValue;
70set
71{
72if (_beginValue == value)
73return;
74
75_beginValue = value;
76NotifyChanged();
77}
78}
79
80private decimal? _currentValue;
81
82/// <summary>
83/// Current position size.
84/// </summary>
85[DataMember]
86[Display(
87ResourceType = typeof(LocalizedStrings),
88Name = LocalizedStrings.CurrentValueKey,
89Description = LocalizedStrings.CurrentPosSizeKey,
90GroupName = LocalizedStrings.StatisticsKey)]
91//[Nullable]
92//[Browsable(false)]
93public decimal? CurrentValue
94{
95get => _currentValue;
96set
97{
98if (_currentValue == value)
99return;
100
101_currentValue = value;
102NotifyChanged();
103}
104}
105
106private decimal? _blockedValue;
107
108/// <summary>
109/// Position size, registered for active orders.
110/// </summary>
111[DataMember]
112[Display(
113ResourceType = typeof(LocalizedStrings),
114Name = LocalizedStrings.BlockedKey,
115Description = LocalizedStrings.PosBlockedSizeKey,
116GroupName = LocalizedStrings.StatisticsKey)]
117//[Nullable]
118[Browsable(false)]
119public decimal? BlockedValue
120{
121get => _blockedValue;
122set
123{
124if (_blockedValue == value)
125return;
126
127_blockedValue = value;
128NotifyChanged();
129}
130}
131
132private decimal? _currentPrice;
133
134/// <summary>
135/// Position price.
136/// </summary>
137//[Ignore]
138[XmlIgnore]
139[Display(
140ResourceType = typeof(LocalizedStrings),
141Name = LocalizedStrings.PosPriceKey,
142Description = LocalizedStrings.PosPriceDescKey,
143GroupName = LocalizedStrings.StatisticsKey)]
144[Browsable(false)]
145public decimal? CurrentPrice
146{
147get => _currentPrice;
148set
149{
150if (_currentPrice == value)
151return;
152
153_currentPrice = value;
154NotifyChanged();
155}
156}
157
158private decimal? _averagePrice;
159
160/// <summary>
161/// Average price.
162/// </summary>
163//[Ignore]
164[XmlIgnore]
165[Display(
166ResourceType = typeof(LocalizedStrings),
167Name = LocalizedStrings.AveragePriceKey,
168Description = LocalizedStrings.AveragePriceCalcTradesKey,
169GroupName = LocalizedStrings.StatisticsKey)]
170[Browsable(false)]
171public decimal? AveragePrice
172{
173get => _averagePrice;
174set
175{
176if (_averagePrice == value)
177return;
178
179_averagePrice = value;
180NotifyChanged();
181}
182}
183
184private decimal? _unrealizedPnL;
185
186/// <summary>
187/// Unrealized profit.
188/// </summary>
189//[Ignore]
190[XmlIgnore]
191[Display(
192ResourceType = typeof(LocalizedStrings),
193Name = LocalizedStrings.UnrealizedProfitKey,
194Description = LocalizedStrings.UnrealizedProfitDescKey,
195GroupName = LocalizedStrings.StatisticsKey)]
196[Browsable(false)]
197public decimal? UnrealizedPnL
198{
199get => _unrealizedPnL;
200set
201{
202if (_unrealizedPnL == value)
203return;
204
205_unrealizedPnL = value;
206NotifyChanged();
207}
208}
209
210private decimal? _realizedPnL;
211
212/// <summary>
213/// Realized profit.
214/// </summary>
215//[Ignore]
216[XmlIgnore]
217[Display(
218ResourceType = typeof(LocalizedStrings),
219Name = LocalizedStrings.RealizedProfitKey,
220Description = LocalizedStrings.RealizedProfitDescKey,
221GroupName = LocalizedStrings.StatisticsKey)]
222[Browsable(false)]
223public decimal? RealizedPnL
224{
225get => _realizedPnL;
226set
227{
228if (_realizedPnL == value)
229return;
230
231_realizedPnL = value;
232NotifyChanged();
233}
234}
235
236private decimal? _variationMargin;
237
238/// <summary>
239/// Variation margin.
240/// </summary>
241[DataMember]
242[Display(
243ResourceType = typeof(LocalizedStrings),
244Name = LocalizedStrings.VariationMarginKey,
245Description = LocalizedStrings.VariationMarginDescKey,
246GroupName = LocalizedStrings.StatisticsKey)]
247//[Nullable]
248[Browsable(false)]
249public decimal? VariationMargin
250{
251get => _variationMargin;
252set
253{
254if (_variationMargin == value)
255return;
256
257_variationMargin = value;
258NotifyChanged();
259}
260}
261
262private decimal? _commission;
263
264/// <summary>
265/// Total commission.
266/// </summary>
267[DataMember]
268[Display(
269ResourceType = typeof(LocalizedStrings),
270Name = LocalizedStrings.CommissionKey,
271Description = LocalizedStrings.TotalCommissionDescKey,
272GroupName = LocalizedStrings.StatisticsKey)]
273//[Nullable]
274[Browsable(false)]
275public decimal? Commission
276{
277get => _commission;
278set
279{
280if (_commission == value)
281return;
282
283_commission = value;
284NotifyChanged();
285}
286}
287
288private decimal? _settlementPrice;
289
290/// <summary>
291/// Settlement price.
292/// </summary>
293[DataMember]
294[Display(
295ResourceType = typeof(LocalizedStrings),
296Name = LocalizedStrings.SettlementPriceKey,
297Description = LocalizedStrings.SettlementPriceDescKey,
298GroupName = LocalizedStrings.StatisticsKey)]
299//[Nullable]
300[Browsable(false)]
301public decimal? SettlementPrice
302{
303get => _settlementPrice;
304set
305{
306if (_settlementPrice == value)
307return;
308
309_settlementPrice = value;
310NotifyChanged();
311}
312}
313
314private DateTimeOffset _lastChangeTime;
315
316/// <summary>
317/// Time of last position change.
318/// </summary>
319[DataMember]
320[Display(
321ResourceType = typeof(LocalizedStrings),
322Name = LocalizedStrings.ChangedKey,
323Description = LocalizedStrings.TimePosLastChangeKey,
324GroupName = LocalizedStrings.StatisticsKey)]
325[Browsable(false)]
326public DateTimeOffset LastChangeTime
327{
328get => _lastChangeTime;
329set
330{
331_lastChangeTime = value;
332NotifyChanged();
333}
334}
335
336private DateTimeOffset _localTime;
337
338/// <summary>
339/// Local time of the last position change.
340/// </summary>
341[DataMember]
342[Display(
343ResourceType = typeof(LocalizedStrings),
344Name = LocalizedStrings.LocalTimeKey,
345Description = LocalizedStrings.LocalTimeDescKey,
346GroupName = LocalizedStrings.StatisticsKey)]
347[Browsable(false)]
348public DateTimeOffset LocalTime
349{
350get => _localTime;
351set
352{
353_localTime = value;
354NotifyChanged();
355}
356}
357
358private string _description;
359
360/// <summary>
361/// Text position description.
362/// </summary>
363[DataMember]
364[Display(
365ResourceType = typeof(LocalizedStrings),
366Name = LocalizedStrings.DescriptionKey,
367Description = LocalizedStrings.PosTextKey,
368GroupName = LocalizedStrings.GeneralKey)]
369public string Description
370{
371get => _description;
372set
373{
374_description = value;
375NotifyChanged();
376}
377}
378
379private CurrencyTypes? _currency;
380
381/// <summary>
382/// Portfolio currency.
383/// </summary>
384[DataMember]
385[Display(
386ResourceType = typeof(LocalizedStrings),
387Name = LocalizedStrings.CurrencyKey,
388Description = LocalizedStrings.PortfolioCurrencyKey,
389GroupName = LocalizedStrings.GeneralKey)]
390public CurrencyTypes? Currency
391{
392get => _currency;
393set
394{
395_currency = value;
396NotifyChanged();
397}
398}
399
400private DateTimeOffset? _expirationDate;
401
402/// <summary>
403/// Expiration date.
404/// </summary>
405[DataMember]
406[Display(
407ResourceType = typeof(LocalizedStrings),
408Name = LocalizedStrings.ExpiryDateKey,
409Description = LocalizedStrings.ExpiryDateKey,
410GroupName = LocalizedStrings.GeneralKey)]
411public DateTimeOffset? ExpirationDate
412{
413get => _expirationDate;
414set
415{
416_expirationDate = value;
417NotifyChanged();
418}
419}
420
421/// <summary>
422/// Client code assigned by the broker.
423/// </summary>
424[DataMember]
425[Display(
426ResourceType = typeof(LocalizedStrings),
427Name = LocalizedStrings.ClientCodeKey,
428Description = LocalizedStrings.ClientCodeDescKey,
429GroupName = LocalizedStrings.GeneralKey)]
430public string ClientCode { get; set; }
431
432/// <summary>
433/// Portfolio, in which position is created.
434/// </summary>
435[DataMember]
436[Display(
437ResourceType = typeof(LocalizedStrings),
438Name = LocalizedStrings.PortfolioKey,
439Description = LocalizedStrings.PosPortfolioKey,
440GroupName = LocalizedStrings.GeneralKey)]
441public Portfolio Portfolio { get; set; }
442
443/// <summary>
444/// Security, for which a position was created.
445/// </summary>
446[DataMember]
447[Display(
448ResourceType = typeof(LocalizedStrings),
449Name = LocalizedStrings.SecurityKey,
450Description = LocalizedStrings.PosSecurityKey,
451GroupName = LocalizedStrings.GeneralKey)]
452public Security Security { get; set; }
453
454/// <summary>
455/// The depositary where the physical security.
456/// </summary>
457[Display(
458ResourceType = typeof(LocalizedStrings),
459Name = LocalizedStrings.DepoKey,
460Description = LocalizedStrings.DepoNameKey,
461GroupName = LocalizedStrings.GeneralKey)]
462[DataMember]
463public string DepoName { get; set; }
464
465/// <summary>
466/// Limit type for Т+ market.
467/// </summary>
468[Display(
469ResourceType = typeof(LocalizedStrings),
470Name = LocalizedStrings.LimitKey,
471Description = LocalizedStrings.PosLimitKey,
472GroupName = LocalizedStrings.GeneralKey)]
473//[Nullable]
474[DataMember]
475public TPlusLimits? LimitType { get; set; }
476
477/// <summary>
478/// Strategy id.
479/// </summary>
480[DataMember]
481[Display(
482ResourceType = typeof(LocalizedStrings),
483Name = LocalizedStrings.StrategyKey,
484Description = LocalizedStrings.IdentifierKey,
485GroupName = LocalizedStrings.GeneralKey,
486Order = 100)]
487public virtual string StrategyId { get; set; }
488
489/// <summary>
490/// Side.
491/// </summary>
492[DataMember]
493[Display(
494ResourceType = typeof(LocalizedStrings),
495Name = LocalizedStrings.SideKey,
496Description = LocalizedStrings.PosSideKey,
497GroupName = LocalizedStrings.GeneralKey,
498Order = 101)]
499public virtual Sides? Side { get; set; }
500
501private decimal? _leverage;
502
503/// <summary>
504/// Margin leverage.
505/// </summary>
506[DataMember]
507[Display(
508ResourceType = typeof(LocalizedStrings),
509Name = LocalizedStrings.LeverageKey,
510Description = LocalizedStrings.MarginLeverageKey,
511GroupName = LocalizedStrings.GeneralKey)]
512//[Nullable]
513public decimal? Leverage
514{
515get => _leverage;
516set
517{
518if (_leverage == value)
519return;
520
521//if (value < 0)
522// throw new ArgumentOutOfRangeException(nameof(value), value, LocalizedStrings.InvalidValue);
523
524_leverage = value;
525NotifyChanged();
526}
527}
528
529private decimal? _commissionTaker;
530
531/// <summary>
532/// Commission (taker).
533/// </summary>
534[XmlIgnore]
535[Browsable(false)]
536public decimal? CommissionTaker
537{
538get => _commissionTaker;
539set
540{
541_commissionTaker = value;
542NotifyChanged();
543}
544}
545
546private decimal? _commissionMaker;
547
548/// <summary>
549/// Commission (maker).
550/// </summary>
551[XmlIgnore]
552[Browsable(false)]
553public decimal? CommissionMaker
554{
555get => _commissionMaker;
556set
557{
558_commissionMaker = value;
559NotifyChanged();
560}
561}
562
563private int? _buyOrdersCount;
564
565/// <summary>
566/// Orders (bids).
567/// </summary>
568[XmlIgnore]
569[Browsable(false)]
570public int? BuyOrdersCount
571{
572get => _buyOrdersCount;
573set
574{
575_buyOrdersCount = value;
576NotifyChanged();
577}
578}
579
580private int? _sellOrdersCount;
581
582/// <summary>
583/// Orders (asks).
584/// </summary>
585[XmlIgnore]
586[Browsable(false)]
587public int? SellOrdersCount
588{
589get => _sellOrdersCount;
590set
591{
592_sellOrdersCount = value;
593NotifyChanged();
594}
595}
596
597private decimal? _buyOrdersMargin;
598
599/// <summary>
600/// Margin (buy).
601/// </summary>
602[XmlIgnore]
603[Browsable(false)]
604public decimal? BuyOrdersMargin
605{
606get => _buyOrdersMargin;
607set
608{
609_buyOrdersMargin = value;
610NotifyChanged();
611}
612}
613
614private decimal? _sellOrdersMargin;
615
616/// <summary>
617/// Margin (sell).
618/// </summary>
619[XmlIgnore]
620[Browsable(false)]
621public decimal? SellOrdersMargin
622{
623get => _sellOrdersMargin;
624set
625{
626_sellOrdersMargin = value;
627NotifyChanged();
628}
629}
630
631private decimal? _ordersMargin;
632
633/// <summary>
634/// Orders (margin).
635/// </summary>
636[XmlIgnore]
637[Browsable(false)]
638public decimal? OrdersMargin
639{
640get => _ordersMargin;
641set
642{
643_ordersMargin = value;
644NotifyChanged();
645}
646}
647
648private int? _ordersCount;
649
650/// <summary>
651/// Orders.
652/// </summary>
653[XmlIgnore]
654[Browsable(false)]
655public int? OrdersCount
656{
657get => _ordersCount;
658set
659{
660_ordersCount = value;
661NotifyChanged();
662}
663}
664
665private int? _tradesCount;
666
667/// <summary>
668/// Trades.
669/// </summary>
670[XmlIgnore]
671[Browsable(false)]
672public int? TradesCount
673{
674get => _tradesCount;
675set
676{
677_tradesCount = value;
678NotifyChanged();
679}
680}
681
682private decimal? _liquidationPrice;
683
684/// <summary>
685/// Liquidation price.
686/// </summary>
687[DataMember]
688[Display(
689ResourceType = typeof(LocalizedStrings),
690Name = LocalizedStrings.LiquidationPriceKey,
691Description = LocalizedStrings.LiquidationPriceKey,
692GroupName = LocalizedStrings.StatisticsKey)]
693[Browsable(false)]
694public decimal? LiquidationPrice
695{
696get => _liquidationPrice;
697set
698{
699if (_liquidationPrice == value)
700return;
701
702_liquidationPrice = value;
703NotifyChanged();
704}
705}
706
707/// <summary>
708/// Create a copy of <see cref="Position"/>.
709/// </summary>
710/// <returns>Copy.</returns>
711public virtual Position Clone()
712{
713var clone = new Position();
714CopyTo(clone);
715return clone;
716}
717
718/// <summary>
719/// To copy fields of the current position to <paramref name="destination" />.
720/// </summary>
721/// <param name="destination">The position in which you should to copy fields.</param>
722public void CopyTo(Position destination)
723{
724if (destination == null)
725throw new ArgumentNullException(nameof(destination));
726
727destination.CurrentValue = CurrentValue;
728destination.BeginValue = BeginValue;
729destination.BlockedValue = BlockedValue;
730destination.Commission = Commission;
731destination.VariationMargin = VariationMargin;
732destination.RealizedPnL = RealizedPnL;
733destination.UnrealizedPnL = UnrealizedPnL;
734destination.AveragePrice = AveragePrice;
735destination.CurrentPrice = CurrentPrice;
736destination.SettlementPrice = SettlementPrice;
737destination.Description = Description;
738destination.Currency = Currency;
739destination.ExpirationDate = ExpirationDate;
740destination.ClientCode = ClientCode;
741//destination.LastChangeTime = LastChangeTime;
742//destination.LocalTime = LocalTime;
743
744destination.Portfolio = Portfolio;
745destination.Security = Security;
746destination.DepoName = DepoName;
747destination.LimitType = LimitType;
748destination.StrategyId = StrategyId;
749destination.Side = Side;
750
751destination.Leverage = Leverage;
752destination.CommissionMaker = CommissionMaker;
753destination.CommissionTaker = CommissionTaker;
754
755destination.BuyOrdersCount = BuyOrdersCount;
756destination.SellOrdersCount = SellOrdersCount;
757destination.BuyOrdersMargin = BuyOrdersMargin;
758destination.SellOrdersMargin = SellOrdersMargin;
759destination.OrdersCount = OrdersCount;
760destination.TradesCount = TradesCount;
761
762destination.LiquidationPrice = LiquidationPrice;
763}
764
765/// <inheritdoc />
766public override string ToString()
767{
768var str = $"{Portfolio}-{Security}";
769
770if (!StrategyId.IsEmpty())
771str += $"-{StrategyId}";
772
773if (Side != null)
774str += $"-{Side.Value}";
775
776return str;
777}
778}
779}
780