Пример #1
0
 public AccountTrunk( int maxEvent )
 {
     this.MAX_EVENT = maxEvent;
     this.events = new Event[this.MAX_EVENT];
     this.accounts = new Account[AccountTrunk.MAX_ACCOUNT];
     this.securities = new Securities();
     this.actAccount = 0;
     this.actEvent = 0;
 }
Пример #2
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)
        {
            Debug($"[{Time}] Warmup: {IsWarmingUp}. Invested: {Portfolio.Invested} {string.Join(",", Securities.Select(pair => $"{pair.Key.Value}:{pair.Value.Price}"))}");
            if (IsWarmingUp)
            {
                _equityGotTradeBars |= data.Bars.ContainsKey("SPY");
                _equityGotQuoteBars |= data.QuoteBars.ContainsKey("SPY");

                _cryptoGotTradeBars |= data.Bars.ContainsKey("BTCUSD");
            }
            else
            {
                if (!Portfolio.Invested)
                {
                    AddEquity("AAPL", Resolution.Hour);
                    SetHoldings("BTCUSD", 0.3);
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Determines whether or not the specified symbol is currently a member of this universe
 /// </summary>
 /// <param name="symbol">The symbol whose membership is to be checked</param>
 /// <returns>True if the specified symbol is part of this universe, false otherwise</returns>
 public bool ContainsMember(Symbol symbol)
 {
     return(Securities.ContainsKey(symbol));
 }
Пример #4
0
 /// <summary>
 /// Create a simple JSON holdings from a Security holding class.
 /// </summary>
 /// <param name="holding"></param>
 public Holding(Securities.SecurityHolding holding)
 {
     Symbol = holding.Symbol;
     Quantity = holding.Quantity;
     AveragePrice = holding.AveragePrice;
     MarketPrice = holding.Price;
 }
Пример #5
0
        /// <summary>
        /// Perform preorder checks to ensure we have sufficient capital,
        /// the market is open, and we haven't exceeded maximum realistic orders per day.
        /// </summary>
        /// <returns>OrderResponse. If no error, order request is submitted.</returns>
        private OrderResponse PreOrderChecksImpl(SubmitOrderRequest request)
        {
            if (IsWarmingUp)
            {
                return(OrderResponse.WarmingUp(request));
            }

            //Most order methods use security objects; so this isn't really used.
            // todo: Left here for now but should review
            Security security;

            if (!Securities.TryGetValue(request.Symbol, out security))
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.MissingSecurity, "You haven't requested " + request.Symbol.ToString() + " data. Add this with AddSecurity() in the Initialize() Method."));
            }

            //Ordering 0 is useless.
            if (request.Quantity == 0)
            {
                return(OrderResponse.ZeroQuantity(request));
            }

            if (Math.Abs(request.Quantity) < security.SymbolProperties.LotSize)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.OrderQuantityLessThanLoteSize, $"Unable to {request.OrderRequestType.ToString().ToLower()} order with id {request.OrderId} which quantity ({Math.Abs(request.Quantity)}) is less than lot size ({security.SymbolProperties.LotSize})."));
            }

            if (!security.IsTradable)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.NonTradableSecurity, "The security with symbol '" + request.Symbol.ToString() + "' is marked as non-tradable."));
            }

            var price = security.Price;

            //Check the exchange is open before sending a market on close orders
            if (request.OrderType == OrderType.MarketOnClose && !security.Exchange.ExchangeOpen)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open."));
            }

            //Check the exchange is open before sending a exercise orders
            if (request.OrderType == OrderType.OptionExercise && !security.Exchange.ExchangeOpen)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open."));
            }

            if (price == 0)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.SecurityPriceZero, request.Symbol.ToString() + ": asset price is $0. If using custom data make sure you've set the 'Value' property."));
            }

            // check quote currency existence/conversion rate on all orders
            Cash quoteCash;
            var  quoteCurrency = security.QuoteCurrency.Symbol;

            if (!Portfolio.CashBook.TryGetValue(quoteCurrency, out quoteCash))
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.QuoteCurrencyRequired, request.Symbol.Value + ": requires " + quoteCurrency + " in the cashbook to trade."));
            }
            if (security.QuoteCurrency.ConversionRate == 0m)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ConversionRateZero, request.Symbol.Value + ": requires " + quoteCurrency + " to have a non-zero conversion rate. This can be caused by lack of data."));
            }

            // need to also check base currency existence/conversion rate on forex orders
            if (security.Type == SecurityType.Forex || security.Type == SecurityType.Crypto)
            {
                Cash baseCash;
                var  baseCurrency = ((IBaseCurrencySymbol)security).BaseCurrencySymbol;
                if (!Portfolio.CashBook.TryGetValue(baseCurrency, out baseCash))
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexBaseAndQuoteCurrenciesRequired, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " in the cashbook to trade."));
                }
                if (baseCash.ConversionRate == 0m)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexConversionRateZero, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " to have non-zero conversion rates. This can be caused by lack of data."));
                }
            }

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

            // We've already processed too many orders: max 10k
            if (!LiveMode && Transactions.OrdersCount > _maxOrders)
            {
                Status = AlgorithmStatus.Stopped;
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExceededMaximumOrders, string.Format("You have exceeded maximum number of orders ({0}), for unlimited orders upgrade your account.", _maxOrders)));
            }

            if (request.OrderType == OrderType.OptionExercise)
            {
                if (security.Type != SecurityType.Option)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.NonExercisableSecurity, "The security with symbol '" + request.Symbol.ToString() + "' is not exercisable."));
                }

                if (security.Holdings.IsShort)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "The security with symbol '" + request.Symbol.ToString() + "' has a short option position. Only long option positions are exercisable."));
                }

                if (request.Quantity > security.Holdings.Quantity)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.UnsupportedRequestType, "Cannot exercise more contracts of '" + request.Symbol.ToString() + "' than is currently available in the portfolio. "));
                }

                if (request.Quantity <= 0.0m)
                {
                    OrderResponse.ZeroQuantity(request);
                }
            }

            if (request.OrderType == OrderType.MarketOnClose)
            {
                var nextMarketClose = security.Exchange.Hours.GetNextMarketClose(security.LocalTime, false);
                // must be submitted with at least 10 minutes in trading day, add buffer allow order submission
                var latestSubmissionTime = nextMarketClose.Subtract(Orders.MarketOnCloseOrder.DefaultSubmissionTimeBuffer);
                if (!security.Exchange.ExchangeOpen || Time > latestSubmissionTime)
                {
                    // tell the user we require a 16 minute buffer, on minute data in live a user will receive the 3:44->3:45 bar at 3:45,
                    // this is already too late to submit one of these orders, so make the user do it at the 3:43->3:44 bar so it's submitted
                    // to the brokerage before 3:45.
                    return(OrderResponse.Error(request, OrderResponseErrorCode.MarketOnCloseOrderTooLate, "MarketOnClose orders must be placed with at least a 16 minute buffer before market close."));
                }
            }

            // passes all initial order checks
            return(OrderResponse.Success(request));
        }
Пример #6
0
            protected override void OnProcessMessage(Message message)
            {
                //_historyMessageAdapter.UpdateCurrentTime(message.LocalTime);

                switch (message.Type)
                {
                case MessageTypes.Connect:
                {
                    if (message.Adapter == MarketDataAdapter)
                    {
                        break;
                    }

                    _isHistory        = true;
                    _isInitialization = true;
                    _connectTime      = message.LocalTime;
                    _strategy.SetIsInitialization(true);

                    _historyMessageAdapter
                    .SecurityProvider
                    .LookupAll()
                    .ForEach(s => SendOutMessage(s.ToMessage()));

                    break;
                }

                case (MessageTypes)(-1):
                {
                    new ChartAutoRangeCommand(false).Process(_strategy);

                    _strategy.PositionManager.Positions = _sessionStrategy.Positions.Select(p => p.Position).ToList();

                    if (_onlyInitialize)
                    {
                        if (message.Adapter == MarketDataAdapter)
                        {
                            new StopStrategyCommand(_strategy).Process(this);
                        }

                        return;
                    }

                    _historyMessageAdapter.StopDate = DateTimeOffset.MaxValue;
                    _historyMessageAdapter.MarketTimeChangedInterval = TimeSpan.FromMilliseconds(10);

                    var messages = new List <Message>();

                    messages.AddRange(_realConnector.Trades.Select(t => t.ToMessage()));
                    messages.AddRange(_realConnector.Orders.Select(o => o.ToMessage()));
                    messages.AddRange(_realConnector.OrderRegisterFails.Select(o => o.ToMessage()));
                    messages.AddRange(_realConnector.OrderCancelFails.Select(o => o.ToMessage()));
                    messages.AddRange(_realConnector.MyTrades.Select(t => t.ToMessage()));

                    messages.ForEach(SendOutMessage);

                    _isHistory = false;

                    return;
                }

                case MessageTypes.Execution:
                {
                    var execMsg = (ExecutionMessage)message;

                    if (execMsg.ExecutionType == ExecutionTypes.Tick && !_isHistory && _isInitialization)
                    {
                        ProcessTime(execMsg.ServerTime, execMsg.SecurityId.BoardCode);
                    }

                    break;
                }

                default:
                {
                    var candleMsg = message as CandleMessage;

                    if (candleMsg == null)
                    {
                        break;
                    }

                    if (!_isHistory)
                    {
                        break;
                    }

                    var stocksharpId = CreateSecurityId(candleMsg.SecurityId.SecurityCode, candleMsg.SecurityId.BoardCode);
                    var security     = Securities.FirstOrDefault(s => s.Id.CompareIgnoreCase(stocksharpId));

                    if (security == null)
                    {
                        throw new InvalidOperationException(LocalizedStrings.Str704Params.Put(candleMsg.SecurityId));
                    }

                    var volumeStep = security.VolumeStep ?? 1m;
                    var decimals   = volumeStep.GetCachedDecimals();

                    var trades = candleMsg.ToTrades(volumeStep, decimals);

                    foreach (var executionMessage in trades)
                    {
                        base.OnProcessMessage(executionMessage);
                    }

                    return;
                }
                }

                base.OnProcessMessage(message);
            }
