public SignalsBBTrendFunds(ISystemDataLoader dataLoader, IStockDataProvider dataProvider, ISystemExecutionLogger systemExecutionLogger)
 {
     _dataLoader            = dataLoader;
     _systemExecutionLogger = systemExecutionLogger;
     _dataRange             = StockDataRange.Monthly;
     _fundsData             = new BBTrendFundsData(_fundsNames.Length);
     BBTrendFundsDataCalculator.Initialize(_fundsData, _fundsNames, BBPeriod, BBSigmaWidth, HLPeriod, dataProvider);
     _rebalanceSignal = new ModNCounter(RebalanceInterval);
 }
        //private readonly ModNCounter _rebalanceSignal;

        public SignalsBBTrendMultiFunds(ISystemDataLoader dataLoader, IStockDataProvider dataProvider, ISystemExecutionLogger systemExecutionLogger)
        {
            _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 BBTrendFundsData(_fundsNames.Length);
            BBTrendFundsDataCalculator.Initialize(_fundsData, _fundsNames, BBPeriod, BBSigmaWidth, HLPeriod, dataProvider);
            //_rebalanceSignal = new ModNCounter(RebalanceInterval);
        }
        public List <Signal> GenerateOnClose(DateTime ts, int leadingIndex, SystemState systemState)
        {
            List <Signal> result = new List <Signal>();

            BBTrendFundsDataCalculator.CalculateTrendsAndExpectations(_fundsData, ts, _dataRange, _dataLoader);
            ResetRebalanceCountersIfNeeded();
            //if (ExecuteRebalance())
            {
                var balance = CalculateBalance();
                result.Add(BBTrendFundsSignalFactory.CreateSignal(balance, _dataRange, _fundsData));
                LogData(ts, balance);
            }
            IncrementRebalanceCounters();

            return(result);
        }
        public List <Signal> GenerateOnClose(DateTime ts, int leadingIndex, SystemState systemState)
        {
            List <Signal> result = new List <Signal>();

            BBTrendFundsDataCalculator.CheckStops(_fundsData, ts, _dataRange, _dataLoader);
            BBTrendFundsDataCalculator.CalculateTrendsAndExpectations(_fundsData, ts, _dataRange, _dataLoader);
            BBTrendFundsDataCalculator.CalculateMaxValuesAndStops(_fundsData, AggressiveStopWidth, ts, _dataRange, _dataLoader);

            //var sortedFunds = OrderStocksByProfit(ts, ProfitBackDataLength);
            var sortedFunds = OrderStocksByUpTrendProfit(ts);

            //ResetRebalanceCountersIfNeeded();
            //if (ExecuteRebalance())
            float[] balance = CalculateBalance(sortedFunds, NumberOfAggressiveFundsTaken);
            result.Add(BBTrendFundsSignalFactory.CreateSignal(balance, _dataRange, _fundsData));
            //IncrementRebalanceCounters();

            LogData(ts, sortedFunds, balance);
            return(result);
        }