| Overall Statistics |
|
Total Trades 3271 Average Win 0.83% Average Loss -0.22% Compounding Annual Return -4.595% Drawdown 51.600% Expectancy -0.103 Net Profit -40.305% Sharpe Ratio -0.178 Probabilistic Sharpe Ratio 0.002% Loss Rate 81% Win Rate 19% Profit-Loss Ratio 3.85 Alpha -0.046 Beta 0.127 Annual Standard Deviation 0.16 Annual Variance 0.025 Information Ratio -0.772 Tracking Error 0.213 Treynor Ratio -0.224 Total Fees $2860.00 |
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Option;
using QuantConnect.Util;
namespace QuantConnect.Algorithm.CSharp
{
public class PerformanceTest : QCAlgorithm
{
private const int MaxInvested = 15;
private static readonly string UnderlyingTicker = "GOOG";
private static readonly Symbol OptionSymbol = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Option, Market.USA);
private static readonly Symbol UnderlyingSymbol = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Equity, Market.USA);
private static readonly ISet<Symbol> tradedSymbols = new HashSet<Symbol>();
private static readonly ISet<Symbol> seenSymbols = new HashSet<Symbol>();
private static readonly ISet<Symbol> chainSymbols = new HashSet<Symbol>();
private DateTime dailyTracking = DateTime.Now;
private bool tradedToday = false;
public override void Initialize()
{
SetStartDate(new DateTime(2010, 1, 1));
SetEndDate(DateTime.Now);
SetCash(1000000);
AddEquity(UnderlyingSymbol, Resolution.Daily, Market.USA, false);
Option option = AddOption(UnderlyingSymbol, Resolution.Minute, Market.USA, false);
option.SetFilter(u =>
u.Expiration(30, 90)
.Strikes(10, 10)
);
// option.PriceModel = OptionPriceModels.BaroneAdesiWhaley();
}
public override void OnData(Slice slice)
{
IEnumerable<SecurityHolding> investedSecurities = Portfolio.Values.Where(sh => sh.Invested);
int count = investedSecurities.Count();
if (count > MaxInvested)
{
int countToLiquidate = count - MaxInvested;
foreach (SecurityHolding securityHolding in investedSecurities)
{
if (IsMarketOpen(securityHolding.Symbol))
{
// Debug($"Liquidating {securityHolding.Symbol} {countToLiquidate}");
Liquidate(securityHolding.Symbol);
if (--countToLiquidate <= 0)
break;
}
}
}
OptionChain chain;
if (CurrentSlice.OptionChains.TryGetValue(OptionSymbol, out chain))
{
chainSymbols.UnionWith(chain.Select(oc => oc.Symbol));
if(!tradedToday)
{
foreach (OptionContract optionContract in chain.SkipWhile(contract => tradedSymbols.Contains(contract.Symbol)))
{
seenSymbols.Add(optionContract.Symbol);
if (IsMarketOpen(optionContract.Symbol))
{
// Debug($"Sending mkt order {optionContract.Symbol}");
MarketOrder(optionContract.Symbol, Decimal.One);
break;
}
}
}
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
if (orderEvent.Status == OrderStatus.Filled || orderEvent.Status == OrderStatus.PartiallyFilled)
{
if(orderEvent.Quantity > 0)
{
// Debug($"Filled {orderEvent.Symbol}");
tradedSymbols.Add(orderEvent.Symbol);
tradedToday = true;
}
// else
// {
// Debug($"Unwound {orderEvent.Symbol}");
// }
}
}
public override void OnEndOfDay()
{
Log($"{(DateTime.Now - dailyTracking).TotalSeconds}, {Portfolio.Count}, {Portfolio.Count(kvp => kvp.Value.Invested)}, {seenSymbols.Count()}, {tradedSymbols.Count()}, {chainSymbols.Count()}");
dailyTracking = DateTime.Now;
tradedToday = false;
}
}
}namespace QuantConnect.Algorithm.Framework.Alphas
{
public class EquityHighLowAlphaModel : AlphaModel
{
private readonly Resolution _resolution;
private readonly TimeSpan _insightDuration;
private readonly Symbol _highs;
private readonly Symbol _lows;
public EquityHighLowAlphaModel(
QCAlgorithm algorithm,
int insightPeriod = 1,
Resolution resolution = Resolution.Daily
)
{
_resolution = resolution;
// Add Quandl data for the Federal Interest Rate
_highs = algorithm.AddData<Quandl52WeekHigh>("URC/NASDAQ_52W_HI" , _resolution).Symbol;
_lows = algorithm.AddData<Quandl52WeekLow>("URC/NYSE_52W_LO" , _resolution).Symbol;
_insightDuration = resolution.ToTimeSpan().Multiply(insightPeriod);
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
// Check for all Quandl Symbols in current data Slice
if (!(data.ContainsKey(_highs) && data.ContainsKey(_lows))){
return insights;
}
// Higher numbers of stocks at their 52-week low naturally correlate with recessions or
// large stock market corrections, and the opposite can be said of large numbers of stocks
// reaching their 52-week highs at the same time. When viewed like this, the spread between
// the two numbers can tell us a lot about the overall direction of the US equities
// market. If the spread between High and Low decreases and/or inverts, this is likely a
// significant indicator of a bear market. This and other metrics can be used to generate
// valuable Insights
// More URC market data can be found at Quandl
// https://www.quandl.com/data/URC-Unicorn-Research-Corporation
// Generate Insights here!
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
}
}
public class Quandl52WeekHigh : Quandl
{
public Quandl52WeekHigh()
: base(valueColumnName: "Numbers of Stocks")
{
}
}
public class Quandl52WeekLow : Quandl
{
public Quandl52WeekLow()
: base(valueColumnName: "Numbers of Stocks")
{
}
}
}using QuantConnect.Data.Custom.CBOE;
namespace QuantConnect
{
public class CboeVixAlphaModel : AlphaModel
{
private Symbol _vix;
public CboeVixAlphaModel(QCAlgorithm algorithm)
{
_vix = algorithm.AddData<CBOE>("VIX").Symbol;
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
if (!data.ContainsKey(_vix))
{
return insights;
}
var vix = data.Get<CBOE>(_vix);
// The Cboe Volatility Index® (VIX® Index) is the most popular benchmark index to measure
// the market’s expectation of future volatility. The VIX Index is based on
// options of the S&P 500® Index, considered the leading indicator of the broad
// U.S. stock market. The VIX Index is recognized as the world’s premier gauge
// of U.S. equity market volatility.
// Generate Insights here!
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
// For instruction on how to use this method, please visit
// https://www.quantconnect.com/docs/algorithm-framework/alpha-creation#Alpha-Creation-Good-Design-Patterns
}
}
}namespace QuantConnect.Algorithm.Framework.Alphas
{
public class FederalInterestRateAlphaModel : AlphaModel
{
private readonly Resolution _resolution;
private readonly TimeSpan _insightDuration;
private readonly Symbol _fedRate;
public FederalInterestRateAlphaModel(
QCAlgorithm algorithm,
int insightPeriod = 30,
Resolution resolution = Resolution.Daily
)
{
_resolution = resolution;
// Add Quandl data for the Federal Interest Rate
_fedRate = algorithm.AddData<QuandlFedRateColumns>("FRED/FEDFUNDS" , _resolution).Symbol;
_insightDuration = resolution.ToTimeSpan().Multiply(insightPeriod);
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
// Check for all Quandl Symbols in current data Slice
if (!data.ContainsKey(_fedRate)){
return insights;
}
// The Federal Interest Rate (Federal Funds Rate) is one of the most important elements
// of the US economy and any change has profound effects across all markets, but especially
// in debt-based securities, currencies, consumer spending, and a negative effect on equities
// whose companies primarily do business in international markets. The data is monthly, so
// Insight generation will not occur with a high frequency.
// Additional Federal Reserve data can be found at Quandl
// https://www.quandl.com/data/FRED-Federal-Reserve-Economic-Data
// Generate Insights here!
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
}
}
public class QuandlFedRateColumns : Quandl
{
public QuandlFedRateColumns()
// Rename the Quandl object column to the data we want, which is the column containing
// the yield in the CSV that our API call returns
: base(valueColumnName: "Value")
{
}
}
}namespace QuantConnect.Algorithm.Framework.Alphas
{
public class TreasuryYieldAlphaModel : AlphaModel
{
private readonly Resolution _resolution;
private readonly TimeSpan _insightDuration;
private readonly double _insightMagnitude;
private readonly Symbol _fedRate;
public TreasuryYieldAlphaModel(
QCAlgorithm algorithm,
int insightPeriod = 15,
double insightMagnitude = 0.0005,
Resolution resolution = Resolution.Daily
)
{
_resolution = resolution;
// Add Quandl data for FRED 10-Year Treasury Constant Maturity Rate
_fedRate = algorithm.AddData<QuandlTreasuryYieldColumns>("FRED/DGS10" , _resolution).Symbol;
_insightDuration = resolution.ToTimeSpan().Multiply(insightPeriod);
_insightMagnitude = insightMagnitude;
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
// Check for all Quandl Symbols in current data Slice
if (!data.ContainsKey(_fedRate)){
return insights;
}
// Treasury rates have been shown to affect the movement of mortgage rate, corporate and municipal bonds,
// mortgage backed securities, and a number of other debt-related securities. This can also trickle down,
// such as mortgage rate movement affecting real estate based securities.
// Additional Federal Reserve data on Treasury Bond Yields can be found at Quandl
// https://www.quandl.com/data/FRED-Federal-Reserve-Economic-Data
// Generate Insights here!
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
}
}
public class QuandlTreasuryYieldColumns : Quandl
{
/// <summary>
/// Initializes a new instance of the <see cref="QuandlMortgagePriceColumns"/> class.
/// </summary>
public QuandlTreasuryYieldColumns()
// Rename the Quandl object column to the data we want, which is the 'Value' column
// of the CSV that our API call returns
: base(valueColumnName: "Value")
{
}
}
}using QuantConnect.Data.Custom.USTreasury;
namespace QuantConnect
{
public class YieldCurveAlphaModel : AlphaModel
{
private Symbol _yieldCurve;
public YieldCurveAlphaModel(QCAlgorithm algorithm)
{
_yieldCurve = algorithm.AddData<USTreasuryYieldCurveRate>("YIELDCURVE").Symbol;
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
{
var insights = new List<Insight>();
if (data.ContainsKey(_yieldCurve))
{
var rate = data.Get<USTreasuryYieldCurveRate>().Values.First();
// The data is sourced directly from the U.S. Department of the Treasury. Also known
// as "Constant Maturity Treasury" (CMT) rates, these market yields are calculated
// from composites of indicative, bid-side market quotations (not actual transactions)
// obtained by the Federal Reserve Bank of New York at or near 3:30 PM each trading day.
// Data can be accessed the normal way via the Slice events. Slice events deliver
// unique articles to your algorithm as they happen. You can access different term
// yield curve fields such as rate.OneMonth, rate.TwoYear, rate.TwentyYear, etc.
// Generate Insights here!
}
return insights;
}
}
}