Overall Statistics
Total Trades
25
Average Win
0.92%
Average Loss
-0.23%
Compounding Annual Return
16.924%
Drawdown
2.200%
Expectancy
1.880
Net Profit
5.318%
Sharpe Ratio
2.28
Loss Rate
42%
Win Rate
58%
Profit-Loss Ratio
3.94
Alpha
0.09
Beta
0.141
Annual Standard Deviation
0.048
Annual Variance
0.002
Information Ratio
-0.426
Tracking Error
0.068
Treynor Ratio
0.778
Total Fees
$0.00
namespace QuantConnect
{
    /// <summary>
    ///     This is a truncated version of the algorithm made for the Trading Strategies Based on Genetic Algorithms project
    ///     for the QuantConnect platform.
    ///     The main difference is that the rules are hard coded in the TradingRule class, instead if being dynamically
    ///     generated as in the original.
    /// </summary>
    /// <seealso cref="QuantConnect.Algorithm.QCAlgorithm" />
    internal class TradingStrategiesBasedOnGeneticAlgorithmsQCVersion : QCAlgorithm
    {
        private readonly int _indicatorSignalCount = 5;
        private TradingRuleQCVersion _entryradingRule;
        private TradingRuleQCVersion _exitTradingRule;
        private Symbol _pair;

        /// <summary>
        ///     Here are the parameters of the individual with the best in-sample fitness.
        /// </summary>
        private readonly Dictionary<string, string> parametersToBacktest = new Dictionary<string, string>
        {
            {"EntryIndicator1", "0"},
            {"EntryIndicator2", "3"},
            {"EntryIndicator3", "3"},
            {"EntryIndicator4", "7"},
            {"EntryIndicator5", "5"},
            {"EntryIndicator1Direction", "0"},
            {"EntryIndicator2Direction", "0"},
            {"EntryIndicator3Direction", "1"},
            {"EntryIndicator4Direction", "1"},
            {"EntryIndicator5Direction", "0"},
            {"ExitIndicator1", "4"},
            {"ExitIndicator2", "3"},
            {"ExitIndicator3", "1"},
            {"ExitIndicator4", "0"},
            {"ExitIndicator5", "7"},
            {"ExitIndicator1Direction", "1"},
            {"ExitIndicator2Direction", "0"},
            {"ExitIndicator3Direction", "0"},
            {"ExitIndicator4Direction", "0"},
            {"ExitIndicator5Direction", "0"}
        };

        public override void Initialize()
        {
            SetCash(startingCash: 1e6);
            var startDate = new DateTime(year: 2017, month: 1, day: 1);
            SetStartDate(startDate);
            SetEndDate(startDate.AddMonths(months: 4));

            _pair = AddForex("EURUSD", leverage: 10).Symbol;

            SetParameters(parametersToBacktest);

            SetUpRules();
        }

        public override void OnData(Slice slice)
        {
            if (!_entryradingRule.IsReady) return;
            if (!Portfolio.Invested)
            {
                if (_entryradingRule.TradeRuleSignal) SetHoldings(_pair, percentage: 1m);
            }
            else
            {
                if (_exitTradingRule.TradeRuleSignal) Liquidate(_pair);
            }
        }

