Example #1
0
 /// <summary>
 /// Clones the provided portfolio
 /// </summary>
 /// <param name="portfolio">Portfolio</param>
 /// <param name="time">Time</param>
 public PointInTimePortfolio(PointInTimePortfolio portfolio, DateTime time)
 {
     Time  = time;
     Order = portfolio.Order;
     TotalPortfolioValue = portfolio.TotalPortfolioValue;
     Holdings            = portfolio.Holdings;
     Leverage            = portfolio.Leverage;
 }
Example #2
0
 /// <summary>
 /// Clones the provided portfolio
 /// </summary>
 /// <param name="portfolio">Portfolio</param>
 /// <param name="time">Time</param>
 public PointInTimePortfolio(PointInTimePortfolio portfolio, DateTime time)
 {
     Time  = time;
     Order = portfolio.Order;
     TotalPortfolioValue = portfolio.TotalPortfolioValue;
     Cash     = portfolio.Cash;
     Holdings = portfolio.Holdings.Select(x => new PointInTimeHolding(x.Symbol, x.HoldingsValue, x.Quantity)).ToList();
     Leverage = portfolio.Leverage;
 }
        /// <summary>
        /// Gets the point in time portfolio over multiple deployments
        /// </summary>
        /// <param name="equityCurve">Equity curve series</param>
        /// <param name="orders">Orders</param>
        /// <returns>Enumerable of <see cref="PointInTimePortfolio"/></returns>
        public static IEnumerable <PointInTimePortfolio> FromOrders(Series <DateTime, double> equityCurve, IEnumerable <Order> orders)
        {
            // Don't do anything if we have no orders or equity curve to process
            if (!orders.Any() || equityCurve.IsEmpty)
            {
                yield break;
            }

            // Chunk different deployments into separate Lists for separate processing
            var portfolioDeployments = new List <List <Order> >();

            // Orders are guaranteed to start counting from 1. This ensures that we have
            // no collision at all with the start of a deployment
            var previousOrderId   = 0;
            var currentDeployment = new List <Order>();

            // Make use of reference semantics to add new deployments to the list
            portfolioDeployments.Add(currentDeployment);

            foreach (var order in orders)
            {
                // In case we have two different deployments with only a single
                // order in the deployments, <= was chosen because it covers duplicate values
                if (order.Id <= previousOrderId)
                {
                    currentDeployment = new List <Order>();
                    portfolioDeployments.Add(currentDeployment);
                }

                currentDeployment.Add(order);
                previousOrderId = order.Id;
            }

            PointInTimePortfolio prev = null;

            foreach (var deploymentOrders in portfolioDeployments)
            {
                // For every deployment, we want to start fresh.
                var looper = new PortfolioLooper(
                    equityCurve.Where(kvp => kvp.Key <= deploymentOrders.First().Time).LastValue(),
                    deploymentOrders
                    );

                foreach (var portfolio in looper.ProcessOrders(deploymentOrders))
                {
                    prev = portfolio;
                    yield return(portfolio);
                }
            }

            if (prev != null)
            {
                yield return(new PointInTimePortfolio(prev, equityCurve.LastKey()));
            }
        }
Example #4
0
        /// <summary>
        /// Gets the point in time portfolio over multiple deployments
        /// </summary>
        /// <param name="equityCurve">Equity curve series</param>
        /// <param name="orders">Orders</param>
        /// <param name="liveSeries">Equity curve series originates from LiveResult</param>
        /// <returns>Enumerable of <see cref="PointInTimePortfolio"/></returns>
        public static IEnumerable <PointInTimePortfolio> FromOrders(Series <DateTime, double> equityCurve, IEnumerable <Order> orders, bool liveSeries = false)
        {
            // Don't do anything if we have no orders or equity curve to process
            if (!orders.Any() || equityCurve.IsEmpty)
            {
                yield break;
            }

            // Chunk different deployments into separate Lists for separate processing
            var portfolioDeployments = new List <List <Order> >();

            // Orders are guaranteed to start counting from 1. This ensures that we have
            // no collision at all with the start of a deployment
            var previousOrderId   = 0;
            var currentDeployment = new List <Order>();

            // Make use of reference semantics to add new deployments to the list
            portfolioDeployments.Add(currentDeployment);

            foreach (var order in orders)
            {
                // In case we have two different deployments with only a single
                // order in the deployments, <= was chosen because it covers duplicate values
                if (order.Id <= previousOrderId)
                {
                    currentDeployment = new List <Order>();
                    portfolioDeployments.Add(currentDeployment);
                }

                currentDeployment.Add(order);
                previousOrderId = order.Id;
            }

            PortfolioLooper      looper = null;
            PointInTimePortfolio prev   = null;

            foreach (var deploymentOrders in portfolioDeployments)
            {
                if (deploymentOrders.Count == 0)
                {
                    Log.Trace($"PortfolioLooper.FromOrders(): Deployment contains no orders");
                    continue;
                }
                var startTime  = deploymentOrders.First().Time;
                var deployment = equityCurve.Where(kvp => kvp.Key <= startTime);
                if (deployment.IsEmpty)
                {
                    Log.Trace($"PortfolioLooper.FromOrders(): Equity series is empty after filtering with upper bound: {startTime}");
                    continue;
                }

                // Skip any deployments that haven't been ran long enough to be generated in live mode
                if (liveSeries && deploymentOrders.First().Time.Date == deploymentOrders.Last().Time.Date)
                {
                    Log.Trace("PortfolioLooper.FromOrders(): Filtering deployment because it has not been deployed for more than one day");
                    continue;
                }

                // For every deployment, we want to start fresh.
                looper = new PortfolioLooper(deployment.LastValue(), deploymentOrders);

                foreach (var portfolio in looper.ProcessOrders(deploymentOrders))
                {
                    prev = portfolio;
                    yield return(portfolio);
                }
            }

            if (prev != null)
            {
                yield return(new PointInTimePortfolio(prev, equityCurve.LastKey()));
            }

            looper.DisposeSafely();
        }