public Trade ConfirmExit(int tradeId, decimal level) { var trade = context.Trades .Include(x => x.TradeSteps) .Include(x => x.Orders) .Include(x => x.Signal).ThenInclude(t => t.SignalSteps) .Include(x => x.Signal).ThenInclude(t => t.BrokerInstrument) .FirstOrDefault(x => x.Id == tradeId); if (trade == null) return null; var lStep = trade.TradeSteps.OrderByDescending(x => x.Created).First(); if (lStep.Type == TradeStepType.Filled) { var diff = trade.Orders.FirstOrDefault(x => x.Function == OrderFunction.Entry).ExecutedLevel - level; // Take Profit? var execFunction = OrderFunction.SL; if (diff > 0 && trade.Signal.TradeDirection == TradeDirection.Long || (diff <= 0 && trade.Signal.TradeDirection == TradeDirection.Short)) execFunction = OrderFunction.TP; var execStepType = TradeStepType.Closed; trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == execFunction).ExecutedLevel = level; trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == execFunction).State = OrderState.Filled; foreach (var order in trade.Orders.Where(x => x.State != OrderState.Filled)) order.State = OrderState.Canceled; var newStep = new TradeStep { Trade = trade, Type = execStepType,EntryLevel = lStep.EntryLevel, ProfitLevel = level}; context.TradeSteps.Add(newStep); } return trade; }
public Trade ConfirmPlaceTrade(int tradeId, int? size = null, decimal? stop = null, decimal? entry = null, decimal? tp = null) { var trade = context.Trades .Include(x => x.TradeSteps) .Include(x => x.Orders) .Include(x => x.Signal).ThenInclude(t => t.SignalSteps) .Include(x => x.Signal).ThenInclude(t => t.BrokerInstrument) .FirstOrDefault(x => x.Id == tradeId); if (trade == null) return null; var lastStep = trade.TradeSteps.OrderByDescending(x => x.Created).First(); if ((lastStep.Type == TradeStepType.Prepped) || (lastStep.Type == TradeStepType.PrepChange)) { if (size == null) size = lastStep.Size; if (stop == null) stop = lastStep.StopLevel; if (entry == null) entry = lastStep.EntryLevel; if (tp == null) tp = lastStep.ProfitLevel; foreach (var order in trade.Orders.Where(x => x.State !=OrderState.Canceled)) order.State = OrderState.Submitted; var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Placed, Size = size, EntryLevel = entry, StopLevel = stop, ProfitLevel = tp }; context.TradeSteps.Add(newStep); } if ((lastStep.Type == TradeStepType.PrepCancel)) { foreach (var order in trade.Orders) order.State = OrderState.Canceled; var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Cancel }; context.TradeSteps.Add(newStep); } return trade; }
public Trade CancelTrade(int tradeId) { var trade = context.Trades .Include(x => x.TradeSteps) .Include(x => x.Orders) .Include(x => x.Signal).ThenInclude(t => t.SignalSteps) .Include(x => x.Signal).ThenInclude(t => t.BrokerInstrument) .FirstOrDefault(x => x.Id == tradeId); if (trade == null) return null; // cancel where nothing happened yet or as confirmation that orders where removed if ((trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.Prepped) || (trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.PrepCancel)) { foreach (var order in trade.Orders) order.State = OrderState.Canceled; var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Cancel }; context.TradeSteps.Add(newStep); } // cancel where orders really need to be removed from Broker if ((trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.Placed) || (trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.PrepChange) ) { var newStep = new TradeStep { Trade = trade, Type = TradeStepType.PrepCancel }; context.TradeSteps.Add(newStep); } trade.SignalState = SignalState.Ok; return trade; }
public Trade ConfirmFilled(int tradeId, decimal executedLevel, int size = 0) { var trade = context.Trades .Include(x => x.TradeSteps) .Include(x => x.Orders) .Include(x => x.Signal).ThenInclude(t => t.SignalSteps) .Include(x => x.Signal).ThenInclude(t => t.BrokerInstrument) .FirstOrDefault(x => x.Id == tradeId); if (trade == null) return null; var lastStep = trade.TradeSteps.OrderByDescending(x => x.Created).First(); if ((lastStep.Type == TradeStepType.Placed) || (lastStep.Type == TradeStepType.PlacedOld)) { trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == OrderFunction.Entry).ExecutedLevel = executedLevel; trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == OrderFunction.Entry).State = OrderState.Filled; if (size != 0) trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == OrderFunction.Entry).Size = size; var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Filled, EntryLevel = executedLevel, StopLevel = lastStep.StopLevel, ProfitLevel = lastStep.ProfitLevel, Size = lastStep.Size }; context.TradeSteps.Add(newStep); return trade; } if ((trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.Filled) || (trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.TGS)) { var initialEntry = (decimal)trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == OrderFunction.Entry).StopLevel; var einstieg = (decimal)trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == OrderFunction.Entry).ExecutedLevel; var ausstieg = (decimal)executedLevel; var initialStop = trade.TradeSteps.OrderBy(x => x.Created).FirstOrDefault(x => x.Type == TradeStepType.Placed).StopLevel; var rrr = Math.Abs(initialEntry - (decimal)initialStop); var rResult = Math.Abs(ausstieg - einstieg) / rrr; OrderFunction func = OrderFunction.SL; if (rResult > 1) func = OrderFunction.TP; trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == func).ExecutedLevel = executedLevel; trade.Orders.Where(x => x.State !=OrderState.Canceled).FirstOrDefault(x => x.Function == func).State = OrderState.Filled; foreach (var order in trade.Orders.Where(x => x.State !=OrderState.Canceled).Where(x => x.Function != func && x.State == OrderState.Submitted)) order.State = OrderState.Canceled; //if(size!=0) trade.Orders.FirstOrDefault(x => x.Function == OrderFunction.Entry).Size = size; var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Closed, ProfitLevel = executedLevel, EntryLevel = lastStep.EntryLevel, Size = lastStep.Size }; context.TradeSteps.Add(newStep); return trade; } return trade; }
public Trade HideTrade(int tradeId) { var trade = context.Trades .Include(x => x.TradeSteps) .FirstOrDefault(x => x.Id == tradeId); if (trade == null) return null; var step = trade.TradeSteps.OrderByDescending(t => t.Created).FirstOrDefault(); if ((trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.Cancel) || (trade.TradeSteps.OrderByDescending(x => x.Created).First().Type == TradeStepType.Closed)) { var newStep = new TradeStep { Trade = trade, Type = TradeStepType.Hide }; context.TradeSteps.Add(newStep); } return trade; }
public void UpdateTradeFromSignal(Trade trade, Signal signal = null, bool create = true) { var entryLevel = signal.SignalSteps.OrderByDescending(s => s.PriceEntry.TimeStamp).FirstOrDefault().Entry; var slLevel = signal.SignalSteps.OrderByDescending(s => s.PriceEntry.TimeStamp).FirstOrDefault().Sl; var r = Math.Abs((Double)entryLevel - (Double)slLevel); var stopLimitBuffer = r / 25; var direction = signal.TradeDirection; var otherDirection = signal.TradeDirection == TradeDirection.Long ? TradeDirection.Short : TradeDirection.Long; var stopLimitLevel = entryLevel > slLevel ? (Double)entryLevel + stopLimitBuffer : (Double)entryLevel - stopLimitBuffer; var tpLevel = (Decimal)(entryLevel > slLevel ? (Double)entryLevel + 2.47 * r : (Double)entryLevel - 2.47 * r); if(trade.Signal.SignalType == SignalType.uNL) tpLevel = (Decimal)entryLevel + 10* (Decimal)(entryLevel-slLevel); var size = (int)(this.getR() / r); var tradeStep = new TradeStep { Trade = trade, Type = TradeStepType.Prepped, Size = size }; context.TradeSteps.Add(tradeStep); tradeStep.EntryLevel = entryLevel; tradeStep.StopLevel = slLevel; tradeStep.ProfitLevel = tpLevel; var autoExitDate = DateTimeOffset.Now.AddBusinessDays(20); Order entryOrder; Order tpOrder; Order slOrder; Order timeExitOrder; if (create == false) { trade.Orders.FirstOrDefault(x => x.State != OrderState.Canceled && x.Function == OrderFunction.Entry).State = OrderState.Canceled; trade.Orders.FirstOrDefault(x => x.State != OrderState.Canceled && x.Function == OrderFunction.TP).State = OrderState.Canceled; trade.Orders.FirstOrDefault(x => x.State != OrderState.Canceled && x.Function == OrderFunction.SL).State = OrderState.Canceled; trade.Orders.FirstOrDefault(x => x.State != OrderState.Canceled && x.Function == OrderFunction.Time).State = OrderState.Canceled; } entryOrder = new Order { Trade = trade, Function = OrderFunction.Entry, Direction = direction, Type = OrderType.StopLimit, StopLevel = entryLevel, LimitLevel = (Decimal)stopLimitLevel, Size = size, State = OrderState.Prepared }; tpOrder = new Order { Trade = trade, Function = OrderFunction.TP, Direction = otherDirection, Type = OrderType.Limit, LimitLevel = tpLevel, Size = size, State = OrderState.Prepared }; slOrder = new Order { Trade = trade, Function = OrderFunction.SL, Direction = otherDirection, Type = OrderType.Stop, StopLevel = slLevel, Size = size, State = OrderState.Prepared }; timeExitOrder = new Order { Trade = trade, Function = OrderFunction.Time, Direction = otherDirection, Type = OrderType.Market, Size = size, State = OrderState.Prepared, ValidAfter = autoExitDate }; context.Orders.Add(entryOrder); context.Orders.Add(tpOrder); context.Orders.Add(slOrder); context.Orders.Add(timeExitOrder); trade.SignalState = SignalState.Ok; }
public static void PlaceOrder(Stock stock, TimeInForce tif, TradeStep tradeStep, Form parentForm) { string errString = string.Empty; PricePoint pricePoint = null; var newOrderSingle = new NewOrderSingle(); try { Account account = rh.DownloadAllAccounts().Result.First(); //if (pricePoint.PendingOrders == null) // pricePoint.PendingOrders = new Dictionary<decimal, String>(); if (tradeStep == TradeStep.Entry) { pricePoint = stock.Entry; } else if (tradeStep == TradeStep.ProfitTarget) { pricePoint = stock.PriceTarget; if (pricePoint.NoOfShares > 0) { pricePoint.NoOfShares *= -1; } } else if (tradeStep == TradeStep.StopLoss) { if (stock.PendingOrders != null && stock.PendingOrders.Any(o => o.Side == Side.Sell && o.Trigger == "stop")) { ThreadPool.QueueUserWorkItem(Robinhood.CancelOrder, new KeyValuePair <Form, ThreadedBindingList <OrderSnapshot> >(parentForm, stock.PendingOrders)); } while (stock.PendingOrders != null && stock.PendingOrders.Count > 0) { Thread.Sleep(1000); } pricePoint = stock.StopLoss; if (pricePoint.NoOfShares > 0) { pricePoint.NoOfShares *= -1; } } else { pricePoint = null; } Instrument instrument = null; while (instrument == null) { try { instrument = rh.FindInstrument(stock.Ticker.ToUpperInvariant()).Result.First(i => i.Symbol == stock.Ticker); } catch (Exception e) { MessageBox.Show("Problem. Try again. " + e.Message); } } lastOrderSuccess = false; if (pricePoint.Execution == CustomControls.PricePointControl.Execution.Limit || pricePoint.Execution == CustomControls.PricePointControl.Execution.Trailing) { newOrderSingle = new NewOrderSingle(instrument); newOrderSingle.AccountUrl = account.AccountUrl; newOrderSingle.TimeInForce = tif; newOrderSingle.Side = pricePoint.NoOfShares > 0 ? Side.Buy : Side.Sell; newOrderSingle.Quantity = Math.Abs(pricePoint.NoOfShares); newOrderSingle.OrderType = (OrderType)Enum.Parse(typeof(OrderType), pricePoint.Type.ToString()); newOrderSingle.Trigger = pricePoint.Trigger; //if (pricePoint.Value == 0) //{ // //newOrderSingle.OrderType = OrderType.Market; //} //else //{ //newOrderSingle.OrderType = OrderType.Limit; if (pricePoint.Trigger == TriggerType.Stop) { //newOrderSingle.OrderType = OrderType.Market; //newOrderSingle.Trigger = "stop"; if (newOrderSingle.OrderType == OrderType.Limit) { newOrderSingle.Price = pricePoint.Price; } else if (newOrderSingle.OrderType == OrderType.Market) { newOrderSingle.Price = stock.LastTradePrice; } newOrderSingle.StopPrice = pricePoint.Price + pricePoint.StopOffset; } else if (pricePoint.Trigger == TriggerType.Immediate) { newOrderSingle.Price = pricePoint.Price; } //} var order = rh.PlaceOrder(newOrderSingle).Result; PlacingOrder.Set(); if (order.State == "queued") { lastOrderSuccess = true; } // var test = rh.DownloadAllOrders().Result; //test.Start(); //test.Wait(); //pricePoint.PendingOrders.Add(pricePoint.Value, order.CancelUrl.Uri.AbsoluteUri.First()); } else if (pricePoint.Execution == CustomControls.PricePointControl.Execution.Spread) { int noOfShare = pricePoint.NoOfShares > 0 ? 1 : -1; foreach (decimal orderValue in pricePoint.ExecutionSpread) { newOrderSingle = new NewOrderSingle(instrument); newOrderSingle.AccountUrl = account.AccountUrl; newOrderSingle.TimeInForce = tif; newOrderSingle.Side = pricePoint.NoOfShares > 0 ? Side.Buy : Side.Sell; newOrderSingle.OrderType = (OrderType)Enum.Parse(typeof(OrderType), pricePoint.Type.ToString()); newOrderSingle.Trigger = pricePoint.Trigger; newOrderSingle.Quantity = Math.Abs(noOfShare); if (pricePoint.Trigger == TriggerType.Stop) { if (newOrderSingle.OrderType == OrderType.Limit) { newOrderSingle.Price = orderValue; } newOrderSingle.StopPrice = orderValue + 0.02m; } else if (pricePoint.Trigger == TriggerType.Immediate) { newOrderSingle.Price = orderValue; } var order = rh.PlaceOrder(newOrderSingle).Result; //pricePoint.PendingOrders.Add(pricePoint.Value, order.CancelUrl); } } Notification notifForm = new Notification(); parentForm.Invoke((MethodInvoker) delegate() { notifForm.label1.Text = string.Format("{0} {1} {2} Order Sent for {3} shares at {4}", stock.Ticker, newOrderSingle.Side, newOrderSingle.OrderType, newOrderSingle.Quantity, newOrderSingle.Price); notifForm.Show(); }); } catch (WebException e) { if (pricePoint.Execution != CustomControls.PricePointControl.Execution.Trailing && !stock.ManageTrade) { if (pricePoint.NoOfShares > 0) { errString = String.Format("Error Placing Buy Order for {0}, Check network connection", stock.Ticker); } else { errString = String.Format("Error Placing Sell Order for {0}, Check network connection", stock.Ticker); } Notification notifForm = new Notification(); parentForm.Invoke((MethodInvoker) delegate() { notifForm.label1.Text = string.Format(errString); notifForm.Show(); }); } } catch (HttpException e) { if (pricePoint.Execution != CustomControls.PricePointControl.Execution.Trailing && !(stock.ManageTrade && tradeStep == TradeStep.StopLoss)) { if (pricePoint.NoOfShares > 0) { errString = String.Format("Error Placing Buy Order for {0}, Check network connection", stock.Ticker); } else { errString = String.Format("Error Placing Sell Order for {0}, Check network connection", stock.Ticker); } Notification notifForm = new Notification(); parentForm.Invoke((MethodInvoker) delegate() { notifForm.label1.Text = string.Format(errString); notifForm.Show(); }); } } catch { if (pricePoint.Execution != CustomControls.PricePointControl.Execution.Trailing && !(stock.ManageTrade && tradeStep == TradeStep.StopLoss)) { if (pricePoint.NoOfShares > 0) { errString = String.Format("Error Placing Buy Order for {0}, Check buying power", stock.Ticker); } else { errString = String.Format("Error Placing Sell Order for {0}, Make sure you have enough shares available", stock.Ticker); } Notification notifForm = new Notification(); parentForm.Invoke((MethodInvoker) delegate() { notifForm.label1.Text = string.Format(errString); notifForm.Show(); }); } } }