Пример #7
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 || symbol == null || 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);
        }
Пример #8
0
 public AccountTrunk()
 {
     this.accounts = new Account[AccountTrunk.MAX_ACCOUNT];
     this.securities = new Securities();
     this.actAccount = 0;
 }
Пример #9
0
 private void SetSecurityInPanel(PanelGraph panel, Securities sec)
 {
     this.SetSecurityInPanel(panel, sec.Code, sec.Class.Code);
 }
Пример #10
0
        public void GetHistory(Selection parameters, HistoryAnswerHandler callback)
        {
            if (_session == null)
            {
                throw new ApplicationException("Can't load history. LMAX data feed is not connected.");
            }

            var symbol     = parameters.Symbol.ToUpper();
            var instrument = Securities.FirstOrDefault(i => i.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase));

            if (instrument == null)
            {
                Logger.Warning($"Invalid symbol {parameters.Symbol} passed for history request over {Name} feed");
                return;
            }

            lock (_historyRequestHandlers)
            {
                if (parameters.To == DateTime.MinValue || parameters.To > DateTime.UtcNow)
                {
                    parameters.To = DateTime.UtcNow;
                }

                //calculate start time
                if (parameters.From == DateTime.MinValue && parameters.BarCount != int.MaxValue)
                {
                    if (parameters.BarCount < 3)
                    {
                        callback(parameters, new List <Bar>());
                        return;
                    }

                    if (parameters.To > DateTime.UtcNow)
                    {
                        parameters.To = DateTime.UtcNow;
                    }

                    if (parameters.Timeframe == Timeframe.Minute)
                    {
                        parameters.From = parameters.To.AddMinutes(-1 * 3 * parameters.BarCount * parameters.TimeFactor);
                    }
                    else if (parameters.Timeframe == Timeframe.Hour)
                    {
                        parameters.From = parameters.To.AddHours(-1 * 3 * parameters.BarCount * parameters.TimeFactor);
                    }
                    else if (parameters.Timeframe == Timeframe.Day)
                    {
                        parameters.From = parameters.To.AddDays(-1 * 2 * parameters.BarCount * parameters.TimeFactor);
                    }
                    else if (parameters.Timeframe == Timeframe.Month)
                    {
                        parameters.From = parameters.To.AddDays(-1 * parameters.BarCount * parameters.TimeFactor * 31);
                    }
                }

                parameters.From = TimeZoneInfo.ConvertTimeFromUtc(parameters.From, TimeZoneInfo);
                parameters.To   = TimeZoneInfo.ConvertTimeFromUtc(parameters.To, TimeZoneInfo);

                var bidParams = (Selection)parameters.Clone();
                bidParams.BidAsk = PriceType.Bid;
                var id = ++_id;
                _historyRequestHandlers.Add(id, callback);
                _originalHistoryRequestParameters.Add(id, bidParams);

                _session?.RequestHistoricMarketData(new AggregateHistoricMarketDataRequest(id, instrument.SecurityId, bidParams.From, bidParams.To,
                                                                                           FromPeriodToResolution(bidParams.Timeframe), Format.Csv, Option.Bid), () => { }, FailureCallback);

                var askParams = (Selection)parameters.Clone();
                askParams.BidAsk = PriceType.Ask;
                id = ++_id;
                _historyRequestHandlers.Add(id, callback);
                _originalHistoryRequestParameters.Add(id, askParams);

                _session?.RequestHistoricMarketData(new AggregateHistoricMarketDataRequest(id, instrument.SecurityId, askParams.From, askParams.To,
                                                                                           FromPeriodToResolution(askParams.Timeframe), Format.Csv, Option.Ask), () => { }, FailureCallback);

                //

                /*var askHistParams = (Selection)parameters.Clone();
                 * askHistParams.BidAsk = PriceType.Unspecified;
                 * id = ++_id;
                 * _historyRequestHandlers.Add(id, callback);
                 * _originalHistoryRequestParameters.Add(id, askHistParams);
                 *
                 * _session?.RequestHistoricMarketData(new TopOfBookHistoricMarketDataRequest(id, instrument.SecurityId, askParams.From, askParams.To, Format.Csv),
                 *  () => { }, FailureCallback);*/
            }
        }
Пример #11
0
 /// <summary>
 /// Add a security to the feed so it receives events
 /// </summary>
 /// <param name="security">Security</param>
 public void AddSecurity(Security security)
 {
     Securities.Add(security.Symbol, security);
 }
Пример #12
0
 /// <summary>
 /// Remove security to the feed so it no longer receives events
 /// </summary>
 /// <param name="security">Security</param>
 public void RemoveSecurity(Security security)
 {
     Securities.Remove(security.Symbol);
 }
Пример #13
0
        static void Main(string[] args)
        {
            User     user     = new User();
            Business business = new Business();

            while (true)
            {
                user.displayMenu();
                Console.WriteLine();
                Console.Write("Enter options > ");
                int options = Convert.ToInt32(Console.ReadLine());

                string            title;
                string            status;
                string            id;
                int               price;
                List <Securities> list;
                switch (options)
                {
                case 1:
                    Console.Write("Enter title > ");
                    title = Console.ReadLine().Trim();
                    Console.Write("Enter status > ");
                    status = Console.ReadLine().Trim();
                    Console.Write("Enter price > ");
                    price = Convert.ToInt32(Console.ReadLine());
                    business.add(title, status, price, DateTime.Now);
                    break;

                case 2:
                    Console.Write("Enter id > ");
                    id = Console.ReadLine().Trim();
                    business.remove(id);
                    break;

                case 3:
                    try
                    {
                        Console.Write("Enter id > ");
                        id = Console.ReadLine().Trim();
                        Console.Write("Enter title > ");
                        title = Console.ReadLine().Trim();
                        Console.Write("Enter status > ");
                        status = Console.ReadLine().Trim();
                        Console.Write("Enter price > ");
                        price = Convert.ToInt32(Console.ReadLine());
                        Console.Write("Enter date y m d > ");
                        string[] date   = Console.ReadLine().Split(" ");
                        DateTime dateIn = new DateTime(Convert.ToInt32(date[0]), Convert.ToInt32(date[1]), Convert.ToInt32(date[2]) + 1);
                        business.edit(id, new Securities {
                            id = id, title = title, status = status, price = price, date = dateIn
                        });
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error: " + e);
                    }
                    break;

                case 4:
                    Console.Write("Enter id > ");
                    id = Console.ReadLine().Trim();
                    try
                    {
                        Securities securities = business.show(id);
                        Console.WriteLine();
                        Console.WriteLine(securities.id + " " + securities.title + " " + securities.status + " " + securities.price + " " + securities.date);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Not found 404");
                    }
                    Console.WriteLine();
                    break;

                case 5:
                    list = business.showAll();
                    Console.WriteLine();
                    foreach (var item in list)
                    {
                        Console.WriteLine(item.id + " " + item.title + " " + item.status + " " + item.price + " " + item.date);
                        Console.WriteLine();
                    }
                    break;

                case 6:
                    Console.Write("Enter start date y m d > ");
                    string[] dateS = Console.ReadLine().Split(" ");
                    Console.WriteLine();
                    Console.Write("Enter end date y m d > ");
                    string[] dateE = Console.ReadLine().Split(" ");
                    DateTime datS  = new DateTime(Convert.ToInt32(dateS[0]), Convert.ToInt32(dateS[1]), Convert.ToInt32(dateS[2]));
                    DateTime datE  = new DateTime(Convert.ToInt32(dateE[0]), Convert.ToInt32(dateE[1]), Convert.ToInt32(dateE[2]));
                    Console.Write("Enter status ([y (is bought)]/[n (is sold)]) > ");
                    status = Console.ReadLine().Trim();
                    Console.Write("Enter title > ");
                    title = Console.ReadLine().Trim();
                    while (true)
                    {
                        if (status != "y" && status != "n")
                        {
                            Console.WriteLine("Incorrect status");
                            Console.Write("Enter status ([y (is bought)]/[n (is sold)]) > ");
                            status = Console.ReadLine().Trim();
                        }
                        else
                        {
                            break;
                        }
                    }
                    bool isBoutht = status == "y";
                    Console.WriteLine(business.getSecByTime(datS, datE, isBoutht, title));
                    break;

                default:
                    Console.WriteLine("Incorrect option");
                    break;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Invoked at the end of every time step. This allows the algorithm
        /// to process events before advancing to the next time step.
        /// </summary>
        public void OnEndOfTimeStep()
        {
            if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0)
            {
                // no point in looping through everything if there's no pending changes
                return;
            }

            // rewrite securities w/ derivatives to be in raw mode
            lock (_pendingUniverseAdditionsLock)
            {
                foreach (var security in Securities.Select(kvp => kvp.Value).Union(_pendingUserDefinedUniverseSecurityAdditions.Keys))
                {
                    // check for any derivative securities and mark the underlying as raw
                    if (Securities.Any(skvp => skvp.Key.HasUnderlyingSymbol(security.Symbol)))
                    {
                        // set data mode raw and default volatility model
                        ConfigureUnderlyingSecurity(security);
                    }

                    if (security.Symbol.HasUnderlying)
                    {
                        Security underlyingSecurity;
                        var      underlyingSymbol = security.Symbol.Underlying;

                        // create the underlying security object if it doesn't already exist
                        if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity))
                        {
                            underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType, underlyingSymbol.Value, security.Resolution,
                                                             underlyingSymbol.ID.Market, false, 0, security.IsExtendedMarketHours);
                        }

                        // set data mode raw and default volatility model
                        ConfigureUnderlyingSecurity(underlyingSecurity);

                        // set the underying security on the derivative -- we do this in two places since it's possible
                        // to do AddOptionContract w/out the underlying already added and normalized properly
                        var derivative = security as IDerivativeSecurity;
                        if (derivative != null)
                        {
                            derivative.Underlying = underlyingSecurity;
                        }
                    }
                }

                // add securities to their respective user defined universes
                foreach (var kvp in _pendingUserDefinedUniverseSecurityAdditions)
                {
                    var security            = kvp.Key;
                    var userDefinedUniverse = kvp.Value;
                    userDefinedUniverse.Add(security.Symbol);
                }

                // finally add any pending universes, this will make them available to the data feed
                foreach (var universe in _pendingUniverseAdditions)
                {
                    UniverseManager.Add(universe.Configuration.Symbol, universe);
                }

                _pendingUniverseAdditions.Clear();
                _pendingUserDefinedUniverseSecurityAdditions.Clear();
            }
        }
