public void MultipleTransactionsInRange()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id        = Guid.NewGuid();
            var dateRange = new DateRange(new Date(2000, 01, 01), new Date(2002, 12, 31));

            var stockResolver = mockRepository.Create <IStockResolver>();
            var factory       = new PortfolioFactory(stockResolver.Object);
            var portfolio     = factory.CreatePortfolio(id);

            portfolio.MakeCashTransaction(new Date(1999, 01, 01), BankAccountTransactionType.Deposit, 100.00m, "", Guid.NewGuid());
            portfolio.MakeCashTransaction(new Date(2000, 04, 01), BankAccountTransactionType.Withdrawl, 50.00m, "", Guid.NewGuid());
            portfolio.MakeCashTransaction(new Date(2001, 01, 01), BankAccountTransactionType.Deposit, 20.00m, "", Guid.NewGuid());

            var service = new CashAccountService(portfolio);

            var result   = service.GetTransactions(dateRange);
            var response = result.Result;

            using (new AssertionScope())
            {
                response.Should().BeEquivalentTo(new
                {
                    OpeningBalance = 100.00m,
                    ClosingBalance = 70.00m,
                });
                response.Transactions.Should().HaveCount(2);
            }

            mockRepository.VerifyAll();
        }
        public void NoTransactionsInRange()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var id        = Guid.NewGuid();
            var dateRange = new DateRange(new Date(2000, 01, 01), new Date(2000, 12, 31));

            var stockResolver = mockRepository.Create <IStockResolver>();
            var factory       = new PortfolioFactory(stockResolver.Object);
            var portfolio     = factory.CreatePortfolio(id);

            var service = new CashAccountService(portfolio);

            var result   = service.GetTransactions(dateRange);
            var response = result.Result;

            using (new AssertionScope())
            {
                response.Should().BeEquivalentTo(new
                {
                    OpeningBalance = 0.00m,
                    ClosingBalance = 0.00m,
                });
                response.Transactions.Should().BeEmpty();
            }

            mockRepository.VerifyAll();
        }
        public void TryGetFetchesEntryNotInCache()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var stockResolver    = mockRepository.Create <IStockResolver>(MockBehavior.Loose);
            var portfolioFactory = new PortfolioFactory(stockResolver.Object);

            var id        = Guid.NewGuid();
            var portfolio = portfolioFactory.CreatePortfolio(id);

            var repositry = mockRepository.Create <IRepository <Portfolio> >();

            repositry.Setup(x => x.Get(id)).Returns(portfolio).Verifiable();

            var cacheEntry = mockRepository.Create <ICacheEntry>(MockBehavior.Loose);

            cacheEntry.SetupSet(x => x.Value = portfolio).Verifiable();

            var memoryCache = mockRepository.Create <IMemoryCache>();

            memoryCache.Setup(x => x.TryGetValue(id, out It.Ref <object> .IsAny)).Returns(false);
            memoryCache.Setup(x => x.CreateEntry(id)).Returns(cacheEntry.Object).Verifiable();

            var cache = new PortfolioCache(repositry.Object, memoryCache.Object);

            var result = cache.TryGet(id, out var cachedPortfolio);

            result.Should().BeTrue();
            cachedPortfolio.Should().Be(portfolio);

            mockRepository.VerifyAll();
        }
        public void TryGetReturnsEntryInCache()
        {
            var mockRepository = new MockRepository(MockBehavior.Strict);

            var stockResolver    = mockRepository.Create <IStockResolver>(MockBehavior.Loose);
            var portfolioFactory = new PortfolioFactory(stockResolver.Object);

            var id        = Guid.NewGuid();
            var portfolio = portfolioFactory.CreatePortfolio(id);

            var repositry = mockRepository.Create <IRepository <Portfolio> >();

            var    memoryCache     = mockRepository.Create <IMemoryCache>();
            object portfolioObject = portfolio;

            memoryCache.Setup(x => x.TryGetValue(id, out portfolioObject)).Returns(true);

            var cache = new PortfolioCache(repositry.Object, memoryCache.Object);

            var result = cache.TryGet(id, out var cachedPortfolio);

            result.Should().BeTrue();
            cachedPortfolio.Should().Be(portfolio);

            mockRepository.VerifyAll();
        }
        /// <summary>
        /// Calculate the efficient frontier for a given covariance matrix and mean vector
        /// </summary>
        /// <param name="covariance">Covariance Matrix of assets included in portfolio</param>
        /// <param name="mean">Expected return of assets in portfolio</param>
        public IPortfolio Calculate()
        {
            // MVO using quadratic programming
            // Optimal portfolio is:
            //         min(-dvec'bvec+1/2x'Dmat*x) - where ' is the transpose of vector/matrix
            // Dmat - Covariance Matrix - quadratic terms
            // dvec - [0..nAssets] - linear terms
            // Amat - variable weigths in constraints equation
            // bvec - constraint equalities
            // with constraints
            //         A'x >= b
            // meq = eqsumW

            // Get mean returns of all instruments in portfolio
            var meanReturns = from sp in _samplePortfolio
                              select sp.Mean;

            // Get covariance matrix for all instruments in portfolio
            var cov = from sp in _samplePortfolio
                      select new KeyValuePair <string, Dictionary <string, double> >(sp.ID, sp.Covariance);

            var covariance = CovarianceMatrix.Create(cov.ToDictionary(a => a.Key, b => b.Value));
            var portfConf  = new ConfigurationManager(_samplePortfolio);

            OptimizationResult result;

            double[] dvec = new double[_samplePortfolio.Count].Zeros(_samplePortfolio.Count);
            try
            {
                result = QuadProg.Solve(covariance, dvec, portfConf.Amat, portfConf.Bvec, portfConf.NumEquals);
            }
            catch (Exception e)
            {
                // Solution not found - create NaN Portfolio
                result = new OptimizationResult(new double[] { double.NaN }, double.NaN);
                // Log error
                Console.WriteLine(e.Message);
            }

            int    q   = 0;
            double sum = 0;

            foreach (var m in meanReturns)
            {
                sum = sum + m * result.Solution[q];
                q++;
            }

            var portf = PortfolioFactory.Create(_samplePortfolio, _samplePortfolio.Name, sum, result.Value);

            for (int c = 0; c < result.Solution.Length; c++)
            {
                portf[_samplePortfolio[c].ID].Weight = result.Solution[c];
            }

            return(portf);
        }
        public void Build_ReturnsDifferentPortfolio_PerInvokation()
        {
            var factory = new PortfolioFactory();

            var portfolioOne = factory.Build();
            var portfolioTwo = factory.Build();

            Assert.IsNotNull(portfolioOne);
            Assert.IsNotNull(portfolioTwo);
            Assert.AreNotEqual(portfolioOne, portfolioTwo);
        }
        /// <summary>
        /// Calculate the efficient frontier for a given covariance matrix and mean vector
        /// </summary>
        /// <param name="covariance">Covariance Matrix of assets included in portfolio</param>
        /// <param name="mean">Expected return of assets in portfolio</param>
        public IEnumerable <IPortfolio> Calculate(int digits = 4)
        {
            // MVO using quadratic programming
            // Optimal portfolio is:
            //         min(-dvec'bvec+1/2x'Dmat*x) - where ' is the transpose of vector/matrix
            // Dmat - Covariance Matrix - quadratic terms
            // dvec - [0..nAssets] - linear terms
            // Amat - variable weigths in constraints equation
            // bvec - constraint equalities
            // with constraints
            //         A'x >= b
            // meq = eqsumW

            var meanReturns = from sp in _samplePortfolio
                              select sp.Mean;

            var cov = from ins in _samplePortfolio
                      select new KeyValuePair <string, Dictionary <string, double> >(ins.ID, ins.Covariance);

            var covariance = CovarianceMatrix.Create(cov.ToDictionary(a => a.Key, b => b.Value));
            List <IPortfolio> portfolios = new List <IPortfolio>();

            // generate sequence of target returns for the efficient frontier and minimum variance locus
            var targetReturns = new double[_numPortfolios].Seq(meanReturns.Min(), meanReturns.Max(), (int)_numPortfolios, digits);

            double[] dvec = new double[_samplePortfolio.Count].Zeros(_samplePortfolio.Count);
            // For every target return find the minimum variance portfolio
            for (int i = 0; i < _numPortfolios; i++)
            {
                var portfConf = new ConfigurationManager(_samplePortfolio, targetReturns[i]);
                OptimizationResult result;
                try
                {
                    result = QuadProg.Solve(covariance, dvec, portfConf.Amat, portfConf.Bvec, portfConf.NumEquals);
                }
                catch (Exception e)
                {
                    // Solution not found - create NaN Portfolio
                    result = new OptimizationResult(new double[] { double.NaN }, double.NaN);
                    // Log error
                    Console.WriteLine(e.Message);
                }
                var portf = PortfolioFactory.Create(_samplePortfolio, i.ToString(), targetReturns[i], result.Value);
                for (int c = 0; c < result.Solution.Length; c++)
                {
                    portf[_samplePortfolio[c].ID].Weight = result.Solution[c];
                }
                portfolios.Add(portf);
            }

            return(portfolios);
        }
