Пример #1
0
        /// <summary>
        /// Gets the list of open orders for this account.
        /// </summary>
        /// <param name="a">Account.</param>
        /// <returns></returns>
        public List <PendingOrder> GetPendingOrderList(SimAccount a)
        {
            List <PendingOrder> res;
            bool worked = MasterOrders.TryGetValue(a, out res);

            return(worked ? res : new List <PendingOrder>());
        }
Пример #2
0
        /// <summary>
        /// Add pending order to local orderbook
        /// </summary>
        /// <param name="o"></param>
        /// <param name="a"></param>
        protected void AddOrder(PendingOrder o, SimAccount a)
        {
            if (!a.IsValid)
            {
                throw new Exception("Invalid account provided"); // account must be good
            }
            //Add event handlers
            o.OnCancel += HandleOrderCancel;
            o.OnUpdate += HandleOrderUpdate;

            // add any remaining order to book as new liquidity route
            List <PendingOrder> tmp;

            // see if we have a book for this account
            if (!MasterOrders.TryGetValue(a, out tmp))
            {
                tmp = new List <PendingOrder>();
                MasterOrders.Add(a, tmp); // if not, create one
            }
            OrderImpl order = (OrderImpl)o.Order;

            order.AccountName = a.Id; // make sure order knows his account
            tmp.Add(o);               // record the order
            // increment pending count
            _pendorders++;
        }
Пример #3
0
        /// <summary>
        /// Sends the order to the broker. (uses the default account)
        /// </summary>
        /// <param name="o">The order to be send.</param>
        /// <returns>status code</returns>
        public int SendOrderStatus(PendingOrder o)
        {
            if (!o.Order.IsValid || CheckOrderIntegrity(o) != StatusType.OK)
            {
                o.Cancel();
                return((int)StatusType.INVALID_TRADE_PARAMETERS);
            }

            // make sure book is clearly stamped
            if (o.Order.AccountName.Equals(string.Empty, StringComparison.OrdinalIgnoreCase))
            {
                OrderImpl order = (OrderImpl)o.Order;
                order.AccountName = Default.Id;
                return(SendOrderAccount(o, Default));
            }

            // get account
            SimAccount a;

            if (!Acctlist.TryGetValue(o.Order.AccountName, out a))
            {
                a = new SimAccount(o.Order.AccountName);
                AddAccount(a);
            }
            return(SendOrderAccount(o, a));
        }
Пример #4
0
        public Order BestBidOrOffer(string sym, Direction direction, SimAccount account)
        {
            Order best = new OrderImpl();

            if (!MasterOrders.ContainsKey(account))
            {
                return(best);
            }
            List <PendingOrder> orders = MasterOrders[account];

            for (int i = 0; i < orders.Count; i++)
            {
                Order o = orders[i].Order;
                if (o.Symbol != sym)
                {
                    continue;
                }
                if (o.Direction != direction)
                {
                    continue;
                }
                if (!best.IsValid)
                {
                    best = new OrderImpl(o);
                    continue;
                }
                Order test = BestBidOrOffer(best, o);
                if (test.IsValid)
                {
                    best = new OrderImpl(test);
                }
            }
            return(best);
        }
Пример #5
0
        public Order BestBidOrOffer(string symbol, Direction direction)
        {
            Order best = new OrderImpl();

            SimAccount[] accts = new SimAccount[MasterOrders.Count];
            MasterOrders.Keys.CopyTo(accts, 0);
            for (int i = 0; i < accts.Length; i++)
            {
                SimAccount a = accts[i];
                // get our first order
                if (!best.IsValid)
                {
                    // if we don't have a valid one yet, check this account
                    best = new OrderImpl(BestBidOrOffer(symbol, direction, a));
                    continue;  // keep checking the accounts till we find a valid one
                }
                // now we have our first order, which will be best if we can't find a second one
                Order next = new OrderImpl(BestBidOrOffer(symbol, direction, a));
                if (!next.IsValid)
                {
                    continue;                      // keep going till we have a second order
                }
                best = BestBidOrOffer(best, next); // when we have two, compare and get best
                // then keep fetching next valid order to see if it's better
            }
            return(best); // if there's no more orders left, this is best
        }
Пример #6
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            SimAccount o = (SimAccount)obj;

            return(Equals(o));
        }
Пример #7
0
        /// <summary>
        /// Add account to this broker (in case multi account trading is used)
        /// </summary>
        /// <param name="a"></param>
        protected void AddAccount(SimAccount a)
        {
            SimAccount t;

            if (Acctlist.TryGetValue(a.Id, out t))
            {
                return;                                    // already had it
            }
            MasterOrders.Add(a, new List <PendingOrder>());
            MasterTrades.Add(a.Id, new List <Trade>());
            Acctlist.Add(a.Id, a);
        }
Пример #8
0
        /// <summary>
        /// Sends the order to the broker for a specific account.
        /// </summary>
        /// <param name="o">The order to be sent.</param>
        /// <param name="a">the account to send with the order.</param>
        /// <returns>status code</returns>
        public int SendOrderAccount(PendingOrder o, SimAccount a)
        {
            if (o.OrderId == 0) // if order id isn't set, set it
            {
                OrderImpl order = (OrderImpl)o.Order;
                order.Id = _nextorderid++;
            }

            AddOrder(o, a);

            if ((GotOrder != null) && a.Notify)
            {
                GotOrder(o);
            }

            return((int)StatusType.OK);
        }
Пример #9
0
        /// <summary>
        /// Gets the open position for the specified account.
        /// </summary>
        /// <param name="symbol">The symbol to get a position for.</param>
        /// <param name="a">the account.</param>
        /// <returns>current position</returns>
        public Position GetOpenPosition(ISecurity symbol, SimAccount a)
        {
            PositionImpl pos = new PositionImpl(symbol);

            if (!MasterTrades.ContainsKey(a.Id))
            {
                return(pos);
            }
            List <Trade> trades = MasterTrades[a.Id];

            for (int i = 0; i < trades.Count; i++)
            {
                if (trades[i].Symbol == symbol.Name)
                {
                    pos.Adjust(trades[i]);
                }
            }
            return(pos);
        }
Пример #10
0
 public bool Equals(SimAccount a)
 {
     return(_id.Equals(a.Id));
 }
Пример #11
0
 public SimBroker(SimAccount account, BrokerModel tcmodel)
 {
     Default     = account;
     BrokerModel = tcmodel;
     Reset();
 }
Пример #12
0
 /// <summary>
 /// Gets the complete execution list for this account
 /// </summary>
 /// <param name="a">account to request blotter from.</param>
 /// <returns></returns>
 public List <Trade> GetTradeList(SimAccount a)
 {
     List <Trade> res; bool worked = MasterTrades.TryGetValue(a.Id, out res); return(worked ? res : new List <Trade>());
 }
Пример #13
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);
        }
Пример #14
0
 public Order BestOffer(string symbol, SimAccount account)
 {
     return(BestBidOrOffer(symbol, Direction.Short, account));
 }