| 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();
}
}
}