/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using Newtonsoft.Json; using System; using System.Collections.Generic; namespace QuantConnect.Statistics { /// /// Represents a closed trade /// public class Trade { private List _symbols; /// /// A unique identifier for the trade /// public string Id { get; set; } /// /// The symbol of the traded instrument /// [Obsolete("Use Symbols property instead")] [JsonIgnore] public Symbol Symbol { get { return _symbols != null && _symbols.Count > 0 ? _symbols[0] : Symbol.Empty; } private set { _symbols = new List() { value }; } } /// /// Just needed so that "Symbol" is never serialized but can be deserialized, if present, for backward compatibility /// [JsonProperty("Symbol")] private Symbol SymbolForDeserialization { set => Symbol = value; } /// /// The symbol associated to the traded instruments /// public List Symbols { get { return _symbols; } set { _symbols = value; } } /// /// The date and time the trade was opened /// public DateTime EntryTime { get; set; } /// /// The price at which the trade was opened (or the average price if multiple entries) /// public decimal EntryPrice { get; set; } /// /// The direction of the trade (Long or Short) /// public TradeDirection Direction { get; set; } /// /// The total unsigned quantity of the trade /// public decimal Quantity { get; set; } /// /// The date and time the trade was closed /// public DateTime ExitTime { get; set; } /// /// The price at which the trade was closed (or the average price if multiple exits) /// public decimal ExitPrice { get; set; } /// /// The gross profit/loss of the trade (as account currency) /// public decimal ProfitLoss { get; set; } /// /// The total fees associated with the trade (always positive value) (as account currency) /// public decimal TotalFees { get; set; } /// /// The Maximum Adverse Excursion (as account currency) /// public decimal MAE { get; set; } /// /// The Maximum Favorable Excursion (as account currency) /// public decimal MFE { get; set; } /// /// Returns the duration of the trade /// public TimeSpan Duration { get { return ExitTime - EntryTime; } } /// /// Returns the amount of profit given back before the trade was closed /// public decimal EndTradeDrawdown { get; set; } /// /// Returns whether the trade was profitable (is a win) or not (a loss) /// /// True if the trade was profitable /// /// Even when a trade is not profitable, it may still be a win: /// - For an ITM option buyer, an option assignment trade is not profitable (money was paid), /// but it might count as a win if the ITM amount is greater than the amount paid for the option. /// - For an ITM option seller, an option assignment trade is profitable (money was received), /// but it might count as a loss if the ITM amount is less than the amount received for the option. /// public bool IsWin { get; set; } /// /// The IDs of the orders related to this trade /// public HashSet OrderIds { get; init; } = new HashSet(); /// /// Creates a new instance of the class /// public Trade() { } /// /// Creates a new instance of the class by copying another trade /// /// The trade to copy public Trade(Trade other) { Id = other.Id; _symbols = other._symbols != null ? [.. other._symbols] : null; EntryTime = other.EntryTime; EntryPrice = other.EntryPrice; Direction = other.Direction; Quantity = other.Quantity; ExitTime = other.ExitTime; ExitPrice = other.ExitPrice; ProfitLoss = other.ProfitLoss; TotalFees = other.TotalFees; MAE = other.MAE; MFE = other.MFE; EndTradeDrawdown = other.EndTradeDrawdown; IsWin = other.IsWin; OrderIds = [.. other.OrderIds]; } } }