Overall Statistics
Total Trades
6666
Average Win
0.02%
Average Loss
-0.02%
Compounding Annual Return
-99.980%
Drawdown
40.700%
Expectancy
-0.627
Net Profit
-40.660%
Sharpe Ratio
-25.099
Loss Rate
81%
Win Rate
19%
Profit-Loss Ratio
0.97
Alpha
-5.611
Beta
-0.498
Annual Standard Deviation
0.224
Annual Variance
0.05
Information Ratio
-24.094
Tracking Error
0.235
Treynor Ratio
11.312
Total Fees
$0.00
namespace QuantConnect
{
    public class TradingSymbols
    {
        public static string[] OandaFXSymbols = {
            "AUDCAD","AUDCHF","AUDHKD","AUDJPY","AUDNZD","AUDSGD","AUDUSD","CADCHF","CADHKD","CADJPY",
            "CADSGD","CHFHKD","CHFJPY","CHFZAR","EURAUD","EURCAD","EURCHF","EURCZK","EURDKK","EURGBP",
            "EURHKD","EURHUF","EURJPY","EURNOK","EURNZD","EURPLN","EURSEK","EURSGD","EURTRY","EURUSD",
            "EURZAR","GBPAUD","GBPCAD","GBPCHF","GBPHKD","GBPJPY","GBPNZD","GBPPLN","GBPSGD","GBPUSD",
            "GBPZAR","HKDJPY","NZDCAD","NZDCHF","NZDHKD","NZDJPY","NZDSGD","NZDUSD","SGDCHF","SGDHKD",
            "SGDJPY","TRYJPY","USDCAD","USDCHF","USDCNH","USDCZK","USDDKK","USDHKD","USDHUF","USDINR",
            "USDJPY","USDMXN","USDNOK","USDPLN","USDSAR","USDSEK","USDSGD","USDTHB","USDTRY","USDZAR",
            "ZARJPY" };

        public static string[] OandaFXMajors2 = {
            "AUDJPY","AUDUSD","EURAUD","EURCHF","EURGBP","EURJPY","EURUSD","GBPCHF","GBPJPY","GBPUSD",
            "NZDUSD","USDCAD","USDCHF","USDJPY" };

        public static string[] OandaFXMajors1 = {
            "EURCHF","EURGBP","EURJPY","EURUSD","GBPCHF","GBPJPY","GBPUSD","USDCHF","USDJPY" };
        public static string[] OandaFXMajors = {
            "EURCHF","EURGBP","EURJPY","EURUSD" };
        public static string[] OandaCFD = {
            "EU50EUR", "FR40EUR", "DE30EUR" };

        public static string[] OandaFXMajors0 = {
            "EURUSD" };
    }
}
using System;
using System.Collections.Generic;

namespace QuantConnect
{

    public class SignalFactory : AbstractSignalFactory
    {

        //todo: derive maximum signals from config keys
        private readonly int _maximumSignals = 5;
        int _period;
        int _slowPeriod;
        int _fastPeriod;
        int _signalPeriod;
        QCAlgorithm _algorithm;
        Resolution _resolution;
        private bool _enableParameterLog = false;

        public enum TechnicalIndicator
        {
            None = -1,
            SimpleMovingAverage = 0,
            MovingAverageConvergenceDivergence = 1,
            Stochastic = 2,
            RelativeStrengthIndex = 3,
            CommodityChannelIndex = 4,
            MomentumPercent = 5,
            WilliamsPercentR = 6,
            PercentagePriceOscillator = 7,
            AverageDirectionalIndex = 8,
            AverageTrueRange = 9,
            BollingerBands = 10,
            ExponentialMovingAverage = 11
        }

        public override Rule Create(QCAlgorithm algorithm, Symbol symbol, bool isEntryRule, Resolution resolution = Resolution.Hour)
        {
            _algorithm = algorithm;
            _resolution = resolution;
            var entryOrExit = isEntryRule ? "Entry" : "Exit";

            _period = GetConfigValue("period");
            _slowPeriod = GetConfigValue("slowPeriod");
            _fastPeriod = GetConfigValue("fastPeriod");
            _signalPeriod = GetConfigValue("signalPeriod");

            ISignal parent = null;
            List<ISignal> list = new List<ISignal>();

            for (var i = 1; i <= _maximumSignals; i++)
            {
                var item = CreateIndicator(symbol, i, entryOrExit);
                if (parent != null)
                {
                    parent.Child = item;
                }

                //last item won't have operator
                if (i < _maximumSignals)
                {
                    var key = entryOrExit + "Operator" + i;
                    Operator op = (Operator)GetConfigValue(key);
                    item.Operator = op;
                }

                item.Parent = parent;
                parent = item;

                list.Add(item);
            }

            return new Rule(symbol, list);
        }

