Пример #1
0
        public void Fill_RegularLiquidity()
        {
            SimBroker broker = new SimBroker();

            broker.BrokerModel = _trans;
            ForexSecurity tsec = new ForexSecurity(S);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;

            OrderImpl limitBuy  = new OrderImpl(tsec, Direction.Long, 1, 133m);
            OrderImpl limitSell = new OrderImpl(tsec, Direction.Short, 1, 133.5m);
            OrderImpl stopBuy   = new OrderImpl(tsec, Direction.Long, 3, 0, 135.70m);
            OrderImpl stopSell  = new OrderImpl(tsec, Direction.Short, 4, 0, 135.75m);

            PendingOrderImpl plimitBuy  = new PendingOrderImpl(limitBuy);
            PendingOrderImpl plimitSell = new PendingOrderImpl(limitSell);
            PendingOrderImpl pstopBuy   = new PendingOrderImpl(stopBuy);
            PendingOrderImpl pstopSell  = new PendingOrderImpl(stopSell);

            broker.SendOrderStatus(plimitBuy);
            broker.SendOrderStatus(plimitSell);
            broker.SendOrderStatus(pstopBuy);
            broker.SendOrderStatus(pstopSell);

            // OHLC for 6/21/2012 on SPY
            TickImpl openingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 135.67m, 10670270, "NYS");
            TickImpl endMornTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 135.78m, 10670270, "NYS");
            TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 132.33m, 10670270, "NYS");
            TickImpl closingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 132.44m, 10670270, "NYS");

            broker.Execute(openingTick);
            broker.Execute(endMornTick);
            broker.Execute(endLunchTick);
            broker.Execute(closingTick);

            List <Trade> trades = broker.GetTradeList();

            Assert.True(trades.Count == 4);

            foreach (Trade trade in trades)
            {
                if (trade.Xsize == 1)
                {
                    Assert.Equal(132.33m, trade.Xprice);
                }
                else if (trade.Xsize == 2)
                {
                    Assert.Equal(132.33m, trade.Xprice);
                }
                else if (trade.Xsize == 3)
                {
                    Assert.Equal(135.78m, trade.Xprice);
                }
                else if (trade.Xsize == 4)
                {
                    Assert.Equal(135.78m, trade.Xprice);
                }
            }
        }
Пример #2
0
        public void MOCs()
        {
            SimBroker broker = new SimBroker();

            broker.BrokerModel = _trans;
            ForexSecurity tsec = new ForexSecurity(S);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;

            OrderImpl moc = new OrderImpl(tsec, Direction.Long, 200);

            moc.ValidInstruct = OrderInstructionType.MOC;
            PendingOrderImpl pmoc = new PendingOrderImpl(moc);

            Assert.True(moc.ValidInstruct == OrderInstructionType.MOC, "unexpected order instruction: " + moc.ValidInstruct);
            Assert.Equal(0, broker.SendOrderStatus(pmoc));

            TickImpl openingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 9, 10000, "NYS");
            TickImpl endMornTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 9, 10000, "NYS");
            TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 9, 10000, "NYS");
            TickImpl closingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 9, 10000, "NYS");

            int c = 0;

            c = broker.Execute(openingTick); Assert.Equal(0, c);
            c = broker.Execute(endMornTick); Assert.Equal(0, c);
            c = broker.Execute(endLunchTick); Assert.Equal(0, c);
            c = broker.Execute(closingTick); Assert.Equal(1, c); // should execute on the first tick at/after 16:00:00
        }
Пример #3
0
        public void DayFill()
        {
            SimBroker broker = new SimBroker();

            broker.BrokerModel = _trans;
            ForexSecurity tsec = new ForexSecurity(S);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;

            OrderImpl        day  = new OrderImpl(tsec, Direction.Long, 200);
            PendingOrderImpl pday = new PendingOrderImpl(day);

            broker.SendOrderStatus(pday);

            TickImpl openingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 9, 10000, "NYS");
            TickImpl endMornTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 9, 10000, "NYS");
            TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 9, 10000, "NYS");
            TickImpl closingTick  = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 9, 10000, "NYS");

            int c;

            c = broker.Execute(openingTick); Assert.Equal(1, c); // should execute on first received tick
            c = broker.Execute(endMornTick); Assert.Equal(0, c);
            c = broker.Execute(endLunchTick); Assert.Equal(0, c);
            c = broker.Execute(closingTick); Assert.Equal(0, c);
        }
