示例#1
0
        public static IActionResult CalculateToBuyStocks(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "calculateToBuyStocks")] AdvisorRequest request)
        {
            var stockPrices   = request.BvbStocks.AsStockPrices();
            var targetWeights = request.BvbStocks.AsStockWeights();

            var existingStocks = request.ExistingStocks.UpdatePrices(stockPrices);

            decimal currentPortfolioValue = existingStocks.Sum(s => s.TotalValue);

            var strategy =
                new MinOrderValueCutOffStrategy(
                    new FollowTargetAdjustmentStrategy(), MIN_ORDER_VALUE / request.ToBuyAmount);

            var portfolio = new PortfolioBuilder()
                            .UseStocks(existingStocks)
                            .UsePrices(stockPrices)
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(request.ToBuyAmount)
                            .UseMinOrderValue(MIN_ORDER_VALUE)
                            .UseWeightAdjustmentStrategy(strategy)
                            .Build();

            return(new OkObjectResult(portfolio.DeriveToBuyStocks(existingStocks)));
        }
        private IPortfolioBuilder PreparePortfolioBuilder(IQuotesDal dal)
        {
            IPortfolioBuilder builder = new PortfolioBuilder();

            // initializing
            IPortfolioBuilderInitParams initParams = builder.CreateInitParams();

            initParams.QuotesDal = dal;
            builder.Init(initParams);

            return(builder);
        }
示例#3
0
        public void BuildPortfolio_AtLeastOneTargetWeightAboveAboveOneHundredPercent_ThrowsArgumentException()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 1.2m }, { "FP", 0.3m }, { "EL", 0.5m }
            };

            var builder = new PortfolioBuilder()
                          .UsePrices(prices)
                          .UseTargetWeights(targetWeights)
                          .UseToBuyAmount(100);

            Assert.Throws <ArgumentException>(() => builder.Build());
        }
示例#4
0
        public void BuildPortfolio_MissingPriceForTargetSymbol_ThrowsArgumentException()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.21m }, { "FP", 0.3m }
            };

            var builder = new PortfolioBuilder()
                          .UsePrices(prices)
                          .UseTargetWeights(targetWeights)
                          .UseToBuyAmount(100);

            Assert.Throws <ArgumentException>(() => builder.Build());
        }
示例#5
0
        public void BuildPortfolio_SumOfTargetWeightApproxEqualWithOneHundredPercent_DoesNotThrow()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.21m }, { "FP", 0.3m }, { "EL", 0.5m }
            };

            var builder = new PortfolioBuilder()
                          .UsePrices(prices)
                          .UseTargetWeights(targetWeights)
                          .UseToBuyAmount(100);

            Assert.DoesNotThrow(() => builder.Build());
        }
示例#6
0
        public void BuildPortfolio_InitialStocks_EnoughAvailableAmount_NewStocksAreAdded()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var stocks = new[]
            {
                new Stock("TLV")
                {
                    Count = 2, Price = 10, Weight = 0.2m
                },                                                                         // should add 2
                new Stock("FP")
                {
                    Count = 1, Price = 20, Weight = 0.2m
                },                                                                        // should add 3
                new Stock("EL")
                {
                    Count = 2, Price = 30, Weight = 0.6m
                }                                                                        // should add 2
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.2m }, { "FP", 0.3m }, { "EL", 0.5m }
            };                                                               // target stock 4 * TLV + 4 * FP + 4 * EL = 240

            var portfolio = new PortfolioBuilder()
                            .UsePrices(prices)
                            .UseStocks(stocks)
                            .UseWeightAdjustmentStrategy(new FollowTargetAdjustmentStrategy())
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(140)
                            .Build();

            Assert.AreEqual(4, portfolio["EL"].Count);
            Assert.AreEqual(4, portfolio["FP"].Count);
            Assert.AreEqual(4, portfolio["TLV"].Count);

            Assert.AreEqual(240, portfolio.TotalValue);
        }
示例#7
0
        public void BuildPortfolio_NotEnoughForAll_PortfolioValueIsCorrect()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.5m }, { "FP", 0.5m }
            };

            var portfolio = new PortfolioBuilder()
                            .UsePrices(prices)
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(20)
                            .Build();

            Assert.AreEqual(10, portfolio.TotalValue);
        }
示例#8
0
        public void BuildPortfolio_NotEnoughForAny_PortfolioValueIsZero()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.5m }, { "FP", 0.5m }
            };

            var portfolio = new PortfolioBuilder()
                            .UsePrices(prices)
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(9)
                            .Build();

            Assert.Zero(portfolio.TotalValue);
        }
示例#9
0
        public void BuildPortfolio_MinOrderValueIsSet_StockTotalValueLessThanMinimal_StockIsNotAddedToPortfolio()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.2m }, { "FP", 0.3m }, { "EL", 0.5m }
            };

            var portfolio = new PortfolioBuilder()
                            .UsePrices(prices)
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(140)
                            .UseMinOrderValue(31)
                            .Build();

            Assert.IsFalse(portfolio.Any(s => s.Symbol == "TLV"));
        }
示例#10
0
        public void PortfolioBuilder_ExpectedDerivedPortfolio()
        {
            var toBuyAmount = 2000m;

            var(currentStocks, bvbStocks, _) = TestResources.ReadStocks();

            var strategy =
                new MinOrderValueCutOffStrategy(
                    new FollowTargetAdjustmentStrategy(), MIN_ORDER_VALUE / toBuyAmount);

            var portfolio = new PortfolioBuilder()
                            .UseStocks(currentStocks)
                            .UsePrices(bvbStocks.AsStockPrices())
                            .UseTargetWeights(bvbStocks.AsStockWeights())
                            .UseToBuyAmount(toBuyAmount)
                            .UseMinOrderValue(MIN_ORDER_VALUE)
                            .UseWeightAdjustmentStrategy(strategy)
                            .Build();

            var toBuyStocks    = portfolio.DeriveToBuyStocks(currentStocks);
            var investedAmount = toBuyStocks.Sum(s => s.Count * s.Price);

            Assert.IsTrue((toBuyAmount / investedAmount).IsApproxOne());
        }
示例#11
0
        public void BuildPortfolio_AlmostEnoughForAll_SmallestEligibleStockIsDecreased()
        {
            var prices = new StockPrices
            {
                { "TLV", 10 }, { "FP", 20 }, { "EL", 30 }
            };

            var targetWeights = new StockWeights
            {
                { "TLV", 0.2m }, { "FP", 0.3m }, { "EL", 0.5m }
            };

            var portfolio = new PortfolioBuilder()
                            .UsePrices(prices)
                            .UseTargetWeights(targetWeights)
                            .UseToBuyAmount(119)
                            .Build();

            Assert.AreEqual(2, portfolio["EL"].Count);
            Assert.AreEqual(2, portfolio["FP"].Count);
            Assert.AreEqual(1, portfolio["TLV"].Count);

            Assert.AreEqual(110, portfolio.TotalValue);
        }
示例#12
0
 public Presenter(IBinanceViewer viewer)
 {
     this.Viewer    = viewer;
     this.Portfolio = PortfolioBuilder.GetSamplePortfolio();
     DisplayBalanceInDifferentCurrencies();
 }