        protected override ISignal CreateIndicator(Symbol pair, int i, string entryOrExit)
        {
            var key = entryOrExit + "Indicator" + i + "Direction";
            var intDirection = GetConfigValue(key);

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

            key = entryOrExit + "Indicator" + i;

            var indicator = (TechnicalIndicator)GetConfigValue(key);
            ISignal signal = null;

            switch (indicator)
            {
                case TechnicalIndicator.SimpleMovingAverage:
                    var fast = _algorithm.SMA(pair, _fastPeriod, _resolution);
                    var slow = _algorithm.SMA(pair, _slowPeriod, _resolution);
                    signal = new CrossingMovingAverageSignal(fast, slow, direction);
                    break;

                case TechnicalIndicator.ExponentialMovingAverage:
                    // Canonical cross moving average parameters.
                    var fastema = _algorithm.EMA(pair, period: 50);
                    var slowema = _algorithm.EMA(pair, period: 200);
                    signal = new CrossingMovingAverageSignal(fastema, slowema, direction);
                    break;

                case TechnicalIndicator.MovingAverageConvergenceDivergence:
                    var macd = _algorithm.MACD(pair, fastPeriod: 12, slowPeriod: 26, signalPeriod: 9, type:MovingAverageType.Simple, resolution:_resolution);
                    signal = new CrossingMovingAverageSignal(macd, macd.Signal, direction);
                    break;

                case TechnicalIndicator.Stochastic:
                    var sto = _algorithm.STO(pair, period: 14, resolution:_resolution);
                    signal = new OscillatorSignal(sto, new[] { 20, 80 }, direction);
                    break;

                case TechnicalIndicator.RelativeStrengthIndex:
                    var rsi = _algorithm.RSI(pair, period: 14);
                    signal = new OscillatorSignal(rsi, new[] { 30, 70 }, direction);
                    break;

                case TechnicalIndicator.CommodityChannelIndex:
                    var cci = _algorithm.CCI(pair, period: 20, movingAverageType:MovingAverageType.Simple, resolution:_resolution);
                    signal = new OscillatorSignal(cci, new[] { -100, 100 }, direction);
                    break;

                case TechnicalIndicator.MomentumPercent:
                    var pm = _algorithm.MOMP(pair, period: 60, resolution:_resolution);
                    signal = new OscillatorSignal(pm, new[] { -5, 5 }, direction);
                    break;

                case TechnicalIndicator.WilliamsPercentR:
                    var wr = _algorithm.WILR(pair, period: 14, resolution:_resolution);
                    signal = new OscillatorSignal(wr, new[] { -20, -80 }, direction);
                    break;

                case TechnicalIndicator.PercentagePriceOscillator:
                    var ppo = _algorithm.MACD(pair, fastPeriod: 12, slowPeriod: 26, signalPeriod: 9, type: MovingAverageType.Simple, resolution: _resolution)
                        .Over(_algorithm.EMA(pair, _period, resolution: _resolution)).Plus(constant: 100m);
                    var compound = new SimpleMovingAverage(_period).Of(ppo);
                    signal = new CrossingMovingAverageSignal(ppo, compound, direction);
                    break;

                case TechnicalIndicator.None:
                    signal = new EmptySignal();
                    break;

                case TechnicalIndicator.AverageDirectionalIndex:
                    var adx = _algorithm.ADX(pair, _period, _resolution);
                    signal = new OscillatorSignal(adx, new[] { 25, 25 }, direction);
                    break;

                    //todo:
                    //case TechnicalIndicator.AverageTrueRange:
                    //    var atr = _algorithm.ATR(pair, _period, MovingAverageType.Simple, _resolution);
                    //    signal = new OscillatorSignal(atr, oscillatorThresholds, direction);
                    //    break;

                case TechnicalIndicator.BollingerBands:
                    var bb = _algorithm.BB(pair, period: 20, k: 2);
                    signal = new BBOscillatorSignal(bb, direction);
                    break;
            }

            return signal;
        }

        protected override int GetConfigValue(string key)
        {
            int value;
            try
            {
                int.TryParse(_algorithm.GetParameter(key), out value);
                //value = Config.GetInt(key, value);
                if (_enableParameterLog)
                {
                    _algorithm.Log(string.Format("Parameter {0} set to {1}", key, value));
                }
            }
            catch (ArgumentNullException e)
            {
                throw new ArgumentNullException(key,
                    "The gene " + key + " is not present either as Config or as Parameter");
            }

            return value;
        }
    }

    public abstract class AbstractSignalFactory
    {
        public abstract Rule Create(QCAlgorithm algorithm, Symbol symbol, bool isEntryRule, Resolution resolution = Resolution.Hour);
        protected abstract ISignal CreateIndicator(Symbol pair, int i, string entryOrExit);
        protected abstract int GetConfigValue(string key);
    }

}
namespace QuantConnect
{

    public class Rule
    {

        public IEnumerable<ISignal> List { get; }
        public Symbol Symbol { get; }
        public Rule(Symbol symbol, IEnumerable<ISignal> signal)
        {
            List = signal;
            Symbol = symbol;
        }

        public bool IsReady()
        {
            return List.All(s => s.IsReady);
        }

        public bool IsTrue()
        {
            string expression = "";

            foreach (var item in List)
            {
                string isTrue = item.IsTrue().ToString().ToLower();

                if (new[] { Operator.NorInclusive, Operator.OrInclusive }.Contains(item.Operator))
                {
                    isTrue = "(" + isTrue;
                }

                if (item.Parent != null && new[] { Operator.NorInclusive, Operator.OrInclusive }.Contains(item.Parent.Operator))
                {
                    isTrue += ")";
                }

                expression = expression+(isTrue);

                if (item.Child != null)
                {
                    if (item.Operator == Operator.And)
                    {
                        expression = expression +(" and ");
                    }
                    else if (new[] { Operator.Or, Operator.OrInclusive }.Contains(item.Operator))
                    {
                        expression = expression +(" or ");
                    }
                    else if (item.Operator == Operator.Not)
                    {
                        expression = expression +(" and !");
                    }
                    else if (new[] { Operator.Nor, Operator.NorInclusive }.Contains(item.Operator))
                    {
                        expression = expression +(" or !");
                    }
                }
            }

            var tokens = new Tokenizer(expression.ToString()).Tokenize();
            var parser = new Parser(tokens);
            return parser.Parse();
        }