Пример #15
0
 public void AddSecurities(Securities sec)
 {
     secs.Add(sec);
 }
Пример #16
0
 /// <summary>
 /// Create a simple JSON holdings from a Security holding class.
 /// </summary>
 /// <param name="holding"></param>
 public Holding(Securities.SecurityHolding holding)
 {
     this.Symbol = holding.Symbol;
     this.Quantity = holding.Quantity;
     this.AveragePrice = holding.AveragePrice;
     this.MarketPrice = holding.Price;
 }
Пример #17
0
        /// <summary>
        /// Perform preorder checks to ensure we have sufficient capital,
        /// the market is open, and we haven't exceeded maximum realistic orders per day.
        /// </summary>
        /// <returns>Negative order errors or zero for pass.</returns>
        private int PreOrderChecks(string symbol, int quantity, OrderType type)
        {
            //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.");
                return(-1);
            }

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

            //Check the exchange is open before sending a market on close orders
            //Allow market orders, they'll just execute when the exchange reopens
            if (type == OrderType.MarketOnClose && !security.Exchange.ExchangeOpen)
            {
                Error(type + " order and exchange not open.");
                return(-3);
            }

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

            if (security.Type == SecurityType.Forex)
            {
                // for forex pairs we need to verify that the conversions to USD have values as well
                string baseCurrency, quoteCurrency;
                Forex.DecomposeCurrencyPair(security.Symbol, out baseCurrency, out quoteCurrency);

                // verify they're in the portfolio
                Cash baseCash, quoteCash;
                if (!Portfolio.CashBook.TryGetValue(baseCurrency, out baseCash) || !Portfolio.CashBook.TryGetValue(quoteCurrency, out quoteCash))
                {
                    Error(symbol + ": requires " + baseCurrency + " and " + quoteCurrency + " in the cashbook to trade.");
                    return(-1);
                }
                // verify we have conversion rates for each leg of the pair back into the account currency
                if (baseCash.ConversionRate == 0m || quoteCash.ConversionRate == 0m)
                {
                    Error(symbol + ": requires " + baseCurrency + " and " + quoteCurrency + " to have non-zero conversion rates. This can be caused by lack of data.");
                    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);
            }

            //We've already processed too many orders: max 100 per day or the memory usage explodes
            if (Transactions.OrdersCount > _maxOrders)
            {
                Error(string.Format("You have exceeded maximum number of orders ({0}), for unlimited orders upgrade your account.", _maxOrders));
                _quit = true;
                return(-5);
            }

            if (type == OrderType.MarketOnClose)
            {
                // must be submitted with at least 10 minutes in trading day, add buffer allow order submission
                var latestSubmissionTime = (Time.Date + security.Exchange.MarketClose).AddMinutes(-10.75);
                if (Time > latestSubmissionTime)
                {
                    // tell the user we require an 11 minute buffer, on minute data in live a user will receive the 3:49->3:50 bar at 3:50,
                    // this is already too late to submit one of these orders, so make the user do it at the 3:48->3:49 bar so it's submitted
                    // to the brokerage before 3:50.
                    Error("MarketOnClose orders must be placed with at least a 11 minute buffer before market close.");
                    return(-6);
                }
            }
            return(0);
        }
Пример #18
0
        /// <summary>
        /// Add specified data to required list. QC will funnel this data to the handle data routine.
        /// </summary>
        /// <param name="securityType">MarketType Type: Equity, Commodity, Future or FOREX</param>
        /// <param name="symbol">Symbol Reference for the MarketType</param>
        /// <param name="resolution">Resolution of the Data Required</param>
        /// <param name="fillDataForward">When no data available on a tradebar, return the last data that was generated</param>
        /// <param name="leverage">Custom leverage per security</param>
        /// <param name="extendedMarketHours">Extended market hours</param>
        /// <remarks> AddSecurity(SecurityType securityType, string symbol, Resolution resolution, bool fillDataForward, decimal leverage, bool extendedMarketHours)</remarks>
        public void AddSecurity(SecurityType securityType, string symbol, Resolution resolution, bool fillDataForward, decimal leverage, bool extendedMarketHours)
        {
            try
            {
                if (_locked)
                {
                    throw new Exception("Algorithm.AddSecurity(): Cannot add another security after algorithm running.");
                }

                symbol = symbol.ToUpper();
                //If it hasn't been set, use some defaults based on the portfolio type:
                if (leverage <= 0)
                {
                    switch (securityType)
                    {
                    case SecurityType.Equity:
                        leverage = 2;     //Cash Ac. = 1, RegT Std = 2 or PDT = 4.
                        break;

                    case SecurityType.Forex:
                        leverage = 50;
                        break;
                    }
                }

                //Add the symbol to Data Manager -- generate unified data streams for algorithm events
                var config = SubscriptionManager.Add(securityType, symbol, resolution, fillDataForward, extendedMarketHours);

                Security security;
                switch (config.SecurityType)
                {
                case SecurityType.Equity:
                    security = new Equity(config, leverage, false);
                    break;

                case SecurityType.Forex:
                    // decompose the symbol into each currency pair
                    string baseCurrency, quoteCurrency;
                    QuantConnect.Securities.Forex.Forex.DecomposeCurrencyPair(symbol, out baseCurrency, out quoteCurrency);

                    if (!Portfolio.CashBook.ContainsKey(baseCurrency))
                    {
                        // since we have none it's safe to say the conversion is zero
                        Portfolio.CashBook.Add(baseCurrency, 0, 0);
                    }
                    if (!Portfolio.CashBook.ContainsKey(quoteCurrency))
                    {
                        // since we have none it's safe to say the conversion is zero
                        Portfolio.CashBook.Add(quoteCurrency, 0, 0);
                    }
                    security = new Forex(Portfolio.CashBook[quoteCurrency], config, leverage, false);
                    break;

                default:
                case SecurityType.Base:
                    security = new Security(config, leverage, false);
                    break;
                }

                //Add the symbol to Securities Manager -- manage collection of portfolio entities for easy access.
                Securities.Add(config.Symbol, security);
            }
            catch (Exception err)
            {
                Error("Algorithm.AddSecurity(): " + err.Message);
            }
        }
        /// <summary>
        /// Adds the security to the user defined universe
        /// </summary>
        /// <param name="security">The security to add</param>
        /// <param name="configurations">The <see cref="SubscriptionDataConfig"/> instances we want to add</param>
        private void AddToUserDefinedUniverse(
            Security security,
            List <SubscriptionDataConfig> configurations)
        {
            var subscription = configurations.First();
            // if we are adding a non-internal security which already has an internal feed, we remove it first
            Security existingSecurity;

            if (Securities.TryGetValue(security.Symbol, out existingSecurity))
            {
                if (!subscription.IsInternalFeed && existingSecurity.IsInternalFeed())
                {
                    var securityUniverse = UniverseManager.Select(x => x.Value).OfType <UserDefinedUniverse>().FirstOrDefault(x => x.Members.ContainsKey(security.Symbol));
                    securityUniverse?.Remove(security.Symbol);

                    Securities.Remove(security.Symbol);
                }
            }

            Securities.Add(security);

            // add this security to the user defined universe
            Universe universe;
            var      universeSymbol = UserDefinedUniverse.CreateSymbol(security.Type, security.Symbol.ID.Market);

            lock (_pendingUniverseAdditionsLock)
            {
                if (!UniverseManager.TryGetValue(universeSymbol, out universe))
                {
                    universe = _pendingUniverseAdditions.FirstOrDefault(x => x.Configuration.Symbol == universeSymbol);
                    if (universe == null)
                    {
                        // create a new universe, these subscription settings don't currently get used
                        // since universe selection proper is never invoked on this type of universe
                        var uconfig = new SubscriptionDataConfig(subscription, symbol: universeSymbol, isInternalFeed: true, fillForward: false);

                        if (security.Type == SecurityType.Base)
                        {
                            // set entry in market hours database for the universe subscription to match the custom data
                            var symbolString = MarketHoursDatabase.GetDatabaseSymbolKey(uconfig.Symbol);
                            MarketHoursDatabase.SetEntry(uconfig.Market, symbolString, uconfig.SecurityType, security.Exchange.Hours, uconfig.DataTimeZone);
                        }

                        universe = new UserDefinedUniverse(uconfig,
                                                           new UniverseSettings(
                                                               subscription.Resolution,
                                                               security.Leverage,
                                                               subscription.FillDataForward,
                                                               subscription.ExtendedMarketHours,
                                                               TimeSpan.Zero),
                                                           QuantConnect.Time.MaxTimeSpan,
                                                           new List <Symbol>());
                        _pendingUniverseAdditions.Add(universe);
                    }
                }
            }

            var userDefinedUniverse = universe as UserDefinedUniverse;

            if (userDefinedUniverse != null)
            {
                lock (_pendingUniverseAdditionsLock)
                {
                    _pendingUserDefinedUniverseSecurityAdditions.Add(
                        new UserDefinedUniverseAddition(userDefinedUniverse, configurations, security));
                }
            }
            else
            {
                // should never happen, someone would need to add a non-user defined universe with this symbol
                throw new Exception("Expected universe with symbol '" + universeSymbol.Value + "' to be of type UserDefinedUniverse.");
            }
        }
