Skip to content

Commit

Permalink
Add more assertions to new options filter api regression algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
jhonabreul committed Jul 30, 2024
1 parent 1a2f118 commit ad0bd54
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 342 deletions.
139 changes: 0 additions & 139 deletions Algorithm.CSharp/BasicTemplateOptionsFilterAlgorithm.cs

This file was deleted.

99 changes: 83 additions & 16 deletions Algorithm.CSharp/OptionUniverseFilterGreeksRegressionAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Securities.Option;
Expand All @@ -31,6 +30,21 @@ public class OptionUniverseFilterGreeksRegressionAlgorithm : QCAlgorithm, IRegre
private Symbol _optionSymbol;
private bool _optionChainReceived;

protected decimal MinDelta { get; set; }
protected decimal MaxDelta { get; set; }
protected decimal MinGamma { get; set; }
protected decimal MaxGamma { get; set; }
protected decimal MinVega { get; set; }
protected decimal MaxVega { get; set; }
protected decimal MinTheta { get; set; }
protected decimal MaxTheta { get; set; }
protected decimal MinRho { get; set; }
protected decimal MaxRho { get; set; }
protected decimal MinIv { get; set; }
protected decimal MaxIv { get; set; }
protected long MinOpenInterest { get; set; }
protected long MaxOpenInterest { get; set; }

public override void Initialize()
{
SetStartDate(2015, 12, 24);
Expand All @@ -41,40 +55,93 @@ public override void Initialize()
var option = AddOption(UnderlyingTicker);
_optionSymbol = option.Symbol;

MinDelta = 0.5m;
MaxDelta = 1.5m;
MinGamma = 0.0001m;
MaxGamma = 0.0006m;
MinVega = 0.01m;
MaxVega = 1.5m;
MinTheta = -2.0m;
MaxTheta = -0.5m;
MinRho = 0.5m;
MaxRho = 3.0m;
MinIv = 1.0m;
MaxIv = 3.0m;
MinOpenInterest = 100;
MaxOpenInterest = 500;

SetOptionFilter(option);
}

protected virtual void SetOptionFilter(Option security)
{
// Contracts can be filtered by greeks, implied volatility, open interest:
security.SetFilter(u => u
.Delta(0.5m, 1.5m)
.Gamma(0.0001m, 0.0006m)
.Vega(0.01m, 1.5m)
.Theta(-2.0m, -0.5m)
.Rho(0.5m, 3.0m)
.ImpliedVolatility(1.0m, 3.0m)
.OpenInterest(100, 500));
.Delta(MinDelta, MaxDelta)
.Gamma(MinGamma, MaxGamma)
.Vega(MinVega, MaxVega)
.Theta(MinTheta, MaxTheta)
.Rho(MinRho, MaxRho)
.ImpliedVolatility(MinIv, MaxIv)
.OpenInterest(MinOpenInterest, MaxOpenInterest));

// Note: there are also shortcuts for these filter methods:
/*
security.SetFilter(u => u
.D(0.5m, 1.5m)
.G(0.0001m, 0.0006m)
.V(0.01m, 1.5m)
.T(-2.0m, -0.5m)
.R(0.5m, 3.0m)
.IV(1.0m, 3.0m)
.OI(100, 500));
.D(MinDelta, MaxDelta)
.G(MinGamma, MaxGamma)
.V(MinVega, MaxVega)
.T(MinTheta, MaxTheta)
.R(MinRho, MaxRho)
.IV(MinIv, MaxIv)
.OI(MinOpenInterest, MaxOpenInterest));
*/
}

