/// <summary> /// Order side to bonary direction /// </summary> /// <param name="position"></param> /// <returns></returns> protected int GetDirection(ITransactionPositionModel position) { switch (position.Side) { case OrderSideEnum.Buy: return(1); case OrderSideEnum.Sell: return(-1); } return(0); }
/// <summary> /// Update position properties based on specified order /// </summary> /// <param name="position"></param> /// <param name="order"></param> protected virtual ITransactionPositionModel UpdatePositionProps(ITransactionPositionModel position, ITransactionOrderModel order) { position.Id = order.Id; position.Name = order.Name; position.Description = order.Description; position.Type = order.Type; position.Size = order.Size; position.Side = order.Side; position.Group = order.Group; position.Price = order.Price; position.OpenPrice = order.Price; position.Instrument = order.Instrument; position.Orders = order.Orders; position.Time = order.Time; return(position); }
/// <summary> /// Create position when there is a position with the same transaction type /// </summary> /// <param name="nextOrder"></param> /// <param name="previousPosition"></param> /// <returns></returns> protected virtual ITransactionPositionModel DecreasePosition(ITransactionOrderModel nextOrder, ITransactionPositionModel previousPosition) { if (previousPosition == null) { return(null); } var isSameBuy = Equals(previousPosition.Side, OrderSideEnum.Buy) && Equals(nextOrder.Side, OrderSideEnum.Buy); var isSameSell = Equals(previousPosition.Side, OrderSideEnum.Sell) && Equals(nextOrder.Side, OrderSideEnum.Sell); if (isSameBuy || isSameSell) { return(null); } var openPrices = GetOpenPrices(nextOrder); var pointModel = nextOrder.Instrument.PointGroups.LastOrDefault(); nextOrder.Time = pointModel.Time; nextOrder.Price = openPrices.Last().Price; nextOrder.Status = OrderStatusEnum.Filled; var nextPosition = UpdatePositionProps(new TransactionPositionModel(), nextOrder); nextPosition.Time = pointModel.Time; nextPosition.OpenPrices = openPrices; nextPosition.Price = nextPosition.OpenPrice = nextOrder.Price; nextPosition.Size = Math.Abs(nextPosition.Size.Value - previousPosition.Size.Value); previousPosition.CloseTime = nextPosition.Time; previousPosition.ClosePrice = nextPosition.OpenPrice; previousPosition.GainLoss = previousPosition.GainLossEstimate; previousPosition.GainLossPoints = previousPosition.GainLossPointsEstimate; Account.Balance += previousPosition.GainLoss; Account.ActiveOrders.Remove(nextOrder); Account.ActivePositions.Remove(previousPosition); DeleteOrders(previousPosition.Orders.ToArray()); Account.Orders.Add(nextOrder); Account.Positions.Add(previousPosition); if (ConversionManager.Compare(nextPosition.Size, 0.0) == false) { Account.ActivePositions.Add(nextPosition); } return(nextPosition); }
/// <summary> /// Create position when there is a position with the same transaction type /// </summary> /// <param name="nextOrder"></param> /// <param name="previousPosition"></param> /// <returns></returns> protected virtual ITransactionPositionModel IncreasePosition(ITransactionOrderModel nextOrder, ITransactionPositionModel previousPosition) { if (previousPosition == null) { return(null); } var isSameBuy = Equals(previousPosition.Side, OrderSideEnum.Buy) && Equals(nextOrder.Side, OrderSideEnum.Buy); var isSameSell = Equals(previousPosition.Side, OrderSideEnum.Sell) && Equals(nextOrder.Side, OrderSideEnum.Sell); if (isSameBuy == false && isSameSell == false) { return(null); } var openPrices = GetOpenPrices(nextOrder); var pointModel = nextOrder.Instrument.PointGroups.LastOrDefault(); nextOrder.Time = pointModel.Time; nextOrder.Price = openPrices.Last().Price; nextOrder.Status = OrderStatusEnum.Filled; var nextPosition = UpdatePositionProps(new TransactionPositionModel(), nextOrder); nextPosition.Time = pointModel.Time; nextPosition.Price = nextOrder.Price; nextPosition.Size = nextOrder.Size + previousPosition.Size; nextPosition.OpenPrices = previousPosition.OpenPrices.Concat(openPrices).ToList(); nextPosition.OpenPrice = nextPosition.OpenPrices.Sum(o => o.Size * o.Price) / nextPosition.OpenPrices.Sum(o => o.Size); previousPosition.CloseTime = nextPosition.Time; previousPosition.ClosePrice = nextPosition.OpenPrice; previousPosition.GainLoss = previousPosition.GainLossEstimate; previousPosition.GainLossPoints = previousPosition.GainLossPointsEstimate; Account.ActiveOrders.Remove(nextOrder); Account.ActivePositions.Remove(previousPosition); Account.Orders.Add(nextOrder); Account.Positions.Add(previousPosition); Account.ActivePositions.Add(nextPosition); return(previousPosition); }
/// <summary> /// Create position when there are no other positions /// </summary> /// <param name="nextOrder"></param> /// <param name="previousPosition"></param> /// <returns></returns> protected virtual ITransactionPositionModel OpenPosition(ITransactionOrderModel nextOrder, ITransactionPositionModel previousPosition) { if (previousPosition != null) { return(null); } var openPrices = GetOpenPrices(nextOrder); var pointModel = nextOrder.Instrument.PointGroups.LastOrDefault(); nextOrder.Time = pointModel.Time; nextOrder.Price = openPrices.Last().Price; nextOrder.Status = OrderStatusEnum.Filled; var nextPosition = UpdatePositionProps(new TransactionPositionModel(), nextOrder); nextPosition.Time = pointModel.Time; nextPosition.OpenPrices = openPrices; nextPosition.Price = nextPosition.OpenPrice = nextOrder.Price; Account.Orders.Add(nextOrder); Account.ActiveOrders.Remove(nextOrder); Account.ActivePositions.Add(nextPosition); return(nextPosition); }