        /// <summary>
        ///     Sets up indicator signal. This method is where the Technical indicator rules are defined.
        /// </summary>
        /// <param name="pair">The pair.</param>
        /// <param name="indicatorN">The number if indicator.</param>
        /// <param name="ruleAction">
        ///     The rule action. Should be 'Entry' or 'Exit' and is only used to differentiate the genes for
        ///     entry and exit
        /// </param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException">WIP</exception>
        public ITechnicalIndicatorSignal SetUpIndicatorSignal(Symbol pair, int indicatorN, string ruleAction)
        {
            var oscillatorThresholds = new OscillatorThresholds {Lower = 20, Upper = 80};
            var key = ruleAction + "Indicator" + indicatorN + "Direction";
            var intDirection = GetGeneIntFromKey(key);

            var direction = intDirection == 0
                ? TradeRuleDirection.LongOnly
                : TradeRuleDirection.ShortOnly;

            key = ruleAction + "Indicator" + indicatorN;
            var indicatorId = GetGeneIntFromKey(key);
            var indicator = (TechicalIndicators) indicatorId;
            ITechnicalIndicatorSignal technicalIndicator = null;
            switch (indicator)
            {
                case TechicalIndicators.SimpleMovingAverage:
                    // Canonical cross moving average parameters.
                    var fast = SMA(pair, period: 50);
                    var slow = SMA(pair, period: 200);
                    technicalIndicator = new CrossingMovingAverages(fast, slow, direction);
                    break;

                case TechicalIndicators.MovingAverageConvergenceDivergence:
                    var macd = MACD(pair, fastPeriod: 12, slowPeriod: 26, signalPeriod: 9);
                    technicalIndicator = new CrossingMovingAverages(macd, macd.Signal, direction);
                    break;

                case TechicalIndicators.Stochastic:
                    var sto = STO(pair, period: 14);
                    technicalIndicator = new OscillatorSignal(sto.StochD, oscillatorThresholds, direction);
                    break;

                case TechicalIndicators.RelativeStrengthIndex:
                    var rsi = RSI(pair, period: 14);
                    technicalIndicator = new OscillatorSignal(rsi, oscillatorThresholds, direction);
                    break;

                case TechicalIndicators.CommodityChannelIndex:
                    var cci = CCI(pair, period: 20);
                    oscillatorThresholds.Lower = -100;
                    oscillatorThresholds.Lower = 100;
                    technicalIndicator = new OscillatorSignal(cci, oscillatorThresholds, direction);
                    break;

                case TechicalIndicators.MomentumPercent:
                    var pm = MOMP(pair, period: 60);
                    oscillatorThresholds.Lower = -5;
                    oscillatorThresholds.Lower = 5;
                    technicalIndicator = new OscillatorSignal(pm, oscillatorThresholds, direction);
                    break;

                case TechicalIndicators.WilliamsPercentR:
                    var wr = WILR(pair, period: 14);
                    technicalIndicator = new OscillatorSignal(wr, oscillatorThresholds, direction);
                    break;

                case TechicalIndicators.PercentagePriceOscillator:
                    var ppo = MACD(pair, fastPeriod: 12, slowPeriod: 26, signalPeriod: 9).Over(EMA(pair, period: 26))
                        .Plus(constant: 100m);
                    var signal = new SimpleMovingAverage(period: 9).Of(ppo);
                    technicalIndicator = new CrossingMovingAverages(ppo, signal, direction);
                    break;

                case TechicalIndicators.BollingerBands:
                    throw new NotImplementedException("WIP");
                    break;
            }

            return technicalIndicator;
        }

        /// <summary>
        ///     Gets the gene int from key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">The gene " + key + " is not present either as Config or as Parameter</exception>
        /// <remarks>
        ///     This method makes the algorithm working with the genes defined from the Config (as in the Lean Optimization) and
        ///     from the Parameters (as the Lean Caller).
        /// </remarks>
        private int GetGeneIntFromKey(string key)
        {
        	// I'll keep this line as in the original code. 
            //var intGene = Config.GetInt(key, int.MinValue);
            var intGene = int.MinValue;
            if (intGene == int.MinValue)
            {
                try
                {
                    intGene = int.Parse(GetParameter(key));
                    Log(string.Format("Parameter {0} set to {1}", key, intGene));
                }
                catch (ArgumentNullException e)
                {
                    throw new ArgumentNullException(key,
                        "The gene " + key + " is not present either as Config or as Parameter");
                }
            }
            return intGene;
        }

