예제 #1
0
        /// <summary>
        /// Creates the brokerage as specified by the job packet
        /// </summary>
        /// <param name="algorithmNodePacket">Job packet</param>
        /// <param name="uninitializedAlgorithm">The algorithm instance before Initialize has been called</param>
        /// <returns>The brokerage instance, or throws if error creating instance</returns>
        public IBrokerage CreateBrokerage(AlgorithmNodePacket algorithmNodePacket, IAlgorithm uninitializedAlgorithm)
        {
            var liveJob = algorithmNodePacket as LiveNodePacket;

            if (liveJob == null)
            {
                throw new ArgumentException("BrokerageSetupHandler.CreateBrokerage requires a live node packet");
            }

            // find the correct brokerage factory based on the specified brokerage in the live job packet
            _factory = Composer.Instance.Single <IBrokerageFactory>(factory => factory.BrokerageType.MatchesTypeName(liveJob.Brokerage));

            // initialize the correct brokerage using the resolved factory
            var brokerage = _factory.CreateBrokerage(liveJob, uninitializedAlgorithm);

            return(brokerage);
        }
예제 #2
0
        /// <summary>
        /// Primary entry point to setup a new algorithm
        /// </summary>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="brokerage">New brokerage output instance</param>
        /// <param name="job">Algorithm job task</param>
        /// <param name="resultHandler">The configured result handler</param>
        /// <param name="transactionHandler">The configurated transaction handler</param>
        /// <param name="realTimeHandler">The configured real time handler</param>
        /// <returns>True on successfully setting up the algorithm state, or false on error.</returns>
        public bool Setup(IAlgorithm algorithm, out IBrokerage brokerage, AlgorithmNodePacket job, IResultHandler resultHandler, ITransactionHandler transactionHandler, IRealTimeHandler realTimeHandler)
        {
            _algorithm = algorithm;
            brokerage  = default(IBrokerage);

            // verify we were given the correct job packet type
            var liveJob = job as LiveNodePacket;

            if (liveJob == null)
            {
                AddInitializationError("BrokerageSetupHandler requires a LiveNodePacket");
                return(false);
            }

            // verify the brokerage was specified
            if (string.IsNullOrWhiteSpace(liveJob.Brokerage))
            {
                AddInitializationError("A brokerage must be specified");
                return(false);
            }


            // attach to the message event to relay brokerage specific initialization messages
            EventHandler <BrokerageMessageEvent> brokerageOnMessage = (sender, args) =>
            {
                if (args.Type == BrokerageMessageType.Error)
                {
                    AddInitializationError(string.Format("Brokerage Error Code: {0} - {1}", args.Code, args.Message));
                }
            };

            try
            {
                Log.Trace("BrokerageSetupHandler.Setup(): Initializing algorithm...");

                resultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Initializing, "Initializing algorithm...");

                //Execute the initialize code:
                var isolator           = new Isolator();
                var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(300), () =>
                {
                    try
                    {
                        //Set the live trading level asset/ram allocation limits.
                        //Protects algorithm from linux killing the job by excess memory:
                        switch (job.ServerType)
                        {
                        case ServerType.Server1024:
                            algorithm.SetAssetLimits(100, 20, 10);
                            break;

                        case ServerType.Server2048:
                            algorithm.SetAssetLimits(400, 50, 30);
                            break;

                        default:     //512
                            algorithm.SetAssetLimits(50, 25, 15);
                            break;
                        }

                        //Algorithm is live, not backtesting:
                        algorithm.SetLiveMode(true);
                        //Initialize the algorithm's starting date
                        algorithm.SetDateTime(DateTime.UtcNow);
                        //Set the source impl for the event scheduling
                        algorithm.Schedule.SetEventSchedule(realTimeHandler);
                        //Initialise the algorithm, get the required data:
                        algorithm.Initialize();
                    }
                    catch (Exception err)
                    {
                        AddInitializationError(err.Message);
                    }
                });

                if (!initializeComplete)
                {
                    AddInitializationError("Initialization timed out.");
                    return(false);
                }
                try
                {
                    // find the correct brokerage factory based on the specified brokerage in the live job packet
                    _factory = Composer.Instance.Single <IBrokerageFactory>(factory => factory.BrokerageType.MatchesTypeName(liveJob.Brokerage));
                }
                catch (Exception err)
                {
                    Log.Error("BrokerageSetupHandler.Setup(): Error resolving brokerage factory for " + liveJob.Brokerage + ". " + err.Message);
                    AddInitializationError("Unable to locate factory for brokerage: " + liveJob.Brokerage);
                }

                // let the world know what we're doing since logging in can take a minute
                resultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.LoggingIn, "Logging into brokerage...");

                // initialize the correct brokerage using the resolved factory
                brokerage = _factory.CreateBrokerage(liveJob, algorithm);

                if (brokerage == null)
                {
                    AddInitializationError("Failed to create instance of brokerage: " + liveJob.Brokerage);
                    return(false);
                }

                brokerage.Message += brokerageOnMessage;

                // set the transaction and settlement models based on the brokerage properties
                SetupHandler.UpdateModels(algorithm, algorithm.BrokerageModel);
                algorithm.Transactions.SetOrderProcessor(transactionHandler);
                algorithm.PostInitialize();

                Log.Trace("BrokerageSetupHandler.Setup(): Connecting to brokerage...");
                try
                {
                    // this can fail for various reasons, such as already being logged in somewhere else
                    brokerage.Connect();
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError(string.Format("Error connecting to brokerage: {0}. " +
                                                         "This may be caused by incorrect login credentials or an unsupported account type.", err.Message));
                    return(false);
                }

                if (!brokerage.IsConnected)
                {
                    // if we're reporting that we're not connected, bail
                    AddInitializationError("Unable to connect to brokerage.");
                    return(false);
                }

                Log.Trace("BrokerageSetupHandler.Setup(): Fetching cash balance from brokerage...");
                try
                {
                    // set the algorithm's cash balance for each currency
                    var cashBalance = brokerage.GetCashBalance();
                    foreach (var cash in cashBalance)
                    {
                        Log.Trace("BrokerageSetupHandler.Setup(): Setting " + cash.Symbol + " cash to " + cash.Quantity);
                        algorithm.SetCash(cash.Symbol, cash.Quantity, cash.ConversionRate);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting cash balance from brokerage: " + err.Message);
                    return(false);
                }

                Log.Trace("BrokerageSetupHandler.Setup(): Fetching open orders from brokerage...");
                try
                {
                    // populate the algorithm with the account's outstanding orders
                    var openOrders = brokerage.GetOpenOrders();
                    foreach (var order in openOrders)
                    {
                        // be sure to assign order IDs such that we increment from the SecurityTransactionManager to avoid ID collisions
                        Log.Trace("BrokerageSetupHandler.Setup(): Has open order: " + order.Symbol + " - " + order.Quantity);
                        order.Id = algorithm.Transactions.GetIncrementOrderId();
                        transactionHandler.Orders.AddOrUpdate(order.Id, order, (i, o) => order);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting open orders from brokerage: " + err.Message);
                    return(false);
                }

                Log.Trace("BrokerageSetupHandler.Setup(): Fetching holdings from brokerage...");
                try
                {
                    // populate the algorithm with the account's current holdings
                    var holdings = brokerage.GetAccountHoldings();
                    var supportedSecurityTypes = new HashSet <SecurityType> {
                        SecurityType.Equity, SecurityType.Forex
                    };
                    var minResolution = new Lazy <Resolution>(() => algorithm.Securities.Min(x => x.Value.Resolution));
                    foreach (var holding in holdings)
                    {
                        var symbol = new Symbol(holding.Symbol);
                        Log.Trace("BrokerageSetupHandler.Setup(): Has existing holding: " + holding);

                        // verify existing holding security type
                        if (!supportedSecurityTypes.Contains(holding.Type))
                        {
                            Log.Error("BrokerageSetupHandler.Setup(): Unsupported security type: " + holding.Type + "-" + holding.Symbol.ToUpper());
                            AddInitializationError("Found unsupported security type in existing brokerage holdings: " + holding.Type + ". " +
                                                   "QuantConnect currently supports the following security types: " + string.Join(",", supportedSecurityTypes));

                            // keep aggregating these errors
                            continue;
                        }

                        if (!algorithm.Portfolio.ContainsKey(symbol))
                        {
                            Log.Trace("BrokerageSetupHandler.Setup(): Adding unrequested security: " + holding.Symbol);
                            // for items not directly requested set leverage to 1 and at the min resolution
                            algorithm.AddSecurity(holding.Type, symbol, minResolution.Value, null, true, 1.0m, false);
                        }
                        algorithm.Portfolio[symbol].SetHoldings(holding.AveragePrice, (int)holding.Quantity);
                        algorithm.Securities[symbol].SetMarketPrice(new TradeBar
                        {
                            Time     = DateTime.Now,
                            Open     = holding.MarketPrice,
                            High     = holding.MarketPrice,
                            Low      = holding.MarketPrice,
                            Close    = holding.MarketPrice,
                            Volume   = 0,
                            Symbol   = symbol,
                            DataType = MarketDataType.TradeBar
                        });
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting account holdings from brokerage: " + err.Message);
                    return(false);
                }

                Log.Trace("BrokerageSetupHandler.Setup(): Ensuring currency data feeds present...");

                // call this after we've initialized everything from the brokerage since we may have added some holdings/currencies
                algorithm.Portfolio.CashBook.EnsureCurrencyDataFeeds(algorithm.Securities, algorithm.SubscriptionManager, SecurityExchangeHoursProvider.FromDataFolder());

                //Set the starting portfolio value for the strategy to calculate performance:
                StartingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                StartingDate           = DateTime.Now;
            }
            catch (Exception err)
            {
                AddInitializationError(err.Message);
            }
            finally
            {
                if (brokerage != null)
                {
                    brokerage.Message -= brokerageOnMessage;
                }
            }

            return(Errors.Count == 0);
        }
예제 #3
0
        /// <summary>
        /// Creates the brokerage as specified by the job packet
        /// </summary>
        /// <param name="algorithmNodePacket">Job packet</param>
        /// <param name="uninitializedAlgorithm">The algorithm instance before Initialize has been called</param>
        /// <returns>The brokerage instance, or throws if error creating instance</returns>
        public IBrokerage CreateBrokerage(AlgorithmNodePacket algorithmNodePacket, IAlgorithm uninitializedAlgorithm)
        {
            var liveJob = algorithmNodePacket as LiveNodePacket;
            if (liveJob == null)
            {
                throw new ArgumentException("BrokerageSetupHandler.CreateBrokerage requires a live node packet");
            }

            // find the correct brokerage factory based on the specified brokerage in the live job packet
            _factory = Composer.Instance.Single<IBrokerageFactory>(factory => factory.BrokerageType.MatchesTypeName(liveJob.Brokerage));

            // initialize the correct brokerage using the resolved factory
            var brokerage = _factory.CreateBrokerage(liveJob, uninitializedAlgorithm);

            return brokerage;
        }
예제 #4
0
        /// <summary>
        /// Primary entry point to setup a new algorithm
        /// </summary>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="brokerage">New brokerage output instance</param>
        /// <param name="job">Algorithm job task</param>
        /// <param name="resultHandler">The configured result handler</param>
        /// <param name="transactionHandler">The configurated transaction handler</param>
        /// <param name="realTimeHandler">The configured real time handler</param>
        /// <returns>True on successfully setting up the algorithm state, or false on error.</returns>
        public bool Setup(IAlgorithm algorithm, out IBrokerage brokerage, AlgorithmNodePacket job, IResultHandler resultHandler, ITransactionHandler transactionHandler, IRealTimeHandler realTimeHandler)
        {
            _algorithm = algorithm;
            brokerage = default(IBrokerage);

            // verify we were given the correct job packet type
            var liveJob = job as LiveNodePacket;
            if (liveJob == null)
            {
                AddInitializationError("BrokerageSetupHandler requires a LiveNodePacket");
                return false;
            }

            // verify the brokerage was specified
            if (string.IsNullOrWhiteSpace(liveJob.Brokerage))
            {
                AddInitializationError("A brokerage must be specified");
                return false;
            }

            // attach to the message event to relay brokerage specific initialization messages
            EventHandler<BrokerageMessageEvent> brokerageOnMessage = (sender, args) =>
            {
                if (args.Type == BrokerageMessageType.Error)
                {
                    AddInitializationError(string.Format("Brokerage Error Code: {0} - {1}", args.Code, args.Message));
                }
            };

            try
            {
                Log.Trace("BrokerageSetupHandler.Setup(): Initializing algorithm...");

                //Execute the initialize code:
                var isolator = new Isolator();
                var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(10), () =>
                {
                    try
                    {
                        //Set the live trading level asset/ram allocation limits.
                        //Protects algorithm from linux killing the job by excess memory:
                        switch (job.ServerType)
                        {
                            case ServerType.Server1024:
                                algorithm.SetAssetLimits(100, 20, 10);
                                break;

                            case ServerType.Server2048:
                                algorithm.SetAssetLimits(400, 50, 30);
                                break;

                            default: //512
                                algorithm.SetAssetLimits(50, 25, 15);
                                break;
                        }

                        //Algorithm is live, not backtesting:
                        algorithm.SetLiveMode(true);
                        //Initialize the algorithm's starting date
                        algorithm.SetDateTime(DateTime.UtcNow);
                        //Set the source impl for the event scheduling
                        algorithm.Schedule.SetEventSchedule(realTimeHandler);
                        //Initialise the algorithm, get the required data:
                        algorithm.Initialize();
                    }
                    catch (Exception err)
                    {
                        AddInitializationError(err.Message);
                    }
                });

                if (!initializeComplete)
                {
                    AddInitializationError("Initialization timed out.");
                    return false;
                }
                try
                {
                    // find the correct brokerage factory based on the specified brokerage in the live job packet
                    _factory = Composer.Instance.Single<IBrokerageFactory>(factory => factory.BrokerageType.MatchesTypeName(liveJob.Brokerage));
                }
                catch (Exception err)
                {
                    Log.Error("BrokerageSetupHandler.Setup(): Error resolving brokerage factory for " + liveJob.Brokerage + ". " + err.Message);
                    AddInitializationError("Unable to locate factory for brokerage: " + liveJob.Brokerage);
                }

                // let the world know what we're doing since logging in can take a minute
                resultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.LoggingIn, "Logging into brokerage...");

                // initialize the correct brokerage using the resolved factory
                brokerage = _factory.CreateBrokerage(liveJob, algorithm);

                if (brokerage == null)
                {
                    AddInitializationError("Failed to create instance of brokerage: " + liveJob.Brokerage);
                    return false;
                }

                brokerage.Message += brokerageOnMessage;

                // set the transaction models base on the brokerage properties
                SetupHandler.UpdateTransactionModels(algorithm, algorithm.BrokerageModel);
                algorithm.Transactions.SetOrderProcessor(transactionHandler);
                algorithm.PostInitialize();

                try
                {
                    // this can fail for various reasons, such as already being logged in somewhere else
                    brokerage.Connect();
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error connecting to brokerage: " + err.Message);
                    return false;
                }

                if (!brokerage.IsConnected)
                {
                    // if we're reporting that we're not connected, bail
                    AddInitializationError("Unable to connect to brokerage.");
                    return false;
                }

                try
                {
                    // set the algorithm's cash balance for each currency
                    var cashBalance = brokerage.GetCashBalance();
                    foreach (var cash in cashBalance)
                    {
                        Log.Trace("BrokerageSetupHandler.Setup(): Setting " + cash.Symbol + " cash to " + cash.Quantity);
                        algorithm.SetCash(cash.Symbol, cash.Quantity, cash.ConversionRate);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting cash balance from brokerage: " + err.Message);
                    return false;
                }

                try
                {
                    // populate the algorithm with the account's outstanding orders
                    var openOrders = brokerage.GetOpenOrders();
                    foreach (var order in openOrders)
                    {
                        // be sure to assign order IDs such that we increment from the SecurityTransactionManager to avoid ID collisions
                        Log.Trace("BrokerageSetupHandler.Setup(): Has open order: " + order.Symbol + " - " + order.Quantity);
                        order.Id = algorithm.Transactions.GetIncrementOrderId();
                        transactionHandler.Orders.AddOrUpdate(order.Id, order, (i, o) => order);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting open orders from brokerage: " + err.Message);
                    return false;
                }

                try
                {
                    // populate the algorithm with the account's current holdings
                    var holdings = brokerage.GetAccountHoldings();
                    var minResolution = new Lazy<Resolution>(() => algorithm.Securities.Min(x => x.Value.Resolution));
                    foreach (var holding in holdings)
                    {
                        Log.Trace("BrokerageSetupHandler.Setup(): Has existing holding: " + holding);
                        if (!algorithm.Portfolio.ContainsKey(holding.Symbol))
                        {
                            Log.Trace("BrokerageSetupHandler.Setup(): Adding unrequested security: " + holding.Symbol);
                            // for items not directly requested set leverage to 1 and at the min resolution
                            algorithm.AddSecurity(holding.Type, holding.Symbol, minResolution.Value, null, true, 1.0m, false);
                        }
                        algorithm.Portfolio[holding.Symbol].SetHoldings(holding.AveragePrice, (int) holding.Quantity);
                        algorithm.Securities[holding.Symbol].SetMarketPrice(new TradeBar
                        {
                            Time = DateTime.Now,
                            Open = holding.MarketPrice,
                            High = holding.MarketPrice,
                            Low = holding.MarketPrice,
                            Close = holding.MarketPrice,
                            Volume = 0,
                            Symbol = holding.Symbol,
                            DataType = MarketDataType.TradeBar
                        });
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting account holdings from brokerage: " + err.Message);
                    return false;
                }

                // call this after we've initialized everything from the brokerage since we may have added some holdings/currencies
                algorithm.Portfolio.CashBook.EnsureCurrencyDataFeeds(algorithm.Securities, algorithm.SubscriptionManager, SecurityExchangeHoursProvider.FromDataFolder());

                //Set the starting portfolio value for the strategy to calculate performance:
                StartingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                StartingDate = DateTime.Now;
            }
            catch (Exception err)
            {
                AddInitializationError(err.Message);
            }
            finally
            {
                if (brokerage != null)
                {
                    brokerage.Message -= brokerageOnMessage;
                }
            }

            return Errors.Count == 0;
        }
예제 #5
0
        /// <summary>
        /// Primary entry point to setup a new algorithm
        /// </summary>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="brokerage">New brokerage output instance</param>
        /// <param name="job">Algorithm job task</param>
        /// <returns>True on successfully setting up the algorithm state, or false on error.</returns>
        public bool Setup(IAlgorithm algorithm, out IBrokerage brokerage, AlgorithmNodePacket job)
        {
            _algorithm = algorithm;
            brokerage  = default(IBrokerage);

            // verify we were given the correct job packet type
            var liveJob = job as LiveNodePacket;

            if (liveJob == null)
            {
                AddInitializationError("BrokerageSetupHandler requires a LiveNodePacket");
                return(false);
            }

            // verify the brokerage was specified
            if (string.IsNullOrWhiteSpace(liveJob.Brokerage))
            {
                AddInitializationError("A brokerage must be specified");
                return(false);
            }

            try
            {
                Log.Trace("BrokerageSetupHandler.Setup(): Initializing algorithm...");

                //Execute the initialize code:
                var initializeComplete = Isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(10), () =>
                {
                    try
                    {
                        //Set the live trading level asset/ram allocation limits.
                        //Protects algorithm from linux killing the job by excess memory:
                        switch (job.ServerType)
                        {
                        case ServerType.Server1024:
                            algorithm.SetAssetLimits(100, 20, 10);
                            break;

                        case ServerType.Server2048:
                            algorithm.SetAssetLimits(400, 50, 30);
                            break;

                        default:     //512
                            algorithm.SetAssetLimits(50, 25, 15);
                            break;
                        }

                        //Algorithm is live, not backtesting:
                        algorithm.SetLiveMode(true);

                        //Initialise the algorithm, get the required data:
                        algorithm.Initialize();
                    }
                    catch (Exception err)
                    {
                        AddInitializationError(err.Message);
                    }
                });

                if (!initializeComplete)
                {
                    AddInitializationError("Initialization timed out.");
                    return(false);
                }
                try
                {
                    // find the correct brokerage factory based on the specified brokerage in the live job packet
                    _factory = Composer.Instance.Single <IBrokerageFactory>(factory => factory.BrokerageType.MatchesTypeName(liveJob.Brokerage));
                }
                catch (Exception err)
                {
                    Log.Error("BrokerageSetupHandler.Setup(): Error resolving brokerage factory for " + liveJob.Brokerage + ". " + err.Message);
                    AddInitializationError("Unable to locate factory for brokerage: " + liveJob.Brokerage);
                }

                // let the world know what we're doing since logging in can take a minute
                Engine.ResultHandler.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.LoggingIn, "Logging into brokerage...");

                // initialize the correct brokerage using the resolved factory
                brokerage = _factory.CreateBrokerage(liveJob, algorithm);

                // set the transaction models base on the brokerage properties
                SetupHandler.UpdateTransactionModels(algorithm, algorithm.BrokerageModel);

                try
                {
                    // this can fail for various reasons, such as already being logged in somewhere else
                    brokerage.Connect();
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error connecting to brokerage.");
                    return(false);
                }

                try
                {
                    // set the algorithm's cash balance for each currency
                    var cashBalance = brokerage.GetCashBalance();
                    foreach (var cash in cashBalance)
                    {
                        Log.Trace("BrokerageSetupHandler.Setup(): Setting " + cash.Symbol + " cash to " + cash.Quantity);
                        algorithm.SetCash(cash.Symbol, cash.Quantity, cash.ConversionRate);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting cash balance from brokerage.");
                    return(false);
                }

                try
                {
                    // populate the algorithm with the account's outstanding orders
                    var openOrders = brokerage.GetOpenOrders();
                    foreach (var order in openOrders)
                    {
                        // be sure to assign order IDs such that we increment from the SecurityTransactionManager to avoid ID collisions
                        Log.Trace("BrokerageSetupHandler.Setup(): Has open order: " + order.Symbol + " - " + order.Quantity);
                        order.Id = algorithm.Transactions.GetIncrementOrderId();
                        algorithm.Orders.AddOrUpdate(order.Id, order, (i, o) => order);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting open orders from brokerage.");
                    return(false);
                }

                try
                {
                    // populate the algorithm with the account's current holdings
                    var holdings      = brokerage.GetAccountHoldings();
                    var minResolution = new Lazy <Resolution>(() => algorithm.Securities.Min(x => x.Value.Resolution));
                    foreach (var holding in holdings)
                    {
                        Log.Trace("BrokerageSetupHandler.Setup(): Has existing holding: " + holding);
                        if (!algorithm.Portfolio.ContainsKey(holding.Symbol))
                        {
                            Log.Trace("BrokerageSetupHandler.Setup(): Adding unrequested security: " + holding.Symbol);
                            // for items not directly requested set leverage to 1 and at the min resolution
                            algorithm.AddSecurity(holding.Type, holding.Symbol, minResolution.Value, true, 1.0m, false);
                        }
                        algorithm.Portfolio[holding.Symbol].SetHoldings(holding.AveragePrice, (int)holding.Quantity);
                        algorithm.Securities[holding.Symbol].SetMarketPrice(DateTime.Now, new TradeBar
                        {
                            Time     = DateTime.Now,
                            Open     = holding.MarketPrice,
                            High     = holding.MarketPrice,
                            Low      = holding.MarketPrice,
                            Close    = holding.MarketPrice,
                            Volume   = 0,
                            Symbol   = holding.Symbol,
                            DataType = MarketDataType.TradeBar
                        });
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    AddInitializationError("Error getting account holdings from brokerage.");
                    return(false);
                }

                // call this after we've initialized everything from the brokerage since we may have added some holdings/currencies
                algorithm.Portfolio.CashBook.EnsureCurrencyDataFeeds(algorithm.Securities, algorithm.SubscriptionManager);

                //Set the starting portfolio value for the strategy to calculate performance:
                StartingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                StartingDate           = DateTime.Now;
            }
            catch (Exception err)
            {
                AddInitializationError(err.Message);
            }

            return(Errors.Count == 0);
        }