Пример #1
0
        private void GetHistoryHelper(HistoryRequest request, Resolution resolution)
        {
            var brokerage = new TradierBrokerage(null, null, null, null, _useSandbox, _accountId, _accessToken);
            var requests  = new[] { request };
            var history   = brokerage.GetHistory(requests, TimeZones.Utc);

            foreach (var slice in history)
            {
                if (resolution == Resolution.Tick)
                {
                    foreach (var tick in slice.Ticks[request.Symbol])
                    {
                        Log.Trace("{0}: {1} - {2} / {3}", tick.Time, tick.Symbol, tick.BidPrice, tick.AskPrice);
                    }
                }
                else
                {
                    var bar = slice.Bars[request.Symbol];

                    Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}, V={6}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume);
                }
            }

            Log.Trace("Data points retrieved: " + brokerage.DataPointCount);
        }
Пример #2
0
        public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
        {
            TestDelegate test = () =>
            {
                var useSandbox  = Config.GetBool("tradier-use-sandbox");
                var accountId   = Config.Get("tradier-account-id");
                var accessToken = Config.Get("tradier-access-token");

                var brokerage = new TradierBrokerage(null, null, null, useSandbox, accountId, accessToken);

                var now = DateTime.UtcNow;

                var requests = new[]
                {
                    new HistoryRequest(now.Add(-period),
                                       now,
                                       typeof(QuoteBar),
                                       symbol,
                                       resolution,
                                       SecurityExchangeHours.AlwaysOpen(TimeZones.EasternStandard),
                                       TimeZones.EasternStandard,
                                       Resolution.Minute,
                                       false,
                                       false,
                                       DataNormalizationMode.Adjusted,
                                       TickType.Quote)
                };

                var history = brokerage.GetHistory(requests, TimeZones.Utc);

                foreach (var slice in history)
                {
                    if (resolution == Resolution.Tick)
                    {
                        foreach (var tick in slice.Ticks[symbol])
                        {
                            Log.Trace("{0}: {1} - {2} / {3}", tick.Time, tick.Symbol, tick.BidPrice, tick.AskPrice);
                        }
                    }
                    else
                    {
                        var bar = slice.Bars[symbol];

                        Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}, V={6}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume);
                    }
                }

                Log.Trace("Data points retrieved: " + brokerage.DataPointCount);
            };

            if (throwsException)
            {
                Assert.Throws <ArgumentException>(test);
            }
            else
            {
                Assert.DoesNotThrow(test);
            }
        }
Пример #3
0
        /********************************************************
         * CONSTRUCTOR
         *********************************************************/
        /// <summary>
        /// Constructor for the tradier transaction handler
        /// </summary>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="brokerage">Brokerage instance</param>
        /// <param name="results">Result handler </param>
        /// <param name="accountId">Tradier account id</param>
        public TradierTransactionHandler(IAlgorithm algorithm, IBrokerage brokerage, IResultHandler results, int accountId)
        {
            _algorithm = algorithm;
            _isActive  = true;
            _ready     = false;
            _accountId = accountId;

            //Connect with Tradier:
            _tradier = (TradierBrokerage)brokerage;
            _results = results;
        }
        public void GetsHistory(Symbol symbol, Resolution resolution, TimeSpan period, bool throwsException)
        {
            TestDelegate test = () =>
            {
                var accessToken = Config.Get("tradier-access-token");

                var brokerage = new TradierBrokerage(null, null, "");
                brokerage.SetTokens(0, accessToken, "", DateTime.Now, Time.OneDay);

                var now = DateTime.UtcNow;

                var requests = new[]
                {
                    new HistoryRequest
                    {
                        Symbol       = symbol,
                        Resolution   = resolution,
                        StartTimeUtc = now.Add(-period),
                        EndTimeUtc   = now
                    }
                };

                var history = brokerage.GetHistory(requests, TimeZones.Utc);

                foreach (var slice in history)
                {
                    if (resolution == Resolution.Tick)
                    {
                        foreach (var tick in slice.Ticks[symbol])
                        {
                            Log.Trace("{0}: {1} - {2} / {3}", tick.Time, tick.Symbol, tick.BidPrice, tick.AskPrice);
                        }
                    }
                    else
                    {
                        var bar = slice.Bars[symbol];

                        Log.Trace("{0}: {1} - O={2}, H={3}, L={4}, C={5}, V={6}", bar.Time, bar.Symbol, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume);
                    }
                }

                Log.Trace("Data points retrieved: " + brokerage.DataPointCount);
            };

            if (throwsException)
            {
                Assert.Throws <ArgumentException>(test);
            }
            else
            {
                Assert.DoesNotThrow(test);
            }
        }
