| Overall Statistics |
|
Total Trades 50 Average Win 0.58% Average Loss -0.73% Compounding Annual Return -1.315% Drawdown 4.800% Expectancy -0.042 Net Profit -1.314% Sharpe Ratio -0.37 Loss Rate 47% Win Rate 53% Profit-Loss Ratio 0.80 Alpha -0.011 Beta 0.095 Annual Standard Deviation 0.028 Annual Variance 0.001 Information Ratio -0.112 Tracking Error 0.131 Treynor Ratio -0.11 Total Fees $34.86 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.ML.Alpha
{
public class CoreyAlphaModel : IAlphaModel
{
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
throw new NotImplementedException();
}
public IEnumerable<Insight> Update(QCAlgorithmFramework algorithm, Slice data)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
namespace QuantConnect.Algorithm.ML.Alpha
{
public class MockAlphaModel : ConstantAlphaModel
{
public MockAlphaModel() : base(InsightType.Price, InsightDirection.Up, TimeSpan.FromMinutes(20), 0.025, null) { }
}
}
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Util;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
namespace QuantConnect.Algorithm.ML.Alphas
{
/// <summary>
/// Uses Wilder's RSI to create insights. Using default settings, a cross over below 30 or above 70 will
/// trigger a new insight.
/// </summary>
public class RsiAlphaModel : IAlphaModel
{
private readonly Dictionary<Symbol, SymbolData> _symbolDataBySymbol = new Dictionary<Symbol, SymbolData>();
private readonly int _period;
private readonly Resolution _resolution;
/// <summary>
/// Initializes a new instance of the <see cref="RsiAlphaModel"/> class
/// </summary>
/// <param name="period">The RSI indicator period</param>
/// <param name="resolution">The resolution of data sent into the RSI indicator</param>
public RsiAlphaModel(
int period = 14,
Resolution resolution = Resolution.Daily
)
{
_period = period;
_resolution = resolution;
}
/// <summary>
/// Updates this alpha model with the latest data from the algorithm.
/// This is called each time the algorithm receives data for subscribed securities
/// </summary>
/// <param name="algorithm">The algorithm instance</param>
/// <param name="data">The new data available</param>
/// <returns>The new insights generated</returns>
public IEnumerable<Insight> Update(QCAlgorithmFramework algorithm, Slice data)
{
var insights = new List<Insight>();
foreach (var kvp in _symbolDataBySymbol)
{
var symbol = kvp.Key;
var rsi = kvp.Value.RSI;
var previousState = kvp.Value.State;
var state = GetState(rsi, previousState);
if (state != previousState && rsi.IsReady)
{
var insightPeriod = _resolution.ToTimeSpan().Multiply(_period);
switch (state)
{
case State.TrippedLow:
insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Up));
break;
case State.TrippedHigh:
insights.Add(Insight.Price(symbol, insightPeriod, InsightDirection.Down));
break;
}
}
kvp.Value.State = state;
}
return insights;
}
/// <summary>
/// Cleans out old security data and initializes the RSI for any newly added securities.
/// This functional also seeds any new indicators using a history request.
/// </summary>
/// <param name="algorithm">The algorithm instance that experienced the change in securities</param>
/// <param name="changes">The security additions and removals from the algorithm</param>
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
// clean up data for removed securities
if (changes.RemovedSecurities.Count > 0)
{
var removed = changes.RemovedSecurities.ToHashSet(x => x.Symbol);
foreach (var subscription in algorithm.SubscriptionManager.Subscriptions)
{
if (removed.Contains(subscription.Symbol))
{
_symbolDataBySymbol.Remove(subscription.Symbol);
subscription.Consolidators.Clear();
}
}
}
// initialize data for added securities
var addedSymbols = new List<Symbol>();
foreach (var added in changes.AddedSecurities)
{
if (!_symbolDataBySymbol.ContainsKey(added.Symbol))
{
var rsi = algorithm.RSI(added.Symbol, _period, MovingAverageType.Wilders, _resolution);
var symbolData = new SymbolData(added.Symbol, rsi);
_symbolDataBySymbol[added.Symbol] = symbolData;
addedSymbols.Add(symbolData.Symbol);
}
}
if (addedSymbols.Count > 0)
{
// warmup our indicators by pushing history through the consolidators
algorithm.History(addedSymbols, _period, _resolution)
.PushThrough(data =>
{
SymbolData symbolData;
if (_symbolDataBySymbol.TryGetValue(data.Symbol, out symbolData))
{
symbolData.RSI.Update(data.EndTime, data.Value);
}
});
}
}
/// <summary>
/// Determines the new state. This is basically cross-over detection logic that
/// includes considerations for bouncing using the configured bounce tolerance.
/// </summary>
private State GetState(RelativeStrengthIndex rsi, State previous)
{
if (rsi > 70m)
{
return State.TrippedHigh;
}
if (rsi < 30m)
{
return State.TrippedLow;
}
if (previous == State.TrippedLow)
{
if (rsi > 35m)
{
return State.Middle;
}
}
if (previous == State.TrippedHigh)
{
if (rsi < 65m)
{
return State.Middle;
}
}
return previous;
}
/// <summary>
/// Contains data specific to a symbol required by this model
/// </summary>
private class SymbolData
{
public Symbol Symbol { get; }
public State State { get; set; }
public RelativeStrengthIndex RSI { get; }
public SymbolData(Symbol symbol, RelativeStrengthIndex rsi)
{
Symbol = symbol;
RSI = rsi;
State = State.Middle;
}
}
/// <summary>
/// Defines the state. This is used to prevent signal spamming and aid in bounce detection.
/// </summary>
private enum State
{
TrippedLow,
Middle,
TrippedHigh
}
}
}/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Securities;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm;
namespace QuantConnect.Algorithm.ML.Alpha
{
/// <summary>
/// Alpha model that uses an EMA cross to create insights
/// </summary>
public class SmaCrossoverAlphaModel : IAlphaModel
{
private readonly int _fastPeriod;
private readonly int _slowPeriod;
private readonly Resolution _resolution;
private readonly int _predictionInterval;
private readonly Dictionary<Symbol, SymbolData> _symbolDataBySymbol;
/// <summary>
/// Initializes a new instance of the <see cref="EmaCrossAlphaModel"/> class
/// </summary>
/// <param name="fastPeriod">The fast EMA period</param>
/// <param name="slowPeriod">The slow EMA period</param>
/// <param name="resolution">The resolution of data sent into the EMA indicators</param>
public SmaCrossoverAlphaModel(
int fastPeriod = 50,
int slowPeriod = 200,
Resolution resolution = Resolution.Daily
)
{
_fastPeriod = fastPeriod;
_slowPeriod = slowPeriod;
_resolution = resolution;
_predictionInterval = fastPeriod;
_symbolDataBySymbol = new Dictionary<Symbol, SymbolData>();
}
/// <summary>
/// Updates this alpha model with the latest data from the algorithm.
/// This is called each time the algorithm receives data for subscribed securities
/// </summary>
/// <param name="algorithm">The algorithm instance</param>
/// <param name="data">The new data available</param>
/// <returns>The new insights generated</returns>
public IEnumerable<Insight> Update(QCAlgorithmFramework algorithm, Slice data)
{
var insights = new List<Insight>();
foreach (var symbolData in _symbolDataBySymbol.Values)
{
if (symbolData.Fast.IsReady && symbolData.Slow.IsReady)
{
var insightPeriod = _resolution.ToTimeSpan().Multiply(_predictionInterval);
if (symbolData.FastIsOverSlow)
{
if (symbolData.Slow > symbolData.Fast)
{
insights.Add(Insight.Price(symbolData.Symbol, insightPeriod, InsightDirection.Down));
}
}
else if (symbolData.SlowIsOverFast)
{
if (symbolData.Fast > symbolData.Slow)
{
insights.Add(Insight.Price(symbolData.Symbol, insightPeriod, InsightDirection.Up));
}
}
}
symbolData.FastIsOverSlow = symbolData.Fast > symbolData.Slow;
}
return insights;
}
/// <summary>
/// Event fired each time the we add/remove securities from the data feed
/// </summary>
/// <param name="algorithm">The algorithm instance that experienced the change in securities</param>
/// <param name="changes">The security additions and removals from the algorithm</param>
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
foreach (var added in changes.AddedSecurities)
{
SymbolData symbolData;
if (!_symbolDataBySymbol.TryGetValue(added.Symbol, out symbolData))
{
// create fast/slow EMAs
var fast = algorithm.SMA(added.Symbol, _fastPeriod);
var slow = algorithm.SMA(added.Symbol, _slowPeriod);
_symbolDataBySymbol[added.Symbol] = new SymbolData
{
Security = added,
Fast = fast,
Slow = slow
};
}
else
{
// a security that was already initialized was re-added, reset the indicators
symbolData.Fast.Reset();
symbolData.Slow.Reset();
}
}
}
/// <summary>
/// Contains data specific to a symbol required by this model
/// </summary>
private class SymbolData
{
public Security Security { get; set; }
public Symbol Symbol => Security.Symbol;
public SimpleMovingAverage Fast { get; set; }
public SimpleMovingAverage Slow { get; set; }
/// <summary>
/// True if the fast is above the slow, otherwise false.
/// This is used to prevent emitting the same signal repeatedly
/// </summary>
public bool FastIsOverSlow { get; set; }
public bool SlowIsOverFast => !FastIsOverSlow;
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.ML.PortfolioConstruction
{
public class JasonPortfolioConstructionModel : IPortfolioConstructionModel
{
public IEnumerable<IPortfolioTarget> CreateTargets(QCAlgorithmFramework algorithm, Insight[] insights)
{
throw new NotImplementedException();
}
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
namespace QuantConnect.Algorithm.ML.PortfolioConstruction
{
public class MockPortfolioConstructionModel : EqualWeightingPortfolioConstructionModel { }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.ML.RiskManagement
{
public class JasonRiskManagementModel : IRiskManagementModel
{
public IEnumerable<IPortfolioTarget> ManageRisk(QCAlgorithmFramework algorithm, IPortfolioTarget[] targets)
{
throw new NotImplementedException();
}
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.ML.RiskManagement
{
public class MockRiskManagementModel : NullRiskManagementModel { }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.ML.UniverseSelection
{
public class AdamUniverseSelectionModel : IUniverseSelectionModel
{
public IEnumerable<Universe> CreateUniverses(QCAlgorithmFramework algorithm)
{
throw new NotImplementedException();
}
}
}
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using System;
using System.Collections.Generic;
using Accord.MachineLearning.VectorMachines;
using Accord.MachineLearning.VectorMachines.Learning;
using System.Linq;
using QuantConnect.Securities.Option;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Using rolling windows for efficient storage of historical data; which automatically clears after a period of time.
/// </summary>
/// <meta name="tag" content="using data" />
/// <meta name="tag" content="history and warm up" />
/// <meta name="tag" content="history" />
/// <meta name="tag" content="warm up" />
/// <meta name="tag" content="indicators" />
/// <meta name="tag" content="rolling windows" />
public class RollingWindowAlgorithm : QCAlgorithm
{
static int trainSize = 25;
// private RollingWindow<TradeBar> _window;
private RollingWindow<IndicatorDataPoint> _smaWin;
private RollingWindow<IndicatorDataPoint> _atrWin;
private RollingWindow<IndicatorDataPoint> _vwapWin;
private RollingWindow<IndicatorDataPoint> _admWin;
private RollingWindow<IndicatorDataPoint> _stdWin;
double prediction = 0;
double actualVol = 0;
double currentATR = 0;
double predictionAtTrade = 0;
double actualVolAtTrade = 0;
double currentVolAtTrade = 0;
private const string UnderlyingTicker = "SPY";
// public readonly Symbol Underlying = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Equity, Market.USA);
public readonly Symbol OptionSymbol = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Option, Market.USA);
LinearRegressionNewtonMethod teacher = new LinearRegressionNewtonMethod();
SupportVectorMachine svm;
Queue<double[]> _samples = new Queue<double[]>(trainSize);
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2015,1,1); // Set Start Date
SetEndDate(2016,1,1); // Set End Date
SetCash(100000); // Set Strategy Cash
// Find more symbols here: http://quantconnect.com/data
//AddEquity(UnderlyingTicker, Resolution.Daily);
var equity = AddEquity(UnderlyingTicker);
var option = AddOption(UnderlyingTicker);
option.PriceModel = OptionPriceModels.CrankNicolsonFD();
option.SetFilter(-1, 1, TimeSpan.Zero, TimeSpan.FromDays(21));
// option.SetFilter(u => u.IncludeWeeklys()
// .Strikes(-2, +2)
// .Expiration(TimeSpan.Zero, TimeSpan.FromDays(10)));
//Creates a Rolling Window indicator to keep the 2 TradeBar
// _window = new RollingWindow<TradeBar>(2); // For other security types, use QuoteBar
// Plot("ATR current",_atrWin[0]);
// Plot("Prediction", prediction);
// Plot("Actual", labels[0]);
//option.SetFilter(-1, 1, TimeSpan.FromDays(19), TimeSpan.FromDays(21));
Chart plotter = new Chart("Plotter");
plotter.AddSeries(new Series("ATR CURRENT", SeriesType.Line,0 ));
plotter.AddSeries(new Series("Prediction", SeriesType.Line,0 ));
plotter.AddSeries(new Series("Label", SeriesType.Line,0));
plotter.AddSeries(new Series("ImpliedVolatility", SeriesType.Scatter,0));
AddChart(plotter);
Chart scatter = new Chart("Scatter");
scatter.AddSeries(new Series("ATR", SeriesType.Line,0));
scatter.AddSeries(new Series("Prediction At Trade", SeriesType.Scatter,0));
//scatter.AddSeries(new Series("Actual At Trade", SeriesType.Scatter,0));
scatter.AddSeries(new Series("ImpliedVolatility At Trade", SeriesType.Scatter,0));
AddChart(scatter);
teacher = new LinearRegressionNewtonMethod()
{
Tolerance = 1e-5,
// UseComplexityHeuristic = true
Complexity = 10
};
// Creates an indicator and adds to a rolling window when it is updated
SMA("SPY", 20).Updated += (sender, updated) => _smaWin.Add(updated);
_smaWin = new RollingWindow<IndicatorDataPoint>(trainSize);
ATR("SPY", 20).Updated += (sender, updated) => _atrWin.Add(updated);
_atrWin = new RollingWindow<IndicatorDataPoint>(trainSize);
VWAP("SPY", 20).Updated += (sender, updated) => _vwapWin.Add(updated);
_vwapWin = new RollingWindow<IndicatorDataPoint>(trainSize);
ADXR("SPY", 20).Updated += (sender, updated) => _admWin.Add(updated);
_admWin = new RollingWindow<IndicatorDataPoint>(trainSize);
STD("SPY", 20).Updated += (sender, updated) => _stdWin.Add(updated);
_stdWin = new RollingWindow<IndicatorDataPoint>(trainSize);
SetBenchmark(equity.Symbol);
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice data)
{
if(!Portfolio.Invested){
// Add SPY TradeBar in rollling window
var contracts = OptionChainProvider.GetOptionContractList(UnderlyingTicker, data.Time);
var underlyingPrice = Securities[UnderlyingTicker].Price;
// Wait for windows to be ready.
if (!_stdWin.IsReady || !_smaWin.IsReady|| !_atrWin.IsReady|| !_vwapWin.IsReady|| !_admWin.IsReady) return;
// double[] labels = new double[trainSize];
// double[] featureRow = new double[4];
// _samples.Clear();
// for(int i = 0; i< trainSize;i++){
// //labels[i] = Convert.ToDouble(_stdWin[i])*Math.Sqrt(252);
// labels[i] = Convert.ToDouble(_atrWin[i]);
// featureRow[0] = Convert.ToDouble(_smaWin[i]);
// featureRow[1] = Convert.ToDouble(_stdWin[i]);
// featureRow[2] = Convert.ToDouble(_vwapWin[i]);
// featureRow[3] = Convert.ToDouble(_admWin[i]);
// _samples.Enqueue(featureRow);
// //Debug("Current label:"+featureRow[3]);
// }
// //Debug("LABEL: "+labels[0]);
// double[][] inputs = _samples.ToArray();
// currentATR = labels[0];
// //labels = labels.Skip(20).ToArray();
// labels = labels.Take(labels.Count()-20).ToArray();
// actualVolAtTrade = labels[0];
// //inputs = inputs.Take(inputs.Count()-20).ToArray();
// inputs = inputs.Skip(20).ToArray();
// //var OffsetInputs = new double[160];
// //Array.Copy(inputs, 20,OffsetInputs,0,160);
// //Debug("Length:"+inputs.Length);
// //Debug("Training...");
// // instantiate new Support Vector Machine
// var teacher = new LinearRegressionNewtonMethod()
// {
// Tolerance = 1e-5,
// // UseComplexityHeuristic = true
// Complexity = 10
// };
// var svm = teacher.Learn(inputs, labels);
// //Debug("Testing...:" + svm.Score(inputs[0]));
//prediction = svm.Score(inputs[0]);
OptionChain chain;
//Debug("Are we invested?:" +Portfolio.Invested);
//Debug("Time: "+ UtcTime);
//if(!Portfolio.Invested){
Train();
prediction = predict(Convert.ToDouble(_smaWin[0]),Convert.ToDouble(_stdWin[0]),Convert.ToDouble(_vwapWin[0]),Convert.ToDouble(_admWin[0]));
if (data.OptionChains.TryGetValue(OptionSymbol, out chain))
{
// we find at the money (ATM) put contract with farthest expiration
var atmPut = chain
.OrderByDescending(x => x.Expiry)
.ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))
.ThenByDescending(x => x.Right)
.FirstOrDefault();
var atmCall = chain
.OrderByDescending(x => x.Expiry)
.ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))
.ThenBy(x => x.Right)
.FirstOrDefault();
if(atmCall.Greeks.Delta == 0)return;
if(atmPut.Greeks.Delta == 0)return;
int numContracts = 3;
int numSharesC = numContracts*(int)Math.Round(100*atmCall.Greeks.Delta);
int numSharesP = numContracts*(int)Math.Round(100*atmPut.Greeks.Delta);
Log("Underlying Price: "+atmCall.UnderlyingLastPrice);
Log("Strike Price: " +atmCall.Strike);
Log("Expiry:" + atmCall.Expiry);
Log("Expiry:" + atmPut.Expiry);
Log("ImpliedVolatility:" + atmCall.ImpliedVolatility);
Log("Prediction:" + prediction);
Log("Delta:" + atmCall.Greeks.Delta);
predictionAtTrade = prediction;
actualVolAtTrade = actualVolAtTrade;
currentVolAtTrade = currentATR;
Plot("Scatter","ATR", currentVolAtTrade);
Plot("Scatter","Prediction At Trade", predictionAtTrade);
//Plot("Scatter","Actual At Trade", actualVolAtTrade);
Plot("Scatter","ImpliedVolatility At Trade", atmPut.ImpliedVolatility);
// if(prediction > (double)atmCall.ImpliedVolatility){
// //MarketOrder(atmPut.Symbol, 1);
// MarketOrder(atmCall.Symbol, numContracts);
// //MarketOrder("SPY",-numSharesC);
// }
// if(prediction < (double)atmCall.ImpliedVolatility){
// MarketOrder(atmCall.Symbol, -numContracts);
// //MarketOrder("SPY",numSharesC);
// numSharesC = -numSharesC;
// }
if(prediction > (double)atmPut.ImpliedVolatility){
//MarketOrder(atmPut.Symbol, 1);
MarketOrder(atmPut.Symbol, numContracts);
numSharesP = -numSharesP;
//MarketOrder("SPY",numSharesP);
}
if(prediction < (double)atmPut.ImpliedVolatility){
//MarketOrder(atmPut.Symbol, -1);
MarketOrder(atmPut.Symbol, -numContracts);
//MarketOrder("SPY",-numSharesP);
}
// MarketOrder("SPY",numSharesC+numSharesP);
MarketOrder("SPY",numSharesP);
}
}
// if (!Portfolio.Invested)
// {
// foreach (var chain in data.OptionChains)
// {
// var underlying = Securities[chain.Key.Underlying];
// //var c = chain.Value.FirstOrDefault();
// foreach (var contract in chain.Value)
// {
// if(contract.Right == OptionRight.Put)continue;
// Debug("ImpliedVolatility: "+(double)contract.ImpliedVolatility*100);
// Debug("Prediction: "+ prediction);
// Debug("Underlying Price: "+contract.UnderlyingLastPrice);
// Debug("Strike Price: " +contract.Strike);
// Debug("Right:" + contract.Right);
// Debug("Expiry:" + contract.Expiry);
// if(prediction>(double)contract.ImpliedVolatility*100){
// Debug("Long");
// MarketOrder(contract.Symbol, 1);
// break;
// }
// if(prediction<(double)contract.ImpliedVolatility*100){
// Debug("Short");
// MarketOrder(contract.Symbol, -1);
// break;
// }
// break;
// }
// break;
// }
// }
}
public void Train()
{
double[] labels = new double[trainSize];
double[] featureRow = new double[4];
_samples.Clear();
for(int i = 0; i< trainSize;i++){
//labels[i] = Convert.ToDouble(_stdWin[i])*Math.Sqrt(252);
labels[i] = Convert.ToDouble(_atrWin[i]);
featureRow[0] = Convert.ToDouble(_smaWin[i]);
featureRow[1] = Convert.ToDouble(_stdWin[i]);
featureRow[2] = Convert.ToDouble(_vwapWin[i]);
featureRow[3] = Convert.ToDouble(_admWin[i]);
_samples.Enqueue(featureRow);
//Debug("Current label:"+featureRow[3]);
}
//Debug("LABEL: "+labels[0]);
double[][] inputs = _samples.ToArray();
currentATR = labels[0];
//labels = labels.Skip(20).ToArray();
labels = labels.Take(labels.Count()-20).ToArray();
actualVolAtTrade = labels[0];
//inputs = inputs.Take(inputs.Count()-20).ToArray();
inputs = inputs.Skip(20).ToArray();
//var OffsetInputs = new double[160];
//Array.Copy(inputs, 20,OffsetInputs,0,160);
//Debug("Length:"+inputs.Length);
//Debug("Training...");
// instantiate new Support Vector Machine
teacher = new LinearRegressionNewtonMethod()
{
Tolerance = 1e-5,
// UseComplexityHeuristic = true
Complexity = 10
};
svm = teacher.Learn(inputs, labels);
}
public double predict(double sma, double std, double vwap, double atd)
{
var row = new double[]{sma,std,vwap,atd};
return svm.Score(row);
}
public override void OnEndOfDay()
{
//Debug("Are we invested?:" +Portfolio.Invested);
//Debug("Time: "+ UtcTime);
//Debug("Holdings: "+Portfolio[UnderlyingTicker].Quantity);
Plot("Plotter","ATR current",_atrWin[0]);
Plot("Plotter","Prediction", prediction);
Plot("Plotter","Label", actualVolAtTrade);
Plot("Scatter","ATR",_atrWin[0]);
}
public override void OnOrderEvent(OrderEvent assignmentEvent)
{
Debug("HELLO:"+ assignmentEvent);
Log(assignmentEvent.ToString());
if(assignmentEvent.Message == "Option Exercise/Assignment"||assignmentEvent.Message == "Adjusting(or removing) the exercised/assigned option"||assignmentEvent.Message == "Simulated option assignment before expiration"){
Liquidate();
}
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Algorithm;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Risk;
namespace QuantConnect.Algorithm.ML.UniverseSelection
{
public class MockUniverseSelectionModel : ManualUniverseSelectionModel
{
public MockUniverseSelectionModel() : base(Symbol.Create("SPY", SecurityType.Equity, Market.USA)) { }
}
}