        public void Update(BaseData data)
        {
            List.First().Update(data);
        }

    }
}
namespace QuantConnect
{
    public partial class GeneticTreeAlgorithmExample : QCAlgorithm
    {
        private readonly bool IsOutOfSampleRun = true;
        private readonly int oosPeriod = 3;
        public bool verbose = false;

        private List<Rule> _entry;
        private List<Rule> _exit;
        public List<Symbol> _symbols;
        FxRiskManagment RiskManager;

        public override void Initialize()
        {
            SetCash(10000);
            SetStartDate(Configuration.GetConfigDateTime("startDate", new DateTime(2017, 1, 12), this));
            //SetEndDate(Config.GetValue<DateTime>("endDate", new DateTime(2017, 7, 22)));

            if (IsOutOfSampleRun)
            {
                //var startDate = new DateTime(year: 2016, month: 1, day: 1);
                //SetStartDate(startDate);
                //SetEndDate(startDate.AddMonths(oosPeriod));
                RuntimeStatistics["ID"] = GetParameter("ID");
                SetParameters(config.ToDictionary(k => k.Key, v => v.Value.ToString()));
            }

            SetBrokerageModel(QuantConnect.Brokerages.BrokerageName.OandaBrokerage);
            var con = new TickConsolidator(new TimeSpan(1, 0, 0));

           // SetBenchmark(_symbol);
           
            _symbols = new List<Symbol>();
            _entry = new List<Rule>();
            _exit = new List<Rule>();
            foreach (var symbol in TradingSymbols.OandaFXMajors)
            {
                var security= AddSecurity(SecurityType.Forex, symbol, Configuration._resolution, Market.Oanda, true, Configuration._leverage, false);
                _symbols.Add(security.Symbol);
            }
            foreach (var symbol in TradingSymbols.OandaCFD)
            {
                //    AddSecurity(SecurityType.Cfd, symbol, _resolution, Market.Oanda, true, _leverage, false);
            }
            var factory = new SignalFactory();
            foreach (var symbol in _symbols)
            {
                Securities[symbol].VolatilityModel = new ThreeSigmaVolatilityModel(STD(symbol: symbol, period: 12 * 60, resolution: Configuration._resolution), 20.0m);

                _entry.Add(factory.Create(this, symbol, true, Configuration._resolution));
                _exit.Add(factory.Create(this, symbol, false, Configuration._resolution));
            }

            RiskManager = new FxRiskManagment(Portfolio, Configuration._riskPerTrade, Configuration._maxExposurePerTrade, Configuration._maxExposure, Configuration._lotSize);

        }

        public void OnData(QuoteBars data)
        {
            foreach (var entry in _entry)
            {
                if (entry.IsReady())
                {
                    EntrySignal(data, entry);
                }
            }
            foreach (var entry in _exit)
            {
                if (entry.IsReady())
                {
                    ExitSignal(entry);
                }
            }
        }

        public void ExitSignal(Rule signal)
        {

            if (verbose && signal.IsTrue())
            {
                Log(string.Format("signal symbol:: {0}", signal.Symbol));
            }
            if (Portfolio[signal.Symbol].Invested && signal.IsTrue())
            {
                Liquidate(signal.Symbol);
            }
            else if (Portfolio[signal.Symbol].Invested && Portfolio[signal.Symbol].UnrealizedProfitPercent > Configuration.takeProfit)
            {
                //safeguard profits, 
                //liquidate half
                MarketOrder(signal.Symbol, -(Portfolio[signal.Symbol].Quantity / 2));
            }
        }

        public void EntrySignal(QuoteBars data, Rule signal)
        {

            if (verbose && signal.IsTrue())
            {
                Log(string.Format("signal symbol:: {0}", signal.Symbol));
            }
            if (!Portfolio[signal.Symbol].Invested)
            {
                if (signal.IsTrue())
                {
                    var openPrice = Securities[signal.Symbol].Price;
                    var entryValues = RiskManager.CalculateEntryOrders(data, signal.Symbol, AgentAction.GoLong);
                    if (entryValues.Item1 != 0)
                    {

                        var ticket = MarketOrder(signal.Symbol, entryValues.Item1);
                        StopMarketOrder(signal.Symbol, -entryValues.Item1, entryValues.Item2, tag: entryValues.Item3.ToString("0.000000"));
                        if (verbose)
                        {
                            Log(string.Format("MarketOrder:: {0} {1}", signal.Symbol, entryValues.Item1));
                        }
                    }
                    //MarketOrder(signal.Symbol, size, false, "");
                }
            }
        }