Пример #4
0
        /// <summary>
        /// Process order update event
        /// </summary>
        /// <param name="pendingorder"></param>
        private void HandleOrderUpdate(PendingOrder pendingorder)
        {
            //Check if order exists
            PendingOrderImpl currentorder = null;
            PendingOrderImpl changedorder = (PendingOrderImpl)pendingorder;

            var account = pendingorder.Account ?? Default;

            if (account == null)
            {
                changedorder.OrderStatus = StatusType.INVALID_ACCOUNT;
                return;
            }

            var masterorders = MasterOrders[account];

            foreach (var po in masterorders)
            {
                if (po.OrderId == pendingorder.OrderId)
                {
                    currentorder = (PendingOrderImpl)po;
                }
            }

            //Check if we could find this order
            if (currentorder == null)
            {
                return;
            }

            //Check order integrity
            var result = CheckOrderIntegrity(currentorder);

            if (result != StatusType.OK)
            {
                currentorder.OrderStatus = result;
                currentorder.Cancel();
                return;
            }

            //Check if we need to remove this order
            if (!pendingorder.Order.IsValid || pendingorder.IsCancelled)
            {
                pendingorder.Cancel();
            }

            //Send updates to any modules
            if (GotOrderUpdate != null)
            {
                GotOrderUpdate(pendingorder);
            }
        }
Пример #5
0
        public void OpGs()
        {
            SimBroker broker = new SimBroker();

            broker.BrokerModel = _trans;
            const string  s    = "NYS";
            ForexSecurity tsec = new ForexSecurity(s);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;

            // build and send an OPG order
            OrderImpl        opg  = new OrderImpl(tsec, Direction.Long, 200, 10);
            PendingOrderImpl popg = new PendingOrderImpl(opg);

            Assert.Equal(0, broker.SendOrderStatus(popg));

            // build a tick on another exchange
            TickImpl it = TickImpl.NewTrade(s, 9, 100);

            it.Exchange = "ISLD";

            // fill order (should fail)
            int c = broker.Execute(it);

            Assert.Equal(0, c);

            // build opening price for desired exchange
            TickImpl nt = TickImpl.NewTrade(s, 9, 10000);

            nt.Exchange = "NYS";
            // fill order (should work)

            c = broker.Execute(nt);

            Assert.Equal(1, c);

            // add another OPG, make sure it's not filled with another tick

            TickImpl next = TickImpl.NewTrade(s, 9, 2000);

            next.Exchange = "NYS";

            OrderImpl        late  = new OrderImpl(tsec, Direction.Long, 200, 10);
            PendingOrderImpl plate = new PendingOrderImpl(late);

            broker.SendOrderStatus(plate);
            c = broker.Execute(next);
            Assert.Equal(0, c);
        }
