Overall Statistics
Total Trades
1242
Average Win
2.43%
Average Loss
-2.54%
Compounding Annual Return
15.169%
Drawdown
33.700%
Expectancy
0.107
Net Profit
268.257%
Sharpe Ratio
0.53
Loss Rate
43%
Win Rate
57%
Profit-Loss Ratio
0.96
Alpha
0.125
Beta
0.021
Annual Standard Deviation
0.238
Annual Variance
0.057
Information Ratio
0.291
Tracking Error
0.293
Treynor Ratio
5.98
Total Fees
$6064.30
using System;
using System.Collections.Generic;
using System.Linq;

namespace QuantConnect
{
 
    public class TrailingStop 
    {
    	public decimal TrailingStopValue {get;set;}
        decimal TrailingStopPercent{get;set;}
        bool IsLong {get;set;}
        
        public TrailingStop ( decimal stopValue, decimal stopPercent, bool isLongEntry )
        {
        	TrailingStopValue = stopValue;
        	TrailingStopPercent = stopPercent;
        	IsLong = isLongEntry;
        }
        
        public bool IsTrailingExit( TradeBar b, out decimal exitPrice)
        {
            bool rtn = false;
            exitPrice = 0;
            
            if ( IsLong == true)
            {
                if(TrailingStopValue != 0)
                {
                	if (  b.Close / TrailingStopValue < 1-TrailingStopPercent/100)
                	{
                    	exitPrice = b.Close;
                    	rtn = true;
                	}
                }
                
            }
            else
            {
                // short
                if(TrailingStopValue != 0)
                {
                	if ( b.Close / TrailingStopValue > 1+TrailingStopPercent/100 )
                	{
                    	exitPrice = b.Close;
                    	rtn = true;
                	}
                }
            }
            
            // update Trailing stop if needed
            if ( rtn != true)
            {
                if ( IsLong == true && b.Close > TrailingStopValue)
                    TrailingStopValue = b.Close;
                
                if ( IsLong == false && b.Close < TrailingStopValue)
                    TrailingStopValue = b.Close;
            }
            return rtn;
        } // IsTrailingExit
    } // TrailingStop

}                        
namespace QuantConnect 
{   
    public class VAAMACrossFX : QCAlgorithm
    {
        
        string _symbol = "EURUSD";
        TrailingStop _trailStop;
        TrailingStop _trailStopSh;
        List<string> _symbols = new List<string>() { "EURUSD" };
        
        //helping objects
        //private TimeSpan _barPeriod = TimeSpan.FromDays(1);
        //private Consolidator _consolidator;
        TradeBars _bars = new TradeBars();
        
        //windows of data
        RollingWindow<TradeBar> _window = new RollingWindow<TradeBar>(75);
        RollingWindow<TradeBar> _windowH = new RollingWindow<TradeBar>(2000);
        
        RollingWindow<decimal> _mW = new RollingWindow<decimal>(45);
        RollingWindow<decimal> _mHW = new RollingWindow<decimal>(1200);
        
        RollingWindow<decimal> _vamaW = new RollingWindow<decimal>(40);
        RollingWindow<decimal> _residW = new RollingWindow<decimal>(40);
        RollingWindow<decimal> _vamaHW = new RollingWindow<decimal>(1200);
        RollingWindow<decimal> _residHW = new RollingWindow<decimal>(1200);

        //indicators
		SimpleMovingAverage _sma;
		RelativeStrengthIndex _rsi;
		StandardDeviation _sd;
		
        decimal _vamaHour;
        decimal _vamaDaily;
        decimal _prevamaHour;
        decimal _prevamaDaily;
        decimal _m;
        decimal _mL;
        decimal _mHL;
        decimal _residual;
        decimal _residualH;
        decimal _residualSm;
        decimal _residualHSm;
        decimal _prersi;
        