        private static Dictionary<string, int> config = new Dictionary<string, int> {
            {"EntryIndicator1",  0},
            {"EntryIndicator2",  10},
            {"EntryIndicator3",  0},
            {"EntryIndicator4",  2},
            {"EntryIndicator5",  3},
            {"EntryIndicator1Direction",  1},
            {"EntryIndicator2Direction",  1},
            {"EntryIndicator3Direction",  1},
            {"EntryIndicator4Direction",  1},
            {"EntryIndicator5Direction",  1},
            {"EntryOperator1",  1},
            {"EntryOperator2",  1},
            {"EntryOperator3",  1},
            {"EntryOperator4",  1},
            {"EntryRelationship1",  0},
            {"EntryRelationship2",  1},
            {"EntryRelationship3",  1},
            {"EntryRelationship4",  0},
            {"ExitIndicator1",  6},
            {"ExitIndicator2",  5},
            {"ExitIndicator3",  4},
            {"ExitIndicator4",  0},
            {"ExitIndicator5",  2},
            {"ExitIndicator1Direction",  0},
            {"ExitIndicator2Direction",  0},
            {"ExitIndicator3Direction",  0},
            {"ExitIndicator4Direction",  0},
            {"ExitIndicator5Direction",  0},
            {"ExitOperator1",  1},
            {"ExitOperator2",  1},
            {"ExitOperator3",  1},
            {"ExitOperator4",  1},
            {"ExitRelationship1",  0},
            {"ExitRelationship2",  1},
            {"ExitRelationship3",  0},
            {"ExitRelationship4",  1},
            {"period",  1},
            {"slowPeriod",  200},
            {"fastPeriod",  20},
            {"signalPeriod",  4 }
        };
    }
}
namespace QuantConnect
{
    public class Configuration
    {
        public static decimal _leverage = 50m;

        // How much of the total strategy equity can be at risk as maximum in all trades.
        public static decimal _maxExposure = 0.8m;

        // How much of the total strategy equity can be at risk in a single trade.
        public static decimal _maxExposurePerTrade = 0.25m;

        // The max strategy equity proportion to put at risk in a single operation.
        public static decimal _riskPerTrade = 0.01m;

        public static decimal takeProfit = 0.05m;

        public static Resolution _resolution = Resolution.Minute;

        public static double accountsize = 10000;

        // Smallest lot
        public static LotSize _lotSize = LotSize.Nano;

        /// <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>
        public static decimal GetConfigDecimal(string key, decimal def, QCAlgorithm algo)
        {
            // I'll keep this line as in the original code. 
            //var gene = Config.GetValue<decimal>(key);
            var gene = decimal.MinValue;
            if (gene == decimal.MinValue)//not found in config, then get from parameter
            {
                try
                {
                    gene = decimal.Parse(algo.GetParameter(key));
                }
#pragma warning disable CS0168 // Variable is declared but never used
                catch (ArgumentNullException e)
#pragma warning restore CS0168 // Variable is declared but never used
                {
                    return def;
                }
            }
            return gene;
        }

        /// <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>
        public static DateTime GetConfigDateTime(string key, DateTime def, QCAlgorithm algo)
        {
            // I'll keep this line as in the original code. 
            //var gene = Config.GetValue<DateTime>(key, null);
            var gene = DateTime.MinValue;
            if (gene == DateTime.MinValue)//not found in config, then get from parameter
            {
                try
                {
                    gene = DateTime.Parse(algo.GetParameter(key));
                }
#pragma warning disable CS0168 // Variable is declared but never used
                catch (ArgumentNullException e)
#pragma warning restore CS0168 // Variable is declared but never used
                {
                    return def;
                }
            }
            return gene;
        }
    }
}
namespace QuantConnect
{
    public abstract class SignalBase : ISignal
    {

        public ISignal Child { get; set; }

        public ISignal Parent { get; set; }

        public Operator Operator { get; set; }

        public abstract bool IsReady { get; }

        public abstract string Name { get; }

        public abstract bool IsTrue();

        public virtual void Update(BaseData data)
        {
            if (Child != null)
            {
                Child.Update(data);
            }
        }

    }
}
namespace QuantConnect
{