Пример #6
0
        public void Basics()
        {
            ForexSecurity tsec = new ForexSecurity(S);

            tsec.LotSize       = 1;
            tsec.PipValue      = 1;
            tsec.PipSize       = 1;
            tsec.OrderStepSize = 1;

            SimAccount account = new SimAccount("TEST", "testing", 1000M, 100);

            account.Securities.AddSecurity(tsec);

            SimBroker broker = new SimBroker(account, _trans);

            broker.BrokerModel = _trans;
            broker.GotFill    += broker_GotFill;
            broker.GotOrder   += broker_GotOrder;
            OrderImpl        o  = new OrderImpl();
            PendingOrderImpl po = new PendingOrderImpl(o);
            int error           = broker.SendOrderStatus(po);

            Assert.NotEqual((int)StatusType.OK, error);
            Assert.True(_orders == 0);
            Assert.True(_fills == 0);

            o  = new OrderImpl(tsec, Direction.Long, 100);
            po = new PendingOrderImpl(o);

            broker.SendOrderStatus(po);
            Assert.True(_orders == 1);
            Assert.True(_fills == 0);
            Assert.True(broker.Execute(TickImpl.NewTrade(S, 10, 200)) == 1);
            Assert.True(_fills == 1);

            // test that a limit order is not filled outside the market
            o  = new OrderImpl(tsec, Direction.Long, 100, 9);
            po = new PendingOrderImpl(o);

            broker.SendOrderStatus(po);
            Assert.Equal(0, broker.Execute(TickImpl.NewTrade(S, 10, 100)));
            Assert.True(_fills == 1); // redundant but for counting

            // test that limit order is filled inside the market
            Assert.Equal(1, broker.Execute(TickImpl.NewTrade(S, 8, 100)));
            Assert.True(_fills == 2);
        }
Пример #7
0
        private void execute_GotTick(Tick t)
        {
            tickcount++;
            // generate fills periodically
            if (fillcount >= desiredfills)
            {
                return;
            }
            if (tickcount % 50 == 0)
            {
                bool             side = fillcount % 2 == 0;
                OrderImpl        o    = new OrderImpl(new ForexSecurity(t.Symbol), side ? Direction.Long : Direction.Short, 100);
                PendingOrderImpl po   = new PendingOrderImpl(o);

                h.SimBroker.SendOrderStatus(po);
            }
        }
Пример #8
0
        public void MultiAccount()
        {
            _broker.BrokerModel = _trans;
            const string  sym  = "TST";
            ForexSecurity tsec = new ForexSecurity(sym);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;

            const string me    = "tester";
            const string other = "anotherguy";
            SimAccount   a     = new SimAccount(me);
            SimAccount   b     = new SimAccount(other);
            SimAccount   c     = new SimAccount("sleeper");
            OrderImpl    oa    = new OrderImpl(tsec, Direction.Long, 100);
            OrderImpl    ob    = new OrderImpl(tsec, Direction.Long, 100);

            oa.AccountName = me;
            ob.AccountName = other;
            // send order to accounts
            PendingOrderImpl poa = new PendingOrderImpl(oa, a);
            PendingOrderImpl pob = new PendingOrderImpl(ob, b);

            _broker.SendOrderStatus(poa);
            _broker.SendOrderStatus(pob);

            TickImpl t = new TickImpl(sym)
            {
                Trade = 100m,
                Size  = 200
            };

            Assert.Equal(2, _broker.Execute(t));
            Position apos = _broker.GetOpenPosition(tsec, a);
            Position bpos = _broker.GetOpenPosition(tsec, b);
            Position cpos = _broker.GetOpenPosition(tsec, c);

            Assert.True(apos.IsLong);
            Assert.Equal(100, apos.Size);
            Assert.True(bpos.IsLong);
            Assert.Equal(100, bpos.Size);
            Assert.True(cpos.IsFlat);
            // make sure that default account doesn't register
            // any trades
            Assert.True(_broker.GetOpenPosition(tsec).IsFlat);
        }
Пример #9
0
        /// <summary>
        /// Process order cancel events
        /// </summary>
        /// <param name="pendingorder"></param>
        private void HandleOrderCancel(PendingOrder pendingorder)
        {
            //Check if order exists
            PendingOrder     currentorder = null;
            PendingOrderImpl changedorder = (PendingOrderImpl)pendingorder;

            var account = pendingorder.Account ?? Default;

            if (account == null)
            {
                changedorder.OrderStatus = StatusType.INVALID_ACCOUNT;
                return;
            }

            var masterorders = MasterOrders[account];

            foreach (var po in masterorders)
            {
                if (po.OrderId == pendingorder.OrderId)
                {
                    currentorder = po;
                }
            }

            //Check if we could find this order
            if (currentorder == null)
            {
                return;
            }

            //Send changes to the broker book
            masterorders.Remove(pendingorder);

            //Notify cancelation
            if (GotOrderCancel != null)
            {
                GotOrderCancel(pendingorder);
            }
        }