Пример #20
0
 /// <summary>
 /// Adds the specified security to this universe
 /// </summary>
 /// <param name="utcTime">The current utc date time</param>
 /// <param name="security">The security to be added</param>
 /// <returns>True if the security was successfully added,
 /// false if the security was already in the universe</returns>
 internal virtual bool AddMember(DateTime utcTime, Security security)
 {
     return(Securities.TryAdd(security.Symbol, new Member(utcTime, security)));
 }
        /// <summary>
        /// Invoked at the end of every time step. This allows the algorithm
        /// to process events before advancing to the next time step.
        /// </summary>
        public void OnEndOfTimeStep()
        {
            if (_pendingUniverseAdditions.Count + _pendingUserDefinedUniverseSecurityAdditions.Count == 0)
            {
                // no point in looping through everything if there's no pending changes
                return;
            }

            var requiredHistoryRequests = new Dictionary <Security, Resolution>();

            // rewrite securities w/ derivatives to be in raw mode
            lock (_pendingUniverseAdditionsLock)
            {
                foreach (var security in Securities.Select(kvp => kvp.Value).Union(
                             _pendingUserDefinedUniverseSecurityAdditions.Select(x => x.Security)))
                {
                    // check for any derivative securities and mark the underlying as raw
                    if (Securities.Any(skvp => skvp.Key.SecurityType != SecurityType.Base && skvp.Key.HasUnderlyingSymbol(security.Symbol)))
                    {
                        // set data mode raw and default volatility model
                        ConfigureUnderlyingSecurity(security);
                    }

                    var configs = SubscriptionManager.SubscriptionDataConfigService
                                  .GetSubscriptionDataConfigs(security.Symbol);
                    if (security.Symbol.HasUnderlying && security.Symbol.SecurityType != SecurityType.Base)
                    {
                        Security underlyingSecurity;
                        var      underlyingSymbol = security.Symbol.Underlying;
                        var      resolution       = configs.GetHighestResolution();

                        // create the underlying security object if it doesn't already exist
                        if (!Securities.TryGetValue(underlyingSymbol, out underlyingSecurity))
                        {
                            underlyingSecurity = AddSecurity(underlyingSymbol.SecurityType,
                                                             underlyingSymbol.Value,
                                                             resolution,
                                                             underlyingSymbol.ID.Market,
                                                             false,
                                                             0,
                                                             configs.IsExtendedMarketHours());
                        }

                        // set data mode raw and default volatility model
                        ConfigureUnderlyingSecurity(underlyingSecurity);

                        if (LiveMode && underlyingSecurity.GetLastData() == null)
                        {
                            if (requiredHistoryRequests.ContainsKey(underlyingSecurity))
                            {
                                // lets request the higher resolution
                                var currentResolutionRequest = requiredHistoryRequests[underlyingSecurity];
                                if (currentResolutionRequest != Resolution.Minute && // Can not be less than Minute
                                    resolution < currentResolutionRequest)
                                {
                                    requiredHistoryRequests[underlyingSecurity] = (Resolution)Math.Max((int)resolution, (int)Resolution.Minute);
                                }
                            }
                            else
                            {
                                requiredHistoryRequests.Add(underlyingSecurity, (Resolution)Math.Max((int)resolution, (int)Resolution.Minute));
                            }
                        }
                        // set the underlying security on the derivative -- we do this in two places since it's possible
                        // to do AddOptionContract w/out the underlying already added and normalized properly
                        var derivative = security as IDerivativeSecurity;
                        if (derivative != null)
                        {
                            derivative.Underlying = underlyingSecurity;
                        }
                    }
                }

                if (!requiredHistoryRequests.IsNullOrEmpty())
                {
                    // Create requests
                    var historyRequests = Enumerable.Empty <HistoryRequest>();
                    foreach (var byResolution in requiredHistoryRequests.GroupBy(x => x.Value))
                    {
                        historyRequests = historyRequests.Concat(
                            CreateBarCountHistoryRequests(byResolution.Select(x => x.Key.Symbol), 3, byResolution.Key));
                    }
                    // Request data
                    var historicLastData = History(historyRequests);
                    historicLastData.PushThrough(x =>
                    {
                        var security = requiredHistoryRequests.Keys.FirstOrDefault(y => y.Symbol == x.Symbol);
                        security?.Cache.AddData(x);
                    });
                }

                // add subscriptionDataConfig to their respective user defined universes
                foreach (var userDefinedUniverseAddition in _pendingUserDefinedUniverseSecurityAdditions)
                {
                    foreach (var subscriptionDataConfig in userDefinedUniverseAddition.SubscriptionDataConfigs)
                    {
                        userDefinedUniverseAddition.Universe.Add(subscriptionDataConfig);
                    }
                }

                // finally add any pending universes, this will make them available to the data feed
                foreach (var universe in _pendingUniverseAdditions)
                {
                    UniverseManager.Add(universe.Configuration.Symbol, universe);
                }

                _pendingUniverseAdditions.Clear();
                _pendingUserDefinedUniverseSecurityAdditions.Clear();
            }
        }
Пример #22
0
        private IEnumerable <OrderTicket> GenerateOrders(OptionStrategy strategy, int strategyQuantity)
        {
            var orders = new List <OrderTicket>();

            // setting up the tag text for all orders of one strategy
            var strategyTag = strategy.Name + " (" + strategyQuantity.ToString() + ")";

            // walking through all option legs and issuing orders
            if (strategy.OptionLegs != null)
            {
                foreach (var optionLeg in strategy.OptionLegs)
                {
                    var optionSeq = Securities.Where(kv => kv.Key.Underlying == strategy.Underlying &&
                                                     kv.Key.ID.OptionRight == optionLeg.Right &&
                                                     kv.Key.ID.Date == optionLeg.Expiration &&
                                                     kv.Key.ID.StrikePrice == optionLeg.Strike);

                    if (optionSeq.Count() != 1)
                    {
                        var error = string.Format("Couldn't find the option contract in algorithm securities list. Underlying: {0}, option {1}, strike {2}, expiration: {3}",
                                                  strategy.Underlying.ToString(), optionLeg.Right.ToString(), optionLeg.Strike.ToString(), optionLeg.Expiration.ToString());
                        throw new InvalidOperationException(error);
                    }

                    var option = optionSeq.First().Key;

                    switch (optionLeg.OrderType)
                    {
                    case OrderType.Market:
                        var marketOrder = MarketOrder(option, optionLeg.Quantity * strategyQuantity, tag: strategyTag);
                        orders.Add(marketOrder);
                        break;

                    case OrderType.Limit:
                        var limitOrder = LimitOrder(option, optionLeg.Quantity * strategyQuantity, optionLeg.OrderPrice, tag: strategyTag);
                        orders.Add(limitOrder);
                        break;

                    default:
                        throw new InvalidOperationException("Order type is not supported in option strategy: " + optionLeg.OrderType.ToString());
                    }
                }
            }

            // walking through all underlying legs and issuing orders
            if (strategy.UnderlyingLegs != null)
            {
                foreach (var underlyingLeg in strategy.UnderlyingLegs)
                {
                    if (!Securities.ContainsKey(strategy.Underlying))
                    {
                        var error = string.Format("Couldn't find the option contract underlying in algorithm securities list. Underlying: {0}", strategy.Underlying.ToString());
                        throw new InvalidOperationException(error);
                    }

                    switch (underlyingLeg.OrderType)
                    {
                    case OrderType.Market:
                        var marketOrder = MarketOrder(strategy.Underlying, underlyingLeg.Quantity * strategyQuantity, tag: strategyTag);
                        orders.Add(marketOrder);
                        break;

                    case OrderType.Limit:
                        var limitOrder = LimitOrder(strategy.Underlying, underlyingLeg.Quantity * strategyQuantity, underlyingLeg.OrderPrice, tag: strategyTag);
                        orders.Add(limitOrder);
                        break;

                    default:
                        throw new InvalidOperationException("Order type is not supported in option strategy: " + underlyingLeg.OrderType.ToString());
                    }
                }
            }
            return(orders);
        }