    /// <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 : SignalBase
    {
        private decimal _previousIndicatorValue;
        private ThresholdState _previousSignal;
        private int[] _thresholds;
        private Direction _direction;
        static int[] defaultThresholds = new int[2] { 20, 80 };

        /// <summary>
        ///     Possibles states of an oscillator respect to its thresholds.
        /// </summary>
        public enum ThresholdState
        {
            CrossLowerFromAbove = -3,
            BelowLower = -2,
            CrossLowerFromBelow = -1,
            InBetween = 0,
            CrossUpperFromBelow = 3,
            AboveUpper = 2,
            CrossUpperFromAbove = 1
        }

        /// <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="direction">
        ///     The trade rule direction. Only used if the instance will be part of a
        ///     <see cref="Rule" /> class
        /// </param>
        /// <remarks>The oscillator must be registered BEFORE being used by this constructor.</remarks>
        public OscillatorSignal(dynamic indicator, int[] thresholds, Direction direction)
        {
            Initialize(indicator, thresholds, direction);
        }

        /// <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, int[] thresholds)
        {
            Initialize(indicator, thresholds, Direction.LongOnly);
        }

        public OscillatorSignal(dynamic indicator, Direction direction)
        {
            Initialize(indicator, defaultThresholds, direction);
        }

        /// <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)
        {
            Initialize(indicator, defaultThresholds, Direction.LongOnly);
        }

        /// <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 ThresholdState 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 override bool IsReady
        {
            get { return Indicator.IsReady; }
        }

        public override string Name { get { return ((string)Indicator.GetType().ToString()).Split('.').Last(); } }

        /// <summary>
        ///     Gets the signal. Only used if the instance will be part of a <see cref="Rule" /> class.
        /// </summary>
        /// <returns>
        ///     <c>true</c> if the actual <see cref="Signal" /> correspond with the instance <see cref="Direction" />.
        ///     <c>false</c>
        ///     otherwise.
        /// </returns>
        public override bool IsTrue()
        {
            var signal = false;
            if (IsReady)
            {
                switch (_direction)
                {
                    case Direction.LongOnly:
                        signal = Signal == ThresholdState.CrossLowerFromBelow;
                        break;

                    case Direction.ShortOnly:
                        signal = Signal == ThresholdState.CrossUpperFromAbove;
                        break;
                }
            }
            return signal;
        }

        /// <summary>
        ///     Updates the <see cref="Signal" /> status.
        /// </summary>
        private void Indicator_Updated(object sender, IndicatorDataPoint updated)
        {
            var actualPositionSignal = GetThresholdState(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>
        protected virtual ThresholdState GetThresholdState(decimal indicatorCurrentValue)
        {
            var positionSignal = ThresholdState.InBetween;
            if (indicatorCurrentValue > _thresholds[1])
            {
                positionSignal = ThresholdState.AboveUpper;
            }
            else if (indicatorCurrentValue < _thresholds[0])
            {
                positionSignal = ThresholdState.BelowLower;
            }
            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 ThresholdState GetActualSignal(ThresholdState previousSignal, ThresholdState actualPositionSignal)
        {
            ThresholdState actualSignal;
            var previous = (int)previousSignal;
            var current = (int)actualPositionSignal;

            if (current == 0)
            {
                if (Math.Abs(previous) > 1)
                {
                    actualSignal = (ThresholdState)Math.Sign(previous);
                }
                else
                {
                    actualSignal = ThresholdState.InBetween;
                }
            }
            else
            {
                if (previous * current <= 0 || Math.Abs(previous + current) == 3)
                {
                    actualSignal = (ThresholdState)(Math.Sign(current) * 3);
                }
                else
                {
                    actualSignal = (ThresholdState)(Math.Sign(current) * 2);
                }
            }
            return actualSignal;
        }

        /// <summary>
        /// Sets up class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <param name="thresholds">The thresholds.</param>
        /// <param name="direction">The trade rule direction.</param>
        private void Initialize(dynamic indicator, int[] thresholds, Direction direction)
        {
            _thresholds = thresholds;
            Indicator = indicator;
            indicator.Updated += new IndicatorUpdatedHandler(Indicator_Updated);
            _direction = direction;
        }

        /// <summary>
        /// Exposes a means to update underlying indicator
        /// </summary>
        /// <param name="data"></param>
        public override void Update(BaseData data)
        {
            if (Indicator.GetType().IsSubclassOf(typeof(IndicatorBase<IBaseDataBar>)))
            {
                if (data.GetType().GetInterfaces().Contains(typeof(IBaseDataBar)))
                {
                    Indicator.Update((IBaseDataBar)data);
                }
            }
            else if (Indicator.GetType().IsSubclassOf(typeof(IndicatorBase<IndicatorDataPoint>)))
            {
                Indicator.Update(new IndicatorDataPoint(data.Time, data.Value));
            }
            else
            {
                Indicator.Update(data);
            }

            base.Update(data);
        }

    }
}
namespace QuantConnect
{


    public interface ISignal
    {
        /// <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; }

        bool IsTrue();

        ISignal Child { get; set; }

        ISignal Parent { get; set; }

        Operator Operator { get; set; }

        void Update(BaseData data);

        string Name { get; }
    }

    public enum Direction
    {
        LongOnly = 1,
        ShortOnly = -1
    }

    public enum Operator
    {
        And = 0,
        Or = 1,
        OrInclusive = 2,
        Not = 3,
        Nor = 4,
        NorInclusive = 5
    }

}
namespace QuantConnect
{
    public class EmptySignal : ISignal
    {

        public bool _isTrue = true;

        public EmptySignal(bool isTrue = true)
        {
            _isTrue = isTrue;
        }

        public bool IsReady { get { return true; } }

        public Operator Operator { get; set; }

        public ISignal Child { get; set; }

        public ISignal Parent { get; set; }

        public string Name { get { return "Empty"; } }

        public bool IsTrue()
        {
            return _isTrue;
        }

        public void Update(BaseData data)
        {
        }
    }
}
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>
    public class CrossingMovingAverageSignal : SignalBase
    {
        private readonly CompositeIndicator<IndicatorDataPoint> _moving_average_difference;
        private readonly Direction _direction;
        private int _lastSignal;
        IndicatorBase<IndicatorDataPoint> _fast { get; set; }
        IndicatorBase<IndicatorDataPoint> _slow { get; set; }
		//todo: name
        public override string Name { get { return "CrossingMovingAverageSignal"; } }

        /// <summary>
        ///     Initializes a new instance of the <see cref="CrossingMovingAverageSignal" /> class.
        /// </summary>
        /// <param name="fast">The fast moving average.</param>
        /// <param name="slow">The slow moving average.</param>
        /// <param name="direction">
        ///     The trade rule direction. Only used if the instance will be part of a
        ///     <see cref="Rule" /> class
        /// </param>
        /// <remarks>
        ///     Both Moving Averages must be registered BEFORE being used by this constructor.
        /// </remarks>
        public CrossingMovingAverageSignal(IndicatorBase<IndicatorDataPoint> fast,
            IndicatorBase<IndicatorDataPoint> slow, Direction direction)
        {
            _fast = fast;
            _slow = slow;
            _moving_average_difference = fast.Minus(slow);
            _moving_average_difference.Updated += ma_Updated;
            _direction = direction;
        }

        /// <summary>
        ///     Gets the actual state of both moving averages.
        /// </summary>
        public CrossingMovingAveragesSignals 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 override bool IsReady
        {
            get { return _moving_average_difference.IsReady; }
        }

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

                    case Direction.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;
        }
        public override void Update(BaseData data)
        {
            var point = new IndicatorDataPoint(data.Time, data.Price);
            AttemptCompositeUpdate(_fast, point);
            AttemptCompositeUpdate(_slow, point);
            _fast.Update(point);
            _slow.Update(point);
            base.Update(data);
        }

        private void AttemptCompositeUpdate(IndicatorBase<IndicatorDataPoint> indicator, IndicatorDataPoint point)
        {
            if (indicator.GetType() == typeof(CompositeIndicator<IndicatorDataPoint>))
            {
                var composite = ((CompositeIndicator<IndicatorDataPoint>)indicator);
                composite.Left.Update(point);
                composite.Right.Update(point);
                AttemptCompositeUpdate(composite.Left, point);
                AttemptCompositeUpdate(composite.Right, point);
            }
        }

    }
}
namespace QuantConnect
{
    /// <summary>
    ///     This class keeps track of an oscillator respect to its thresholds and updates an <see cref="BBOscillatorSignal" />
    ///     for each given state.
    /// </summary>
    /// <seealso cref="QuantConnect.Algorithm.CSharp.ITechnicalIndicatorSignal" />
    public class BBOscillatorSignal : OscillatorSignal
    {
        private BollingerBands _bb;