Пример #5
0
        /// <summary>
        /// Creates the brokerage under test
        /// </summary>
        /// <returns>A connected brokerage instance</returns>
        protected override IBrokerage CreateBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider)
        {
            var accountID = TradierBrokerageFactory.Configuration.AccountID;
            var tradier   = new TradierBrokerage(orderProvider, securityProvider, accountID);

            var qcUserID = TradierBrokerageFactory.Configuration.QuantConnectUserID;
            var tokens   = TradierBrokerageFactory.GetTokens();

            tradier.SetTokens(qcUserID, tokens.AccessToken, tokens.RefreshToken, tokens.IssuedAt, TimeSpan.FromSeconds(tokens.ExpiresIn));

            // keep the tokens up to date in the event of a refresh
            tradier.SessionRefreshed += (sender, args) =>
            {
                File.WriteAllText(TradierBrokerageFactory.TokensFile, JsonConvert.SerializeObject(args, Formatting.Indented));
            };

            return(tradier);
        }
Пример #6
0
        /********************************************************
         * CLASS CONSTRUCTOR
         *********************************************************/
        /// <summary>
        /// Tradier datafeed handler for getting free data from the tradier brokerage api.
        /// </summary>
        /// <param name="algorithm">Algorithm requesting data</param>
        /// <param name="job">Job packet requesting data</param>
        /// <param name="brokerage">Brokerage instance to avoid access token duplication.</param>
        public TradierDataFeed(IAlgorithm algorithm, IBrokerage brokerage, LiveNodePacket job)
        {
            //Subscription Count:
            _subscriptions     = algorithm.SubscriptionManager.Subscriptions;
            _subscriptionCount = Subscriptions.Count;

            //Set Properties:
            _dataFeed             = DataFeedEndpoint.Tradier;
            _isActive             = true;
            _bridge               = new ConcurrentQueue <List <BaseData> > [_subscriptionCount];
            _endOfBridge          = new bool[_subscriptionCount];
            _subscriptionManagers = new SubscriptionDataReader[_subscriptionCount];

            //Class Privates:
            _job       = job;
            _algorithm = algorithm;

            //Setup the arrays:
            for (var i = 0; i < _subscriptionCount; i++)
            {
                _endOfBridge[i] = false;
                _bridge[i]      = new ConcurrentQueue <List <BaseData> >();

                //This is quantconnect data source, store here for speed/ease of access
                _isQuantConnectData.Add(algorithm.Securities[_subscriptions[i].Symbol].IsQuantConnectData);

                //Subscription managers for downloading user data:
                _subscriptionManagers[i] = new SubscriptionDataReader(_subscriptions[i], algorithm.Securities[_subscriptions[i].Symbol], DataFeedEndpoint.LiveTrading, new DateTime(), new DateTime(9999, 12, 12));

                //Set up the source file for today:
                _subscriptionManagers[i].RefreshSource(DateTime.Now.Date);
            }

            //Setup Brokerage Access:
            _tradier = (TradierBrokerage)brokerage;
        }
