private void AcceptOrder(int orderId, IB.Contract contract, IB.Order order)
        {
            int filled    = 0;
            int remaining = order.TotalQuantity;

            // Accept
            mockIBClient.Raise(ib => ib.OrderStatus += null,
                               new OrderStatusEventArgs(orderId, IB.OrderStatus.Submitted, filled, remaining,
                                                        (decimal)order.LimitPrice, 333333, 0, (decimal)0.0, order.ClientId, ""));
        }
        public bool MatchOrders(IB.Order expected, IB.Order actual)
        {
            Assert.AreEqual(expected.Account, actual.Account, "Order.Account");
            Assert.AreEqual(expected.Action, actual.Action, "Order.Action");
            Assert.AreEqual(expected.ClientId, actual.ClientId, "Order.ClientId");
            Assert.AreEqual(expected.OcaGroup, actual.OcaGroup, "Order.OcaGroup");
            Assert.AreEqual(expected.OrderId, actual.OrderId, "Order.OrderId");
            Assert.AreEqual(expected.TotalQuantity, actual.TotalQuantity, "Order.TotalQuantity");
            Assert.AreEqual((double)expected.LimitPrice, (double)actual.LimitPrice, 0.05, "Order.LimitPrice");
            Assert.AreEqual((double)expected.AuxPrice, (double)actual.AuxPrice, 0.005, "Order.AuxPrice");
            Assert.AreEqual(expected.Tif, actual.Tif, "Order.Tif");
            Assert.AreEqual(expected.OrderType, actual.OrderType, "Order.OrderType");

            return(true);
        }
        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");
        }
        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");
        }