        /// <summary>
        ///     Initializes a new instance of the <see cref="BBOscillatorSignal" /> class.
        /// </summary>
        /// <param name="indicator">The indicator.</param>
        /// <remarks>The oscillator must be registered BEFORE being used by this constructor.</remarks>
        public BBOscillatorSignal(BollingerBands indicator, Direction direction) : base(indicator, direction)
        {

            _bb = indicator;
        }

        /// <summary>
        ///     Gets the actual position respect to the thresholds.
        /// </summary>
        /// <param name="indicatorCurrentValue">The indicator current value.</param>
        /// <returns></returns>
        protected override ThresholdState GetThresholdState(decimal indicatorCurrentValue)
        {
            var positionSignal = ThresholdState.InBetween;
            if (indicatorCurrentValue > _bb.UpperBand)
            {
                positionSignal = ThresholdState.AboveUpper;
            }
            else if (indicatorCurrentValue < _bb.LowerBand)
            {
                positionSignal = ThresholdState.BelowLower;
            }
            return positionSignal;
        }
    }
}
namespace QuantConnect
{
    /// <summary>
    /// Provides an implementation of <see cref="IVolatilityModel"/> that computes the
    /// relative standard deviation as the volatility of the security
    /// </summary>
    public class ThreeSigmaVolatilityModel : IVolatilityModel
    {
        private readonly TimeSpan _periodSpan;
        private StandardDeviation _standardDeviation;
        private decimal _percentage;

        /// <summary>
        /// Gets the volatility of the security as a percentage
        /// </summary>
        public decimal Volatility
        {
            get { return _standardDeviation * _percentage; }
        }

        /// <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(StandardDeviation standardDeviation, decimal percentage = 2.5m)
        {
            _standardDeviation = standardDeviation;
            _percentage = percentage;
            _periodSpan = TimeSpan.FromMinutes(standardDeviation.Period);
        }

        /// <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)
        {
        }

        public IEnumerable<HistoryRequest> GetHistoryRequirements(Security security, DateTime utcTime)
        {
            return Enumerable.Empty<HistoryRequest>();
        }
    }
}
namespace QuantConnect
{
    public enum LotSize
    {
        Standard = 100000,
        Mini = 10000,
        Micro = 1000,
        Nano = 100,
    }

    public enum AgentAction
    {
        GoShort = -1,
        DoNothing = 0,
        GoLong = 1
    }

    public class FxRiskManagment
    {
        // Maximum equity proportion to put at risk in a single operation.
        private decimal _riskPerTrade;

        // Maximum equity proportion at risk in open positions in a given time.
        private decimal _maxExposure;

        // Maximum equity proportion at risk in a single trade.
        private decimal _maxExposurePerTrade;

        private int _lotSize;

        private int _minQuantity;

        private SecurityPortfolioManager _portfolio;