Пример #23
0
        /// <summary>
        /// Gets <see cref="OptionHistory"/> object for a given symbol, date and resolution
        /// </summary>
        /// <param name="symbol">The symbol to retrieve historical option data for</param>
        /// <param name="start">The history request start time</param>
        /// <param name="end">The history request end time. Defaults to 1 day if null</param>
        /// <param name="resolution">The resolution to request</param>
        /// <returns>A <see cref="OptionHistory"/> object that contains historical option data.</returns>
        public OptionHistory GetOptionHistory(Symbol symbol, DateTime start, DateTime?end = null, Resolution?resolution = null)
        {
            if (!end.HasValue || end.Value == start)
            {
                end = start.AddDays(1);
            }

            // Load a canonical option Symbol if the user provides us with an underlying Symbol
            if (!symbol.SecurityType.IsOption())
            {
                var option = AddOption(symbol, resolution, symbol.ID.Market);

                // Allow 20 strikes from the money for futures. No expiry filter is applied
                // so that any future contract provided will have data returned.
                if (symbol.SecurityType == SecurityType.Future && symbol.IsCanonical())
                {
                    throw new ArgumentException("The Future Symbol provided is a canonical Symbol (i.e. a Symbol representing all Futures), which is not supported at this time. " +
                                                "If you are using the Symbol accessible from `AddFuture(...)`, use the Symbol from `AddFutureContract(...)` instead. " +
                                                "You can use `qb.FutureOptionChainProvider(canonicalFuture, datetime)` to get a list of futures contracts for a given date, and add them to your algorithm with `AddFutureContract(symbol, Resolution)`.");
                }
                if (symbol.SecurityType == SecurityType.Future && !symbol.IsCanonical())
                {
                    option.SetFilter(universe => universe.Strikes(-10, +10));
                }

                symbol = option.Symbol;
            }

            IEnumerable <Symbol> symbols;

            if (symbol.IsCanonical())
            {
                // canonical symbol, lets find the contracts
                var option = Securities[symbol] as Option;
                var resolutionToUseForUnderlying = resolution ?? SubscriptionManager.SubscriptionDataConfigService
                                                   .GetSubscriptionDataConfigs(symbol)
                                                   .GetHighestResolution();
                if (!Securities.ContainsKey(symbol.Underlying))
                {
                    if (symbol.Underlying.SecurityType == SecurityType.Equity)
                    {
                        // only add underlying if not present
                        AddEquity(symbol.Underlying.Value, resolutionToUseForUnderlying);
                    }
                    if (symbol.Underlying.SecurityType == SecurityType.Future && symbol.Underlying.IsCanonical())
                    {
                        AddFuture(symbol.Underlying.ID.Symbol, resolutionToUseForUnderlying);
                    }
                    else if (symbol.Underlying.SecurityType == SecurityType.Future)
                    {
                        AddFutureContract(symbol.Underlying, resolutionToUseForUnderlying);
                    }
                }
                var allSymbols = new List <Symbol>();
                for (var date = start; date < end; date = date.AddDays(1))
                {
                    if (option.Exchange.DateIsOpen(date))
                    {
                        allSymbols.AddRange(OptionChainProvider.GetOptionContractList(symbol.Underlying, date));
                    }
                }

                var optionFilterUniverse = new OptionFilterUniverse();
                var distinctSymbols      = allSymbols.Distinct();
                symbols = base.History(symbol.Underlying, start, end.Value, resolution)
                          .SelectMany(x =>
                {
                    // the option chain symbols wont change so we can set 'exchangeDateChange' to false always
                    optionFilterUniverse.Refresh(distinctSymbols, x, exchangeDateChange: false);
                    return(option.ContractFilter.Filter(optionFilterUniverse));
                })
                          .Distinct().Concat(new[] { symbol.Underlying });
            }
            else
            {
                // the symbol is a contract
                symbols = new List <Symbol> {
                    symbol
                };
            }

            return(new OptionHistory(History(symbols, start, end.Value, resolution)));
        }
Пример #24
0
        /// <summary>
        /// Liquidate all holdings and cancel open orders. Called at the end of day for tick-strategies.
        /// </summary>
        /// <param name="symbolToLiquidate">Symbols we wish to liquidate</param>
        /// <param name="tag">Custom tag to know who is calling this.</param>
        /// <returns>Array of order ids for liquidated symbols</returns>
        /// <seealso cref="MarketOrder(QuantConnect.Symbol,decimal,bool,string)"/>
        public List <int> Liquidate(Symbol symbolToLiquidate = null, string tag = "Liquidated")
        {
            var orderIdList = new List <int>();

            if (!Settings.LiquidateEnabled)
            {
                Debug("Liquidate() is currently disabled by settings. To re-enable please set 'Settings.LiquidateEnabled' to true");
                return(orderIdList);
            }

            IEnumerable <Symbol> toLiquidate;

            if (symbolToLiquidate != null)
            {
                toLiquidate = Securities.ContainsKey(symbolToLiquidate)
                    ? new[] { symbolToLiquidate } : Enumerable.Empty <Symbol>();
            }
            else
            {
                toLiquidate = Securities.Keys.OrderBy(x => x.Value);
            }


            foreach (var symbol in toLiquidate)
            {
                // get open orders
                var orders = Transactions.GetOpenOrders(symbol);

                // get quantity in portfolio
                var quantity = Portfolio[symbol].Quantity;

                // if there is only one open market order that would close the position, do nothing
                if (orders.Count == 1 && quantity != 0 && orders[0].Quantity == -quantity && orders[0].Type == OrderType.Market)
                {
                    continue;
                }

                // cancel all open orders
                var marketOrdersQuantity = 0m;
                foreach (var order in orders)
                {
                    if (order.Type == OrderType.Market)
                    {
                        // pending market order
                        var ticket = Transactions.GetOrderTicket(order.Id);
                        if (ticket != null)
                        {
                            // get remaining quantity
                            marketOrdersQuantity += ticket.Quantity - ticket.QuantityFilled;
                        }
                    }
                    else
                    {
                        Transactions.CancelOrder(order.Id, tag);
                    }
                }

                // Liquidate at market price
                if (quantity != 0)
                {
                    // calculate quantity for closing market order
                    var ticket = Order(symbol, -quantity - marketOrdersQuantity, tag: tag);
                    if (ticket.Status == OrderStatus.Filled)
                    {
                        orderIdList.Add(ticket.OrderId);
                    }
                }
            }

            return(orderIdList);
        }
