Overall Statistics
Total Trades
990
Average Win
0.23%
Average Loss
-0.22%
Compounding Annual Return
-1.616%
Drawdown
5.300%
Expectancy
-0.014
Net Profit
-1.619%
Sharpe Ratio
-0.18
Loss Rate
52%
Win Rate
48%
Profit-Loss Ratio
1.04
Alpha
-0.01
Beta
-0.024
Annual Standard Deviation
0.054
Annual Variance
0.003
Information Ratio
-0.089
Tracking Error
0.145
Treynor Ratio
0.404
Total Fees
$0.00
namespace QuantConnect 
{  
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        //Configure which securities you'd like to use:
        public string[] Symbols = { "EURUSD", "GBPUSD" } ;
        
        //Risk in dollars per trade ($ or the quote currency of the assets)
        public decimal RiskPerTrade = 10;
        
        //Roughly how long does our "alpha" take to run
        public TimeSpan AverageInvestmentPeriod = TimeSpan.FromHours(6.5);
        
        //Cap the investment maximum size ($).
		public decimal MaximumTradeSize = 10000;
		
        private  Resolution _dataResolution = Resolution.Minute;
        private Dictionary<Symbol, TradeProfile> _trades;
        private Slice _data;
        private Random random = new Random(131);
     
        public override void Initialize()
        {
            SetStartDate(2015, 1, 1);
            SetEndDate(2016, 01, 01);
            SetCash(2500);
            
            //Hold a trade profile per asset we're trading.
           	_trades = new Dictionary<Symbol, TradeProfile>();
            
            //Add as many securities as you like. All the data will be passed into the event handler:
            foreach (var symbol in Symbols)
            {
                AddSecurity(SecurityType.Forex, symbol, _dataResolution);
                
                //Roughly 4c per 1000 traded, roughly 8c fees per trade.
                Securities[symbol].FeeModel = new ConstantFeeModel(0.0m);
                
                //Set our volatility model: the expected price movement for the day is 3 sigma of the standard deviation
                Securities[symbol].VolatilityModel = new ThreeSigmaVolatilityModel(_dataResolution.ToTimeSpan(), (int)AverageInvestmentPeriod.TotalMinutes);
                
                //Initialize the default
                _trades.Add(symbol, new TradeProfile(Securities[symbol].VolatilityModel.Volatility, RiskPerTrade, 1m, MaximumTradeSize));
            }
            
            //Might but bug with the FXCM model? Fees way higher than normal?
           	// SetBrokerageModel(BrokerageName.FxcmBrokerage);
            var dates = new [] {DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday};


			// SUPER SECRET ALHA INDICATOR!!!!! Trade every day at 930, exit at 4pm :D
            Schedule.On(DateRules.Every(dates), TimeRules.At(09, 30), () =>
            {
                foreach (var symbol in Symbols)
                {
                	// ENTER THE MARKET RANDOM DIRECTION...!
                    if (Securities[symbol].VolatilityModel.Volatility == 0) continue;
                    _trades[symbol] = Enter(symbol, RandomOrderDirection());
                }
            });

            Schedule.On(DateRules.Every(dates), TimeRules.At(16, 00), () =>
            {
                foreach (var symbol in Symbols)
                {
                	// If the stoploss hasn't triggered, quit
                    if (!Portfolio[symbol].Invested) continue;
                    Exit(_trades[symbol]);
                }
            });
        }

		/// <summary>
        /// Generate a random order direction for the "super secret alpha signal"
        /// </summary>
        private OrderDirection RandomOrderDirection()
        {
            if(random.NextDouble() > 0.5) return OrderDirection.Buy;
            return OrderDirection.Sell;
        }

        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        public override void OnData(Slice data)
        {
            _data = data;
        }

		/// <summary>
        /// Enter the market, for a given direction, and symbol: add a stop loss to the trade we make.
        /// </summary>
        public TradeProfile Enter(string symbol, OrderDirection orderDirection)
        {
            var price = _data[symbol].Close;
            var trade = new TradeProfile(Securities[symbol].VolatilityModel.Volatility, RiskPerTrade, price, MaximumTradeSize);
            var direction = (orderDirection == OrderDirection.Buy) ? 1 : -1;

            trade.OpenTicket = MarketOrder(symbol, direction*trade.Quantity);
            
			// Attach a stop loss at the average fill price - stopPrice.
            var stopPrice = trade.OpenTicket.AverageFillPrice - (direction*trade.DeltaStopLoss);
            trade.StopTicket = StopMarketOrder(symbol, -direction * trade.Quantity, stopPrice);      
            
            return trade;
        }