        /// <summary>
        /// Initializes a new instance of the <see cref="FxRiskManagment"/> class.
        /// </summary>
        /// <param name="portfolio">The QCAlgorithm Portfolio.</param>
        /// <param name="riskPerTrade">The max risk per trade.</param>
        /// <param name="maxExposurePerTrade">The maximum exposure per trade.</param>
        /// <param name="maxExposure">The maximum exposure in all trades.</param>
        /// <param name="lotsize">The minimum quantity to trade.</param>
        /// <exception cref="System.NotImplementedException">The pairs should be added to the algorithm before initialize the risk manager.</exception>
        public FxRiskManagment(SecurityPortfolioManager portfolio, decimal riskPerTrade, decimal maxExposurePerTrade,
                               decimal maxExposure, LotSize lotsize = LotSize.Micro, int minQuantity = 5)
        {
            _portfolio = portfolio;
            if (_portfolio.Securities.Count == 0)
            {
                throw new NotImplementedException("The pairs should be added to the algorithm before initialize the risk manager.");
            }
            this._riskPerTrade = riskPerTrade;
            _maxExposurePerTrade = maxExposurePerTrade;
            this._maxExposure = maxExposure;
            _lotSize = (int)lotsize;
            _minQuantity = minQuantity;
        }

        /// <summary>
        /// Calculates the entry orders and stop-loss price.
        /// </summary>
        /// <param name="pair">The Forex pair Symbol.</param>
        /// <param name="action">The order direction.</param>
        /// <returns>a Tuple with the quantity as Item1 and the stop-loss price as Item2. If quantity is zero, then means that no trade must be done.</returns>
        public Tuple<int, decimal, decimal> CalculateEntryOrders(QuoteBars data, Symbol pair, AgentAction action)
        {
            // If exposure is greater than the max exposure, then return zero.
            if (_portfolio.TotalMarginUsed > _portfolio.TotalPortfolioValue * _maxExposure)
            {
                return Tuple.Create(0, 0m, 0m);
            }
            var closePrice = _portfolio.Securities[pair].Price;
            var leverage = _portfolio.Securities[pair].Leverage;
            var exchangeRate = _portfolio.Securities[pair].QuoteCurrency.ConversionRate;
            var volatility = _portfolio.Securities[pair].VolatilityModel.Volatility;

            // Estimate the maximum entry order quantity given the risk per trade.
            var moneyAtRisk = _portfolio.TotalPortfolioValue * _riskPerTrade;
            var quantity = action == AgentAction.GoLong ? _lotSize : -_lotSize;
            if((volatility * exchangeRate)>0)
            {
                var maxQuantitybyRisk = moneyAtRisk / (volatility * exchangeRate);
                // Estimate the maximum entry order quantity given the exposure per trade.
                var maxBuySize = Math.Min(_portfolio.MarginRemaining, _portfolio.TotalPortfolioValue * _maxExposurePerTrade) * leverage;
                var maxQuantitybyExposure = maxBuySize / (closePrice * exchangeRate);
                // The final quantity is the lowest of both.
                quantity = (int)(Math.Round(Math.Min(maxQuantitybyRisk, maxQuantitybyExposure) / _lotSize, 0) * _lotSize);
                // If the final quantity is lower than the minimum quantity of the given lot size, then return zero.
                if (quantity < _lotSize * _minQuantity) return Tuple.Create(0, 0m, 0m);

                quantity = action == AgentAction.GoLong ? quantity : -quantity;
            }

            var stopLossPrice = closePrice + (action == AgentAction.GoLong ? -volatility : volatility);
            return Tuple.Create(quantity, stopLossPrice, action == AgentAction.GoLong ? data[pair].Ask.Close : data[pair].Bid.Close);
        }

        /// <summary>
        /// Updates the stop-loss price of all open StopMarketOrders.
        /// </summary>
        public void UpdateTrailingStopOrders(QuoteBars data)
        {
            // Get all the spot-loss orders.
            var openStopLossOrders = _portfolio.Transactions.GetOrderTickets(o => o.OrderType == OrderType.StopMarket && o.Status == OrderStatus.Submitted);
            foreach (var ticket in openStopLossOrders)
            {
                var stopLossPrice = ticket.SubmitRequest.StopPrice;
                var volatility = _portfolio.Securities[ticket.Symbol].VolatilityModel.Volatility;
                var actualPrice = _portfolio.Securities[ticket.Symbol].Price;
                // The StopLossOrder has the opposite direction of the original order.
                var originalOrderDirection = ticket.Quantity > 0 ? OrderDirection.Sell : OrderDirection.Buy;
                if (originalOrderDirection == OrderDirection.Sell)
                {
                    actualPrice = data[ticket.Symbol].Ask.Close;
                }
                if (originalOrderDirection == OrderDirection.Buy)
                {
                    actualPrice = data[ticket.Symbol].Bid.Close;
                }
                var newStopLossPrice = actualPrice + (volatility * (originalOrderDirection == OrderDirection.Buy ? -1 : 1));
                if ((originalOrderDirection == OrderDirection.Buy && newStopLossPrice > stopLossPrice)
                    || (originalOrderDirection == OrderDirection.Sell && newStopLossPrice < stopLossPrice))
                {

                    /*
                      if (originalOrderDirection == OrderDirection.Sell && data[ticket.Symbol].Ask.Close < System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                      {
                        if(newStopLossPrice>System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                        {
                            newStopLossPrice =  System.Convert.ToDecimal(ticket.SubmitRequest.Tag);
                        }
                      }
                      if (originalOrderDirection == OrderDirection.Buy && data[ticket.Symbol].Bid.Close > System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                      {
                        //price is on right direction
                        if(newStopLossPrice<System.Convert.ToDecimal(ticket.SubmitRequest.Tag))
                        {
                            newStopLossPrice =  System.Convert.ToDecimal(ticket.SubmitRequest.Tag);
                        }
                      }
                      */
                    ticket.Update(new UpdateOrderFields { Quantity = -(_portfolio[ticket.Symbol].Quantity), StopPrice = newStopLossPrice });
                }
                else if (!_portfolio[ticket.Symbol].Invested)
                {
                    ticket.Cancel();
                }
                else if(_portfolio[ticket.Symbol].Quantity!=ticket.Quantity)
                {
                    ticket.Update(new UpdateOrderFields { Quantity = -(_portfolio[ticket.Symbol].Quantity) });
     
                }

            }
        }
    }

}
namespace QuantConnect
{
    // Expression         := [ "!" ] <Boolean> { <BooleanOperator> <Boolean> } ...
    // Boolean            := <BooleanConstant> | <Expression> | "(" <Expression> ")"
    // BooleanOperator    := "And" | "Or" 
    // BooleanConstant    := "True" | "False"
    public class Parser
    {
        private readonly IEnumerator<Token> _tokens;