Пример #25
0
        /// <summary>
        /// <see cref = "QuantBook" /> constructor.
        /// Provides access to data for quantitative analysis
        /// </summary>
        public QuantBook() : base()
        {
            try
            {
                using (Py.GIL())
                {
                    _pandas = Py.Import("pandas");
                }

                // Issue #4892 : Set start time relative to NY time
                // when the data is available from the previous day
                var newYorkTime   = DateTime.UtcNow.ConvertFromUtc(TimeZones.NewYork);
                var hourThreshold = Config.GetInt("qb-data-hour", 9);

                // If it is after our hour threshold; then we can use today
                if (newYorkTime.Hour >= hourThreshold)
                {
                    SetStartDate(newYorkTime);
                }
                else
                {
                    SetStartDate(newYorkTime - TimeSpan.FromDays(1));
                }

                // Sets PandasConverter
                SetPandasConverter();

                // Reset our composer; needed for re-creation of QuantBook
                Composer.Instance.Reset();
                var composer = Composer.Instance;

                // Create our handlers with our composer instance
                var algorithmHandlers = LeanEngineAlgorithmHandlers.FromConfiguration(composer);
                var systemHandlers    = LeanEngineSystemHandlers.FromConfiguration(composer);

                // init the API
                systemHandlers.Initialize();
                systemHandlers.LeanManager.Initialize(systemHandlers,
                                                      algorithmHandlers,
                                                      new BacktestNodePacket(),
                                                      new AlgorithmManager(false));
                systemHandlers.LeanManager.SetAlgorithm(this);

                algorithmHandlers.DataPermissionsManager.Initialize(new AlgorithmNodePacket(PacketType.BacktestNode)
                {
                    UserToken      = Config.Get("api-access-token"),
                    UserId         = Config.GetInt("job-user-id"),
                    ProjectId      = Config.GetInt("project-id"),
                    OrganizationId = Config.Get("job-organization-id"),
                    Version        = Globals.Version
                });

                algorithmHandlers.ObjectStore.Initialize(Config.Get("research-object-store-name", "QuantBook"),
                                                         Config.GetInt("job-user-id"),
                                                         Config.GetInt("project-id"),
                                                         Config.Get("api-access-token"),
                                                         new Controls
                {
                    // if <= 0 we disable periodic persistence and make it synchronous
                    PersistenceIntervalSeconds = -1,
                    StorageLimitMB             = Config.GetInt("storage-limit-mb", 5),
                    StorageFileCount           = Config.GetInt("storage-file-count", 100),
                    StoragePermissions         = (FileAccess)Config.GetInt("storage-permissions", (int)FileAccess.ReadWrite)
                });
                SetObjectStore(algorithmHandlers.ObjectStore);

                _dataCacheProvider = new ZipDataCacheProvider(algorithmHandlers.DataProvider);
                _dataProvider      = algorithmHandlers.DataProvider;

                var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder();
                var registeredTypes          = new RegisteredSecurityDataTypesProvider();
                var securityService          = new SecurityService(Portfolio.CashBook,
                                                                   MarketHoursDatabase,
                                                                   symbolPropertiesDataBase,
                                                                   this,
                                                                   registeredTypes,
                                                                   new SecurityCacheProvider(Portfolio));
                Securities.SetSecurityService(securityService);
                SubscriptionManager.SetDataManager(
                    new DataManager(new NullDataFeed(),
                                    new UniverseSelection(this, securityService, algorithmHandlers.DataPermissionsManager, algorithmHandlers.DataProvider),
                                    this,
                                    TimeKeeper,
                                    MarketHoursDatabase,
                                    false,
                                    registeredTypes,
                                    algorithmHandlers.DataPermissionsManager));

                var mapFileProvider = algorithmHandlers.MapFileProvider;
                HistoryProvider = new HistoryProviderManager();
                HistoryProvider.Initialize(
                    new HistoryProviderInitializeParameters(
                        null,
                        null,
                        algorithmHandlers.DataProvider,
                        _dataCacheProvider,
                        mapFileProvider,
                        algorithmHandlers.FactorFileProvider,
                        null,
                        true,
                        algorithmHandlers.DataPermissionsManager
                        )
                    );

                SetOptionChainProvider(new CachingOptionChainProvider(new BacktestingOptionChainProvider(_dataCacheProvider, mapFileProvider)));
                SetFutureChainProvider(new CachingFutureChainProvider(new BacktestingFutureChainProvider(_dataCacheProvider)));
            }
            catch (Exception exception)
            {
                throw new Exception("QuantBook.Main(): " + exception);
            }
        }
Пример #26
0
        public override void OnData(Slice data)
        {
            if (!IsWarmingUp && Time.Month != pmonth && VOL_PROTECT)
            {
                SetHoldings("VIXM", 0.1m);
                pmonth = Time.Month;
            }

            if (Time.Minute != 0)
            {
                return;
            }

            foreach (var s in symbols)
            {
                if (!Securities.ContainsKey(s))
                {
                    continue;
                }
                TradeMonitor.RecordPerf(s, Securities[s].Price);


                if (pvalue[s] > 50 & pfe[s] < 50 || pfe[s] < -50)
                {
                    if (activate[s])
                    {
                        jitter++;
                    }
                    activate[s] = false;
                }
                else if (pvalue[s] < -50 & pfe[s] > -50 || pfe[s] > 0 && pfe[s] > pvalue[s])
                {
                    if (!activate[s])
                    {
                        jitter++;
                    }
                    activate[s] = true;
                }
                pvalue[s] = pfe[s];



                if (eit[s].IsReady)
                {
                    if (Securities.ContainsKey(s) && data.Bars.ContainsKey(s))
                    {
                        var ratio = 1.0m / MAX_POS;      ///(symbols.Contains("VXX.1")) ? 1.0/(symbols.Count()-1) : 1.0 / (symbols.Count());
                        //if (POS_COUNT >= 10) ratio = 0.1;

                        if (activate[s] && Portfolio[s].Quantity == 0)
                        {
                            if (eit[s] > 0 && data[s].Close > Math.Max(eit[s].Lag, eit[s].InstantaneousTrend))
                            {
                                BuyRatio(data, s, ratio);
                            }
                        }

                        if (eit[s] < 0 || data[s].Close < Math.Min(eit[s].Lag, eit[s].InstantaneousTrend))
                        {
                            UpdateReference(s);
                            if (Securities.ContainsKey(s))
                            {
                                TradeMonitor.CloseAt(s, Securities[s].Price, Time);
                            }
                            if (Portfolio.ContainsKey(s) && Portfolio[s].Quantity != 0 && !IsWarmingUp)
                            {
                                SetHoldings(s, 0);                        //, tag:TradeMonitor.GetPerfReport(s));
                            }
                        }
                        else if (!activate[s] && data.Bars.ContainsKey(s) && data.Bars[s].Close < eit[s].Lag)                //tightening the grip when trend slowing down according to PFE
                        {
                            UpdateReference(s);
                            TradeMonitor.CloseAt(s, Securities[s].Price, Time);
                            if (Portfolio[s].Quantity != 0 && !IsWarmingUp)
                            {
                                SetHoldings(s, 0);                        //, tag:TradeMonitor.GetPerfReport(s));
                            }
                        }
                        //risk mgmt kinda redundant with algo so little impact on DD
                        // else //if (data.Bars.ContainsKey(s))
                        // {
                        //  // if (stopLoss.ContainsKey(s) && data[s].Close < stopLoss[s])
                        //  // {
                        //  //  UpdateReference(s);
                        //  //  TradeMonitor.CloseAt(s, Securities[s].Price, Time);
                        //  //  if (Portfolio[s].Quantity != 0)
                        //  //      SetHoldings(s, 0, tag:TradeMonitor.GetPerfReport(s));
                        //  // }
                        //  // else if (takeProfit.ContainsKey(s) && data[s].Close >= takeProfit[s])
                        //  // {
                        //  //  if (Portfolio[s].Quantity != 0)
                        //  //      MarketOrder(s, -0.5m * Portfolio[s].Quantity);
                        //  //  takeProfit.Remove(s);
                        //  // }
                        //  // else if (!takeProfit.ContainsKey(s) && data[s].Close < Portfolio[s].AveragePrice)
                        //  // {
                        //  //  UpdateReference(s);
                        //  //  TradeMonitor.CloseAt(s, Securities[s].Price, Time);
                        //  //  if (Portfolio[s].Quantity != 0)
                        //  //      SetHoldings(s, 0, tag:TradeMonitor.GetPerfReport(s));
                        //  // }
                        // }
                    }
                }
            }
        }
Пример #27
0
        /// <summary>
        /// Perform preorder checks to ensure we have sufficient capital,
        /// the market is open, and we haven't exceeded maximum realistic orders per day.
        /// </summary>
        /// <returns>OrderResponse. If no error, order request is submitted.</returns>
        private OrderResponse PreOrderChecksImpl(SubmitOrderRequest request)
        {
            //Ordering 0 is useless.
            if (request.Quantity == 0 || request.Symbol == null || request.Symbol == QuantConnect.Symbol.Empty)
            {
                return(OrderResponse.ZeroQuantity(request));
            }

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

            //Set a temporary price for validating order for market orders:
            var security = Securities[request.Symbol];
            var price    = security.Price;

            //Check the exchange is open before sending a market on close orders
            //Allow market orders, they'll just execute when the exchange reopens
            if (request.OrderType == OrderType.MarketOnClose && !security.Exchange.ExchangeOpen)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open."));
            }

            if (price == 0)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.SecurityPriceZero, request.Symbol.ToString() + ": asset price is $0. If using custom data make sure you've set the 'Value' property."));
            }

            if (security.Type == SecurityType.Forex)
            {
                // for forex pairs we need to verify that the conversions to USD have values as well
                string baseCurrency, quoteCurrency;
                Forex.DecomposeCurrencyPair(security.Symbol.Value, out baseCurrency, out quoteCurrency);

                // verify they're in the portfolio
                Cash baseCash, quoteCash;
                if (!Portfolio.CashBook.TryGetValue(baseCurrency, out baseCash) || !Portfolio.CashBook.TryGetValue(quoteCurrency, out quoteCash))
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexBaseAndQuoteCurrenciesRequired, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " in the cashbook to trade."));
                }
                // verify we have conversion rates for each leg of the pair back into the account currency
                if (baseCash.ConversionRate == 0m || quoteCash.ConversionRate == 0m)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexConversionRateZero, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " to have non-zero conversion rates. This can be caused by lack of data."));
                }
            }

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

            //We've already processed too many orders: max 100 per day or the memory usage explodes
            if (Transactions.OrdersCount > _maxOrders)
            {
                Status = AlgorithmStatus.Stopped;
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExceededMaximumOrders, string.Format("You have exceeded maximum number of orders ({0}), for unlimited orders upgrade your account.", _maxOrders)));
            }

            if (request.OrderType == OrderType.MarketOnClose)
            {
                // must be submitted with at least 10 minutes in trading day, add buffer allow order submission
                var latestSubmissionTime = (Time.Date + security.Exchange.MarketClose).AddMinutes(-10.75);
                if (Time > latestSubmissionTime)
                {
                    // tell the user we require an 11 minute buffer, on minute data in live a user will receive the 3:49->3:50 bar at 3:50,
                    // this is already too late to submit one of these orders, so make the user do it at the 3:48->3:49 bar so it's submitted
                    // to the brokerage before 3:50.
                    return(OrderResponse.Error(request, OrderResponseErrorCode.MarketOnCloseOrderTooLate, "MarketOnClose orders must be placed with at least a 11 minute buffer before market close."));
                }
            }

            // passes all initial order checks
            return(OrderResponse.Success(request));
        }
