Beispiel #1
0
        /// <summary>
        /// Market order implementation: Send a market order and wait for it to be filled.
        /// </summary>
        /// <param name="symbol">Symbol of the MarketType Required.</param>
        /// <param name="quantity">Number of shares to request.</param>
        /// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
        /// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
        /// <returns>int Order id</returns>
        public int MarketOrder(string symbol, int quantity, bool asynchronous = false, string tag = "")
        {
            //Initalize the Market order parameters:
            var error = PreOrderChecks(symbol, quantity, OrderType.Market);

            if (error < 0)
            {
                return(error);
            }

            var order = new MarketOrder(symbol, quantity, Time, tag, Securities[symbol].Type);

            //Set the rough price of the order for buying power calculations
            order.Price = Securities[symbol].Price;

            //Add the order and create a new order Id.
            var orderId = Transactions.AddOrder(order);

            //Wait for the order event to process:
            //Enqueue means send to order queue but don't wait for response:
            if (!asynchronous)
            {
                //Wait for the market order to fill.
                //This is processed in a parallel thread.
                while (!Transactions.Orders.ContainsKey(orderId) ||
                       (Transactions.Orders[orderId].Status != OrderStatus.Filled &&
                        Transactions.Orders[orderId].Status != OrderStatus.Invalid &&
                        Transactions.Orders[orderId].Status != OrderStatus.Canceled) || _processingOrder)
                {
                    Thread.Sleep(1);
                }
            }

            return(orderId);
        }
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice data)
        {
            if (!data.ContainsKey("SPY"))
            {
                return;
            }

            // After an order is placed, it will decrease in quantity by one for each minute, being cancelled altogether
            // if not filled within 10 minutes.
            if (Transactions.GetOpenOrders().Count == 0)
            {
                var goLong = Time.Day < 9;
                _negative = goLong ? 1 : -1;
                var orderRequest = new SubmitOrderRequest(OrderType.LimitIfTouched, SecurityType.Equity, "SPY",
                                                          _negative * 10, 0,
                                                          data["SPY"].Price - (decimal)_negative, data["SPY"].Price - (decimal)0.25 * _negative, UtcTime,
                                                          $"LIT - Quantity: {_negative * 10}");
                _request = Transactions.AddOrder(orderRequest);
                return;
            }

            // Order updating if request exists
            if (_request != null)
            {
                if (_request.Quantity == 1)
                {
                    Transactions.CancelOpenOrders();
                    _request = null;
                    return;
                }

                var newQuantity = _request.Quantity - _negative;
                _request.UpdateQuantity(newQuantity, $"LIT - Quantity: {newQuantity}");
            }
        }
Beispiel #3
0
        /// <summary>
        /// Send a stop limit order to the transaction handler:
        /// </summary>
        /// <param name="symbol">String symbol for the asset</param>
        /// <param name="quantity">Quantity of shares for limit order</param>
        /// <param name="stopPrice">Stop price for this order</param>
        /// <param name="limitPrice">Limit price to fill this order</param>
        /// <param name="tag">String tag for the order (optional)</param>
        /// <returns>Order id</returns>
        public int StopLimitOrder(string symbol, int quantity, decimal stopPrice, decimal limitPrice, string tag = "")
        {
            var error = PreOrderChecks(symbol, quantity, OrderType.StopLimit);

            if (error < 0)
            {
                return(error);
            }

            var order = new StopLimitOrder(symbol, quantity, stopPrice, limitPrice, Time, tag, Securities[symbol].Type);

            //Add the order and create a new order Id.
            return(Transactions.AddOrder(order));
        }
Beispiel #4
0
        /// <summary>
        /// Market on close order implementation: Send a market order when the exchange closes
        /// </summary>
        /// <param name="symbol">The symbol to be ordered</param>
        /// <param name="quantity">The number of shares to required</param>
        /// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
        /// <returns>The order ID</returns>
        public int MarketOnClose(string symbol, int quantity, string tag = "")
        {
            var error = PreOrderChecks(symbol, quantity, OrderType.MarketOnClose);

            if (error < 0)
            {
                return(error);
            }

            var security = Securities[symbol];
            var order    = new MarketOnCloseOrder(symbol, security.Type, quantity, Time, security.Price, tag);

            return(Transactions.AddOrder(order));
        }