		/// <summary>
        /// Exit the market for a given trade profile
        /// </summary>
        public void Exit(TradeProfile trade)
        {
            Liquidate(trade.OpenTicket.Symbol);
            if (trade.StopTicket != null && trade.StopTicket.Status != OrderStatus.Filled)
            {
            	//If we haven't hit the stop loss then kill it.
                trade.StopTicket.Cancel();
            }
        }
    }
}                        
using System;
using MathNet.Numerics.Statistics;
using QuantConnect.Data;
using QuantConnect.Indicators;

namespace QuantConnect {

	
	public class ThreeSigmaVolatilityModel : IVolatilityModel {
		
	
        private bool _needsUpdate;
        private decimal _volatility;
        private DateTime _lastUpdate;
        private readonly TimeSpan _periodSpan;
        private readonly object _sync = new object();
        private readonly RollingWindow<double> _window;

        /// <summary>
        /// Gets the volatility of the security as a percentage
        /// </summary>
        public decimal Volatility
        {
            get
            {
                lock (_sync)
                {
                    if (_window.Count < 2)
                    {
                        return 0m;
                    }

                    if (_needsUpdate)
                    {
                        _needsUpdate = false;
                            // volatility here is supposed to be a percentage
                            var std = _window.StandardDeviation().SafeDecimalCast();
                            _volatility = std*3;
                    }
                }
                return _volatility;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="QuantConnect.Securities.RelativeStandardDeviationVolatilityModel"/> class
        /// </summary>
        /// <param name="periodSpan">The time span representing one 'period' length</param>
        /// <param name="periods">The nuber of 'period' lengths to wait until updating the value</param>
        public ThreeSigmaVolatilityModel(TimeSpan periodSpan, int periods)
        {
            if (periods < 2) throw new ArgumentOutOfRangeException("periods", "'periods' must be greater than or equal to 2.");
            _periodSpan = periodSpan;
            _window = new RollingWindow<double>(periods);
            _lastUpdate = DateTime.MinValue + TimeSpan.FromMilliseconds(periodSpan.TotalMilliseconds * periods);
        }

        /// <summary>
        /// Updates this model using the new price information in
        /// the specified security instance
        /// </summary>
        /// <param name="security">The security to calculate volatility for</param>
        /// <param name="data"></param>
        public void Update(Security security, BaseData data)
        {
            var timeSinceLastUpdate = data.EndTime - _lastUpdate;
            if (timeSinceLastUpdate >= _periodSpan)
            {
                lock (_sync)
                {
                    _needsUpdate = true;
                    // we purposefully use security.Price for consistency in our reporting
                    // some streams of data will have trade/quote data, so if we just use
                    // data.Value we could be mixing and matching data streams
                    _window.Add((double)security.Price);
                }
                _lastUpdate = data.EndTime;
            }
        }
	}
	
}                        
namespace QuantConnect {

    // Tracking all the Trade information in a single class
    public class TradeProfile 
    {
    	
    	//Ticket tracking the open order
     	public OrderTicket OpenTicket, StopTicket;
		
        private decimal _risk;
        private decimal _currentPrice;
		private int _maximumTradeQuantity;
        protected decimal _volatility;

		// Calclate the quantity based on the target risk in dollars.
        public int Quantity
        {
            get
            {
            	if(_volatility == 0) return 0;
            	
            	long quantity = (long)(_risk / _volatility);
                if (quantity > _maximumTradeQuantity) return _maximumTradeQuantity;
                return (int)quantity;
            }
        }

		//What is the stoploss move from current price
        public decimal DeltaStopLoss
        {
            get 
            { 
                return _risk / Quantity;
            }
        }

		//Create a new tradeProfile and limit the maximum risk.
        public TradeProfile(decimal volatility, decimal risk, decimal currentPrice, decimal maximumTradeSize)
        {
            _volatility = volatility;
            _risk = risk;
            _currentPrice = currentPrice;
            _maximumTradeQuantity = (int)(maximumTradeSize/_currentPrice);
        }
    }

}