Пример #10
0
        public void BBO()
        {
            SimBroker broker = new SimBroker();

            broker.BrokerModel = _trans;
            ForexSecurity tsec = new ForexSecurity(S);

            tsec.LotSize       = 1;
            tsec.OrderStepSize = 1;
            const decimal p1 = 10m;
            const decimal p2 = 11m;
            const int     x = 100;
            Order         bid, offer;

            // send bid, make sure it's BBO (since it's only order on any book)
            broker.SendOrderStatus(new PendingOrderImpl(new OrderImpl(tsec, Direction.Long, x, p1)));
            bid   = broker.BestBid(S);
            offer = broker.BestOffer(S);
            Assert.True(bid.IsValid && (bid.LimitPrice == p1) && (bid.Quantity == x), bid.ToString());
            Assert.True(!offer.IsValid, offer.ToString());

            // add better bid, make sure it's BBO
            OrderImpl o;

            // Order#1... 100 shares buy at $11
            o = new OrderImpl(tsec, Direction.Long, x, p2);
            PendingOrderImpl po = new PendingOrderImpl(o);

            broker.SendOrderStatus(po);
            bid   = broker.BestBid(S);
            offer = broker.BestOffer(S);
            Assert.True(bid.IsValid);
            Assert.Equal(p2, bid.LimitPrice);
            Assert.Equal(x, bid.Size);
            Assert.True(!offer.IsValid, offer.ToString());

            // add another bid at same price on another account, make sure it's additive
            //order #2... 100 shares buy at $11
            o             = new OrderImpl(tsec, Direction.Long, x, p2);
            po            = new PendingOrderImpl(o, new SimAccount("ANOTHER_ACCOUNT"));
            o.AccountName = "ANOTHER_ACCOUNT";
            broker.SendOrderStatus(po);
            bid   = broker.BestBid(S);
            offer = broker.BestOffer(S);
            Assert.True(bid.IsValid);
            Assert.Equal(p2, bid.LimitPrice);
            Assert.Equal(x * 2, bid.Size);
            Assert.True(!offer.IsValid, offer.ToString());

            // cancel order and make sure bbo returns
            po.Cancel();
            bid   = broker.BestBid(S);
            offer = broker.BestOffer(S);
            Assert.True(bid.IsValid);
            Assert.Equal(p2, bid.LimitPrice);
            Assert.Equal(x, bid.Size);
            Assert.True(!offer.IsValid, offer.ToString());

            // other test ideas
            // replicate above tests for sell-side
        }
