Overall Statistics
Total Trades
1815
Average Win
0.06%
Average Loss
-0.07%
Compounding Annual Return
-94.959%
Drawdown
9.000%
Expectancy
-0.114
Net Profit
-7.789%
Sharpe Ratio
0
Loss Rate
51%
Win Rate
49%
Profit-Loss Ratio
0.82
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
using System;
using System.Collections;
using System.Collections.Generic;

namespace QuantConnect.Algorithm.CSharp
{
    class CircularBuffer<T> : IEnumerable<T>
    {
        private class Iterator : IEnumerator<T>
        {
            private readonly CircularBuffer<T> _circularBuffer;
            private int _index;
            private int _count;

            public Iterator(CircularBuffer<T> circularBuffer)
            {
                _circularBuffer = circularBuffer;
                Reset();
            }

            public T Current
            {
                get
                {
                    return _circularBuffer._array[_index];
                }
            }

            object IEnumerator.Current
            {
                get
                {
                    return _circularBuffer._array[_index];
                }
            }

            public void Dispose()
            {
            }

            public bool MoveNext()
            {
                if (_count < _circularBuffer.Count)
                {
                    _count += 1;
                    if (_index < _circularBuffer._array.Length - 1)
                        _index += 1;
                    else
                        _index = 0;

                    return true;
                }

                return false;
            }

            public void Reset()
            {
                _index = _circularBuffer._position >= _circularBuffer._array.Length?
                    _circularBuffer._position % _circularBuffer._array.Length //oldest element is next we will overwrite
                    : 0; //oldest element is at start
                _count = 0;
            }
        }

        private class ReverseIterator : IEnumerator<T>
        {
            private readonly CircularBuffer<T> _circularBuffer;
            private int _index;
            private int _count;

            public ReverseIterator(CircularBuffer<T> circularBuffer)
            {
                _circularBuffer = circularBuffer;
                Reset();
            }

            public T Current
            {
                get
                {
                    return _circularBuffer._array[_index];
                }
            }

            object IEnumerator.Current
            {
                get
                {
                    return _circularBuffer._array[_index];
                }
            }

            public void Dispose()
            {
            }

            public bool MoveNext()
            {
                if (_count < _circularBuffer.Count)
                {
                    _count += 1;
                    if (_index > 0)
                        _index -= 1;
                    else
                        _index = _circularBuffer._array.Length - 1;

                    return true;
                }

                return false;
            }

            public void Reset()
            {
                _index = (_circularBuffer._position - 1) % _circularBuffer._array.Length;
                _count = 0;
            }
        }

        private class ReverseEnumerable : IEnumerable<T>
        {
            private readonly CircularBuffer<T> _circularBuffer;

            public ReverseEnumerable(CircularBuffer<T> circularBuffer)
            {
                _circularBuffer = circularBuffer;
            }

            public IEnumerator<T> GetEnumerator()
            {
                return new ReverseIterator(_circularBuffer);
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return new ReverseIterator(_circularBuffer);
            }
        }

        readonly T[] _array;
        private int _position;

        public CircularBuffer(T[] array)
        {
            _array = array;
        }

        public CircularBuffer(int numElements)
        {
            _array = new T[numElements];
        }

        public int Count
        {
            get { return Math.Min(_position, _array.Length); }
        }

        public void Clear()
        {
            _position = 0;

            for (int i = 0; i < _array.Length; ++i)
            {
                _array[i] = default(T);
            }
        }

        public void Add(T element)
        {
            _array[_position++ % _array.Length] = element;
        }

        public T Take()
        {
            return _array[_position++ % _array.Length]; //basically, to allow object reuse
        }

        public T Swap(T element)
        {
            int index = _position++ % _array.Length;
            T oldElement = _array[index];
            _array[index] = element;
            return oldElement;
        }

        public T GetOldest()
        {
            return _position >= _array.Length? _array[_position % _array.Length] : _array[0];
        }

        public T GetNewest()
        {
            return _array[(_position - 1) % _array.Length];
        }

        public IEnumerator<T> GetEnumerator()
        {
            return new Iterator(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Iterator(this);
        }

        public IEnumerable<T> Reverse()
        {
            return new ReverseEnumerable(this);
        }

        public bool IsFull
        {
            get { return _position >= _array.Length; }
        }

        public bool IsEmpty
        {
            get { return _position == 0; }
        }

        public void Restart()
        {
            _position = 0;
        }

        public T[] Underlying
        {
            get { return _array; }
        }
    }
}
using Accord.Statistics.Models.Regression.Linear;
using QuantConnect.Data.Market;
using QuantConnect.Securities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics.Statistics;
using Accord.Statistics.Models.Fields.Functions;
using Accord.Statistics.Models.Fields;
using Accord.Statistics.Models.Fields.Learning;
using QuantConnect.Indicators;

namespace QuantConnect.Algorithm.CSharp
{
    partial class SuperSlowSetHoldings : QCAlgorithm
    {
        private const decimal _securityLeverage = 10m;
        private const decimal _portfolioLeverage = 4.0m;