Ejemplo n.º 8
0
        private void AddPortfolios(IEventStore eventStore)
        {
            var repository = new Repository <Stock>(eventStore.GetEventStream <Stock>("Stocks"));

            var stockCache = new EntityCache <Stock>();

            stockCache.PopulateCache(repository);

            var stockResolver = new StockResolver(stockCache);

            var factory   = new PortfolioFactory(stockResolver);
            var portfolio = factory.CreatePortfolio(Ids.PortfolioId);

            portfolio.Create("Test", Ids.UserId);

            portfolio.MakeCashTransaction(new Date(2000, 01, 01), BankAccountTransactionType.Deposit, 50000.00m, "", Guid.NewGuid());
            portfolio.AquireShares(Ids.BHP, new Date(2000, 06, 30), 100, 12.00m, 19.95m, true, "", Guid.NewGuid());

            var eventStream = eventStore.GetEventStream <Portfolio>("Portfolios");

            eventStream.Add(portfolio.Id, "Portfolio", portfolio.FetchEvents());

            _PortfolioAccessor = new TestPortfolioAccessor(portfolio);
        }
        public static Portfolio CreateEmptyPortfolio()
        {
            var arg = new Stock(Stock_ARG.Id);

            arg.List(Stock_ARG.AsxCode, Stock_ARG.Name, new Date(2000, 01, 01), false, AssetCategory.AustralianStocks);
            _StockCache.Add(arg);

            arg.CorporateActions.AddCapitalReturn(ARG_CapitalReturn, new Date(2001, 01, 01), "ARG Capital Return", new Date(2001, 01, 02), 10.00m);

            var argStockPrice = new StockPriceHistory(arg.Id);

            arg.SetPriceHistory(argStockPrice);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 01), 1.00m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 03), 1.01m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 04), 1.00m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 05), 1.03m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 06), 1.02m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 07), 1.01m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 10), 1.05m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 14), 1.07m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 17), 1.08m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 01, 31), 1.09m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 02, 29), 1.10m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 03, 31), 1.07m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 04, 28), 1.07m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 05, 25), 1.03m);
            argStockPrice.UpdateClosingPrice(new Date(2000, 12, 29), 1.04m);
            argStockPrice.UpdateClosingPrice(new Date(2001, 01, 01), 1.05m);
            argStockPrice.UpdateClosingPrice(new Date(2001, 12, 31), 1.01m);
            argStockPrice.UpdateClosingPrice(new Date(2002, 12, 31), 0.99m);
            argStockPrice.UpdateClosingPrice(new Date(2003, 12, 31), 1.29m);
            argStockPrice.UpdateClosingPrice(new Date(2003, 05, 23), 1.40m);
            argStockPrice.UpdateClosingPrice(new Date(2007, 01, 02), 0.90m);
            argStockPrice.UpdateClosingPrice(new Date(2009, 01, 02), 1.70m);
            argStockPrice.UpdateClosingPrice(new Date(2010, 01, 01), 2.00m);

            var wam = new Stock(Stock_WAM.Id);

            wam.List(Stock_WAM.AsxCode, Stock_WAM.Name, new Date(2000, 01, 01), false, AssetCategory.AustralianStocks);
            _StockCache.Add(wam);

            wam.CorporateActions.AddSplitConsolidation(WAM_Split, new Date(2002, 01, 01), "WAM Split", 1, 2);

            var wamStockPrice = new StockPriceHistory(wam.Id);

            wam.SetPriceHistory(wamStockPrice);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 01), 1.20m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 03), 1.21m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 04), 1.20m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 05), 1.23m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 06), 1.22m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 07), 1.21m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 10), 1.25m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 14), 1.24m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 17), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 01, 31), 1.28m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 02, 29), 1.29m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 03, 31), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 04, 28), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 05, 25), 1.23m);
            wamStockPrice.UpdateClosingPrice(new Date(2000, 12, 29), 1.14m);
            wamStockPrice.UpdateClosingPrice(new Date(2001, 01, 01), 1.15m);
            wamStockPrice.UpdateClosingPrice(new Date(2001, 12, 31), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2002, 12, 31), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2003, 12, 31), 1.27m);
            wamStockPrice.UpdateClosingPrice(new Date(2003, 05, 23), 1.40m);
            wamStockPrice.UpdateClosingPrice(new Date(2005, 01, 02), 1.10m);
            wamStockPrice.UpdateClosingPrice(new Date(2007, 01, 02), 0.90m);
            wamStockPrice.UpdateClosingPrice(new Date(2009, 01, 02), 1.30m);
            wamStockPrice.UpdateClosingPrice(new Date(2010, 01, 01), 1.50m);

            var portfolioFactory = new PortfolioFactory(StockResolver);
            var portfolio        = portfolioFactory.CreatePortfolio(Guid.NewGuid());

            portfolio.Create("Test", Guid.NewGuid());

            // Remove Events
            portfolio.FetchEvents();

            return(portfolio);
        }