Пример #7
0
        /// <summary>
        /// Creates a new IBrokerage instance
        /// </summary>
        /// <param name="job">The job packet to create the brokerage for</param>
        /// <param name="algorithm">The algorithm instance</param>
        /// <returns>A new brokerage instance</returns>
        public override IBrokerage CreateBrokerage(LiveNodePacket job, IAlgorithm algorithm)
        {
            var errors       = new List <string>();
            var accountID    = Read <long>(job.BrokerageData, "tradier-account-id", errors);
            var accessToken  = Read <string>(job.BrokerageData, "tradier-access-token", errors);
            var refreshToken = Read <string>(job.BrokerageData, "tradier-refresh-token", errors);
            var issuedAt     = Read <DateTime>(job.BrokerageData, "tradier-issued-at", errors);
            var lifeSpan     = TimeSpan.FromSeconds(Read <double>(job.BrokerageData, "tradier-lifespan", errors));

            var brokerage = new TradierBrokerage(algorithm.Transactions, algorithm.Portfolio, accountID);

            // if we're running live locally we'll want to save any new tokens generated so that they can easily be retrieved
            if (Config.GetBool("tradier-save-tokens"))
            {
                brokerage.SessionRefreshed += (sender, args) =>
                {
                    File.WriteAllText(TokensFile, JsonConvert.SerializeObject(args, Formatting.Indented));
                };
            }

            brokerage.SetTokens(job.UserId, accessToken, refreshToken, issuedAt, lifeSpan);

            return(brokerage);
        }
