using Accord.Extensions;
using QuantConnect.Data.Market;
namespace QuantConnect.Indicators
{
public class WilliamsFractals : TradeBarIndicator
{
private readonly RollingWindow<TradeBar> _fractal;
private readonly int _fractalMidIndex;
private decimal _barryUp;
private decimal _barryDown;
public decimal BarryUp => _barryUp;
public decimal BarryDown => _barryDown;
public decimal MidPoint => (_barryUp - _barryDown) / 2m;
public override bool IsReady => _fractal.IsReady;
public WilliamsFractals(int fractalLength = 5) : this("WilliamsFractals" + fractalLength, fractalLength)
{
}
public WilliamsFractals(string name, int fractalLength = 5) : base(name)
{
_fractal = new RollingWindow<TradeBar>(fractalLength);
_fractalMidIndex = fractalLength / 2 - (fractalLength % 2 == 0 ? 1 : 0);
}
protected override decimal ComputeNextValue(TradeBar input)
{
_fractal.Add(input);
if (!_fractal.IsReady) return MidPoint;
if (_fractal.IndexOfMax((bar, index) => bar.High) == _fractalMidIndex)
{
_barryUp = input.High;
}
if (_fractal.IndexOfMin((bar, index) => bar.Low) == _fractalMidIndex)
{
_barryDown = input.Low;
}
return MidPoint;
}
}
}
namespace QuantConnect.CSharp.Algorithms
{
public class ScalpingAlgorithm : QCAlgorithm
{
private WilliamsFractals _wf;
private string symbol = "SPXL";
public override void Initialize()
{
SetStartDate(2016, 4, 1);
SetEndDate(2016, 6, 5);
SetCash(30000);
AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
Securities[symbol].FeeModel = new ConstantFeeModel(1.0m);
_wf = new WilliamsFractals();
var fiveMinuteConsolidator= new TradeBarConsolidator(TimeSpan.FromMinutes(35));
fiveMinuteConsolidator.DataConsolidated += FiveMinuteBarHandler;
SubscriptionManager.AddConsolidator(symbol, fiveMinuteConsolidator);
}
public void FiveMinuteBarHandler(object sender, TradeBar data)
{
_wf.Update(data);
if (_wf.IsReady)
{
if (data.Price >= _wf.BarryUp)
{
SetHoldings(symbol, -.50m);
}
else if (data.Price <= _wf.BarryDown)
{
SetHoldings(symbol, .50m);
}
}
}
}
}