public OrderTransaction RemoveSell() { OrderTransaction transaction = null; Sells.TryDequeue(out transaction); return(transaction); }
private OrderTransaction CopyTransaction(OrderTransaction trans) { OrderTransaction l = new OrderTransaction(); l.Symbol = trans.Symbol; l.Exchange = trans.Exchange; l.Broker = trans.Broker; l.Quantity = trans.Quantity; l.Price = trans.Price; l.ActionNameUS = trans.ActionNameUS; l.TradeDate = trans.TradeDate; l.SettledDate = trans.SettledDate; l.Interest = trans.Interest; l.Amount = trans.Amount; l.Commission = trans.Commission; l.Fees = trans.Fees; l.CUSIP = trans.CUSIP; l.Description = trans.Description; l.ActionId = trans.ActionId; l.TradeNumber = trans.TradeNumber; l.RecordType = trans.RecordType; l.TaxLotNumber = trans.TaxLotNumber; l.OrderType = trans.OrderType; l.OrderId = trans.OrderId; l.Direction = trans.Direction; return(l); }
public OrderTransaction RemoveBuy() { OrderTransaction transaction = null; Buys.TryDequeue(out transaction); return(transaction); }
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); } } }
public void FifoAddsSell() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Sell; fifo.Add(trans); Assert.IsTrue(fifo.Sells.Count == 1); fifo.Remove(Sell); Assert.IsTrue(fifo.Sells.Count == 0); }
public void LifoAddsBuy() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; lifo.Add(trans); Assert.IsTrue(lifo.BuysCount() == 1); lifo.Remove(Buy); Assert.IsTrue(lifo.BuysCount() == 0); }
public void FifoAddsBuy() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; fifo.Add(trans); Assert.IsTrue(fifo.Buys.Count == 1); fifo.Remove(Buy); Assert.IsTrue(fifo.Buys.Count == 0); }
public OrderTransaction RemoveBuy() { OrderTransaction transaction = null; if (Buys.Count > 0) { Buys.TryPop(out transaction); } return(transaction); }
public void CanOpenPosition() { OrderTransaction trans = new OrderTransaction(); trans.Symbol = "AAPL"; trans.Direction = OrderDirection.Buy; OrderTransactionProcessor processor = new OrderTransactionProcessor(); IPositionInventory openPosition = processor.OpenPosition(trans, PositionInventoryMethod.Fifo); processor.OpenPositions.Add(openPosition); Assert.IsTrue(processor.OpenPositions.Count > 0); }
public OrderTransaction RemoveSell() { OrderTransaction transaction = null; if (Sells.Count > 0) { Sells.TryPop(out transaction); } return(transaction); }
public void Add(OrderTransaction transaction) { Symbol = transaction.Symbol; if (transaction.Direction == OrderDirection.Buy) { Buys.Push(transaction); } if (transaction.Direction == OrderDirection.Sell) { Sells.Push(transaction); } }
public void InterfaceOk() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; IPositionInventory lifo = new PositionInventoryLifo(); lifo.Add(trans); var count = lifo.BuysCount(); Assert.IsTrue(lifo.BuysCount() == 1); trans = lifo.RemoveBuy(); Assert.IsNotNull(trans); Assert.IsTrue(lifo.BuysCount() == 0); }
public void Add(OrderTransaction transaction) { Symbol = transaction.Symbol; if (transaction.Direction == OrderDirection.Buy) { Buys.Enqueue(transaction); } if (transaction.Direction == OrderDirection.Sell) { Sells.Enqueue(transaction); } }
public void MatchedAndUnmatchedTransactions() { string path = @"C:\Users\Nick\Documents\Visual Studio 2013\Projects\LeanITrend\Engine\bin\Debug\"; string pathname = path + "transactions.csv"; // This part of the test is just to look at the JsonConvert //string txt; //using (StreamReader sr = new StreamReader(pathname)) //{ // txt = sr.ReadToEnd(); // sr.Close(); //} //int index = txt.IndexOf("\r\n", System.StringComparison.Ordinal); //string titlesremoved = txt.Substring(index + 2); int counter = 0; List<OrderTransaction> list = new List<OrderTransaction>(); OrderTransactionProcessor processor = new OrderTransactionProcessor(); using (StreamReader sr = new StreamReader(pathname)) { string line = sr.ReadLine(); // read the header but do not count it. while (!sr.EndOfStream) { line = sr.ReadLine(); if (line != null && line.Contains("Symbol")) continue; Assert.IsNotNull(line); counter++; OrderTransaction t = new OrderTransaction(); CsvSerializer.Deserialize(",",line,ref t,false); list.Add(t); processor.ProcessTransaction(t); } sr.Close(); } var csv = CsvSerializer.Serialize(",", processor.Trades, true); using (StreamWriter sw = new StreamWriter(path + "Trades.csv")) { foreach (var s in csv) { sw.WriteLine(s); } sw.Flush(); sw.Close(); } var x = JsonConvert.SerializeObject(list); Assert.IsTrue(counter == list.Count); Assert.IsTrue(processor.TotalProfit == 52.75m); Assert.IsTrue(processor.TotalCommission == -26m); }
public OrderTransaction Remove(string queueName) { OrderTransaction transaction = null; if (queueName.Contains(Buy)) { Buys.TryDequeue(out transaction); } if (queueName.Contains(Sell)) { Sells.TryDequeue(out transaction); } return(transaction); }
/// <summary> /// Logs the OrderEvent Transaction /// </summary> /// <param name="orderEvent">the OrderEvent being logged</param> /// <param name="includeHeader">Includes the field names</param> public OrderTransaction Create(OrderEvent orderEvent, OrderTicket ticket, bool includeHeader = true) { var security = _algorithm.Securities[ticket.Symbol]; Order order = _algorithm.Transactions.GetOrderById(orderEvent.OrderId); OrderTransaction t = new OrderTransaction(); // According to Scottrade a Buy is a negative amount (funds flow from my account to the seller's) // However the Quantity filled is a negative number for Sell/Short and a positive for Buy/Long // So multiply by -1 to give order value the correct sign decimal orderValue = -1 * ticket.QuantityFilled * ticket.AverageFillPrice; if (order != null) { var orderDateTime = _algorithm.Time; DateTime settleDate = orderDateTime.AddDays(orderDateTime.DayOfWeek < DayOfWeek.Wednesday ? 3 : 5); // Order Fees are a cost and negative to my account, therefore a negative number var orderFees = security.TransactionModel.GetOrderFee(security, order) * -1; #region "Create OrderTransaction" t.ActionId = orderEvent.Direction.ToString() == "Buy" ? 1 : 13; t.ActionNameUS = orderEvent.Direction.ToString(); t.Amount = orderValue; t.Broker = "IB"; t.CUSIP = "CUSIP"; t.Commission = orderFees; t.Description = string.Format("{0} {1} shares of {2} at ${3}", orderEvent.Direction, ticket.Quantity, orderEvent.Symbol, order.Price); t.Direction = orderEvent.Direction; t.Exchange = ""; t.Fees = 0; // need to calculate based upon difference in Portfolio[symbol].HoldingsValue between buy and sell t.Id = 0; t.Interest = 0; t.Net = orderValue + orderFees; t.OrderId = order.Id; t.OrderType = ticket.OrderType; t.Price = ticket.AverageFillPrice; t.Quantity = ticket.Quantity; t.RecordType = "Trade"; t.SettledDate = settleDate; t.Symbol = ticket.Symbol.Value; t.TaxLotNumber = String.Empty; t.TradeDate = orderDateTime; t.TradeNumber = 0; #endregion } return t; }
public IPositionInventory OpenPosition(OrderTransaction trans, PositionInventoryMethod positionResolution) { IPositionInventory position; if (positionResolution == PositionInventoryMethod.Fifo) { position = new PositionInventoryFifo(); } else { position = new PositionInventoryLifo(); } position.Add(trans); return(position); }
public void ConvertsACsvLineToObjectAndBack() { OrderTransaction t = new OrderTransaction(); string csv = @"0,AAPL,,IB,135,109.93,Buy,9/2/2015 1:41:00 PM,9/6/2015 1:41:00 PM,0,-14840.55,-1,0,-14841.55,CUSIP,Buy 135 shares of AAPL at $109.93,1,0,Trade,,Limit,1,Buy"; CsvSerializer.Deserialize<OrderTransaction>(",", csv, ref t, false); Assert.IsTrue(t.Symbol == "AAPL"); // the ObjectToCsv call needs an IEnumerable, so convert to a list List<OrderTransaction> list = new List<OrderTransaction>(); list.Add(t); var csvout = CsvSerializer.Serialize(",", list, false); var newcsv = csvout.FirstOrDefault(); Assert.IsTrue(System.String.Compare(csv, newcsv, System.StringComparison.Ordinal) == 0); }
public void ProcessTransaction(OrderTransaction trans) { 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); } } }
public OrderTransaction Remove(string direction) { OrderTransaction transaction = null; if (direction.Contains(Buy)) { if (Buys.Count > 0) { Buys.TryPop(out transaction); } } if (direction.Contains(Sell)) { if (Sells.Count > 0) { Sells.TryPop(out transaction); } } return(transaction); }
/// <summary> /// Local processing of the order event. It only logs the transaction and orderEvent /// </summary> /// <param name="orderEvent">OrderEvent - the order event</param> private void ProcessOrderEvent(OrderEvent orderEvent) { IEnumerable <OrderTicket> tickets; //add to the list of order events which is saved to a file when running locally // I will use this file to test Stefano Raggi's code if (orderEvent.Status == OrderStatus.Filled) { _orderEvents.Add(orderEvent); } orderId = orderEvent.OrderId; tradeResult = orderEvent.Status; switch (orderEvent.Status) { case OrderStatus.New: case OrderStatus.None: case OrderStatus.Submitted: // just checking to make sure they are coming through tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); break; case OrderStatus.Canceled: // just checking tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); break; case OrderStatus.Filled: case OrderStatus.PartiallyFilled: tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); if (tickets != null) { foreach (OrderTicket ticket in tickets) { #region logging if (Portfolio[orderEvent.Symbol].Invested) { nEntryPrice = Portfolio[symbol].IsLong ? orderEvent.FillPrice : orderEvent.FillPrice * -1; nExitPrice = 0; } else { nExitPrice = nEntryPrice < 0 ? orderEvent.FillPrice : orderEvent.FillPrice * -1; nEntryPrice = 0; } #region "log the ticket as a OrderTransacton" OrderTransactionFactory transactionFactory = new OrderTransactionFactory((QCAlgorithm)this); OrderTransaction t = transactionFactory.Create(orderEvent, ticket, false); _transactions.Add(t); _orderTransactionProcessor.ProcessTransaction(t); _tradecount++; if (_orderTransactionProcessor.TotalProfit != totalProfit) { CalculateTradeProfit(); } totalProfit = _orderTransactionProcessor.TotalProfit; #endregion #endregion "logging" } } break; } }
public void NoOpenPositionsReturnNull() { OrderTransaction trans = new OrderTransaction(); trans.Symbol = "AAPL"; IPositionInventory openPosition = p.OpenPositions.FirstOrDefault(s => s.GetSymbol() == trans.Symbol); Assert.IsNull(openPosition); }
private OrderTransaction CreateTrade(OrderTransaction buytrans, OrderTransaction selltrans) { var l = new OrderTransaction(); if (buytrans == null && selltrans == null) { return(l); } if (buytrans.Amount >= 0) { throw new ArgumentException("Buy trans amount >= 0"); } if (selltrans.Amount <= 0) { throw new ArgumentException("Sell trans amount <= 0"); } if (buytrans.Quantity <= 0) { throw new ArgumentException("Buy quantity <= 0"); } if (selltrans.Quantity >= 0) { throw new ArgumentException("Sell quantity >= 0"); } MatchedTrade trade = new MatchedTrade { Id = ++tradeId, Symbol = buytrans.Symbol, DescriptionOfProperty = string.Format("{0} {1}", buytrans.Quantity, buytrans.Symbol), DateAcquired = buytrans.TradeDate, DateSoldOrDisposed = selltrans.TradeDate, AdjustmentAmount = 0, ReportedToIrs = true, ReportedToMe = true, Brokerage = selltrans.Broker, BuyOrderId = buytrans.OrderId, SellOrderId = selltrans.OrderId }; // Buy quantities are positive, sell quantities are negative // Buy Amount is negative, sell Amount is positive. // commission and fees are always negative if (Math.Abs(buytrans.Quantity) == Math.Abs(selltrans.Quantity)) { trade.Quantity = buytrans.Quantity; trade.Proceeds = Math.Abs(selltrans.Net); trade.CostOrBasis = Math.Abs(buytrans.Net); //Long Term Short Term TimeSpan diff = trade.DateSoldOrDisposed.Subtract(trade.DateAcquired); if (diff.TotalDays > 365) { trade.LongTermGain = true; } //if (trade.DateSoldOrDisposed.Year == 2014) TotalCommission += buytrans.Commission; TotalCommission += selltrans.Commission; LastTradeCommission = buytrans.Commission + selltrans.Commission; TotalProfit += trade.GainOrLoss; //if (Math.Abs(trade.GainOrLoss) > 1000) // throw new Exception("Invalid gain or loss"); trade.CumulativeProfit = TotalProfit; Trades.Add(trade); } 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; }
private OrderTransaction CreateTrade(OrderTransaction buytrans, OrderTransaction selltrans) { var l = new OrderTransaction(); if (buytrans == null && selltrans == null) return l; if (buytrans.Amount >= 0) throw new ArgumentException("Buy trans amount >= 0"); if (selltrans.Amount <= 0) throw new ArgumentException("Sell trans amount <= 0"); if (buytrans.Quantity <= 0) throw new ArgumentException("Buy quantity <= 0"); if (selltrans.Quantity >= 0) throw new ArgumentException("Sell quantity >= 0"); MatchedTrade trade = new MatchedTrade { Id = ++tradeId, Symbol = buytrans.Symbol, DescriptionOfProperty = string.Format("{0} {1}", buytrans.Quantity, buytrans.Symbol), DateAcquired = buytrans.TradeDate, DateSoldOrDisposed = selltrans.TradeDate, AdjustmentAmount = 0, ReportedToIrs = true, ReportedToMe = true, Brokerage = selltrans.Broker, BuyOrderId = buytrans.OrderId, SellOrderId = selltrans.OrderId }; // Buy quantities are positive, sell quantities are negative // Buy Amount is negative, sell Amount is positive. // commission and fees are always negative if (Math.Abs(buytrans.Quantity) == Math.Abs(selltrans.Quantity)) { trade.Quantity = buytrans.Quantity; trade.Proceeds = Math.Abs(selltrans.Net); trade.CostOrBasis = Math.Abs(buytrans.Net); //Long Term Short Term TimeSpan diff = trade.DateSoldOrDisposed.Subtract(trade.DateAcquired); if (diff.TotalDays > 365) trade.LongTermGain = true; //if (trade.DateSoldOrDisposed.Year == 2014) TotalCommission += buytrans.Commission; TotalCommission += selltrans.Commission; LastTradeCommission = buytrans.Commission + selltrans.Commission; TotalProfit += trade.GainOrLoss; //if (Math.Abs(trade.GainOrLoss) > 1000) // throw new Exception("Invalid gain or loss"); trade.CumulativeProfit = TotalProfit; Trades.Add(trade); } return l; }
private OrderTransaction CopyTransaction(OrderTransaction trans) { OrderTransaction l = new OrderTransaction(); l.Symbol = trans.Symbol; l.Exchange = trans.Exchange; l.Broker = trans.Broker; l.Quantity = trans.Quantity; l.Price = trans.Price; l.ActionNameUS = trans.ActionNameUS; l.TradeDate = trans.TradeDate; l.SettledDate = trans.SettledDate; l.Interest = trans.Interest; l.Amount = trans.Amount; l.Commission = trans.Commission; l.Fees = trans.Fees; l.CUSIP = trans.CUSIP; l.Description = trans.Description; l.ActionId = trans.ActionId; l.TradeNumber = trans.TradeNumber; l.RecordType = trans.RecordType; l.TaxLotNumber = trans.TaxLotNumber; l.OrderType = trans.OrderType; l.OrderId = trans.OrderId; l.Direction = trans.Direction; return l; }
public IPositionInventory OpenPosition(OrderTransaction trans, PositionInventoryMethod positionResolution) { IPositionInventory position; if (positionResolution == PositionInventoryMethod.Fifo) position = new PositionInventoryFifo(); else { position = new PositionInventoryLifo(); } position.Add(trans); return position; }
/// <summary> /// Local processing of the order event. It only logs the transaction and orderEvent /// </summary> /// <param name="orderEvent">OrderEvent - the order event</param> private void ProcessOrderEvent(OrderEvent orderEvent) { IEnumerable <OrderTicket> tickets; //add to the list of order events which is saved to a file when running locally // I will use this file to test Stefano Raggi's code var currentSignalInfo = signalInfos.FirstOrDefault(s => s.Symbol == orderEvent.Symbol); orderId = orderEvent.OrderId; if (currentSignalInfo != null) { currentSignalInfo.Status = orderEvent.Status; } tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId); switch (orderEvent.Status) { case OrderStatus.New: case OrderStatus.None: case OrderStatus.Submitted: case OrderStatus.Invalid: break; case OrderStatus.PartiallyFilled: if (currentSignalInfo != null) { nEntryPrice = Portfolio[symbol].HoldStock ? Portfolio[symbol].AveragePrice : 0; } break; case OrderStatus.Canceled: if (currentSignalInfo != null) { currentSignalInfo.IsActive = true; } break; case OrderStatus.Filled: if (currentSignalInfo != null) { currentSignalInfo.IsActive = true; } nEntryPrice = Portfolio[symbol].HoldStock ? Portfolio[symbol].AveragePrice : 0; if (tickets != null) { foreach (OrderTicket ticket in tickets) { //int infoId = Convert.ToInt32(ticket.Tag); #region "save the ticket as a OrderTransacton" OrderTransactionFactory transactionFactory = new OrderTransactionFactory((QCAlgorithm)this); OrderTransaction t = transactionFactory.Create(orderEvent, ticket, false); _transactions.Add(t); _orderTransactionProcessor.ProcessTransaction(t); _tradecount++; if (_orderTransactionProcessor.TotalProfit != totalProfit) { tradenet = CalculateTradeProfit(t.Symbol); } totalProfit = _orderTransactionProcessor.TotalProfit; #endregion } } break; } }
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 void SendTransaction(OrderTransaction t) { string j = JsonConvert.SerializeObject(t); try { using (var client = new HttpClient()) { var uri = new Uri(@"http://localhost:55293/"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.BaseAddress = uri; //HttpResponseMessage response = client.PostAsJsonAsync("api/OrderTransaction", t).Result; //if (!response.IsSuccessStatusCode) //{ // string r = "Error Code" + response.StatusCode + " : Message - " + response.ReasonPhrase; // Log(r); //} } } catch (AggregateException aggregateException) { WebSiteAvailable = false; StringBuilder sb = new StringBuilder(); sb.AppendLine(); SummarizeExceptions(sb, aggregateException); sb.AppendLine(aggregateException.StackTrace); Log(sb.ToString()); } }
public void TransactionHistoryAddsOK() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; p.TransactionHistory.Add(trans); Assert.IsTrue(p.TransactionHistory.Count > 0); }
public void OpenTradesAddsOk() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; p.OpenTrades.Add(trans); Assert.IsTrue(p.OpenTrades.Count > 0); }
public void OpenPositionOpensABuyPositionPosition() { OrderTransaction trans = new OrderTransaction(); trans.Direction = OrderDirection.Buy; trans.Symbol = "AAPL"; p.ProcessTransaction(trans); Assert.IsTrue(p.OpenPositions.Count > 0); }
/// <summary> /// Local processing of the order event. It only logs the transaction and orderEvent /// </summary> /// <param name="orderEvent">OrderEvent - the order event</param> private void ProcessOrderEvent(OrderEvent orderEvent) { IEnumerable <OrderTicket> tickets; //add to the list of order events which is saved to a file when running locally // I will use this file to test Stefano Raggi's code if (orderEvent.Status == OrderStatus.Filled) { _orderEvents.Add(orderEvent); } orderId = orderEvent.OrderId; tradeResult = orderEvent.Status; switch (orderEvent.Status) { case OrderStatus.New: case OrderStatus.None: case OrderStatus.Submitted: // just checking to make sure they are coming through tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); break; case OrderStatus.Canceled: tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); if (tickets != null) { foreach (OrderTicket ticket in tickets) { int infoId = Convert.ToInt32(ticket.Tag); SignalInfo si = signalInfos.FirstOrDefault(f => f.Id == infoId); if (si != null) { si.IsActive = true; } } } break; case OrderStatus.Filled: case OrderStatus.PartiallyFilled: tickets = Transactions.GetOrderTickets(t => t.OrderId == orderId && t.Status == orderEvent.Status); if (tickets != null) { foreach (OrderTicket ticket in tickets) { int infoId = Convert.ToInt32(ticket.Tag); SignalInfo si = signalInfos.FirstOrDefault(f => f.Id == infoId); if (si != null) { si.IsActive = true; } #region "log the ticket as a OrderTransacton" OrderTransactionFactory transactionFactory = new OrderTransactionFactory((QCAlgorithm)this); OrderTransaction t = transactionFactory.Create(orderEvent, ticket, false); _transactions.Add(t); _orderTransactionProcessor.ProcessTransaction(t); _tradecount++; if (_orderTransactionProcessor.TotalProfit != totalProfit) { CalculateTradeProfit(t.Symbol); } totalProfit = _orderTransactionProcessor.TotalProfit; #endregion } } break; } }