Overall Statistics
Total Trades
65
Average Win
3.81%
Average Loss
-1.88%
Compounding Annual Return
5.354%
Drawdown
30.900%
Expectancy
0.442
Net Profit
61.395%
Sharpe Ratio
0.468
Loss Rate
52%
Win Rate
48%
Profit-Loss Ratio
2.02
Alpha
0.063
Beta
-0.023
Annual Standard Deviation
0.13
Annual Variance
0.017
Information Ratio
-0.147
Tracking Error
0.251
Treynor Ratio
-2.679
namespace QuantConnect 
{   
    
    //---------------------------------------------------------------------------- ALGO
    public class HV : QCAlgorithm
    {
        
        //primary instrument to trade
        string symbol = "SPY";
        
        //indicators
        StandardDeviation _sd;
        SimpleMovingAverage _sma;
        
        //other
        decimal delta;
        decimal prevClose;
        
        //consolidating
        private TimeSpan _barPeriod = TimeSpan.FromDays(1);
        private Consolidator _consolidator;
        
        //---------------------------------------------------------------------------- INIT
        public override void Initialize()
        {
            //Start and End Date range for the backtest:
            SetStartDate(2006, 1, 1);
            SetEndDate(DateTime.Now);
            
            //Cash allocation
            SetCash(25000);
            
            AddSecurity(SecurityType.Equity, symbol, Resolution.Minute, true, 1, false);
            
            //Setup Consolidator bar bar
            _consolidator = new Consolidator(_barPeriod);
            
            //Custom Data Indicators:
            _sd = new StandardDeviation(30);
            _sma = new SimpleMovingAverage(20);
            
        }

        public void OnData(TradeBars data)
        {
            if (_consolidator.Update(data[symbol]))
            {
                try
                {
                    //log returns
                    if(prevClose != 0)
                    {
                    delta = (decimal)Math.Log((double)data[symbol].Close/(double)prevClose)*100;
                    }
                    
                    //updating custom indies
                    TradeBar bar;
                    if (data.TryGetValue(symbol, out bar))
                    {
                        // pump the daily data into our sma
                        _sd.Update(bar.Time, delta);
                        _sma.Update(bar.Time, _sd);
                    }
                    
                    //Plot indicators
                    Plot("Indicators", "HV", _sd);
                    Plot("Indicators", "HVsma", _sma);
                    
                    //---------------------------------------------------------------------------- ENTRIES
                    if(_sd < _sma)
                    {
                        SetHoldings(symbol, 1);
                    } else
                    if(_sd > _sma)
                    {
                        Liquidate(symbol);
                    }
                 
                 //adding data for future
                 prevClose = data[symbol].Close;
                    
                } catch(Exception err)
                {
                    Debug(err.Message);
                }
                
        
                
            }// end of consolidator
        
        } // end of ondata
        
    }// end of algo
    
}//end of namespace
using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;

namespace QuantConnect 
{
    
    /*
    *   TimeSpanConsolidator Helper Routine: Assemble generic timespan bar lengths: e.g. 10 minutes:
    *
    *   1. Setup the new Consolidator class with the timespan period:
    *   var _consolidator = new Consolidator(TimeSpan.FromMinutes(10));
    *
    *   2. Add in the data with the update routine. It will return true when bar ready
    *   if (_consolidator.Update(data["MSFT"])) {   UseBar    }
    */
    public class Consolidator 
    {
        private TradeBar _resultBar;
        private TradeBar _workingBar;
        private DateTime _start;
        private TimeSpan _period;
        
        //Result:
        public TradeBar Bar
        {
            get
            {
                return _resultBar;
            }
        }
        
        //Constructor: Set the period we'd like to scan
        public Consolidator(TimeSpan span) 
        {
            this._period = span;
            this._resultBar = new TradeBar();
            this._workingBar = new TradeBar(new DateTime(), "", Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
        }
        
        //Submit this bar, return true if we've started a new one.
        public bool Update(TradeBar newBar)
        {
            //Intialize:
            if (_start == new DateTime()) 
            {
                _start = newBar.Time;
            }
            
            //While we're less than end date, keep adding to this bar:
            if (newBar.Time < (_start + _period))
            {
                //Building bar:
                AddToBar(newBar);
                return false;
            } 
            else 
            {
                //Completed bar: start new one:
                _resultBar = _workingBar;
                //Create a new bar:
                _workingBar = new TradeBar(newBar.Time, newBar.Symbol, Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
                //Start of this bar:
                _start = newBar.Time;
                AddToBar(newBar);
                return true;
            }
        }
        
        //Add to a tradebar
        private void AddToBar(TradeBar newBar)
        {
            //Add this data to working bar:
            if (_workingBar.Time == new DateTime()) _workingBar.Time = newBar.Time;
            if (_workingBar.Symbol == "") _workingBar.Symbol = newBar.Symbol;
            if (_workingBar.Open == Decimal.Zero) _workingBar.Open = newBar.Open;
            if (newBar.High > _workingBar.High) _workingBar.High = newBar.High;
            if (newBar.Low < _workingBar.Low) _workingBar.Low = newBar.Low;
            _workingBar.Close = newBar.Close;
            _workingBar.Volume = newBar.Volume;
        }
    }

}