public static EnumOpenClose CheckOpenClose(Order order) { string text = order.Text; EnumOpenClose OpenClose = EnumOpenClose.OPEN; if (text.StartsWith("{") && text.EndsWith("}")) { TextParameter parameter = JsonConvert.DeserializeObject<TextParameter>(text); switch (parameter.Type) { case EnumGroupType.COMMON: { TextCommon t = JsonConvert.DeserializeObject<TextCommon>(text); OpenClose = t.OpenClose; } break; case EnumGroupType.QUOTE: { TextQuote t = JsonConvert.DeserializeObject<TextQuote>(text); OpenClose = t.OpenClose; } break; } } return OpenClose; }
public void CancelTest() { // Arrange OQ.Order order = CreateOQOrder(456); int clientID = target.ClientId; // Accept Order mockIBClient.Setup(ib => ib.PlaceOrder(It.IsAny <int>(), It.IsAny <IB.Contract>(), It.IsAny <IB.Order>())) .Callback((int id, IB.Contract ctr, IB.Order ord) => AcceptOrder(id, ctr, ord)); // Cancel Order mockIBClient.Setup(ib => ib.CancelOrder(It.IsAny <int>())) .Callback((int id) => cancelOrder(id, clientID)); target.Send(order); // Act target.Cancel(order); // Assert // Order Accepted logger.Verify(log => log.AddLog(LoggerLevel.Information, "ibclient_OrderStatus: received from TWS ID: 42, ClientID: 9876, Filled: 0, Remaining: 456, Status: Submitted")); userProvider.Verify(up => up.EmitAccepted(It.Is <OQ.Order>(ord => ord.OrderID == "42"))); // Cancel // ibClient.Cancel mockIBClient.Verify(ib => ib.CancelOrder(42)); // OnOrderCanceled logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("START.* OnOrderCanceled"))); userProvider.Verify(up => up.EmitCancelled(It.Is <OQ.Order>(ord => ord.OrderID == "42"))); logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("END.* OnOrderCanceled"))); // never saw an error? logger.Verify(log => log.AddLog(LoggerLevel.Error, It.IsAny <string>()), Times.Never(), "unexpected error log"); }
public override void OnOrderRejected(Order order) { EnumOpenClose OpenClose = DualPosition.OrderRejected(order); double flag = order.Side == OrderSide.Buy ? 1 : -1; if (EnumOpenClose.OPEN == OpenClose) { // 开仓被拒绝,不再新开仓 // 有可能是钱不够 // 有可能是超出持仓限制 // 有可能是非交易时间 TargetPosition -= flag * order.LeavesQty; return; } EnumError error = TextResponse.FromText(order.Text); // 无法平仓,不重发单 // 能出现这个问题是持仓计算错误,这已经是策略持仓计算错误了 if (error == EnumError.OVER_CLOSETODAY_POSITION || error == EnumError.OVER_CLOSEYESTERDAY_POSITION || error == EnumError.OVER_CLOSE_POSITION) { TargetPosition -= flag * order.LeavesQty; return; } // 当前状态禁止此项操作,时间不对,应当等下次操作 }
public override void OnOrderFilled(Order order) { dualPosition.Filled(order); // 检查仓位是否正确,是否要发新单 Process(); }
public override void OnOrderPartiallyFilled(Order order) { //lock (this) { SubOrder(order); base.OnOrderPartiallyFilled(order); } }
public override void OnOrderRejected(Order order) { //lock(this) { SubOrder(order); base.OnOrderRejected(order); } }
public OrderTracker(Order order) { Order = order; this.QuantityToFill = order.Qty; this.OriginalPrice = order.Price; this.AmountToFill = this.QuantityToFill*this.OriginalPrice; FilledAmount = 0; FilledQuantity = 0; }
public override void OnOrderCancelled(Order order) { dualPosition.OrderCancelled(order); // 追单 if (!timeHelper.IsTradingTime()) { return; } ResendOrder(order); }
public override void OnOrderCancelled(Order order) { dualPosition.OrderCancelled(order); // 追单 if (!IsWorkingTime()) { return; } ResendOrder(order); }
private static void SQ_OrderManager_OrderListUpdated(object sender, EventArgs e) { OpenQuant.orders.Clear(); Map.OQ_SQ_Order.Clear(); Map.SQ_OQ_Order.Clear(); foreach (SingleOrder singleOrder in OrderManager.Orders.All) { Order order = new Order(singleOrder); OpenQuant.orders.Add(order); Map.OQ_SQ_Order[order] = singleOrder; Map.SQ_OQ_Order[singleOrder] = order; } }
public static EnumOpenClose CheckOpenClose(Order order) { string text = order.Text; EnumOpenClose OpenClose = EnumOpenClose.OPEN; if (text.StartsWith("{") && text.EndsWith("}")) { TextCommon parameter = JsonConvert.DeserializeObject<TextCommon>(text); OpenClose = parameter.OpenClose; } return OpenClose; }
protected override void AdjustPostOrderProcessing(Order order) { if (IsLegComplete) return; double temp = FilledAmount - AmountToFill; if (temp < order.AvgPrice) { Log.WriteDebugLog( LegName, this.Instrument, string.Format("The remainder amount is {0:c2} which is less than the price {1:c2}. So finalizing ther leg", temp, order.AvgPrice)); FilledAmount = AmountToFill; } }
// 这下面有问题,不能这么直接减,因为撤单可能只是中间状态,后面还要补上来的 // 而其它状态可以认为单子改变,可以修改了 // 但如果是手动撤单,因为目标挂单没减,会再自动重挂 // 但如果这么一减,想挂单的数就少了,系统的撤单重挂功能就无效了 public override void OnOrderCancelled(Order order) { //lock(this) { // 如果不是通过双向持仓工具,而是手工下单,就不会记录下来 // 这样还是有问题,如果是使用的双向持仓工具,手工下单就会出错 // 有这个单子,是调整所产生,不改变挂单表 if (!cancelList.Remove(order)) { // 没有找到,表示非调整,要改变挂单表 SubOrder(order); } base.OnOrderCancelled(order); } }
/// <summary> /// /// </summary> /// <param name="bar"></param> public virtual void HandleBarOpen(Bar bar) { if (bar.BeginTime >= triggerTime) { if (openPrice == null) { openPrice = bar.Open; } if (!HasPosition && closingOrder == null) { OrderSide? side = null; double targetPrice = openPrice.Value; double targetQuantity = 0; if (longPositionQuantity.HasValue && longPositionQuantity.Value > 0) { side = OrderSide.Sell; targetPrice = GetSlippageAdjustedPrice(openPrice.Value, side.Value); targetQuantity = longPositionQuantity.Value; } if (shortPositionQuantity.HasValue && shortPositionQuantity.Value > 0) { side = OrderSide.Buy; targetPrice = GetSlippageAdjustedPrice(openPrice.Value, side.Value); targetQuantity = shortPositionQuantity.Value; } targetPrice = RoundPrice(targetPrice); if (side.HasValue) { closingOrder = LimitOrder(side.Value, targetQuantity, targetPrice, "Auto closing order"); LogOrder("Closing", Instrument.Symbol, side.Value, targetQuantity, targetPrice); if (AutoSubmit) closingOrder.Send(); } } } }
public static PositionSide CheckLongShort(Order order,EnumOpenClose OpenClose) { if (EnumOpenClose.OPEN == OpenClose) { if (order.Side == OrderSide.Buy) { return PositionSide.Long; } } else { if (order.Side == OrderSide.Buy) { } else { return PositionSide.Long; } } return PositionSide.Short; }
private void SubOrder(Order order) { // 市价不会挂单,所以不会记录到目标挂单助手中 if (order.Type != OrderType.Limit) return; double price = order.Price; double size = order.LastQty; //lock(this) { if (order.Side == OrderSide.Buy) { TargetOrderBook.Buy.Change(price, -size); } else { TargetOrderBook.Sell.Change(price, -size); } } }
private OQ.Order CreateOQOrder(int quantity) { OQ.Order order = new OQ.Order(); order.Account = "U111"; order.ClientID = "9999"; // will be overidden with value from Settings order.Instrument = new Instrument(); order.Instrument.Currency = "CHF"; order.Instrument.Exchange = "Brasil"; order.Instrument.Symbol = "OQOQ"; order.Instrument.Type = InstrumentType.Stock; order.OCAGroup = "MyOCA"; order.Price = 12.34; order.OrderID = "7777"; // will be overridden from Broker order.Qty = quantity; order.Side = OrderSide.Buy; order.StopPrice = 45.57; order.Text = "My Order Text"; order.TimeInForce = TimeInForce.GTC; order.Type = OpenQuant.API.OrderType.Limit; return(order); }
// 重新发单 private void ResendOrder(Order order) { SendOrder(order.Side, OpenCloseHelper.CheckOpenClose(order), order.LeavesQty); }
internal void Remove(Order order) { this.list.Remove(order); }
internal void Add(Order order) { this.list.Add(order); }
public static void Init() { FreeQuant.Instruments.Currency.Converter = new DefaultCurrencyConverter(); foreach (FreeQuant.Instruments.Instrument fq_instrument in FreeQuant.Instruments.InstrumentManager.Instruments) OpenQuant.AddInstrument(fq_instrument); FreeQuant.Instruments.InstrumentManager.InstrumentAdded += (e) => { OpenQuant.AddInstrument(e.Instrument); }; FreeQuant.Instruments.InstrumentManager.InstrumentRemoved += (e) => { OpenQuant.RemoveInstrument(e.Instrument); }; foreach (FreeQuant.Instruments.Portfolio sq_portfolio in PortfolioManager.Portfolios) OpenQuant.AddPortfolio(sq_portfolio); PortfolioManager.PortfolioAdded += (e) => { OpenQuant.AddPortfolio(e.Portfolio); }; OpenQuant.InitOrders(); OrderManager.NewOrder += (e) => { Order order; if (Map.FQ_OQ_Order.ContainsKey(e.Order)) { order = Map.FQ_OQ_Order[e.Order] as Order; } else { order = new Order(e.Order); Map.OQ_FQ_Order[order] = e.Order; Map.FQ_OQ_Order[e.Order] = order; } OpenQuant.orders.Add(order); }; OrderManager.OrderRemoved += (e) => { Order order = Map.FQ_OQ_Order[e.Order] as Order; OpenQuant.orders.Remove(order); Map.FQ_OQ_Order.Remove(e.Order); Map.OQ_FQ_Order.Remove(order); }; OrderManager.OrderListUpdated += (sender, e) => { OpenQuant.orders.Clear(); Map.OQ_FQ_Order.Clear(); Map.FQ_OQ_Order.Clear(); foreach (SingleOrder order1 in OrderManager.Orders.All) { Order order2 = new Order(order1); OpenQuant.orders.Add(order2); Map.OQ_FQ_Order[order2] = order1; Map.FQ_OQ_Order[order1] = order2; } }; }
public SrOrderInfo(OQ.Order oqorder, SrOrderInfoState state = SrOrderInfoState.New) { this.oqorder = oqorder; this.state = state; }
public DateTime SubmittedDate = DateTime.MaxValue; // form IB to Exchange #endregion Fields #region Constructors public SrOrder(OQ.Order oqorder) { this.oqorder = oqorder; }
public bool acknowledged = false; // arrived at exchange #region constructor public SrOrder(OQ.Order oqorder) { this.oqorder = oqorder; }
public override void OnOrderCancelReject(Order order) { // 撤单被拒绝,暂不操作 }
protected abstract void HandlePartiallyFilledQuantity(Order order);
public override void OnOrderPartiallyFilled(Order order) { dualPosition.Filled(order); // 单子部分成交,不做操作,等单子完全执行完 }
public override void OnNewOrder(Order order) { dualPosition.NewOrder(order); }
public double newStopPrice; // for new order after a replace/cancel #region constructor public SrOrderInfo(OQ.Order oqorder, SrOrderInfoState state = SrOrderInfoState.New) { this.oqorder = oqorder; this.state = state; }
protected virtual bool RetryOrder(Bar bar, HandlerStrategyStartHandler strategyStartHandler) { bool returnValue = false; if (IsItTimeToRetryOrder(bar)) { try { /* while (!strategyOrder.IsCancelled) { strategyOrder.Cancel(); Thread.Sleep(1); } */ strategyOrder.Cancel(); strategyOrder = null; triggerTime = triggerTime.Value.AddMinutes(RetryTriggerIntervalMinute); //strategyStartHandler(); retryCount++; returnValue = true; } catch (Exception ex) { LoggingUtility.WriteError(LoggingConfig, string.Format("Error happened while trying to retry order: {0}", ex)); } finally { } } return returnValue; }
/// <summary> /// 订单被拒绝 /// </summary> /// <param name="order"></param> /// <returns></returns> public EnumOpenClose OrderRejected(Order order) { lock (this) { double LeavesQty = order.LeavesQty;//得到剩余的订单数量 EnumOpenClose OpenClose = GetOpenClose(order);//开平标记 switch (OpenClose) { case EnumOpenClose.OPEN: if (order.Side == OrderSide.Buy) { //Long.FrozenOpen -= LeavesQty; Long.OrderRejectedOpen(LeavesQty); } else { //Short.FrozenOpen -= LeavesQty; Short.OrderRejectedOpen(LeavesQty); } break; case EnumOpenClose.CLOSE: if (order.Side == OrderSide.Buy) { //Short.FrozenClose -= LeavesQty; Short.OrderRejectedClose(LeavesQty); } else { //Long.FrozenClose -= LeavesQty; Long.OrderRejectedClose(LeavesQty); } break; case EnumOpenClose.CLOSE_TODAY: if (order.Side == OrderSide.Buy) { //Short.FrozenCloseToday -= LeavesQty; //Short.FrozenClose -= LeavesQty; Short.OrderRejectedCloseToday(LeavesQty); } else { //Long.FrozenCloseToday -= LeavesQty; //Long.FrozenClose -= LeavesQty; Long.OrderRejectedCloseToday(LeavesQty); } break; default: MessageBox.Show("OrderRejected"); break; } //if (IsDone) { if (order.Side == OrderSide.Buy) { Buy.Remove(order); } else { Sell.Remove(order); } Order_OpenClose.Remove(order); } return OpenClose; } }
public override void OnOrderStatusChanged(Order order) { if (order.Status == OrderStatus.Filled) { IsStrategyOrderFilled = true; } else if (order.Status == OrderStatus.PartiallyFilled) { HandlePartiallyFilledQuantity(order); IsStrategyOrderPartiallyFilled = true; } else if (order.Status == OrderStatus.Rejected || order.Status == OrderStatus.Cancelled) { LoggingUtility.WriteInfo(this, "Order in rejected/cancelled state. " + GetEntrySignalName()); IsStrategyOrderInFailedState = true; } else if (order.IsDone) { LoggingUtility.WriteInfo(this, "Order in rejected state. " + GetEntrySignalName()); IsStrategyOrderInFailedState = true; } string message = string.Format("ORDER UPDATE: {0}, Status={1}", order.Text, order.Status); LoggingUtility.WriteHorizontalBreak(this); LoggingUtility.WriteInfo(this, message); LoggingUtility.WriteHorizontalBreak(this); RunPostOrderStatusChangedImpl(); }
public override void OnOrderCancelled(Order order) { DualPosition.OrderCancelled(order); ResendOrder(order); }
public override void OnOrderRejected(Order order) { dualPosition.OrderRejected(order); ErrorType et = ParseErrorType.GetError(order.Text); double flag = order.Side == OrderSide.Buy ? 1 : -1; if (EnumOpenClose.OPEN == OpenCloseHelper.CheckOpenClose(order)) { // 开仓被拒绝,不再新开仓 TargetPosition -= flag * order.LeavesQty; return; } // 无法平仓,不重发单 if (et == ErrorType.OVER_CLOSETODAY_POSITION || et == ErrorType.OVER_CLOSEYESTERDAY_POSITION || et == ErrorType.OVER_CLOSE_POSITION) { TargetPosition -= flag * order.LeavesQty; return; } // 当前状态禁止此项操作,时间不对,应当等下次操作 }
public void SendTest() { // Arrange OQ.Order order = CreateOQOrder(456); // Accept and Fill Order mockIBClient.Setup(ib => ib.PlaceOrder(It.IsAny <int>(), It.IsAny <IB.Contract>(), It.IsAny <IB.Order>())) .Callback((int id, IB.Contract ctr, IB.Order ord) => AcceptAndFillOrder(id, ctr, ord)); target.Send(order); // Act // info PlaceOrder string expected_text = @"PlaceOrder.ID=42, Orderref=, Symbol=OQOQ, Action=Buy, Size=456, OrderType=Limit, limit price=12.34, Aux price=45.57."; logger.Verify(log => log.AddLog(LoggerLevel.Information, It.IsRegex(expected_text))); // expected contract Contract exp_contract = new Contract(); exp_contract.Currency = "CHF"; exp_contract.Exchange = "Brasil"; exp_contract.SecurityType = SecurityType.Stock; exp_contract.Symbol = "OQOQ"; // expected order IB.Order exp_iborder = new IB.Order(); exp_iborder.Account = "U111"; exp_iborder.ClientId = 9876; // must come from Settings exp_iborder.OcaGroup = "MyOCA"; exp_iborder.OrderId = 42; exp_iborder.TotalQuantity = 456; exp_iborder.Action = ActionSide.Buy; exp_iborder.AuxPrice = (decimal)45.57; exp_iborder.LimitPrice = (decimal)12.34; exp_iborder.Tif = Krs.Ats.IBNet96.TimeInForce.GoodTillCancel; exp_iborder.OrderType = OrderType.Limit; mockIBClient.Verify(ib => ib.PlaceOrder(42, It.Is <IB.Contract>(ctr => MatchContracts(exp_contract, ctr)), It.Is <IB.Order>(ord => MatchOrders(exp_iborder, ord)))); // check Info returned in OQ.Order Assert.AreEqual("42", order.OrderID); Assert.AreEqual("9876", order.ClientID); // from Settings / StingrayOQ.ClientId Property // ibclient_OrderStatus logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("START.* ibclient_OrderStatus.*"))); logger.Verify(log => log.AddLog(LoggerLevel.Information, "ibclient_OrderStatus: received from TWS ID: 42, ClientID: 9876, Filled: 0, Remaining: 456, Status: Submitted")); // OnOrderAccepted logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("START.* OnOrderAccepted"))); userProvider.Verify(up => up.EmitAccepted(It.Is <OQ.Order>(ord => ord.OrderID == "42"))); logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("END.* OnOrderAccepted"))); logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("END.* ibclient_OrderStatus.*"))); // OnOrderFilled logger.Verify(log => log.AddLog(LoggerLevel.Information, "ibclient_OrderStatus: received from TWS ID: 42, ClientID: 9876, Filled: 456, Remaining: 0, Status: Filled")); logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("START.* OnOrderFilled"))); userProvider.Verify(up => up.EmitFilled(It.Is <OQ.Order>(ord => ord.OrderID == "42"), 12.34, 456)); logger.Verify(log => log.AddLog(LoggerLevel.Detail, It.IsRegex("END.* OnOrderFilled"))); // never saw an error? logger.Verify(log => log.AddLog(LoggerLevel.Error, It.IsAny <string>()), Times.Never(), "unexpected error log"); }