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(); } } } }