public override void Add(StockOrder stockOrder) { if (stockOrder.State != StockOrder.OrderStatus.Executed) { throw new System.Exception("Cannot add a not executed order to a position"); } if (stockOrder.IsShortOrder ^ this.IsShortPosition) { throw new System.Exception("Cannot add a short order to a long position"); } if (stockOrder.IsBuyOrder()) { this.UnitCost = (this.UnitCost * this.Number + stockOrder.UnitCost * stockOrder.Number) / (float)(this.Number + stockOrder.Number); this.Number += stockOrder.Number; } else { if (this.Number > stockOrder.Number) { this.Number -= stockOrder.Number; } else { if (this.Number == stockOrder.Number) { this.Number = 0; this.Status = PositionStatus.Closed; } else { throw new System.Exception("Cannot sell more stock than owned"); } } } }
/// <summary> /// Return a new order matching new position. THis method should be rewritten using StockPositions. /// </summary> /// <param name="stockOrder"></param> /// <returns></returns> public StockOrder Add(StockOrder stockOrder) { // #### Need to be reviewed due to the Buy at market OPEN or CLOSE difference. if (this.StockName == stockOrder.StockName) { int newNumber = 0; float newValue = 0; if (this.IsBuyOrder()) { if (stockOrder.IsBuyOrder()) { // Add new order to current position newNumber = this.Number + stockOrder.Number; newValue = (this.Value * this.Number + stockOrder.Value * stockOrder.Number) / (float)newNumber; return CreateExecutedOrder(this.StockName, this.Type, false, this.CreationDate, stockOrder.ExecutionDate, newNumber, newValue, this.Fee + stockOrder.Fee); } else // Sell order { newNumber = this.Number - stockOrder.Number; //if (newNumber == 0) //{ // // Everything is sold. // return null; //} //else //{ // Keep same value as initial order when selling it partially. newValue = this.Value; return CreateExecutedOrder(this.StockName, this.Type, false, this.CreationDate, stockOrder.ExecutionDate, newNumber, newValue, this.Fee + stockOrder.Fee); //} } } else // Sell order { if (stockOrder.IsBuyOrder()) { newNumber = stockOrder.Number - this.Number; if (newNumber == 0) { return null; } else { // Keep same value as initial order when covering it partially. newValue = (stockOrder.Value * stockOrder.Number - this.Value * this.Number) / (float)newNumber; return CreateExecutedOrder(this.StockName, this.Type, false, this.CreationDate, stockOrder.ExecutionDate, newNumber, newValue, this.Fee + stockOrder.Fee); } } else // Sell order { // TODO test newNumber = this.Number + stockOrder.Number; newValue = (this.Value * this.Number + stockOrder.Value * stockOrder.Number) / (float)newNumber; return CreateExecutedOrder(this.StockName, this.Type, false, this.CreationDate, stockOrder.ExecutionDate, newNumber, newValue, this.Fee + stockOrder.Fee); } } } else { throw new System.ArithmeticException("Cannot add orders for different stock name"); } }
public static StockOrder CreateFromStockBrokers(string line, ref string errorMsg) { StockOrder stockOrder = new StockOrder(); try { string[] fields = line.Split('|'); // Find order date stockOrder.ExecutionDate = DateTime.Parse(fields[0]); stockOrder.CreationDate = DateTime.Parse(fields[0]); // Find order type if (fields[1] == "Buy") { stockOrder.Type = StockOrder.OrderType.BuyAtLimit; } else if (fields[1] == "Sell") { stockOrder.Type = StockOrder.OrderType.SellAtLimit; } else { errorMsg = "Invalid order type: " + fields[1]; return null; } // Find Stock Name stockOrder.StockName = fields[2]; // Find number of stocks stockOrder.Number = int.Parse(fields[4]); // Find stock unit value stockOrder.Value = float.Parse(fields[5], StockAnalyzerApp.Global.EnglishCulture) / 100.0f; // Find Total order value and fee float totalOrderValue = 0.0f; if (stockOrder.IsBuyOrder()) { totalOrderValue = float.Parse(fields[6], StockAnalyzerApp.Global.EnglishCulture); stockOrder.Fee = totalOrderValue - stockOrder.Number * stockOrder.Value; } else { totalOrderValue = float.Parse(fields[7], StockAnalyzerApp.Global.EnglishCulture); stockOrder.Fee = stockOrder.Number * stockOrder.Value - totalOrderValue; } } catch (System.Exception e) { errorMsg = e.Message; stockOrder = null; } return stockOrder; }