Пример #11
0
        /// <summary>
        /// Executes any open orders allowed by the specified tick.
        /// </summary>
        /// <param name="tick">The tick.</param>
        /// <returns>the number of orders executed using the tick.</returns>
        public int Execute(TickImpl tick)
        {
            //TODO: in order to calculate the floating PnL ticks are send to the account for calculations.
            //Also this location is incorrect!
            Default.OnTick(tick);
            BrokerCostCalculation(tick);
            if (_pendorders == 0)
            {
                return(0);
            }

            //Check if we need to process the order as a trade or use the bid ask fills
            UseBidAskFills = tick.HasAsk && tick.HasBid;

            int filledorders = 0;

            SimAccount[] accts = new SimAccount[MasterOrders.Count];
            MasterOrders.Keys.CopyTo(accts, 0);

            for (int idx = 0; idx < accts.Length; idx++)
            {
                // go through each account
                SimAccount a = accts[idx];

                // if account has requested no executions, skip it
                if (!a.Execute)
                {
                    continue;
                }
                //Check for a margin call by the broker
                if (a.MarginLevel <= BrokerModel.StopOutLevel())
                {
                    //cancel this order
                    MasterOrders[a].ForEach(x =>
                    {
                        ((PendingOrderImpl)x).OrderStatus = StatusType.INSUFFICIENT_CAPITAL;
                        x.Cancel();
                    });
                }

                // make sure we have a record for this account
                if (!MasterTrades.ContainsKey(a.Id))
                {
                    MasterTrades.Add(a.Id, new List <Trade>());
                }

                // track orders being removed and trades that need notification
                List <int> notifytrade = new List <int>();
                List <int> remove      = new List <int>();

                // go through each order in the account
                for (int i = 0; i < MasterOrders[a].Count; i++)
                {
                    //Get the order object
                    PendingOrderImpl po = (PendingOrderImpl)MasterOrders[a][i];
                    OrderImpl        o  = (OrderImpl)po.Order;

                    //make sure tick is for the right stock, and right exchange
                    if (tick.Symbol != o.Symbol)
                    {
                        continue;
                    }
                    //Check if order is in a correct state
                    if (po.OrderStatus != StatusType.OK)
                    {
                        remove.Add(i);
                        // count the trade
                        filledorders++;
                        continue;
                    }

                    if (UseHighLiquidityFillsEod)
                    {
                        po.OrderStatus = o.Fill(tick, BrokerModel, UseBidAskFills, false, true);
                    }
                    else if (o.ValidInstruct <= OrderInstructionType.GTC)
                    {
                        po.OrderStatus = o.Fill(tick, BrokerModel, UseBidAskFills, false); // fill our trade
                    }
                    else if (o.ValidInstruct == OrderInstructionType.OPG)
                    {
                        // if it's already opened, we missed our shot
                        if (_hasopened.Contains(o.Symbol))
                        {
                            continue;
                        }
                        // otherwise make sure it's really the opening
                        if (tick.Source == Opgex)
                        {
                            // it's the opening tick, so fill it as an opg
                            po.OrderStatus = o.Fill(tick, BrokerModel, UseBidAskFills, true);
                            // mark this symbol as already being open
                            _hasopened.Add(tick.Symbol);
                        }
                    }
                    // other orders fill normally, except MOC orders which are at 4:00PM
                    else if (o.ValidInstruct == OrderInstructionType.MOC)
                    {
                        if (tick.Time >= 160000000)
                        {
                            po.OrderStatus = o.Fill(tick, BrokerModel, UseBidAskFills, false); // fill our trade
                        }
                    }
                    else
                    {
                        po.OrderStatus = o.Fill(tick, BrokerModel, UseBidAskFills, false); // fill our trade
                    }
                    if (po.OrderStatus == StatusType.ORDER_FILLED)
                    {
                        // remove filled size from size available in trade
                        tick.Size -= o.UnsignedSize;

                        // get copy of trade for recording
                        TradeImpl trade = new TradeImpl(o);

                        // if trade represents entire requested order, mark order for removal
                        if (trade.UnsignedSize == o.UnsignedSize)
                        {
                            remove.Add(i);
                        }
                        else // otherwise reflect order's remaining size
                        {
                            o.Size = (o.UnsignedSize - trade.UnsignedSize) * (o.Direction == Direction.Long ? 1 : -1);
                        }

                        // record trade
                        MasterTrades[a.Id].Add(trade);

                        // mark it for notification
                        notifytrade.Add(MasterTrades[a.Id].Count - 1);

                        // count the trade
                        filledorders++;
                    }
                }

                // notify subscribers of trade
                if ((GotFill != null) && a.Notify)
                {
                    for (int tradeidx = 0; tradeidx < notifytrade.Count; tradeidx++)
                    {
                        TradeImpl t       = (TradeImpl)MasterTrades[a.Id][notifytrade[tradeidx]];
                        var       account = Acctlist[Accounts[0]];
                        t.Account     = account;
                        t.AccountName = t.Account.Id;
                        account.OnFill(t);
                        GotFill(t, MasterOrders[a][remove[tradeidx]]);
                    }
                }

                int rmcount = remove.Count;

                // remove the filled orders
                for (int i = remove.Count - 1; i >= 0; i--)
                {
                    MasterOrders[a].RemoveAt(remove[i]);
                }

                // unmark filled orders as pending
                _pendorders -= rmcount;
                if (_pendorders < 0)
                {
                    _pendorders = 0;
                }
            }
            return(filledorders);
        }