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