Overall Statistics |
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 14.535% Drawdown 7.300% Expectancy 0 Net Profit 0% Sharpe Ratio 1.248 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.12 Beta -0.043 Annual Standard Deviation 0.092 Annual Variance 0.008 Information Ratio -0.01 Tracking Error 0.14 Treynor Ratio -2.642 Total Fees $1.00 |
namespace QuantConnect { /* * QuantConnect University: Full Basic Template: * * The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect. * We have explained some of these here, but the full algorithm can be found at: * https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs */ public class BasicTemplateAlgorithm : QCAlgorithm { private YangZhang yz; private StandardDeviation std; //Initialize the data and resolution you require for your strategy: public override void Initialize() { //Start and End Date range for the backtest: SetStartDate(2014, 1, 1); SetEndDate(2015, 1, 1); //Cash allocation SetCash(25000); //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily); yz = new YangZhang(30); std = new StandardDeviation(30); RegisterIndicator("SPY", yz, Resolution.Daily); RegisterIndicator("SPY", std, Resolution.Daily, Field.Close); PlotIndicator("Std", true, std); PlotIndicator("YZ", true, yz); } //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol. public void OnData(TradeBars data) { if (!yz.IsReady) return; SetHoldings("SPY", 1); //Log((yz.Current.Value).ToString()); //Log(yz.CloseVol.Current.Value.ToString()); //Log(yz.RSVol.Current.Value.ToString()); //Log(yz.RSVol.Current.Value.ToString()); //Plot("Std Price", std); //Plot("Std YZ", yz*100m); } } }
using MathNet.Numerics; namespace QuantConnect { public class AnnualizedExponentialSlope : WindowIndicator<IndicatorDataPoint> { public AnnualizedExponentialSlope(int period) : base("AdjustedSlope" + period, period) { } public AnnualizedExponentialSlope(string name, int period) : base(name, period) { } protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input) { if (window.Count < 3) return 0m; var xVals = new double[window.Count]; var yVals = new double[window.Count]; // load input data for regression for (int i = 0; i < window.Count; i++) { xVals[i] = i; // we want the log of our y values yVals[i] = Math.Log((double)window[window.Count - i - 1].Value); } //http://numerics.mathdotnet.com/Regression.html // solves y=a + b*x via linear regression var fit = Fit.Line(xVals, yVals); var intercept = fit.Item1; var slope = fit.Item2; // compute rsquared var rsquared = GoodnessOfFit.RSquared(xVals.Select(x => intercept + slope*x), yVals); // anything this small can be viewed as flat if (double.IsNaN(slope) || Math.Abs(slope) < 1e-25) return 0m; // trading days per year for us equities const int dayCount = 252; // annualize dy/dt var annualSlope = ((Math.Pow(Math.Exp(slope), dayCount)) - 1) * 100; // scale with rsquared annualSlope = annualSlope * rsquared; return (decimal) annualSlope; } } }
/* * 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 QuantConnect.Data.Market; namespace QuantConnect.Indicators { /// <summary> /// Yang Zhang Volatility /// </summary> public class YangZhang : TradeBarIndicator { private int _period; /// <summary> /// Components of the YZ Volatitily /// </summary> public IndicatorBase<TradeBar> OcCp { get; private set; } public IndicatorBase<TradeBar> CcOc { get; private set; } public IndicatorBase<TradeBar> OHL { get; private set; } public IndicatorBase<IndicatorDataPoint> MuOpen { get; private set; } public IndicatorBase<IndicatorDataPoint> MuClose { get; private set; } public IndicatorBase<IndicatorDataPoint> CloseVol { get; private set; } public IndicatorBase<IndicatorDataPoint> OpenVol { get; private set; } public IndicatorBase<IndicatorDataPoint> RSVol { get; private set; } public override bool IsReady { get { return Samples > _period; } } public YangZhang(string name, int period) : base(name) { _period = period; MuClose= new SimpleMovingAverage("MuC", period); MuOpen= new SimpleMovingAverage("MuO", period); CloseVol= new Sum("CV", period); OpenVol= new Sum("OV", period); RSVol= new SimpleMovingAverage("OV", period); TradeBar previous = null; OcCp = new FunctionalIndicator<TradeBar>(name + "_e", currentBar => { var nextValue = ComputeOcCp(previous, currentBar); previous = currentBar; return nextValue; } // in our IsReady function we just need at least two sample , trueRangeIndicator => trueRangeIndicator.Samples >= _period ); CcOc = new FunctionalIndicator<TradeBar>(name + "_", currentBar => ComputeCcOc(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period); OHL = new FunctionalIndicator<TradeBar>(name + "_", currentBar => ComputeOHL(currentBar) , trueRangeIndicator => trueRangeIndicator.Samples >= _period); } public YangZhang(int period) : this("YangZhang" + period, period) { } public static decimal ComputeOcCp(TradeBar previous, TradeBar current) { if (previous == null) { return 0m; } return (decimal)Math.Log((double)(current.Open/previous.Close)); } public static decimal ComputeCcOc(TradeBar current) { return (decimal)Math.Log((double)(current.Close/current.Open)); } public static decimal ComputeOHL(TradeBar current) { var temp1 = Math.Log((double)(current.High / current.Close))*Math.Log((double)(current.High / current.Open)); var temp2 = Math.Log((double)(current.Low / current.Close))*Math.Log((double)(current.Low / current.Open)); return (decimal)(temp1 + temp2); } protected override decimal ComputeNextValue(TradeBar input) { decimal N = (decimal)_period; CcOc.Update(input); OcCp.Update(input); OHL.Update(input); MuOpen.Update(input.Time,OcCp.Current.Value ); MuClose.Update(input.Time,CcOc.Current.Value ); var delta_sq = Math.Pow((double)(OcCp.Current.Value-MuOpen.Current.Value),2); OpenVol.Update(input.Time, (decimal) delta_sq); decimal SigmaOpen = OpenVol.Current.Value * (1/(N-1)); var delta_sq2 = Math.Pow((double)(CcOc.Current.Value-MuClose.Current.Value),2); CloseVol.Update(input.Time, (decimal) delta_sq2); decimal SigmaClose = CloseVol.Current.Value * (1/(N-1)); RSVol.Update(input.Time,OHL.Current.Value ); decimal SigmaRS = RSVol.Current.Value * (1/(N-1)); decimal sum= (SigmaOpen + (decimal).16433333 * SigmaClose + (decimal).83566667 * SigmaRS); decimal res = (decimal)(Math.Sqrt((double)sum)*Math.Sqrt((double)252)); return res ; } public override void Reset() { MuClose.Reset(); MuOpen.Reset(); OHL.Reset(); OcCp.Reset(); CcOc.Reset(); OpenVol.Reset(); CloseVol.Reset(); RSVol.Reset(); base.Reset(); } } }