        public override void Initialize()
        {
            SetStartDate(2014, 11, 1);
            SetEndDate(2016, 09, 01);
            //SetStartDate(2005, 11, 1);
            //SetEndDate(2016, 09, 01);
            SetCash(10000);

            try
            {
                ActualInitialization();
            }
            catch (Exception e)
            {
                ReportException(e, this);
            }
        }

        private class Tradable
        {
            private readonly Security _security;
            internal readonly SuperSlowSetHoldings _algo;
            private readonly Random _rng = new Random();

            public Tradable(SuperSlowSetHoldings algo, Security security)
            {
                _algo = algo;
                _security = security;

                _algo.Schedule.On(_algo.DateRules.EveryDay(security.Symbol), _algo.TimeRules.AfterMarketOpen(security.Symbol, 1), OnAfterOpen);
                _algo.Schedule.On(_algo.DateRules.EveryDay(security.Symbol), _algo.TimeRules.BeforeMarketClose(security.Symbol, 7), OnBeforeClose);
            }

            public Security Security
            {
                get { return _security; }
            }

            public Symbol Symbol
            {
                get { return _security.Symbol; }
            }

            public double GetScoreForRank()
            {
                return _rng.NextDouble();
            }

            private void OnAfterOpen()
            {
                if (_security.HoldStock)
                {
                    _algo.Log("Liquidating " + Symbol.ID + " on open, not supposed to be held");
                    _algo.Liquidate(Symbol);
                }

                _algo.EnableTradable(this);
            }

            private void OnBeforeClose()
            {
                _algo.DisableTradable(this);

                 _algo.Liquidate(Symbol);
            }

        }

        private readonly List<Tradable> _tradables = new List<Tradable>();

        private void ActualInitialization()
        {
            SetBrokerageModel(Brokerages.BrokerageName.OandaBrokerage);

            const Resolution resolution = Resolution.Minute;

            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURAUD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURCAD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURCHF", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURCZK", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURDKK", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURGBP", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURHKD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURHUF", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURJPY", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURNOK", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURNZD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURPLN", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURSEK", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURSGD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURTRY", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURUSD", resolution, Market.Oanda, true, _securityLeverage, false)));
            _tradables.Add(new Tradable(this, AddSecurity(SecurityType.Forex, "EURZAR", resolution, Market.Oanda, true, _securityLeverage, false)));

            //SetBenchmark(security.Symbol);

            Schedule.On(DateRules.Every(DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday),
                TimeRules.Every(TimeSpan.FromMinutes(15)), RebalanceTick);
        }

        private void RebalanceTick()
        {
            Tradable goLong = null;
            Tradable goShort = null;
            if (_enabledTradables.Count >= 2)
            {
                _enabledTradables.Sort((x, y) => x.GetScoreForRank().CompareTo(y.GetScoreForRank()));

                var lowest = _enabledTradables[0];
                var highest = _enabledTradables[_enabledTradables.Count - 1];
                if (lowest.GetScoreForRank() != 0 && highest.GetScoreForRank() != 0)
                {
                    goLong = highest;
                    goShort = lowest;
                }
            }

            if (_currentLong != goLong || _currentShort != goShort)
            {
                _currentLong = goLong;
                _currentShort = goShort;
                Rebalance();
            }
        }

        public static void ReportException(Exception e, QCAlgorithm algo)
        {
            algo.Error(algo.Time + ": " + e.Message + "\n" + e.StackTrace);
            algo.Log(algo.Time + ": " + e.Message + "\n" + e.StackTrace);
        }

        private Tradable _currentLong;
        private Tradable _currentShort;

        public void OnData(TradeBars bars)
        {
            /*foreach (var tradable in _tradables)
            {
                var symbol = tradable.Symbol;
                if (bars.ContainsKey(symbol))
                    tradable.OnBar(bars[symbol]);
            }*/
        }

        private readonly List<Tradable> _enabledTradables = new List<Tradable>();
        private void EnableTradable(Tradable tradable)
        {
            _enabledTradables.Add(tradable);
        }

        private void DisableTradable(Tradable tradable)
        {
            _enabledTradables.Remove(tradable);
        }

        //private double _lastPortfolioLeverage;
        private void Rebalance()
        {
            double targetPortfolioLeverage = (double)_portfolioLeverage;

            if (_currentLong != null || _currentShort != null)
            {
                if (_currentLong != null)
                {
                    try
                    {
                        SetHoldings(_currentLong.Symbol, targetPortfolioLeverage * 0.5);
                    }
                    catch (DivideByZeroException) //yes... SetHoldings implementation is somewhat sketchy ;)
                    {

                    }
                }
                
                if (_currentShort != null)
                {
                    try
                    {
                        SetHoldings(_currentShort.Symbol, targetPortfolioLeverage * -0.5);
                    }
                    catch (DivideByZeroException)
                    {

                    }
                }
                
                var liquidate = Securities.Where(x => x.Value.HoldStock && x.Key != _currentShort.Symbol && x.Key != _currentLong.Symbol);
                foreach (var kv in liquidate)
                {
                    Liquidate(kv.Key);
                }
            }
            else
            {
                if (Portfolio.HoldStock)
                    Liquidate();
            }
        }
    }
}