Exemple #5
0
        private void Send2(OQ.Order order, double newQty = double.NaN, double newPrice = double.NaN, double newStopPrice = double.NaN)
        {
            if (!CheckTWS()) return;

            if (!IsConnected)
            {
                EmitError("Not connected.");
                return;
            }
            // check Account
            if(activeAccounts.Count > 1)
            {
                if(string.IsNullOrWhiteSpace(order.Account))
                {
                    throw new Exception("no account specified");
                }
            }

            int orderId;
            Contract contract = new Contract();
            IB.Order iborder = new IB.Order();

            // OrderId
            int nextId;
            lock (private_lock)
            {
                nextId = nextValidId;
                nextValidId++;
            }
            iborder.OrderId = nextId;

            // Order Attributes
            iborder.Account = order.Account;
            IB.ActionSide ibaction;
            if (!Helpers.OrderSideToActionSide(order.Side, out ibaction)) // Buy / Sell
            {
                error("unknown order side in Order " + order.Instrument.Symbol);
                return;
            }
            iborder.Action = ibaction;
            if (!double.IsNaN(newStopPrice)) iborder.AuxPrice = (decimal) newStopPrice;
            else iborder.AuxPrice = (decimal)order.StopPrice; // stop orders only
            iborder.ClientId = ClientId;

            IB.FinancialAdvisorAllocationMethod faMethod;
            if (order.IB.FaMethod == IBFaMethod.Undefined) // use Order Defaults form Settings
            {
                iborder.FAMethod = FAMethod;
                iborder.FAGroup = FAGroup;
                iborder.FAPercentage = FAPercentage;
                iborder.FAProfile = FAProfile;
            }
            else
            {
                if (!Helpers.OQFAMethodTOIBFAMethod(order.IB.FaMethod, out faMethod))
                {
                    error("bad FA allocation method in order " + order.Instrument.Symbol);
                }
                iborder.FAMethod = faMethod;
                iborder.FAGroup = order.IB.FaGroup;
                iborder.FAPercentage = order.IB.FaPercentage.ToString();
                iborder.FAProfile = order.IB.FaProfile;
                OQ.IBFaMethod oqfamethod;
                if (!Helpers.FAAllocationMethodTOIBFAMethod(iborder.FAMethod, out oqfamethod))
                {
                    error("unknown FA allocation method in settings");
                }
                order.IB.FaMethod = oqfamethod;
                order.IB.FaGroup = iborder.FAGroup;
                if (iborder.FAPercentage == "") order.IB.FaPercentage = 0.0;
                else order.IB.FaPercentage = double.Parse(iborder.FAPercentage, CultureInfo.InvariantCulture);
                order.IB.FaProfile = order.IB.FaProfile;
            }
            // iborder.GoodAfterTime = order.StrategyPrice??
            // iborder.GoodTillDate = order.ExpireTime;
            iborder.Hidden = order.IB.Hidden;
            if (!double.IsNaN(newPrice)) iborder.LimitPrice = (decimal)newPrice;
            else iborder.LimitPrice = (decimal)order.Price;
            // iborder.MinQty
            // iborder.NbboPriceCap
            // = order.IB.DisplaySize;
            iborder.OcaGroup = order.OCAGroup;
             		    IB.OrderType ibtype;
            if (!Helpers.OQOrderTypeToIBOrderType(order.Type, out ibtype))
            {
                error("bad order type in order " + order.Instrument.Symbol);
                return;
            }
            iborder.OrderType = ibtype;
            // iborder.Origin
            // iborder.OutsideRth = order.???
            // iborder.OverridePercentageConstraints = ???
            // iborder.ParentId
            // iborder.PercentOffset
            // iborder.PermId
            // iborder.ReferencePriceType
            // iborder.Rule80A
            // iborder.StartingPrice
            // iborder.StockRangeLower
            // iborder.StockRangeUpper
            // iborder.StockRefPrice
            // iborder.SweepToFill
            IB.TimeInForce ibtif;
            if (!Helpers.OQTimeInForceToIBTimeInForce(order.TimeInForce, out ibtif))
            {
                error("unknown time in force in order " + order.Instrument.Symbol);
                return;
            }
            iborder.Tif = ibtif;
            if (!double.IsNaN(newQty)) iborder.TotalQuantity = (int) Math.Round(newQty);
            else iborder.TotalQuantity = (int)Math.Round(order.Qty);
            // iborder.TrailStopPrice = order.???
            iborder.Transmit = AutoTransmit;
            // iborder.TriggerMethod
            // iborder.Volatility
            // iborder.VolatilityType
            // iborder.WhatIf

            // Contract
            // contract.ComboLegs
            // contract.ComboLegsDescription
            // contract.ContractId
            contract.Currency = order.Instrument.Currency;
            contract.Exchange = order.Instrument.Exchange;
            contract.Expiry = order.Instrument.Maturity.ToString("yyyyMM"); // YYYYMM
            // contract.IncludeExpired
            // contract.LocalSymbol
            contract.Multiplier = order.Instrument.Factor.ToString();
            // contract.PrimaryExchange
            // contract.Right
            // contract.SecId
            IB.SecurityType secType;
            if (!Helpers.InstrumentTypeToSecurityType(order.Instrument.Type, out secType))
            {
                error("bad instrument type in order " + order.Instrument.Symbol);
            }
            contract.SecurityType = secType;
            contract.Strike = order.Instrument.Strike;
            contract.Symbol = order.Instrument.Symbol;
            // contract.UnderlyingComponent

            // parse advanced order attributes
            if (!string.IsNullOrWhiteSpace(order.Text))
            {
                string[] fields = order.Text.Split(';');
                foreach(string field in fields)
                {
                    if (!field.Contains("=") && !field.Contains(":")) continue;
                    string[] nameval = field.Split(new char[] {'=', ':'});
                    string name = nameval[0].Trim().ToLower();
                    string value = nameval[1].Trim();
                    switch(name)
                    {
                        case "orderref":
                            iborder.OrderRef = value;
                            break;
                        default:
                            error("unknown name \"" + name + "\" in text of order " + order.Instrument.Symbol);
                            break;
                    }
                }
            }
            // send to TWS
            info("PlaceOrder("
                + "ID=" + iborder.OrderId.ToString()
                + ", Orderref=" + (iborder.OrderRef  ?? "")
                + ", Symbol=" + contract.Symbol
                + ", Action=" + iborder.Action.ToString()
                + ", Size=" + iborder.TotalQuantity.ToString()
                + ", OrderType=" + iborder.OrderType.ToString()
                + ", limit price=" + iborder.LimitPrice.ToString()
                + ", Aux price=" + iborder.AuxPrice.ToString()
                + ")");

            // Set Infos back to OQ.Order
            order.OrderID = iborder.OrderId.ToString();
            order.ClientID = iborder.ClientId.ToString();
            // Remember active orders
            workingOrders[iborder.OrderId.ToString()] = new SrOrderInfo(order);

            // finally send to broker
            ibclient.PlaceOrder(iborder.OrderId, contract, iborder);
        }