        //parameters
        int _volSmooth = 4;
        decimal _fast = 4;
        decimal _slow = 4;
        
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {
			
            //Start and End Date range for the backtest:
            SetStartDate(2007, 7, 1);
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            
            //Cash allocation
            SetCash(10000);
            
            //benchmark
            SetBenchmark("SPY");
            
            foreach (var symbol in _symbols)
            {
            	//Setup Consolidator bar
            	//_consolidator = new Consolidator(_barPeriod);
            	
            	//Add as many securities as you like. All the data will be passed into the event handler:
            	AddSecurity(SecurityType.Forex, symbol, Resolution.Minute, true, 50, true);
            	//Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.Raw);
            	
            	// define hourly consoldiator
            	var _hourConsolidator = new TradeBarConsolidator(TimeSpan.FromHours(1));
            	
            	_hourConsolidator.DataConsolidated += OnHour;
            	SubscriptionManager.AddConsolidator(symbol, _hourConsolidator);
            	
            	// define daily consoldiator
            	var _dailyConsolidator = new TradeBarConsolidator(TimeSpan.FromDays(1));
            	
            	_dailyConsolidator.DataConsolidated += OnDaily;
            	SubscriptionManager.AddConsolidator(symbol, _dailyConsolidator);
            }
            
            /*_sd = new StandardDeviation(30);
            _min = new Minimum(50);
            _max = new Maximum(50);
            _suml = new Sum(30);
            _sumh = new Sum(30);*/
            
            _sma = new SimpleMovingAverage(400);
            _rsi = RSI(_symbol, 6,  MovingAverageType.Simple, Resolution.Hour);
            _sd = STD(_symbol, 100, Resolution.Hour);
            
            //_slope = new AnnualizedExponentialSlope(180);
            //RegisterIndicator(_symbol, _slope, Resolution.Daily, Field.Close);
        }

        //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) 
        {   
        }
        
        //daily--------------------------------------------------------------------------------------------------------------------------------------------------------
        public void OnDaily(object sender, TradeBar data)
        {
			//UpdateBars(data);
            //if (_bars.Count != _symbols.Count) return;
			//if (!_slope.IsReady) return;
			
			//if(_consolidator.Update(_bars[_symbol]))
            //{
            	//add symbol data to window
            	_window.Add(data);
            	if(!_window.IsReady) return;
            	
            	_m = Math.Max(Math.Max((_window[0].High - _window[1].Close), (_window[0].High - _window[0].Low)), Math.Max((_window[0].Low - _window[1].Close), 0));
            	
            	_mW.Add(_m);
            	if(!_mW.IsReady) return;
            	
            	_mL = LSMA(_mW, _volSmooth);

            	if(_prevamaDaily != 0)
            	{
            		_vamaDaily = _prevamaDaily + _mL*_slow*(_window[0].Close - _prevamaDaily);
            	} else
            	{
            		_vamaDaily = _window[0].Close;
            	}
            	
            	_vamaW.Add(_vamaDaily);
            	if(!_vamaW.IsReady) return;
            	
            	_residual = _window[0].Close - LSMA(_vamaW, 40);
            	
            	_residW.Add(_residual);
            	if(!_residW.IsReady) return;
            	
            	_residualSm = LSMA(_residW, 40);
            	
            	//Log("vamas"+ _vamaSlow+" prev "+_prevamaSlow);
            	
            	//Plot("Indicators", "f", _vamaFast);
            	Plot("Indicators", "s", _vamaDaily);
            	Plot("Indicators", "p", _window[0].Close);

            	//updates
            	_prevamaDaily = _vamaDaily;
            	
            //} //close of daily consolidator

        } // end of on daily
        