public override void OnData(Slice slice)
{
if (slice.OptionChains.TryGetValue(_optionSymbol, out var chain) && chain.Contracts.Count > 0)
{
Log($"[{Time}] :: Recieved option chain with {chain.Contracts.Count} contracts");
Log($"[{Time}] :: Received option chain with {chain.Contracts.Count} contracts");
_optionChainReceived = true;

foreach (var contract in chain)
{
if (contract.Greeks.Delta < MinDelta || contract.Greeks.Delta > MaxDelta)
{
throw new RegressionTestException($"Delta {contract.Greeks.Delta} is not within {MinDelta} and {MaxDelta}");
}

if (contract.Greeks.Gamma < MinGamma || contract.Greeks.Gamma > MaxGamma)
{
throw new RegressionTestException($"Gamma {contract.Greeks.Gamma} is not within {MinGamma} and {MaxGamma}");
}

if (contract.Greeks.Vega < MinVega || contract.Greeks.Vega > MaxVega)
{
throw new RegressionTestException($"Vega {contract.Greeks.Vega} is not within {MinVega} and {MaxVega}");
}

if (contract.Greeks.Theta < MinTheta || contract.Greeks.Theta > MaxTheta)
{
throw new RegressionTestException($"Theta {contract.Greeks.Theta} is not within {MinTheta} and {MaxTheta}");
}

if (contract.Greeks.Rho < MinRho || contract.Greeks.Rho > MaxRho)
{
throw new RegressionTestException($"Rho {contract.Greeks.Rho} is not within {MinRho} and {MaxRho}");
}

if (contract.ImpliedVolatility < MinIv || contract.ImpliedVolatility > MaxIv)
{
throw new RegressionTestException($"Implied volatility {contract.ImpliedVolatility} is not within {MinIv} and {MaxIv}");
}

if (contract.OpenInterest < MinOpenInterest || contract.OpenInterest > MaxOpenInterest)
{
throw new RegressionTestException($"Open interest {contract.OpenInterest} is not within {MinOpenInterest} and {MaxOpenInterest}");
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ protected override void SetOptionFilter(Option security)
{
// Contracts can be filtered by greeks, implied volatility, open interest:
security.SetFilter(u => u
.D(0.5m, 1.5m)
.G(0.0001m, 0.0006m)
.V(0.01m, 1.5m)
.T(-2.0m, -0.5m)
.R(0.5m, 3.0m)
.IV(1.0m, 3.0m)
.OI(100, 500));
.D(MinDelta, MaxDelta)
.G(MinGamma, MaxGamma)
.V(MinVega, MaxVega)
.T(MinTheta, MaxTheta)
.R(MinRho, MaxRho)
.IV(MinIv, MaxIv)
.OI(MinOpenInterest, MaxOpenInterest));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ protected override void SetOptionFilter(Option security)
// but it is more flexible and allows for more complex filtering:

//security.SetFilter(u => u
// .Delta(0.5m, 1.5m)
// .Gamma(0.0001m, 0.0006m)
// .Vega(0.01m, 1.5m)
// .Theta(-2.0m, -0.5m)
// .Rho(0.5m, 3.0m)
// .ImpliedVolatility(1.0m, 3.0m)
// .OpenInterest(100, 500));
// .Delta(MinDelta, MaxDelta)
// .Gamma(MinGamma, MaxGamma)
// .Vega(MinVega, MaxVega)
// .Theta(MinTheta, MaxTheta)
// .Rho(MinRho, MaxRho)
// .ImpliedVolatility(MinIv, MaxIv)
// .OpenInterest(MinOpenInterest, MaxOpenInterest));

security.SetFilter(u => u
// This requires the following using statement in order to avoid ambiguity with the System.Linq namespace:
Expand All @@ -54,13 +54,13 @@ protected override void SetOptionFilter(Option security)
var openInterest = contractData.OpenInterest;

// More complex math can be done here for filtering, but will be simple here for demonstration sake:
return greeks.Delta > 0.5m && greeks.Delta < 1.5m &&
greeks.Gamma > 0.0001m && greeks.Gamma < 0.0006m &&
greeks.Vega > 0.01m && greeks.Vega < 1.5m &&
greeks.Theta > -2.0m && greeks.Theta < -0.5m &&
greeks.Rho > 0.5m && greeks.Rho < 3.0m &&
iv > 1.0m && iv < 3.0m &&
openInterest > 100 && openInterest < 500;
return greeks.Delta > MinDelta && greeks.Delta < MaxDelta &&
greeks.Gamma > MinGamma && greeks.Gamma < MaxGamma &&
greeks.Vega > MinVega && greeks.Vega < MaxVega &&
greeks.Theta > MinTheta && greeks.Theta < MaxTheta &&
greeks.Rho > MinRho && greeks.Rho < MaxRho &&
iv > MinIv && iv < MaxIv &&
openInterest > MinOpenInterest && openInterest < MaxOpenInterest;
})
.Select(contractData =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ protected override void SetOptionFilter(Option security)
// but it is more flexible and allows for more complex filtering:

//security.SetFilter(u => u
// .Delta(0.5m, 1.5m)
// .Gamma(0.0001m, 0.0006m)
// .Vega(0.01m, 1.5m)
// .Theta(-2.0m, -0.5m)
// .Rho(0.5m, 3.0m)
// .ImpliedVolatility(1.0m, 3.0m)
// .OpenInterest(100, 500));
// .Delta(MinDelta, MaxDelta)
// .Gamma(MinGamma, MaxGamma)
// .Vega(MinVega, MaxVega)
// .Theta(MinTheta, MaxTheta)
// .Rho(MinRho, MaxRho)
// .ImpliedVolatility(MinIv, MaxIv)
// .OpenInterest(MinOpenInterest, MaxOpenInterest));

security.SetFilter(u => u.Contracts(contracts =>
{
Expand All @@ -54,13 +54,13 @@ protected override void SetOptionFilter(Option security)
var openInterest = contract.OpenInterest;

// More complex math can be done here for filtering, but will be simple here for demonstration sake:
return greeks.Delta > 0.5m && greeks.Delta < 1.5m &&
greeks.Gamma > 0.0001m && greeks.Gamma < 0.0006m &&
greeks.Vega > 0.01m && greeks.Vega < 1.5m &&
greeks.Theta > -2.0m && greeks.Theta < -0.5m &&
greeks.Rho > 0.5m && greeks.Rho < 3.0m &&
iv > 1.0m && iv < 3.0m &&
openInterest > 100 && openInterest < 500;
return greeks.Delta > MinDelta && greeks.Delta < MaxDelta &&
greeks.Gamma > MinGamma && greeks.Gamma < MaxGamma &&
greeks.Vega > MinVega && greeks.Vega < MaxVega &&
greeks.Theta > MinTheta && greeks.Theta < MaxTheta &&
greeks.Rho > MinRho && greeks.Rho < MaxRho &&
iv > MinIv && iv < MaxIv &&
openInterest > MinOpenInterest && openInterest < MaxOpenInterest;
})
.Select(contract => contract.Symbol);
}));
Expand Down
Loading

0 comments on commit ad0bd54

Please sign in to comment.