        private void SetUpRules()
        {
            bool[] bools = {true, false};

            foreach (var isEntryRule in bools)
            {
                var technicalIndicatorSignals = new List<ITechnicalIndicatorSignal>();
                var ruleAction = isEntryRule ? "Entry" : "Exit";
                for (var i = 1; i <= _indicatorSignalCount; i++)
                {
                    var indicatorSignal = SetUpIndicatorSignal(_pair, i, ruleAction);
                    technicalIndicatorSignals.Add(indicatorSignal);
                }

                if (isEntryRule)
                {
                    _entryradingRule = new TradingRuleQCVersion(technicalIndicatorSignals.ToArray(), isEntryRule);
                }
                else
                {
                    _exitTradingRule = new TradingRuleQCVersion(technicalIndicatorSignals.ToArray(), isEntryRule);
                }
            }
        }
    }
}
namespace QuantConnect
{
    /// <summary>
    ///     Interface used by the <see cref="TradingRule" /> class to flag technical indicator signals as crossing moving
    ///     averages or oscillators crossing its thresholds.
    /// </summary>
    public interface ITechnicalIndicatorSignal
    {
        /// <summary>
        ///     Gets a value indicating whether this instance is ready.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is ready; otherwise, <c>false</c>.
        /// </value>
        bool IsReady { get; }

        /// <summary>
        ///     Gets the signal. Only used if the instance will be part of a <see cref="TradingRule" /> class.
        /// </summary>
        /// <returns>
        ///     <c>true</c> if the actual <see cref="Signal" /> correspond with the instance <see cref="TradeRuleDirection" />.
        ///     <c>false</c>
        ///     otherwise.
        /// </returns>
        bool GetSignal();
    }

    /// <summary>
    ///     The <see cref="TradingStrategiesBasedOnGeneticAlgorithms" /> implementation requires a direction for every
    ///     technical indicator.
    /// </summary>
    public enum TradeRuleDirection
    {
        LongOnly = 1,
        ShortOnly = -1
    }

    /// <summary>
    ///     List of the technical indicator implemented... well not really, Bollinger bands wasn't implemented.
    /// </summary>
    public enum TechicalIndicators
    {
        SimpleMovingAverage = 0,
        MovingAverageConvergenceDivergence = 1,
        Stochastic = 2,
        RelativeStrengthIndex = 3,
        CommodityChannelIndex = 4,
        MomentumPercent = 5,
        WilliamsPercentR = 6,
        PercentagePriceOscillator = 7,
        BollingerBands = 8
    }
}
namespace QuantConnect
{
    /// <summary>
    ///     Possibles states of two moving averages.
    /// </summary>
    public enum CrossingMovingAveragesSignals
    {
        Bullish = 1,
        FastCrossSlowFromAbove = -2,
        Bearish = -1,
        FastCrossSlowFromBelow = 2
    }

    /// <summary>
    ///     This class keeps track of two crossing moving averages and updates a <see cref="CrossingMovingAveragesSignals" />
    ///     for each given state.
    /// </summary>
    /// <seealso cref="QuantConnect.Algorithm.CSharp.ITechnicalIndicatorSignal" />
    public class CrossingMovingAverages : ITechnicalIndicatorSignal
    {
        private readonly CompositeIndicator<IndicatorDataPoint> _moving_average_difference;
        private readonly TradeRuleDirection _tradeRuleDirection;
        private int _lastSignal;

        /// <summary>
        ///     Initializes a new instance of the <see cref="CrossingMovingAverages" /> class.
        /// </summary>
        /// <param name="fast_moving_average">The fast moving average.</param>
        /// <param name="slow_moving_average">The slow moving average.</param>
        /// <param name="tradeRuleDirection">
        ///     The trade rule direction. Only used if the instance will be part of a
        ///     <see cref="TradingRule" /> class
        /// </param>
        /// <remarks>
        ///     Both Moving Averages must be registered BEFORE being used by this constructor.
        /// </remarks>
        public CrossingMovingAverages(IndicatorBase<IndicatorDataPoint> fast_moving_average,
            IndicatorBase<IndicatorDataPoint> slow_moving_average, TradeRuleDirection? tradeRuleDirection = null)
        {
            _moving_average_difference = fast_moving_average.Minus(slow_moving_average);
            _moving_average_difference.Updated += ma_Updated;
            if (tradeRuleDirection != null) _tradeRuleDirection = (TradeRuleDirection)tradeRuleDirection;
        }