        //hourly--------------------------------------------------------------------------------------------------------------------------------------------------------
        public void OnHour(object sender, TradeBar data)
        {
            if(!_rsi.IsReady) return;
            if(!_sd.IsReady) return;
            
            //add symbol data to window
            _windowH.Add(data);
            if(!_windowH.IsReady) return;
            
            decimal _mH = Math.Max(Math.Max((_windowH[0].High - _windowH[1].Close), (_windowH[0].High - _windowH[0].Low)), Math.Max((_windowH[0].Low - _windowH[1].Close), 0));
            	
            _mHW.Add(_m);
            if(!_mHW.IsReady) return;
            	
            _mHL = LSMA(_mW, _volSmooth);

            if(_prevamaHour != 0)
            {
            	_vamaHour = _prevamaHour + _mL*_fast*(_windowH[0].Close - _prevamaHour);
            } else
            {
            	_vamaHour = _windowH[0].Close;
            }
            	
            _vamaHW.Add(_vamaHour);
            if(!_vamaHW.IsReady) return;
            	
            _residualH = _windowH[0].Close - LSMA(_vamaHW, 40);
            
            _residHW.Add(_residualH);
            if(!_residHW.IsReady) return;
            
            _residualHSm = LSMA(_residHW, 40);
            
            //update filter
            TradeBar bar;
            _sma.Update(data.Time, _sd);
            if(!_sma.IsReady) return;

        	//Plot("IndicatorsH", "s", _vamaHour);
            //Plot("IndicatorsH", "p", _window[0].Close);
            //Plot("IndicatorsHRSI", "rsi", _rsi);
            Plot("Cash", "c", Portfolio.Cash);
        	
        	//exits
           	if(_prevamaHour != 0)
           	{
           	decimal exitPrice = data.Close;
           	if(Portfolio[_symbol].Invested)
           	{
           		//SL
	           	if(Securities[_symbol].Holdings.UnrealizedProfit < -Portfolio.TotalPortfolioValue*0.05m)
				{
					Liquidate(_symbol);
				}
					
				//TP
				/*if(Securities[_symbol].Holdings.UnrealizedProfit > -Portfolio.TotalPortfolioValue*0.02m)
				{
					Liquidate(_symbol);
				}*/
					
           		if(Portfolio[_symbol].IsLong)
           		{
           			if(_rsi > 70)
           			{
           				Liquidate(_symbol);
           			}
            		
           			/*if(_trailStop.IsTrailingExit(_bars[_symbol], out exitPrice))
           			{
           				Liquidate(_symbol);
           			}*/
           		}
           		if(Portfolio[_symbol].IsShort)
           		{
           			if(_rsi < 30)
           			{
           				Liquidate(_symbol);
           			}
            		
           			/*if(_trailStop.IsTrailingExit(_bars[_symbol], out exitPrice))
           			{
           				Liquidate(_symbol);
           			}*/
           		}
           	}

			//entries	
			//if(!Portfolio[_symbol].Invested && _vamaHour > _prevamaHour && _vamaW[0] > _vamaW[1] && _residualSm > 0 && _residualHSm > 0 && _rsi > 40 && _prersi < 40&& _sd > 0.005m) //5.6%
			if(!Portfolio[_symbol].Invested && data.Close > _vamaHour && data.Close > _vamaW[0] && _residualSm > 0 && _residualHSm > 0 && _rsi > 40 && _prersi < 40 && _sd > 0.005m) //6.5%
			{
           		SetHoldings(_symbol, 10);
           		//_trailStop = new TrailingStop(data[_symbol].Close, 2, true);
			} else
			if(!Portfolio[_symbol].Invested && data.Close < _vamaHour && data.Close < _vamaW[0] && _residualSm < 0 && _residualHSm < 0 && _rsi < 60 && _prersi > 60 && _sd > 0.005m) //6.5%
			{
           		SetHoldings(_symbol, -10);
           		//_trailStopSh = new TrailingStop(data[_symbol].Close, 2, false);
           	}
           	}
           	
           	//updates
            _prevamaHour = _vamaHour;
            _prersi = _rsi;
            
        } // end of hour conslidator
        
        //calculate LSMA
        private decimal LSMA(RollingWindow<decimal> _dataW, int _lsmaPeriod)
        {
        		decimal _lsma;
        		decimal _delta = 0;
        		
       			//calculate lsma
				_delta = 0;
				for(int i=_lsmaPeriod; i >= 1; i--)
				{
					_delta += (i-(_lsmaPeriod+1)/3.0m)*_dataW[_lsmaPeriod-i];
				}
 
				_lsma = _delta*6/(_lsmaPeriod*(_lsmaPeriod+1));
				return _lsma;
        }
        
        //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;
            }
        }
        
    }

	
}