Пример #28
0
        /// <summary>
        /// Perform preorder checks to ensure we have sufficient capital,
        /// the market is open, and we haven't exceeded maximum realistic orders per day.
        /// </summary>
        /// <returns>OrderResponse. If no error, order request is submitted.</returns>
        private OrderResponse PreOrderChecksImpl(SubmitOrderRequest request)
        {
            //Ordering 0 is useless.
            if (request.Quantity == 0 || request.Symbol == null || request.Symbol == QuantConnect.Symbol.Empty)
            {
                return(OrderResponse.ZeroQuantity(request));
            }

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

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

            if (!security.IsTradable)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.NonTradableSecurity, "The security with symbol '" + request.Symbol.ToString() + "' is marked as non-tradable."));
            }

            var price = security.Price;

            //Check the exchange is open before sending a market on close orders
            if (request.OrderType == OrderType.MarketOnClose && !security.Exchange.ExchangeOpen)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExchangeNotOpen, request.OrderType + " order and exchange not open."));
            }

            if (price == 0)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.SecurityPriceZero, request.Symbol.ToString() + ": asset price is $0. If using custom data make sure you've set the 'Value' property."));
            }

            // check quote currency existence/conversion rate on all orders
            Cash quoteCash;
            var  quoteCurrency = security.QuoteCurrency.Symbol;

            if (!Portfolio.CashBook.TryGetValue(quoteCurrency, out quoteCash))
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.QuoteCurrencyRequired, request.Symbol.Value + ": requires " + quoteCurrency + " in the cashbook to trade."));
            }
            if (security.QuoteCurrency.ConversionRate == 0m)
            {
                return(OrderResponse.Error(request, OrderResponseErrorCode.ConversionRateZero, request.Symbol.Value + ": requires " + quoteCurrency + " to have a non-zero conversion rate. This can be caused by lack of data."));
            }

            // need to also check base currency existence/conversion rate on forex orders
            if (security.Type == SecurityType.Forex)
            {
                Cash baseCash;
                var  baseCurrency = ((Forex)security).BaseCurrencySymbol;
                if (!Portfolio.CashBook.TryGetValue(baseCurrency, out baseCash))
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexBaseAndQuoteCurrenciesRequired, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " in the cashbook to trade."));
                }
                if (baseCash.ConversionRate == 0m)
                {
                    return(OrderResponse.Error(request, OrderResponseErrorCode.ForexConversionRateZero, request.Symbol.Value + ": requires " + baseCurrency + " and " + quoteCurrency + " to have non-zero conversion rates. This can be caused by lack of data."));
                }
            }

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

            //We've already processed too many orders: max 100 per day or the memory usage explodes
            if (Transactions.OrdersCount > _maxOrders)
            {
                Status = AlgorithmStatus.Stopped;
                return(OrderResponse.Error(request, OrderResponseErrorCode.ExceededMaximumOrders, string.Format("You have exceeded maximum number of orders ({0}), for unlimited orders upgrade your account.", _maxOrders)));
            }

            if (request.OrderType == OrderType.MarketOnClose)
            {
                var nextMarketClose = security.Exchange.Hours.GetNextMarketClose(security.LocalTime, false);
                // must be submitted with at least 10 minutes in trading day, add buffer allow order submission
                var latestSubmissionTime = nextMarketClose.AddMinutes(-15.50);
                if (!security.Exchange.ExchangeOpen || Time > latestSubmissionTime)
                {
                    // tell the user we require a 16 minute buffer, on minute data in live a user will receive the 3:44->3:45 bar at 3:45,
                    // this is already too late to submit one of these orders, so make the user do it at the 3:43->3:44 bar so it's submitted
                    // to the brokerage before 3:45.
                    return(OrderResponse.Error(request, OrderResponseErrorCode.MarketOnCloseOrderTooLate, "MarketOnClose orders must be placed with at least a 16 minute buffer before market close."));
                }
            }

            // passes all initial order checks
            return(OrderResponse.Success(request));
        }
Пример #29
0
        public void InitAutoStopLoss()
        {
            ASLObject.Load();

            comboBoxASLAccount.Click += (s, e) =>
            {
                if (comboBoxASLAccount.Items.Count == 0)
                {
                    comboBoxASLAccount.SetListValues(this.Trader.Objects.tClients.ToArray()
                                                     .Select(c => c.Code).ToArray());
                }
            };
            comboBoxASLSec.SetListValues(Global.GetWorkingListSec().ToArray());
            comboBoxASLSec.TextChanged += (s, e) =>
            {
                StopLossSec = null;
                var text = comboBoxASLSec.Text;
                if (text.Length >= 2)
                {
                    var listSec = Trader.Objects.tSecurities.SearchAll(el => el.Code.ToLower().Contains(text.ToLower()) ||
                                                                       el.Name.ToLower().Contains(text.ToLower())).Select(el => el.ToString());
                    if (listSec.Count() > 0)
                    {
                        comboBoxASLSec.Clear();
                        comboBoxASLSec.SetListValues(listSec);
                        AutoSLUpdateGrid();
                    }
                }
                comboBoxASLSec.Select(text.Length, 0);
                AutoSLUpdateGrid();
            };
            comboBoxASLSec.KeyPress += (s, e) =>
            {
                var k = e.KeyChar;
                if (e.KeyChar == 13)
                {
                    if (comboBoxASLSec.Items.Count > 0)
                    {
                        comboBoxASLSec.SelectedItem = comboBoxASLSec.Items[0];
                        AutoSLUpdatePanel();
                        AutoSLUpdateGrid();
                    }
                }
            };
            comboBoxASLSec.SelectedIndexChanged += (s, e) =>
            {
                AutoSLUpdatePanel();
            };

            ASLObject.OnAdd += (condOrder) =>
            {
                AutoSLUpdateGrid();
            };
            ASLObject.OnDelete += (condOrder) =>
            {
                AutoSLUpdateGrid();
            };

            buttonASLDelete.Click += (s, e) =>
            {
                if (dataGridViewASLList.SelectedRows.NotIsNull() && dataGridViewASLList.SelectedRows.Count > 0)
                {
                    foreach (var row in dataGridViewASLList.SelectedRows)
                    {
                        if (row is DataGridViewRow)
                        {
                            var rowEl = (DataGridViewRow)row;
                            if (rowEl.Tag.NotIsNull())
                            {
                                ASLObject.Delete((AutoStopLoss.Item)rowEl.Tag);
                            }
                        }
                    }
                }
                AutoSLUpdateGrid();
            };

            checkBoxASLBySec.CheckedChanged += (s, e) =>
            {
                AutoSLUpdateGrid();
            };

            buttonASLAdd.Click += (s, e) =>
            {
                AddSLControl();
            };

            AutoSLUpdateGrid();
        }
Пример #30
0
        /// <summary>
        /// <see cref = "QuantBook" /> constructor.
        /// Provides access to data for quantitative analysis
        /// </summary>
        public QuantBook() : base()
        {
            try
            {
                using (Py.GIL())
                {
                    _pandas = Py.Import("pandas");
                }

                // By default, set start date to end data which is yesterday
                SetStartDate(EndDate);

                // Sets PandasConverter
                SetPandasConverter();

                // Initialize History Provider
                var composer          = new Composer();
                var algorithmHandlers = LeanEngineAlgorithmHandlers.FromConfiguration(composer);
                var systemHandlers    = LeanEngineSystemHandlers.FromConfiguration(composer);
                // init the API
                systemHandlers.Initialize();
                systemHandlers.LeanManager.Initialize(systemHandlers,
                                                      algorithmHandlers,
                                                      new BacktestNodePacket(),
                                                      new AlgorithmManager(false));
                systemHandlers.LeanManager.SetAlgorithm(this);

                algorithmHandlers.ObjectStore.Initialize("QuantBook",
                                                         Config.GetInt("job-user-id"),
                                                         Config.GetInt("project-id"),
                                                         Config.Get("api-access-token"),
                                                         new Controls
                {
                    // if <= 0 we disable periodic persistence and make it synchronous
                    PersistenceIntervalSeconds = -1
                });
                SetObjectStore(algorithmHandlers.ObjectStore);

                _dataCacheProvider = new ZipDataCacheProvider(algorithmHandlers.DataProvider);

                var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder();
                var registeredTypes          = new RegisteredSecurityDataTypesProvider();
                var securityService          = new SecurityService(Portfolio.CashBook,
                                                                   MarketHoursDatabase,
                                                                   symbolPropertiesDataBase,
                                                                   this,
                                                                   registeredTypes,
                                                                   new SecurityCacheProvider(Portfolio));
                Securities.SetSecurityService(securityService);
                SubscriptionManager.SetDataManager(
                    new DataManager(new NullDataFeed(),
                                    new UniverseSelection(this, securityService),
                                    this,
                                    TimeKeeper,
                                    MarketHoursDatabase,
                                    false,
                                    registeredTypes));

                var mapFileProvider = algorithmHandlers.MapFileProvider;
                HistoryProvider = composer.GetExportedValueByTypeName <IHistoryProvider>(Config.Get("history-provider", "SubscriptionDataReaderHistoryProvider"));
                HistoryProvider.Initialize(
                    new HistoryProviderInitializeParameters(
                        null,
                        null,
                        algorithmHandlers.DataProvider,
                        _dataCacheProvider,
                        mapFileProvider,
                        algorithmHandlers.FactorFileProvider,
                        null,
                        true
                        )
                    );

                SetOptionChainProvider(new CachingOptionChainProvider(new BacktestingOptionChainProvider()));
                SetFutureChainProvider(new CachingFutureChainProvider(new BacktestingFutureChainProvider()));
            }
            catch (Exception exception)
            {
                throw new Exception("QuantBook.Main(): " + exception);
            }
        }
