public void ProcessTransaction(OrderTransaction trans) { string comment; if (trans.OrderId == 8) { comment = ""; } IPositionInventory openPosition = OpenPositions.FirstOrDefault(p => p.GetSymbol() == trans.Symbol); if (openPosition == null) { openPosition = OpenPosition(trans, PositionInventoryMethod.Lifo); OpenPositions.Add(openPosition); } else { OrderTransaction transaction = ResolvePosition(openPosition, trans); if (openPosition.BuysCount() == 0 && openPosition.SellsCount() == 0) { OpenPositions.Remove(openPosition); } } }
private OrderTransaction ResolvePosition(IPositionInventory position, OrderTransaction trans) { OrderTransaction buytrans = new OrderTransaction(); OrderTransaction selltrans = new OrderTransaction(); OrderTransaction l = new OrderTransaction(); if (trans.Direction == OrderDirection.Buy) { if (position.SellsCount() > 0) { selltrans = position.RemoveSell(); if (Math.Abs(trans.Quantity) == Math.Abs(selltrans.Quantity)) { return(CreateTrade(trans, selltrans)); } // if the buytrans qty is greater than the selltrans qty, split the buy if (trans.Quantity > Math.Abs(selltrans.Quantity)) { #region "Trans is Buy and buy greater than sell" var unitcost = Math.Abs(trans.Amount / trans.Quantity); // split the (buy)trans to equalize with the selltrans quantity l = CopyTransaction(trans); l.Quantity = trans.Quantity + selltrans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; buytrans = CopyTransaction(trans); buytrans.Quantity = Math.Abs(selltrans.Quantity); buytrans.Amount = unitcost * buytrans.Quantity * -1; buytrans.Net = buytrans.Amount + buytrans.Commission + buytrans.Fees; CreateTrade(buytrans, selltrans); return(ResolvePosition(position, l)); #endregion } else { #region "Trans is Buy and sell greater than buy" var unitcost = Math.Abs(selltrans.Amount / selltrans.Quantity); // Split the sell l = CopyTransaction(selltrans); l.Quantity = selltrans.Quantity + trans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; // split the sell. The Sell gets no ICF selltrans.Quantity = selltrans.Quantity - l.Quantity; // sell qty is negative selltrans.Amount = unitcost * selltrans.Quantity * -1; selltrans.Net = selltrans.Amount + selltrans.Commission + selltrans.Fees; CreateTrade(trans, selltrans); return(ResolvePosition(position, l)); #endregion } } else { position.Add(trans); } } else { if (position.BuysCount() > 0) { buytrans = position.RemoveBuy(); if (Math.Abs(trans.Quantity) == Math.Abs(buytrans.Quantity)) { return(CreateTrade(buytrans, trans)); } Decimal unitcost = 0; if (Math.Abs(trans.Quantity) > buytrans.Quantity) { #region "Trans is sell and sell is greater than buy" unitcost = Math.Abs(trans.Amount / trans.Quantity); // split the sell, buytrans keeps the IFC l = CopyTransaction(trans); l.Quantity = trans.Quantity + buytrans.Quantity; l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; selltrans = CopyTransaction(trans); selltrans.Quantity = selltrans.Quantity - l.Quantity; selltrans.Amount = unitcost * selltrans.Quantity * -1; selltrans.Net = selltrans.Amount + selltrans.Commission + selltrans.Fees; CreateTrade(buytrans, selltrans); return(ResolvePosition(position, l)); #endregion } else { #region "Trans is sell and buy is greater than sell" unitcost = Math.Abs(buytrans.Amount / buytrans.Quantity); // split the (buy)trans to equalize with the selltrans quantity l = CopyTransaction(buytrans); l.Quantity = buytrans.Quantity + trans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; buytrans.Quantity = buytrans.Quantity - l.Quantity; buytrans.Amount = unitcost * buytrans.Quantity * -1; buytrans.Net = buytrans.Amount + buytrans.Commission + buytrans.Fees; CreateTrade(buytrans, trans); return(ResolvePosition(position, l)); #endregion } } else { position.Add(trans); } } return(l); }
private OrderTransaction ResolvePosition(IPositionInventory position, OrderTransaction trans) { OrderTransaction buytrans = new OrderTransaction(); OrderTransaction selltrans = new OrderTransaction(); OrderTransaction l = new OrderTransaction(); if (trans.Direction == OrderDirection.Buy) { if (position.SellsCount() > 0) { selltrans = position.RemoveSell(); if (Math.Abs(trans.Quantity) == Math.Abs(selltrans.Quantity)) { return CreateTrade(trans, selltrans); } // if the buytrans qty is greater than the selltrans qty, split the buy if (trans.Quantity > Math.Abs(selltrans.Quantity)) { #region "Trans is Buy and buy greater than sell" var unitcost = Math.Abs(trans.Amount / trans.Quantity); // split the (buy)trans to equalize with the selltrans quantity l = CopyTransaction(trans); l.Quantity = trans.Quantity + selltrans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; buytrans = CopyTransaction(trans); buytrans.Quantity = Math.Abs(selltrans.Quantity); buytrans.Amount = unitcost * buytrans.Quantity * -1; buytrans.Net = buytrans.Amount + buytrans.Commission + buytrans.Fees; CreateTrade(buytrans, selltrans); return ResolvePosition(position, l); #endregion } else { #region "Trans is Buy and sell greater than buy" var unitcost = Math.Abs(selltrans.Amount / selltrans.Quantity); // Split the sell l = CopyTransaction(selltrans); l.Quantity = selltrans.Quantity + trans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; // split the sell. The Sell gets no ICF selltrans.Quantity = selltrans.Quantity - l.Quantity; // sell qty is negative selltrans.Amount = unitcost * selltrans.Quantity * -1; selltrans.Net = selltrans.Amount + selltrans.Commission + selltrans.Fees; CreateTrade(trans, selltrans); return ResolvePosition(position, l); #endregion } } else { position.Add(trans); } } else { if (position.BuysCount() > 0) { buytrans = position.RemoveBuy(); if (Math.Abs(trans.Quantity) == Math.Abs(buytrans.Quantity)) { return CreateTrade(buytrans, trans); } Decimal unitcost = 0; if (Math.Abs(trans.Quantity) > buytrans.Quantity) { #region "Trans is sell and sell is greater than buy" unitcost = Math.Abs(trans.Amount / trans.Quantity); // split the sell, buytrans keeps the IFC l = CopyTransaction(trans); l.Quantity = trans.Quantity + buytrans.Quantity; l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; selltrans = CopyTransaction(trans); selltrans.Quantity = selltrans.Quantity - l.Quantity; selltrans.Amount = unitcost * selltrans.Quantity * -1; selltrans.Net = selltrans.Amount + selltrans.Commission + selltrans.Fees; CreateTrade(buytrans, selltrans); return ResolvePosition(position, l); #endregion } else { #region "Trans is sell and buy is greater than sell" unitcost = Math.Abs(buytrans.Amount / buytrans.Quantity); // split the (buy)trans to equalize with the selltrans quantity l = CopyTransaction(buytrans); l.Quantity = buytrans.Quantity + trans.Quantity; // sell quantity will be negative l.Amount = unitcost * l.Quantity * -1; l.Commission = 0; l.Fees = 0; l.Interest = 0; l.Net = l.Amount; buytrans.Quantity = buytrans.Quantity - l.Quantity; buytrans.Amount = unitcost * buytrans.Quantity * -1; buytrans.Net = buytrans.Amount + buytrans.Commission + buytrans.Fees; CreateTrade(buytrans, trans); return ResolvePosition(position, l); #endregion } } else { position.Add(trans); } } return l; }