        public Parser(IEnumerable<Token> tokens)
        {
            _tokens = tokens.GetEnumerator();
            _tokens.MoveNext();
        }

        public bool Parse()
        {
            while (_tokens.Current != null)
            {
                var isNegated = _tokens.Current is NegationToken;
                if (isNegated)
                    _tokens.MoveNext();

                var boolean = ParseBoolean();
                if (isNegated)
                    boolean = !boolean;

                while (_tokens.Current is OperandToken)
                {
                    var operand = _tokens.Current;
                    if (!_tokens.MoveNext())
                    {
                        throw new Exception("Missing expression after operand");
                    }
                    var nextBoolean = ParseBoolean();

                    if (operand is AndToken)
                        boolean = boolean && nextBoolean;
                    else
                        boolean = boolean || nextBoolean;

                }

                return boolean;
            }

            throw new Exception("Empty expression");
        }

        private bool ParseBoolean()
        {
            if (_tokens.Current is BooleanValueToken)
            {
                var current = _tokens.Current;
                _tokens.MoveNext();

                if (current is TrueToken)
                    return true;

                return false;
            }
            if (_tokens.Current is OpenParenthesisToken)
            {
                _tokens.MoveNext();

                var expInPars = Parse();

                if (!(_tokens.Current is ClosedParenthesisToken))
                    throw new Exception("Expecting Closing Parenthesis");
                    
                _tokens.MoveNext(); 

                return expInPars;
            }
            if (_tokens.Current is ClosedParenthesisToken)
                throw new Exception("Unexpected Closed Parenthesis");

            // since its not a BooleanConstant or Expression in parenthesis, it must be a expression again
            var val = Parse();
            return val;
        }
    }
}
namespace QuantConnect
{
     public class Tokenizer
    {
        private string _text;

        private int i = 0;
        public Tokenizer(string text)
        {
            _text = text;
        }

        public IEnumerable<Token> Tokenize()
        {

            var tokens = new List<Token>();
            while (_text.Length > i)
            {
                while (Char.IsWhiteSpace((char) _text[i]))
                {
                    i++;
                }

                if (_text.Length <= i)
                    break;

                var c = (char) _text[i];
                switch (c)
                {
                    case '!':
                        tokens.Add(new NegationToken());
                        i++;
                        break;
                    case '(':
                        tokens.Add(new OpenParenthesisToken());
                        i++;
                        break;
                    case ')':
                        tokens.Add(new ClosedParenthesisToken());
                        i++;
                        break;
                    default:
                        if (Char.IsLetter(c))
                        {
                            var token = ParseKeyword();
                            tokens.Add(token);
                        }
                        else
                        {
                            var remainingText = _text.Substring(i) ?? string.Empty;
                            throw new Exception(string.Format("Unknown grammar found at position {0} : '{1}'", _text.Length - remainingText.Length, remainingText));
                        }
                        break;
                }
            }
            return tokens;
        }

        private Token ParseKeyword()
        {
            var text = "";
            while (_text.Length > i && Char.IsLetter((char) _text[i]))
            {
                text = text + ((char) _text[i]);
                i++;
            }

            var potentialKeyword = text.ToString().ToLower();

            switch (potentialKeyword)
            {
                case "true":
                    return new TrueToken();
                case "false":
                    return new FalseToken();
                case "and":
                    return new AndToken();
                case "or":
                    return new OrToken();
                default:
                    throw new Exception("Expected keyword (True, False, And, Or) but found "+ potentialKeyword);
            }
        }
    }
}
//https://github.com/spavkov/BooleanLogicExpressionParser
namespace QuantConnect
{
    public class OperandToken : Token
    {
        
    }
    public class OrToken : OperandToken
    {
    }

    public class AndToken : OperandToken
    {
    }

    public class BooleanValueToken : Token
    {
        
    }

    public class FalseToken : BooleanValueToken
    {
    }

    public class TrueToken : BooleanValueToken
    {
    }

    public class ParenthesisToken : Token
    {

    }

    public class ClosedParenthesisToken : ParenthesisToken
    {
    }


    public class OpenParenthesisToken : ParenthesisToken
    {
    }

    public class NegationToken : Token
    {
    }

    public abstract class Token
    {

    }
}