Пример #31
0
 protected override void OnStartExport()
 {
     base.OnStartExport();
     Securities.ForEach(s => _adapter.SendOutMessage(s.ToMessage(GetSecurityId(s))));
     Portfolios.ForEach(p => _adapter.SendOutMessage(p.ToMessage()));
 }
Пример #32
0
        public override void OnData(Slice data)
        {
            // verify expectations
            if (SubscriptionManager.Subscriptions.Count(x => x.Symbol == OptionChainSymbol)
                != (_expectUniverseSubscription ? 1 : 0))
            {
                Log($"SubscriptionManager.Subscriptions:  {string.Join(" -- ", SubscriptionManager.Subscriptions)}");
                throw new Exception($"Unexpected {OptionChainSymbol} subscription presence");
            }
            if (!data.ContainsKey(Underlying))
            {
                // TODO : In fact, we're unable to properly detect whether or not we auto-added or it was manually added
                // this is because when we auto-add the underlying we don't mark it as an internal security like we do with other auto adds
                // so there's currently no good way to remove the underlying equity without invoking RemoveSecurity(underlying) manually
                // from the algorithm, otherwise we may remove it incorrectly. Now, we could track MORE state, but it would likely be a duplication
                // of the internal flag's purpose, so kicking this issue for now with a big fat note here about it :) to be considerd for any future
                // refactorings of how we manage subscription/security data and track various aspects about the security (thinking a flags enum with
                // things like manually added, auto added, internal, and any other boolean state we need to track against a single security)
                throw new Exception("The underlying equity data should NEVER be removed in this algorithm because it was manually added");
            }
            if (_expectedSecurities.AreDifferent(LinqExtensions.ToHashSet(Securities.Keys)))
            {
                var expected = string.Join(Environment.NewLine, _expectedSecurities.OrderBy(s => s.ToString()));
                var actual   = string.Join(Environment.NewLine, Securities.Keys.OrderBy(s => s.ToString()));
                throw new Exception($"{Time}:: Detected differences in expected and actual securities{Environment.NewLine}Expected:{Environment.NewLine}{expected}{Environment.NewLine}Actual:{Environment.NewLine}{actual}");
            }
            if (_expectedUniverses.AreDifferent(LinqExtensions.ToHashSet(UniverseManager.Keys)))
            {
                var expected = string.Join(Environment.NewLine, _expectedUniverses.OrderBy(s => s.ToString()));
                var actual   = string.Join(Environment.NewLine, UniverseManager.Keys.OrderBy(s => s.ToString()));
                throw new Exception($"{Time}:: Detected differences in expected and actual universes{Environment.NewLine}Expected:{Environment.NewLine}{expected}{Environment.NewLine}Actual:{Environment.NewLine}{actual}");
            }
            if (_expectedData.AreDifferent(LinqExtensions.ToHashSet(data.Keys)))
            {
                var expected = string.Join(Environment.NewLine, _expectedData.OrderBy(s => s.ToString()));
                var actual   = string.Join(Environment.NewLine, data.Keys.OrderBy(s => s.ToString()));
                throw new Exception($"{Time}:: Detected differences in expected and actual slice data keys{Environment.NewLine}Expected:{Environment.NewLine}{expected}{Environment.NewLine}Actual:{Environment.NewLine}{actual}");
            }

            // 10AM add GOOG option chain
            if (Time.TimeOfDay.Hours == 10 && Time.TimeOfDay.Minutes == 0)
            {
                if (Securities.ContainsKey(OptionChainSymbol))
                {
                    throw new Exception("The option chain security should not have been added yet");
                }

                var googOptionChain = AddOption(UnderlyingTicker);
                googOptionChain.SetFilter(u =>
                {
                    // find first put above market price
                    return(u.IncludeWeeklys()
                           .Strikes(+1, +1)
                           .Expiration(TimeSpan.Zero, TimeSpan.FromDays(1))
                           .Contracts(c => c.Where(s => s.ID.OptionRight == OptionRight.Put)));
                });

                _expectedSecurities.Add(OptionChainSymbol);
                _expectedUniverses.Add(OptionChainSymbol);
                _expectUniverseSubscription = true;
            }

            // 11:30AM remove GOOG option chain
            if (Time.TimeOfDay.Hours == 11 && Time.TimeOfDay.Minutes == 30)
            {
                RemoveSecurity(OptionChainSymbol);
                // remove contracts from expected data
                _expectedData.RemoveWhere(s => _expectedContracts.Contains(s));
                // remove option chain universe from expected universes
                _expectedUniverses.Remove(OptionChainSymbol);
                // OptionChainSymbol universe subscription should not be present
                _expectUniverseSubscription = false;
            }
        }
Пример #33
0
        /// <summary> Кликеры по таблице стакана </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridViewDepth_Click(object sender, EventArgs e)
        {
            if (Securities.IsNull())
            {
                return;
            }
            var MouseEvent = (MouseEventArgs)e;
            var dataGrid   = (DataGridView)sender;

            dataGrid.ClearSelection();
            var hti      = dataGrid.HitTest(MouseEvent.X, MouseEvent.Y);
            int indexRow = hti.RowIndex;
            int indexCol = hti.ColumnIndex;

            if (indexRow < 0 || indexCol < 0)
            {
                return;
            }

            DataGridViewCell cell = dataGrid.Rows[indexRow].Cells[indexCol];

            if (MouseEvent.Button == MouseButtons.Left)
            {
                if (cell.Tag != null)
                {
                    int Volume = Convert.ToInt32(numericUpDownVolume.Value);
                    if (Volume == 0)
                    {
                        ShowTransReply("Не указан объем!");
                    }
                    if (cell.Tag.GetType().ToString().Contains("StructClickDepth"))
                    {
                        var data = (StructClickDepth)cell.Tag;

                        OrderDirection?direction = null;
                        if (data.Flag == "buy")
                        {
                            direction = OrderDirection.Buy;
                        }
                        if (data.Flag == "sell")
                        {
                            direction = OrderDirection.Sell;
                        }
                        var clientCode = comboBoxCodeClient.SelectedItem.NotIsNull() ? comboBoxCodeClient.SelectedItem.ToString() : "";
                        MThread.InitThread(() =>
                        {
                            Trader.CreateOrder(new Order()
                            {
                                Sec        = Securities,
                                Direction  = direction,
                                Price      = data.Price,
                                Volume     = Volume,
                                ClientCode = clientCode
                            });
                        });
                    }
                }
            }
            if (MouseEvent.Button == MouseButtons.Right)
            {
                if (cell.Tag != null)
                {
                    if (cell.Tag.GetType().ToString().Contains("StructClickDepth"))
                    {
                        var data = (StructClickDepth)cell.Tag;
                        if (data.Flag == "buy" || data.Flag == "sell")
                        {
                            MThread.InitThread(() =>
                            {
                                var ords = Trader.Objects.tOrders.SearchAll(o => o.Sec == Securities && o.Price == data.Price && o.IsActive());
                                if (ords.NotIsNull())
                                {
                                    foreach (var ord in ords)
                                    {
                                        Trader.CancelOrder(ord.Sec, ord.OrderNumber);
                                    }
                                }
                            });
                        }
                    }
                }
            }
        }
Пример #34
0
        /// <summary>
        /// Create a simple JSON holdings from a Security holding class.
        /// </summary>
        /// <param name="holding">Holdings object we'll use to initialize the transport</param>
        public Holding(Securities.SecurityHolding holding)
            : this()
        {
            Symbol = holding.Symbol;
            Type = holding.Type;
            Quantity = holding.Quantity;

            var rounding = 2;
            if (holding.Type == SecurityType.Forex)
            {
                rounding = 5;
                string basec, quotec;
                Forex.DecomposeCurrencyPair(holding.Symbol, out basec, out quotec);
                CurrencySymbol = Forex.CurrencySymbols[quotec];
                ConversionRate = ((ForexHolding) holding).ConversionRate;
            }

            AveragePrice = Math.Round(holding.AveragePrice, rounding);
            MarketPrice = Math.Round(holding.Price, rounding);
        }
Пример #35
0
 /// <summary>
 /// Set header
 /// </summary>
 /// <param name="securities"></param>
 private void SetHead(Securities securities)
 {
     Text = "(" + securities.Code + ":" + securities.Class.Code + ") " + securities.Name;
 }