public static void Initialize(SimplexFundsData data, string[] fundsNames, IStockDataProvider dataProvider) { for (int i = 0; i < fundsNames.Length; i++) { data.Stocks[i] = dataProvider.GetStockDefinition(fundsNames[i]); } }
public SimplexExecutorData(SimplexFundsData fundsData) { ActiveFunds = fundsData.Active.Select((b, i) => (b, i)).Where(x => x.b && (x.i > 0)).Select(x => x.i).ToArray(); //ActiveFunds = fundsData.Active.Select((b, i) => (b, i)).Where(x => x.b).Select(x => x.i).ToArray(); Prices = ActiveFunds.Select(i => fundsData.Prices[i]).ToArray(); AvgChange = ActiveFunds.Select(i => fundsData.AvgChange[i]).ToArray(); AvgChangeSigma = ActiveFunds.Select(i => fundsData.AvgChangeSigma[i]).ToArray(); AvgProfit = ActiveFunds.Select(i => fundsData.AvgProfit[i]).ToArray(); }
private static float[] CalculateBalance(Solution solution, SimplexFundsData fundsData, double portfolioValue, int truncateBalanceToNthPlace) { float[] result = new float[fundsData.Stocks.Length]; foreach (Decision decision in solution.Decisions) { int idx = Int32.Parse(decision.Name.Substring(1)); result[idx] = ((float)(fundsData.Prices[idx] * decision.ToDouble() / portfolioValue)).TruncateToNthPlace(truncateBalanceToNthPlace); } result[0] = 1f - result.Skip(1).Sum(); return(result); }
public SignalsSimplexMultiFunds(ISystemDataLoader dataLoader, IStockDataProvider dataProvider, ISystemExecutionLogger systemExecutionLogger, MOParams systemParams) { _avgProfitRange = systemParams.Get(SimplexMultiFundsParams.AvgProfitRange).As <int>(); _avgChangeRange = systemParams.Get(SimplexMultiFundsParams.AvgChangeRange).As <int>(); _acceptableSingleDD = systemParams.Get(SimplexMultiFundsParams.AcceptableSingleDD).As <double>(); _riskSigmaMultiplier = systemParams.Get(SimplexMultiFundsParams.RiskSigmaMultiplier).As <double>(); _maxSinglePositionSize = systemParams.Get(SimplexMultiFundsParams.MaxSinglePositionSize).As <double>(); _maxPortfolioRisk = systemParams.Get(SimplexMultiFundsParams.MaxPortfolioRisk).As <double>(); _truncateBalanceToNthPlace = systemParams.Get(SimplexMultiFundsParams.TruncateBalanceToNthPlace).As <int>(); _aggressiveFunds = _fundsNames.Select((_, i) => i > 0).ToArray(); if (_fundsNames.Length != _aggressiveFunds.Length) { throw new Exception("_fundsNames != _aggressiveFunds"); } _dataLoader = dataLoader; _systemExecutionLogger = systemExecutionLogger; _dataRange = StockDataRange.Monthly; _fundsData = new SimplexFundsData(_fundsNames.Length); SimplexFundsDataCalculator.Initialize(_fundsData, _fundsNames, dataProvider); }
public static float[] Execute(SimplexFundsData fundsData, double portfolioValue, double acceptableSingleDD, double riskSigmaMultiplier, double maxSinglePositionSize, double maxPortfolioRisk, int truncateBalanceToNthPlace) { SimplexExecutorData data = new SimplexExecutorData(fundsData); if (data.ActiveFunds.Length == 0) { return(new float[fundsData.Stocks.Length]); } double maxSingleDDValue = portfolioValue * acceptableSingleDD; double maxPositionValue = portfolioValue * maxSinglePositionSize; double maxPortfolioAggressiveValue = portfolioValue * maxPortfolioRisk; SolverContext solverContext = new SolverContext(); Model model = solverContext.CreateModel(); model.AddDecisions(data.ActiveFunds.Select(i => new Decision(Domain.RealNonnegative, $"_{i}")).ToArray()); model.AddConstraint("acceptable_single_DD", TermBuilder.SumProducts(model.Decisions, (i) => data.Prices[i] * (data.AvgChange[i] + data.AvgChangeSigma[i] * riskSigmaMultiplier)) <= maxSingleDDValue); model.AddConstraint("max_portfolio_aggressive_value", TermBuilder.SumProducts(model.Decisions, data.Prices) <= maxPortfolioAggressiveValue); model.AddConstraints("max_single_position_size", TermBuilder.BuildTerms(model.Decisions, (decision, i) => data.Prices[i] * decision <= maxPositionValue)); model.AddConstraints("all_positions_positive", TermBuilder.BuildTerms(model.Decisions, (decision, i) => data.AvgProfit[i] * decision >= 0)); model.AddConstraints("nonnegative", TermBuilder.NonNegative(model.Decisions)); model.AddGoal("max_avg_profit", GoalKind.Maximize, TermBuilder.SumProducts(model.Decisions, data.AvgProfit)); return(CalculateBalance(solverContext.Solve(new SimplexDirective()), fundsData, portfolioValue, truncateBalanceToNthPlace)); }
public static void Calculate(SimplexFundsData data, DateTime ts, int profitRange, int changeRange, StockDataRange dataRange, ISystemDataLoader dataLoader) { dataLoader.GetWithIndex(data.Stocks[0].FullName, dataRange, ts, 0, out StockPricesData spData0, out _); DateTime simLastTs = spData0.TS[spData0.TS.Length - 1]; for (int i = 0; i < data.Stocks.Length; i++) { data.Active[i] = dataLoader.GetWithIndex(data.Stocks[i].FullName, dataRange, ts, Math.Max(profitRange, changeRange) + 1, out StockPricesData spData, out int dataIndex); if (!data.Active[i]) { continue; } data.Active[i] = NotLastButOneDataIndex(spData, dataIndex, simLastTs); if (!data.Active[i]) { continue; } data.Prices[i] = spData.C[dataIndex]; data.AvgProfit[i] = AvgChangeInPercent(spData.C, dataIndex, profitRange, null); data.AvgChange[i] = AvgChangeInPercent(spData.C, dataIndex, changeRange, Math.Abs); data.AvgChangeSigma[i] = StdDev(spData.C, dataIndex, changeRange, data.AvgChange[i]); } }
private Signal CreateSignal(float[] newBalance, StockDataRange dataRange, SimplexFundsData fundsData) =>