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); }
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()); }
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()); }
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()); }
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); }
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); }
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); }
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")); }
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()); }
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); }
public Presenter(IBinanceViewer viewer) { this.Viewer = viewer; this.Portfolio = PortfolioBuilder.GetSamplePortfolio(); DisplayBalanceInDifferentCurrencies(); }