/// <summary> /// This function is called prior to calling the GetOrderSignals to check to see if a ticket was filled /// If the ticket did not fill within one bar, cancel it and assume the market moved away from the limit order /// /// </summary> private List <ProformaOrderTicket> HandleTickets() { List <ProformaOrderTicket> proformaOrderTickets = new List <ProformaOrderTicket>(); foreach (OrderTicket queuedTicket in _ticketsQueue) { ProformaOrderTicket proformaLiveTicket = new ProformaOrderTicket(); // Check the ticket against the Transactions version of the ticket OrderTicket liveticket = Transactions.GetOrderTickets(t => t.OrderId == queuedTicket.OrderId).FirstOrDefault(); if (liveticket != null) { proformaLiveTicket.Status = liveticket.Status; proformaLiveTicket.OrderId = liveticket.OrderId; proformaLiveTicket.Symbol = liveticket.Symbol; proformaLiveTicket.Source = liveticket.Tag; proformaLiveTicket.TicketTime = liveticket.Time; proformaLiveTicket.Security_Type = liveticket.SecurityType; proformaLiveTicket.Tag = liveticket.Tag; proformaLiveTicket.TicketOrderType = liveticket.OrderType; if (liveticket.Status == OrderStatus.Submitted) { liveticket.Cancel(); proformaLiveTicket.Status = OrderStatus.Canceled; proformaLiveTicket.QuantityFilled = 0; // they are probably already 0 proformaLiveTicket.AverageFillPrice = 0; } // ToDo: Handle partial tickets if (liveticket.Status == OrderStatus.Filled) { proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; proformaLiveTicket.Status = OrderStatus.Filled; proformaLiveTicket.QuantityFilled = (int)liveticket.QuantityFilled; proformaLiveTicket.AverageFillPrice = liveticket.AverageFillPrice; } } else { proformaLiveTicket.ErrorMessage = string.Format("Ticket with Id {0} could not be found in Transactions.", queuedTicket.OrderId); } proformaOrderTickets.Add(proformaLiveTicket); } return(proformaOrderTickets); }
/// <summary> /// Executes the ITrend strategy orders. /// </summary> /// <param name="symbol">The symbol to be traded.</param> /// <param name="actualOrder">The actual arder to be execute.</param> /// <param name="data">The actual TradeBar data.</param> private void ExecuteStrategy(string symbol, decimal entryPrice, OrderSignal actualOrder, TradeBars data) { int shares; decimal limitPrice = 0m; switch (actualOrder) { case OrderSignal.goLong: shares = PositionShares(symbol, actualOrder); Tickets[symbol].Add(MarketOrder(symbol, shares)); Strategy[symbol].Position = StockState.shortPosition; Strategy[symbol].nEntryPrice = entryPrice; LastOrderSent[symbol] = actualOrder; break; case OrderSignal.goShort: shares = PositionShares(symbol, actualOrder); Tickets[symbol].Add(MarketOrder(symbol, shares)); Strategy[symbol].Position = StockState.longPosition; Strategy[symbol].nEntryPrice = entryPrice; LastOrderSent[symbol] = actualOrder; break; case OrderSignal.goLongLimit: shares = PositionShares(symbol, actualOrder); // Define the limit price. //limitPrice = Math.Max(data[symbol].Low, (data[symbol].Close - (data[symbol].High - data[symbol].Low) * RngFac)); limitPrice = Math.Round(Math.Max(data[symbol].Low, (data[symbol].Close - (data[symbol].High - data[symbol].Low) * RngFac)), 2, MidpointRounding.ToEven); // Send the order. Tickets[symbol].Add(LimitOrder(symbol, shares, limitPrice)); // Update the LastOrderSent dictionary. LastOrderSent[symbol] = actualOrder; break; case OrderSignal.goShortLimit: // Define the operation size. shares = PositionShares(symbol, actualOrder); // Define the limit price. //limitPrice = Math.Min(data[symbol].High, (data[symbol].Close + (data[symbol].High - data[symbol].Low) * RngFac)); limitPrice = Math.Round(Math.Min(data[symbol].High, (data[symbol].Close + (data[symbol].High - data[symbol].Low) * RngFac)), 2, MidpointRounding.ToEven); // Send the order. var security = Securities[symbol]; ProformaOrderTicket x = _brokerSimulator.LimitOrder(symbol, shares, limitPrice); Tickets[symbol].Add(LimitOrder(symbol, shares, limitPrice)); // Update the LastOrderSent dictionary. LastOrderSent[symbol] = actualOrder; break; case OrderSignal.closeLong: case OrderSignal.closeShort: // Define the operation size. shares = PositionShares(symbol, actualOrder); // Send the order. Tickets[symbol].Add(MarketOrder(symbol, shares)); // Because the order is an synchronously market order, they'll fill // immediately. So, update the ITrend strategy and the LastOrder Dictionary. Strategy[symbol].Position = StockState.noInvested; Strategy[symbol].nEntryPrice = entryPrice; LastOrderSent[symbol] = OrderSignal.doNothing; break; case OrderSignal.revertToLong: case OrderSignal.revertToShort: // Define the operation size. shares = PositionShares(symbol, actualOrder); // Send the order. Tickets[symbol].Add(MarketOrder(symbol, shares)); // Beacuse the order is an synchronously market order, they'll fill // immediately. So, update the ITrend strategy and the LastOrder Dictionary. if (actualOrder == OrderSignal.revertToLong) { Strategy[symbol].Position = StockState.longPosition; } else if (actualOrder == OrderSignal.revertToShort) { Strategy[symbol].Position = StockState.shortPosition; } Strategy[symbol].nEntryPrice = Tickets[symbol].Last().AverageFillPrice; LastOrderSent[symbol] = actualOrder; break; default: break; } }
/// <summary> /// This function is called prior to calling the GetOrderSignals to check to see if a ticket was filled /// If the ticket did not fill within one bar, cancel it and assume the market moved away from the limit order /// /// </summary> private List<ProformaOrderTicket> HandleTickets() { List<ProformaOrderTicket> proformaOrderTickets = new List<ProformaOrderTicket>(); foreach (OrderTicket queuedTicket in _ticketsQueue) { ProformaOrderTicket proformaLiveTicket = new ProformaOrderTicket(); // Check the ticket against the Transactions version of the ticket OrderTicket liveticket = Transactions.GetOrderTickets(t => t.OrderId == queuedTicket.OrderId).FirstOrDefault(); if (liveticket != null) { proformaLiveTicket.Status = liveticket.Status; proformaLiveTicket.OrderId = liveticket.OrderId; proformaLiveTicket.Symbol = liveticket.Symbol; proformaLiveTicket.Source = liveticket.Tag; proformaLiveTicket.TicketTime = liveticket.Time; proformaLiveTicket.Security_Type = liveticket.SecurityType; proformaLiveTicket.Tag = liveticket.Tag; proformaLiveTicket.TicketOrderType = liveticket.OrderType; if (liveticket.Status == OrderStatus.Submitted) { liveticket.Cancel(); proformaLiveTicket.Status = OrderStatus.Canceled; proformaLiveTicket.QuantityFilled = 0; // they are probably already 0 proformaLiveTicket.AverageFillPrice = 0; } // ToDo: Handle partial tickets if (liveticket.Status == OrderStatus.Filled) { proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; proformaLiveTicket.Status = OrderStatus.Filled; proformaLiveTicket.QuantityFilled = (int)liveticket.QuantityFilled; proformaLiveTicket.AverageFillPrice = liveticket.AverageFillPrice; } } else { proformaLiveTicket.ErrorMessage = string.Format("Ticket with Id {0} could not be found in Transactions.", queuedTicket.OrderId); } proformaOrderTickets.Add(proformaLiveTicket); } return proformaOrderTickets; }
/// <summary> /// This function is called prior to calling the GetOrderSignals to check to see if a ticket was filled /// If the ticket did not fill within one bar, cancel it and assume the market moved away from the limit order /// /// It re /// </summary> private List<ProformaOrderTicket> HandleTickets() { List<ProformaOrderTicket> proformaOrderTickets = new List<ProformaOrderTicket>(); //if (maketrade) //{ // process a real order foreach (OrderTicket queuedTicket in _ticketsQueue) { ProformaOrderTicket proformaLiveTicket = new ProformaOrderTicket(); // Check the ticket against the Transactions version of the ticket IEnumerable<OrderTicket> livetickets = Transactions.GetOrderTickets(t => t.OrderId == queuedTicket.OrderId); if (livetickets != null) { foreach (OrderTicket liveticket in livetickets) { proformaLiveTicket.Status = liveticket.Status; proformaLiveTicket.OrderId = liveticket.OrderId; proformaLiveTicket.Symbol = liveticket.Symbol; proformaLiveTicket.Source = liveticket.Tag; proformaLiveTicket.TicketTime = liveticket.Time; proformaLiveTicket.Security_Type = liveticket.SecurityType; proformaLiveTicket.Tag = liveticket.Tag; proformaLiveTicket.TicketOrderType = liveticket.OrderType; switch (liveticket.Status) { case OrderStatus.Canceled: case OrderStatus.New: case OrderStatus.None: break; case OrderStatus.Invalid: proformaLiveTicket.ErrorMessage = liveticket.GetMostRecentOrderResponse().ErrorMessage; break; case OrderStatus.Submitted: liveticket.Cancel(); proformaLiveTicket.Status = OrderStatus.Canceled; proformaLiveTicket.QuantityFilled = 0; // they are probably already 0 proformaLiveTicket.AverageFillPrice = 0; break; case OrderStatus.Filled: case OrderStatus.PartiallyFilled: #region logging if (Portfolio[symbol].Invested) { nEntryPrice = Portfolio[symbol].IsLong ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nExitPrice = 0; } else { nExitPrice = nEntryPrice != 0 ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nEntryPrice = 0; } #endregion proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; proformaLiveTicket.Status = OrderStatus.Filled; proformaLiveTicket.QuantityFilled = (int)liveticket.QuantityFilled; proformaLiveTicket.AverageFillPrice = liveticket.AverageFillPrice; break; } } } else { proformaLiveTicket.ErrorMessage = string.Format("Ticket with Id {0} could not be found in Transactions.", queuedTicket.OrderId); } proformaOrderTickets.Add(proformaLiveTicket); } return proformaOrderTickets; }
/// <summary> /// This function is called prior to calling the GetOrderSignals to check to see if a ticket was filled /// If the ticket did not fill within one bar, cancel it and assume the market moved away from the limit order /// /// It re /// </summary> private List <ProformaOrderTicket> HandleTickets() { List <ProformaOrderTicket> proformaOrderTickets = new List <ProformaOrderTicket>(); //if (maketrade) //{ // process a real order foreach (OrderTicket queuedTicket in _ticketsQueue) { ProformaOrderTicket proformaLiveTicket = new ProformaOrderTicket(); // Check the ticket against the Transactions version of the ticket IEnumerable <OrderTicket> livetickets = Transactions.GetOrderTickets(t => t.OrderId == queuedTicket.OrderId); if (livetickets != null) { foreach (OrderTicket liveticket in livetickets) { proformaLiveTicket.Status = liveticket.Status; proformaLiveTicket.OrderId = liveticket.OrderId; proformaLiveTicket.Symbol = liveticket.Symbol; proformaLiveTicket.Source = liveticket.Tag; proformaLiveTicket.TicketTime = liveticket.Time; proformaLiveTicket.Security_Type = liveticket.SecurityType; proformaLiveTicket.Tag = liveticket.Tag; proformaLiveTicket.TicketOrderType = liveticket.OrderType; switch (liveticket.Status) { case OrderStatus.Canceled: case OrderStatus.New: case OrderStatus.None: break; case OrderStatus.Invalid: proformaLiveTicket.ErrorMessage = liveticket.GetMostRecentOrderResponse().ErrorMessage; break; case OrderStatus.Submitted: liveticket.Cancel(); proformaLiveTicket.Status = OrderStatus.Canceled; proformaLiveTicket.QuantityFilled = 0; // they are probably already 0 proformaLiveTicket.AverageFillPrice = 0; break; case OrderStatus.Filled: case OrderStatus.PartiallyFilled: #region logging if (Portfolio[symbol].Invested) { nEntryPrice = Portfolio[symbol].IsLong ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nExitPrice = 0; } else { nExitPrice = nEntryPrice != 0 ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nEntryPrice = 0; } #endregion proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; proformaLiveTicket.Status = OrderStatus.Filled; proformaLiveTicket.QuantityFilled = (int)liveticket.QuantityFilled; proformaLiveTicket.AverageFillPrice = liveticket.AverageFillPrice; break; } } } else { proformaLiveTicket.ErrorMessage = string.Format("Ticket with Id {0} could not be found in Transactions.", queuedTicket.OrderId); } proformaOrderTickets.Add(proformaLiveTicket); } return(proformaOrderTickets); }
/// <summary> /// This function is called prior to calling the GetOrderSignals to check to see if a ticket was filled /// If the ticket did not fill within one bar, cancel it and assume the market moved away from the limit order /// /// It re /// </summary> private List <ProformaOrderTicket> HandleTickets() { List <ProformaOrderTicket> proformaOrderTickets = new List <ProformaOrderTicket>(); //if (maketrade) //{ // process a real order foreach (OrderTicket queuedTicket in _ticketsQueue) { ProformaOrderTicket proformaLiveTicket = new ProformaOrderTicket(); // Check the ticket against the Transactions version of the ticket OrderTicket liveticket = Transactions.GetOrderTickets(t => t.OrderId == queuedTicket.OrderId).FirstOrDefault(); if (liveticket != null) { proformaLiveTicket.Status = liveticket.Status; proformaLiveTicket.OrderId = liveticket.OrderId; proformaLiveTicket.Symbol = liveticket.Symbol; proformaLiveTicket.Source = liveticket.Tag; proformaLiveTicket.TicketTime = liveticket.Time; proformaLiveTicket.Security_Type = liveticket.SecurityType; proformaLiveTicket.Tag = liveticket.Tag; proformaLiveTicket.TicketOrderType = liveticket.OrderType; proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; if (liveticket.Status == OrderStatus.Submitted) { liveticket.Cancel(); proformaLiveTicket.Status = OrderStatus.Canceled; proformaLiveTicket.QuantityFilled = 0; // they are probably already 0 proformaLiveTicket.AverageFillPrice = 0; } // ToDo: Handle partial tickets if (liveticket.Status == OrderStatus.Filled) { proformaLiveTicket.Direction = liveticket.Quantity > 0 ? OrderDirection.Buy : OrderDirection.Sell; proformaLiveTicket.Status = OrderStatus.Filled; proformaLiveTicket.QuantityFilled = (int)liveticket.QuantityFilled; proformaLiveTicket.AverageFillPrice = liveticket.AverageFillPrice; #region logging if (Portfolio[symbol].Invested) { nEntryPrice = Portfolio[symbol].IsLong ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nExitPrice = 0; } else { nExitPrice = nEntryPrice != 0 ? liveticket.AverageFillPrice : liveticket.AverageFillPrice * -1; nEntryPrice = 0; } #endregion } } else { proformaLiveTicket.ErrorMessage = string.Format("Ticket with Id {0} could not be found in Transactions.", queuedTicket.OrderId); } proformaOrderTickets.Add(proformaLiveTicket); } return(proformaOrderTickets); //} //else //{ // // Process a sumulated order // var tickets = _ticketsSubmitted.Where(t => System.Convert.ToInt32(t.Source) == sigId); // foreach (var ticket in tickets) // { // var simticket = sim._orderTickets.FirstOrDefault(s => s.Value.OrderId == ticket.OrderId).Value; // if (simticket.Status == OrderStatus.Submitted) // { // // Todo: do something with the cancelled ticket such as save it to a file or collection for later analysis // if (sim.TryCancelTicket(simticket)) // { // // remove the cancelled ticket from the simulator // var cancelledTicket = sim.RemoveCancelledTicket(simticket); // // remove the cancelled ticket from the _ticketsSubmitted collection // _ticketsSubmitted.Remove(ticket); // // it was cancelled so the ticket did not fill // orderfilled = false; // return cancelledTicket; // } // return null; // } // if (simticket.Status == OrderStatus.Filled) // { // // Create a transaction and add it to the OrderProcessor // OrderTransactionFactory fac = new OrderTransactionFactory(this); // OrderTransaction transaction = fac.Create(sim, simticket); // if (simticket.OrderId == 27) // comment = ""; // _proformatransactions.Add(transaction); // _proformaProcessor.ProcessTransaction(transaction); // ProformaOrderTicket filledTicket = sim.RemoveTicket(simticket); // _ticketsSubmitted.Remove(ticket); // // orderfilled = true; // no need to change the filled // return filledTicket; // } // orderfilled = false; // _ticketsSubmitted.Remove(ticket); // return simticket; // // ToDo: Partial fills // } //} return(null); }