        /// <summary>
        ///     Gets a value indicating whether this instance is ready.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is ready; otherwise, <c>false</c>.
        /// </value>
        public bool IsReady
        {
            get { return _moving_average_difference.IsReady; }
        }

        /// <summary>
        ///     Gets the actual state of both moving averages.
        /// </summary>
        public CrossingMovingAveragesSignals Signal { get; private set; }

        /// <summary>
        ///     Gets the signal. Only used if the instance will be part of a <see cref="TradingRule" /> class.
        /// </summary>
        /// <returns>
        ///     <c>true</c> if the actual <see cref="Signal" /> correspond with the instance <see cref="TradeRuleDirection" />.
        ///     <c>false</c>
        ///     otherwise.
        /// </returns>
        public bool GetSignal()
        {
            var signal = false;
            if (IsReady)
            {
                switch (_tradeRuleDirection)
                {
                    case TradeRuleDirection.LongOnly:
                        signal = Signal == CrossingMovingAveragesSignals.FastCrossSlowFromBelow;
                        break;

                    case TradeRuleDirection.ShortOnly:
                        signal = Signal == CrossingMovingAveragesSignals.FastCrossSlowFromAbove;
                        break;
                }
            }
            return signal;
        }

        private void ma_Updated(object sender, IndicatorDataPoint updated)
        {
            if (!IsReady)
            {
                return;
            }
            var actualSignal = Math.Sign(_moving_average_difference);
            if (actualSignal == _lastSignal || _lastSignal == 0)
            {
                Signal = (CrossingMovingAveragesSignals)actualSignal;
            }
            else if (_lastSignal == -1 && actualSignal == 1)
            {
                Signal = CrossingMovingAveragesSignals.FastCrossSlowFromBelow;
            }
            else if (_lastSignal == 1 && actualSignal == -1)
            {
                Signal = CrossingMovingAveragesSignals.FastCrossSlowFromAbove;
            }

            _lastSignal = actualSignal;
        }
    }
}
namespace QuantConnect
{
    /// <summary>
    ///     Possibles states of an oscillator respect to its thresholds.
    /// </summary>
    public enum OscillatorSignals
    {
        CrossLowerThresholdFromAbove = -3,
        BellowLowerThreshold = -2,
        CrossLowerThresholdFromBelow = -1,
        BetweenThresholds = 0,
        CrossUpperThresholdFromBelow = 3,
        AboveUpperThreshold = 2,
        CrossUpperThresholdFromAbove = 1
    }

    public struct OscillatorThresholds
    {
        public decimal Lower;
        public decimal Upper;
    }

    /// <summary>
    ///     This class keeps track of an oscillator respect to its thresholds and updates an <see cref="OscillatorSignal" />
    ///     for each given state.
    /// </summary>
    /// <seealso cref="QuantConnect.Algorithm.CSharp.ITechnicalIndicatorSignal" />
    public class OscillatorSignal : ITechnicalIndicatorSignal
    {
        private decimal _previousIndicatorValue;
        private OscillatorSignals _previousSignal;
        private OscillatorThresholds _thresholds;
        private TradeRuleDirection _tradeRuleDirection;