Пример #8
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="baseJob">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 baseJob)
        {
            //-> Initialize:
            var initializeComplete = false;
            var job = baseJob as LiveNodePacket;
            var portfolioResolution = PortfolioResolution(algorithm.Securities);

            //-> Connect to Tradier:
            _tradier = new TradierBrokerage();
            //_tradier = (Tradier)brokerage;
            _tradier.SetTokens(job.UserId, job.AccessToken, job.RefreshToken, job.IssuedAt, job.LifeTime);
            brokerage = _tradier;

            // -> Refresh the session immediately, buy us 24 hours:
            if (!_tradier.RefreshSession())
            {
                Errors.Add("Failed to refresh access token. Please login again.");
                return(false);
            }

            //-> Setup any user specific code:
            try
            {
                algorithm.Initialize();
            }
            catch (Exception err)
            {
                Errors.Add("Failed to initialize user algorithm, Initialize() returned error - " + err.Message);
                return(false);
            }

            Log.Trace("TradierSetupHandler.Setup(): Algorithm initialized");

            //-> Strip any FOREX Symbols:
            var symbols = algorithm.Securities.Keys.ToList();

            foreach (var symbol in symbols)
            {
                if (algorithm.Securities[symbol].Type == SecurityType.Forex)
                {
                    algorithm.Securities.Remove(symbol);
                }
            }

            //-> Fetch the orders on the account:
            var orders = _tradier.FetchOrders(job.AccountId);

            foreach (var order in orders)
            {
                //Ignore option orders for now.
                if (order.Class != TradierOrderClass.Equity)
                {
                    continue;
                }

                var qcPrice    = order.Price;
                var qcQuantity = order.Quantity;
                var qcType     = OrderType.Limit;
                var qcStatus   = OrderStatus.None;

                // Get the order type:
                switch (order.Type)
                {
                case TradierOrderType.Market:
                    qcType = OrderType.Market;
                    break;

                case TradierOrderType.Limit:
                    qcType = OrderType.Limit;
                    break;

                case TradierOrderType.StopMarket:
                    qcType = OrderType.StopMarket;
                    break;
                }

                // Convert order direction to a quantity
                switch (order.Direction)
                {
                case TradierOrderDirection.Buy:
                case TradierOrderDirection.BuyToCover:
                    break;

                case TradierOrderDirection.Sell:
                case TradierOrderDirection.SellShort:
                    qcQuantity *= -1;     //Invert quantity.
                    break;
                }

                //Set the QC Order Status Flag:
                switch (order.Status)
                {
                case TradierOrderStatus.Canceled:
                    qcStatus = OrderStatus.Canceled;
                    break;

                case TradierOrderStatus.Filled:
                    qcStatus = OrderStatus.Filled;
                    break;

                case TradierOrderStatus.Open:
                case TradierOrderStatus.Submitted:
                case TradierOrderStatus.Pending:
                    qcStatus = OrderStatus.Submitted;
                    break;

                case TradierOrderStatus.PartiallyFilled:
                    qcStatus = OrderStatus.PartiallyFilled;
                    break;

                case TradierOrderStatus.Rejected:
                    qcStatus = OrderStatus.Invalid;
                    break;
                }

                //Create the new qcOrder
                var qcOrder = new Order(order.Symbol, Convert.ToInt32((decimal)qcQuantity), qcType, order.CreatedDate, qcPrice);
                //Set Status for Order:
                qcOrder.Status = qcStatus;

                //Create any fill information:
                var fill = new OrderEvent(qcOrder, "Pre-existing Tradier Order");
                fill.FillPrice    = order.AverageFillPrice;
                fill.FillQuantity = Convert.ToInt32((decimal)order.QuantityExecuted);
                var fillList = new List <OrderEvent>()
                {
                    fill
                };

                //Get a unique qc-id: set to fill
                var qcid = algorithm.Transactions.GetIncrementOrderId();
                order.Id = qcid; fill.OrderId = qcid; qcOrder.Id = qcid;

                //Add the order to our internal records:
                algorithm.Transactions.Orders.AddOrUpdate <int, Order>(Convert.ToInt32((long)order.Id), qcOrder);

                //Add the fill quantity to the list:
                algorithm.Transactions.OrderEvents.AddOrUpdate <int, List <OrderEvent> >(Convert.ToInt32((long)order.Id), fillList);

                //If we don't have this symbol, add it manually:
                if (!algorithm.Portfolio.ContainsKey(order.Symbol))
                {
                    algorithm.AddSecurity(SecurityType.Equity, order.Symbol, portfolioResolution, true, 1, false);
                }
            }

            //-> Retrieve/Set Tradier Portfolio Positions:
            var positions = _tradier.Positions(job.AccountId);

            foreach (var position in positions)
            {
                //We can't support options.
                if (position.Symbol.Length >= 10)
                {
                    continue;
                }

                //If we don't have this symbol, add it manually:
                if (!algorithm.Portfolio.ContainsKey(position.Symbol))
                {
                    algorithm.AddSecurity(SecurityType.Equity, position.Symbol, portfolioResolution, true, 1, false);
                }
                //Once we have the symbol, set the holdings:
                var avgPrice = Math.Round(position.CostBasis / Convert.ToDecimal((long)position.Quantity), 4);
                algorithm.Portfolio[position.Symbol].SetHoldings(avgPrice, (int)position.Quantity);
                Log.Trace("TradierSetupHandler.Setup(): Portfolio security added to algorithm: " + position.Symbol + " with " + position.Quantity + " shares at " + avgPrice.ToString("C"));
            }


            //-> Retrieve/Set Tradier Cash Positions:
            var balanceFound = false;

            //HACK:
            //balanceFound = true;
            //algorithm.Portfolio.SetCash(100000);
            //_startingCapital = 100000;

            var balance = _tradier.Balance(job.AccountId);

            if (balance != null)
            {
                if (balance.AccountNumber == job.AccountId)
                {
                    //Set the cash in this account:
                    var cash = balance.TotalCash - balance.OptionRequirement;
                    algorithm.Portfolio.SetCash(cash);
                    StartingCapital = cash;
                    balanceFound    = true;
                    Log.Trace("TradierSetupHandler.Setup(): Free Cash: " + cash.ToString("C"));
                    Log.Trace("TradierSetupHandler.Setup(): Total Cash: " + balance.TotalCash.ToString("C"));
                }

                //Set the leverage on all the securities:
                switch (balance.Type)
                {
                //Maximum 1x Leverage
                case TradierAccountType.Cash:
                    foreach (var security in algorithm.Securities.Values)
                    {
                        if (security.Type == SecurityType.Equity)
                        {
                            security.SetLeverage(1m);
                        }
                    }
                    break;

                //Maximum 2x Leverage
                case TradierAccountType.Margin:
                    foreach (var security in algorithm.Securities.Values)
                    {
                        if (security.Type == SecurityType.Equity && security.Leverage > 2)
                        {
                            security.SetLeverage(2m);
                        }
                    }
                    break;

                case TradierAccountType.DayTrader:
                    //Do nothing, let the user set their own leverage:
                    foreach (var security in algorithm.Securities.Values)
                    {
                        if (security.Type == SecurityType.Equity && security.Leverage > 4)
                        {
                            security.SetLeverage(4m);
                        }
                    }
                    break;
                }
            }

            // Maximum number of orders or the algorithm
            MaxOrders = int.MaxValue;

            if (!balanceFound)
            {
                Errors.Add("Could not get the account cash balance");
            }

            if (Errors.Count == 0)
            {
                initializeComplete = true;
            }
            return(initializeComplete);
        }