Overall Statistics
namespace QuantConnect 
{   

    public class Mundo : QCAlgorithm
    {
    	//List of Currencies you would like to trade and get the indexes for 
        List<string> _symbols = new List<string>() { "EURUSD", "GBPUSD", "AUDUSD", "NZDUSD"};
        

        TradeBars _bars = new TradeBars();
        private Dictionary<string, SymbolData> _symbolData = new Dictionary<string, SymbolData>();
        public readonly int RollingWindowSize = 2;
        public readonly TimeSpan BarPeriod = TimeSpan.FromDays(1);
        

        //parameters
        int _normPeriod = 60;
        int _period = 20;

        //Initialize the data and resolution you require for your strategy:
        public override void Initialize()
        {

            //Start and End Date range for the backtest:
            SetStartDate(2007, 4, 1);
           // SetEndDate(2007, 5, 1);
            SetEndDate(DateTime.Now.Date.AddDays(-1));

            //Cash allocation
            SetCash(30000);

            // initialize data for all the symbols
            foreach (var symbol in _symbols)
            {
                _symbolData.Add(symbol, new SymbolData(symbol, SecurityType.Forex, BarPeriod, RollingWindowSize));
            }
			
			//Set forex securities and Consolidate all the data
            foreach (var kvp in _symbolData)
            {

                var symbolData = kvp.Value;
                //AddSecurity(symbolData.SecurityType, symbolData.Symbol, Resolution.Hour);
				AddForex(symbolData.Symbol, Resolution.Hour, "fxcm");
                // define a consolidator to consolidate data for this symbol on the requested period
                var consolidator = new TradeBarConsolidator(BarPeriod);

                // define indicators
                symbolData._sd = new StandardDeviation(_period);
                symbolData._min = new Minimum(_normPeriod);
                symbolData._max = new Maximum(_normPeriod);

                //update indicators
                consolidator.DataConsolidated += (sender, bar) =>
                {
                    // 'bar' here is our newly consolidated data
                    symbolData._min.Update(bar.Time, symbolData._portfolio);
                    symbolData._max.Update(bar.Time, symbolData._portfolio);
                    symbolData._sd.Update(bar.Time, bar.Close);

                    // we're also going to add this bar to our rolling window so we have access to it later
                    symbolData.Bars.Add(bar);
                 
                };

                // we need to add this consolidator so it gets auto updates
                SubscriptionManager.AddConsolidator(symbolData.Symbol, consolidator);

            }

        }

        //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
        public void OnData(TradeBars data)
        {
            UpdateBars(data);
            if (_bars.Count != _symbols.Count) return;
            decimal _totalSd = 0;
            decimal _beta = 0;
            decimal _prt = 0;
			
			// Calculate total SD
            foreach (var _data in _symbolData.Values)
            {
                if (!_data._sd.IsReady) return;
                if (_data._sd != 0)
                {
                    _totalSd += _data._sd;
                    _beta += _data._sd;
                }
            }

            foreach (var _data in _symbolData.Values)
            {

                //make portfolio with Mundo index beta weights
                if (_beta != 0) _prt += _bars[_data.Symbol].Close * _data._sd / (_beta / 4m);
            }

            foreach (var _data in _symbolData.Values)
            {

                _data._portfolio = _prt;
                
                // Do a basic 0-1 Min-Max Normalization to normalize all the values
                if ((_data._max - _data._min) != 0) _data._norm = (_prt - _data._min) / (_data._max - _data._min);
                

                //------------------------------------------------------------------------------------------ EXITS
                if (Portfolio[_data.Symbol].IsLong && _data._norm > 1m)
                {
                    Liquidate();
                }

                if (Portfolio[_data.Symbol].IsShort && _data._norm < 0m)
                {
                    Liquidate();
                }

                //------------------------------------------------------------------------------------------ ENTRIES
                if (!Portfolio[_data.Symbol].Invested && _data._norm > 0 && _data._prenorm < 0)
                {
                    if ((_beta / 4m) != 0 && _data._sd != 0) SetHoldings(_data.Symbol, 0.4m / (_data._sd / (_beta / 4m)));
                }

                if (!Portfolio[_data.Symbol].Invested && _data._norm < 1m && _data._prenorm > 1m)
                {
                    if ((_beta / 4m) != 0 && _data._sd != 0) SetHoldings(_data.Symbol, -0.6m / (_data._sd / (_beta / 4m)));
                }
                
                _data._prenorm = _data._norm; //Keep track of the previous normalized values
            }


        } // end of ondata


        //Update the global "_bars" object
        private void UpdateBars(TradeBars data)
        {
            foreach (var bar in data.Values)
            {
                if (!_bars.ContainsKey(bar.Symbol))
                {
                    _bars.Add(bar.Symbol, bar);
                }
                _bars[bar.Symbol] = bar;
            }
        }
		
		
		//Create a class to manage all the Symbol Data
        class SymbolData
        {
            //stuff
            public readonly string Symbol;
            public readonly SecurityType SecurityType;
            public readonly RollingWindow<TradeBar> Bars;
            public readonly TimeSpan BarPeriod;

            //indcators
            public StandardDeviation _sd;
            public Minimum _min;
            public Maximum _max;
           

            public decimal _portfolio;
            public decimal _norm;
            public decimal _prenorm;


			// Constructor for the class
            public SymbolData(string symbol, SecurityType securityType, TimeSpan barPeriod, int windowSize) 
            {
                Symbol = symbol;
                SecurityType = securityType;
                BarPeriod = barPeriod;
                Bars = new RollingWindow<TradeBar>(windowSize);

                _portfolio = new decimal();
                _norm = new decimal();
                _prenorm = new decimal();
            }

            public bool IsReady
            {
                get
                {
                    return Bars.IsReady
                    && _sd.IsReady
                    && _min.IsReady
                    && _max.IsReady
                    ;
                }
            }

         //   public bool WasJustUpdated(DateTime current)
          //  {
           //     return Bars.Count > 0 && Bars[0].Time == current - BarPeriod;
            //}
        }
    } // end of algorithm

	
}