        /// <summary>
        ///     Initializes a new instance of the <see cref="OscillatorSignal" /> class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <param name="thresholds">The thresholds.</param>
        /// <param name="tradeRuleDirection">
        ///     The trade rule direction. Only used if the instance will be part of a
        ///     <see cref="TradingRule" /> class
        /// </param>
        /// <remarks>The oscillator must be registered BEFORE being used by this constructor.</remarks>
        public OscillatorSignal(dynamic indicator, OscillatorThresholds thresholds,
            TradeRuleDirection tradeRuleDirection)
        {
            SetUpClass(ref indicator, ref thresholds, tradeRuleDirection);
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="OscillatorSignal" /> class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <param name="thresholds">The thresholds.</param>
        /// <remarks>The oscillator must be registered BEFORE being used by this constructor.</remarks>
        public OscillatorSignal(dynamic indicator, OscillatorThresholds thresholds)
        {
            SetUpClass(ref indicator, ref thresholds);
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="OscillatorSignal" /> class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <remarks>The oscillator must be registered BEFORE being used by this constructor.</remarks>
        public OscillatorSignal(dynamic indicator)
        {
            var defaultThresholds = new OscillatorThresholds {Lower = 20, Upper = 80};
            SetUpClass(ref indicator, ref defaultThresholds);
        }

        /// <summary>
        ///     The underlying indicator, must be an oscillator.
        /// </summary>
        public dynamic Indicator { get; private set; }

        /// <summary>
        ///     Gets the actual state of the oscillator.
        /// </summary>
        public OscillatorSignals Signal { get; private set; }

        /// <summary>
        ///     Gets a value indicating whether this instance is ready.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is ready; otherwise, <c>false</c>.
        /// </value>
        public bool IsReady
        {
            get { return Indicator.IsReady; }
        }

        /// <summary>
        ///     Gets the signal. Only used if the instance will be part of a <see cref="TradingRule" /> class.
        /// </summary>
        /// <returns>
        ///     <c>true</c> if the actual <see cref="Signal" /> correspond with the instance <see cref="TradeRuleDirection" />.
        ///     <c>false</c>
        ///     otherwise.
        /// </returns>
        public bool GetSignal()
        {
            var signal = false;
            if (IsReady)
            {
                switch (_tradeRuleDirection)
                {
                    case TradeRuleDirection.LongOnly:
                        signal = Signal == OscillatorSignals.CrossLowerThresholdFromBelow;
                        break;

                    case TradeRuleDirection.ShortOnly:
                        signal = Signal == OscillatorSignals.CrossUpperThresholdFromAbove;
                        break;
                }
            }
            return signal;
        }

        /// <summary>
        ///     Updates the <see cref="Signal" /> status.
        /// </summary>
        private void Indicator_Updated(object sender, IndicatorDataPoint updated)
        {
            var actualPositionSignal = GetActualPositionSignal(updated);
            if (!Indicator.IsReady)
            {
                _previousIndicatorValue = updated.Value;
                _previousSignal = actualPositionSignal;
                Signal = _previousSignal;
                return;
            }

            var actualSignal = GetActualSignal(_previousSignal, actualPositionSignal);

            Signal = actualSignal;
            _previousIndicatorValue = updated.Value;
            _previousSignal = actualSignal;
        }

        /// <summary>
        ///     Gets the actual position respect to the thresholds.
        /// </summary>
        /// <param name="indicatorCurrentValue">The indicator current value.</param>
        /// <returns></returns>
        private OscillatorSignals GetActualPositionSignal(decimal indicatorCurrentValue)
        {
            var positionSignal = OscillatorSignals.BetweenThresholds;
            if (indicatorCurrentValue > _thresholds.Upper)
            {
                positionSignal = OscillatorSignals.AboveUpperThreshold;
            }
            else if (indicatorCurrentValue < _thresholds.Lower)
            {
                positionSignal = OscillatorSignals.BellowLowerThreshold;
            }
            return positionSignal;
        }

        /// <summary>
        ///     Gets the actual signal from the actual position respect to the thresholds and the last signal.
        /// </summary>
        /// <param name="previousSignal">The previous signal.</param>
        /// <param name="actualPositionSignal">The actual position signal.</param>
        /// <returns></returns>
        private OscillatorSignals GetActualSignal(OscillatorSignals previousSignal,
            OscillatorSignals actualPositionSignal)
        {
            OscillatorSignals actualSignal;
            var previousSignalInt = (int) previousSignal;
            var actualPositionSignalInt = (int) actualPositionSignal;

            if (actualPositionSignalInt == 0)
            {
                if (Math.Abs(previousSignalInt) > 1)
                {
                    actualSignal = (OscillatorSignals) Math.Sign(previousSignalInt);
                }
                else
                {
                    actualSignal = OscillatorSignals.BetweenThresholds;
                }
            }
            else
            {
                if (previousSignalInt * actualPositionSignalInt <= 0 ||
                    Math.Abs(previousSignalInt + actualPositionSignalInt) == 3)
                {
                    actualSignal = (OscillatorSignals) (Math.Sign(actualPositionSignalInt) * 3);
                }
                else
                {
                    actualSignal = (OscillatorSignals) (Math.Sign(actualPositionSignalInt) * 2);
                }
            }
            return actualSignal;
        }

        /// <summary>
        ///     Sets up class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <param name="thresholds">The thresholds.</param>
        /// <param name="tradeRuleDirection">The trade rule direction.</param>
        private void SetUpClass(ref dynamic indicator, ref OscillatorThresholds thresholds,
            TradeRuleDirection? tradeRuleDirection = null)
        {
            _thresholds = thresholds;
            Indicator = indicator;
            indicator.Updated += new IndicatorUpdatedHandler(Indicator_Updated);
            if (tradeRuleDirection != null) _tradeRuleDirection = (TradeRuleDirection) tradeRuleDirection;
        }
    }
}
namespace QuantConnect
{
    internal class TradingRuleQCVersion
    {
        private readonly ITechnicalIndicatorSignal[] _technicalIndicatorSignals;
        private readonly bool _isEntryRule;