Beispiel #5
0
        /// <summary>
        /// Market order implementation: Send a market order and wait for it to be filled.
        /// </summary>
        /// <param name="symbol">Symbol of the MarketType Required.</param>
        /// <param name="quantity">Number of shares to request.</param>
        /// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
        /// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
        /// <returns>int Order id</returns>
        public int MarketOrder(string symbol, int quantity, bool asynchronous = false, string tag = "")
        {
            var security = Securities[symbol];

            // check the exchange is open before sending a market order, if it's not open
            // then convert it into a market on open order
            if (!security.Exchange.ExchangeOpen)
            {
                var id = MarketOnOpen(symbol, quantity, tag);
                Debug("Converted OrderID: " + id + " into a MarketOnOpen order.");
                return(id);
            }

            //Initalize the Market order parameters:
            var error = PreOrderChecks(symbol, quantity, OrderType.Market);

            if (error < 0)
            {
                return(error);
            }

            var order = new MarketOrder(symbol, quantity, Time, tag, security.Type);

            //Set the rough price of the order for buying power calculations
            order.Price = security.Price;

            //Add the order and create a new order Id.
            var orderId = Transactions.AddOrder(order);

            //Wait for the order event to process:
            //Enqueue means send to order queue but don't wait for response:
            if (!asynchronous)
            {
                //Wait for the market order to fill.
                //This is processed in a parallel thread.
                while (!Transactions.Orders.ContainsKey(orderId) ||
                       (Transactions.Orders[orderId].Status != OrderStatus.Filled &&
                        Transactions.Orders[orderId].Status != OrderStatus.Invalid &&
                        Transactions.Orders[orderId].Status != OrderStatus.Canceled) || _processingOrder)
                {
                    Thread.Sleep(1);
                }
            }

            return(orderId);
        }
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice data)
        {
            if (!data.Bars.ContainsKey(symbol))
            {
                return;
            }

            // each month make an action
            if (Time.Month != LastMonth)
            {
                // we'll submit the next type of order from the queue
                var orderType = _orderTypesQueue.Dequeue();
                //Log("");
                Log("\r\n--------------MONTH: " + Time.ToString("MMMM") + ":: " + orderType + "\r\n");
                //Log("");
                LastMonth = Time.Month;
                Log("ORDER TYPE:: " + orderType);
                var isLong     = Quantity > 0;
                var stopPrice  = isLong ? (1 + StopPercentage) * data.Bars[symbol].High : (1 - StopPercentage) * data.Bars[symbol].Low;
                var limitPrice = isLong ? (1 - LimitPercentage) * stopPrice : (1 + LimitPercentage) * stopPrice;
                if (orderType == OrderType.Limit)
                {
                    limitPrice = !isLong ? (1 + LimitPercentage) * data.Bars[symbol].High : (1 - LimitPercentage) * data.Bars[symbol].Low;
                }
                var request = new SubmitOrderRequest(orderType, SecType, symbol, Quantity, stopPrice, limitPrice, Time, orderType.ToString());
                var ticket  = Transactions.AddOrder(request);
                _tickets.Add(ticket);
            }
            else if (_tickets.Count > 0)
            {
                var ticket = _tickets.Last();
                if (Time.Day > 8 && Time.Day < 14)
                {
                    if (ticket.UpdateRequests.Count == 0 && ticket.Status.IsOpen())
                    {
                        Log("TICKET:: " + ticket);
                        ticket.Update(new UpdateOrderFields
                        {
                            Quantity = ticket.Quantity + Math.Sign(Quantity) * DeltaQuantity,
                            Tag      = "Change quantity: " + Time
                        });
                        Log("UPDATE1:: " + ticket.UpdateRequests.Last());
                    }
                }
                else if (Time.Day > 13 && Time.Day < 20)
                {
                    if (ticket.UpdateRequests.Count == 1 && ticket.Status.IsOpen())
                    {
                        Log("TICKET:: " + ticket);
                        ticket.Update(new UpdateOrderFields
                        {
                            LimitPrice = Security.Price * (1 - Math.Sign(ticket.Quantity) * LimitPercentageDelta),
                            StopPrice  = Security.Price * (1 + Math.Sign(ticket.Quantity) * StopPercentageDelta),
                            Tag        = "Change prices: " + Time
                        });
                        Log("UPDATE2:: " + ticket.UpdateRequests.Last());
                    }
                }
                else
                {
                    if (ticket.UpdateRequests.Count == 2 && ticket.Status.IsOpen())
                    {
                        Log("TICKET:: " + ticket);
                        ticket.Cancel(Time + " and is still open!");
                        Log("CANCELLED:: " + ticket.CancelRequest);
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice data)
        {
            if (!_security.HasData)
            {
                Log("::::: NO DATA :::::");
                return;
            }

            // each month make an action
            if (Time.Minute != _lastMinute && Time.Second == 0)
            {
                Log("");
                Log("--------------Minute: " + Time.Minute);
                Log("");
                _lastMinute = Time.Minute;
                // we'll submit the next type of order from the queue
                var orderType = _orderTypesQueue.Dequeue();
                Log("ORDER TYPE:: " + orderType);
                var isLong     = _quantity > 0;
                var stopPrice  = isLong ? (1 + StopPercentage) * _security.High : (1 - StopPercentage) * _security.Low;
                var limitPrice = isLong ? (1 - LimitPercentage) * stopPrice : (1 + LimitPercentage) * stopPrice;
                if (orderType == OrderType.Limit)
                {
                    limitPrice = !isLong ? (1 + LimitPercentage) * _security.High : (1 - LimitPercentage) * _security.Low;
                }
                var request = new SubmitOrderRequest(orderType, SecType, Securities[_symbol].Symbol, _quantity, stopPrice, limitPrice, Time, orderType.ToString());
                var ticket  = Transactions.AddOrder(request);
                _tickets.Add(ticket);
                if ((decimal)Random.NextDouble() < ImmediateCancelPercentage)
                {
                    Log("Immediate cancellation requested!");
                    _immediateCancellations.Add(ticket.OrderId);
                }
            }
            else if (_tickets.Count > 0)
            {
                var ticket = _tickets.Last();
                if (Time.Second > 15 && Time.Second < 30)
                {
                    if (ticket.UpdateRequests.Count == 0 && ticket.Status.IsOpen())
                    {
                        Log(ticket.ToString());
                        ticket.Update(new UpdateOrderFields
                        {
                            Quantity = ticket.Quantity + Math.Sign(_quantity) * DeltaQuantity,
                            Tag      = "Change quantity: " + Time
                        });
                        Log("UPDATE1:: " + ticket.UpdateRequests.Last());
                    }
                }
                else if (Time.Second > 29 && Time.Second < 45)
                {
                    if (ticket.UpdateRequests.Count == 1 && ticket.Status.IsOpen())
                    {
                        Log(ticket.ToString());
                        ticket.Update(new UpdateOrderFields
                        {
                            LimitPrice = _security.Price * (1 - Math.Sign(ticket.Quantity) * LimitPercentageDelta),
                            StopPrice  = _security.Price * (1 + Math.Sign(ticket.Quantity) * StopPercentageDelta),
                            Tag        = "Change prices: " + Time
                        });
                        Log("UPDATE2:: " + ticket.UpdateRequests.Last());
                    }
                }
                else
                {
                    if (ticket.UpdateRequests.Count == 2 && ticket.Status.IsOpen())
                    {
                        Log(ticket.ToString());
                        ticket.Cancel(Time + " and is still open!");
                        Log("CANCELLED:: " + ticket.CancelRequest);
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Submit a new order for quantity of symbol using type order.
        /// </summary>
        /// <param name="type">Buy/Sell Limit or Market Order Type.</param>
        /// <param name="symbol">Symbol of the MarketType Required.</param>
        /// <param name="quantity">Number of shares to request.</param>
        /// <param name="asynchronous">Send the order asynchrously (false). Otherwise we'll block until it fills</param>
        /// <param name="tag">Place a custom order property or tag (e.g. indicator data).</param>
        /// <seealso cref="Order(string, double, OrderType)"/>
        public int Order(string symbol, int quantity, OrderType type = OrderType.Market, bool asynchronous = false, string tag = "")
        {
            //Add an order to the transacion manager class:
            var     orderId = -1;
            decimal price   = 0;

            //Ordering 0 is useless.
            if (quantity == 0 || string.IsNullOrEmpty(symbol))
            {
                return(-1);
            }

            //Internals use upper case symbols.
            symbol = symbol.ToUpper();

            //If we're not tracking this symbol: throw error:
            if (!Securities.ContainsKey(symbol) && !_sentNoDataError)
            {
                _sentNoDataError = true;
                Error("You haven't requested " + symbol + " data. Add this with AddSecurity() in the Initialize() Method.");
            }

            //Set a temporary price for validating order for market orders:
            var security = Securities[symbol];

            price = security.Price;
            if (price == 0)
            {
                Error("Asset price is $0. If using custom data make sure you've set the 'Value' property.");
                return(-1);
            }

            //Make sure the security has some data:
            if (!security.HasData)
            {
                Error("There is no data for this symbol yet, please check the security.HasData flag to ensure there is at least one data point.");
                return(-1);
            }

            //Check the exchange is open before sending a market order.
            if (type == OrderType.Market && !security.Exchange.ExchangeOpen)
            {
                Error("Market order and exchange not open");
                return(-3);
            }

            //We've already processed too many orders: max 100 per day or the memory usage explodes
            if (Orders.Count > (_endDate - _startDate).TotalDays * 100)
            {
                Error("You have exceeded 100 orders per day");
                return(-5);
            }

            //Add the order and create a new order Id.
            orderId = Transactions.AddOrder(new Order(symbol, security.Type, quantity, type, Time, price, tag));

            //Wait for the order event to process:
            //Enqueue means send to order queue but don't wait for response:
            if (!asynchronous && type == OrderType.Market)
            {
                //Wait for the market order to fill.
                //This is processed in a parallel thread.
                while (!Transactions.Orders.ContainsKey(orderId) ||
                       (Transactions.Orders[orderId].Status != OrderStatus.Filled &&
                        Transactions.Orders[orderId].Status != OrderStatus.Invalid &&
                        Transactions.Orders[orderId].Status != OrderStatus.Canceled) || _processingOrder)
                {
                    Thread.Sleep(1);
                }
            }

            return(orderId);
        }