        public TradingRuleQCVersion(ITechnicalIndicatorSignal[] technicalIndicatorSignals, bool isEntryRule)
        {
            _technicalIndicatorSignals = technicalIndicatorSignals;
            _isEntryRule = isEntryRule;
        }

        public bool IsReady
        {
            get
            {
                var isReady = true;
                foreach (var indicator in _technicalIndicatorSignals)
                {
                    isReady = indicator.IsReady && isReady;
                }
                return isReady;
            }
        }

        public bool TradeRuleSignal
        {
            get { return GetTradeRuleSignal(); }
        }

        /// <summary>
        /// Gets the trade rule signal for the best in-sample performance individual.
        /// </summary>
        /// <returns></returns>
        private bool GetTradeRuleSignal()
        {
            var signal = false;
            if (_isEntryRule)
            {
                signal = _technicalIndicatorSignals[0].GetSignal() &&   //  Long SimpleMovingAverage
                         _technicalIndicatorSignals[1].GetSignal() ||   //  Long Stochastic
                         _technicalIndicatorSignals[2].GetSignal() &&   //  Long RelativeStrengthIndex
                         _technicalIndicatorSignals[3].GetSignal() ||   //  Short MovingAverageConvergenceDivergence
                         _technicalIndicatorSignals[4].GetSignal();     //  Short MomentumPercent
            }
            else
            {
                signal = _technicalIndicatorSignals[0].GetSignal() ||   //  Short CommodityChannelIndex
                         _technicalIndicatorSignals[1].GetSignal() &&	//  Long RelativeStrengthIndex
                         _technicalIndicatorSignals[2].GetSignal() ||	//  Short Stochastic
                         _technicalIndicatorSignals[3].GetSignal() &&	//  Long MovingAverageConvergenceDivergence
                         _technicalIndicatorSignals[4].GetSignal();		//  Long Stochastic

            }
            return signal;
        }
    }
}