| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
namespace QuantConnect
{
public class OptimizedVRP : QCAlgorithm
{
// Notes
/*
SUMMARY:
https://www.quantconnect.com/forum/discussion/comment/2442#Comment_2442
https://www.quantconnect.com/forum/discussion/444
https://www.quantconnect.com/forum/discussion/435
*/
// User-editable Fields
private string _metricsymbol = "SPY";
private int _historicalvolatilitydays = 2;
private string _quandlcode = "SPDJ/SPVIXSTR";
// Class Fields
public enum Direction { Long, Short };
private bool _firstondatacall = true;
private bool _enabletrading = true;
private Direction _direction = Direction.Long;
private int _warmupdays = 1;
StandardDeviation _lnstd;
decimal _metricdelta = 0.0m;
decimal _metricprevclose = 0.0m;
private TimeSpan _metricbarperiod = TimeSpan.FromDays(1);
private Consolidator _metricconsolidator;
// Initializer
public override void Initialize()
{
SetStartDate(2016, 1, 5);
SetEndDate(2016, 1, 7);
SetCash(10000);
AddSecurity(SecurityType.Equity, _metricsymbol, Resolution.Minute);
Securities[_metricsymbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
Securities[_metricsymbol].SetLeverage(1);
AddData<QuandlVixContract>(_quandlcode, Resolution.Daily);
// Custom Indicator: natural log version of standard deviation = standard deviation(ln(todaysclose/yesterdaysclose) : ln(yesterdaysclose/twodaysagoclose))
_metricconsolidator = new Consolidator(_metricbarperiod);
_lnstd = new StandardDeviation(_historicalvolatilitydays);
SetWarmup(_warmupdays);
}
// Event-Driven Methods
public override void OnData(Slice data)
{
UpdateLNStd(data.Bars);
// Abandon method if we're warming up the algorithm with historical data
if (IsWarmingUp)
{
if (IsEvaluationTime())
{
Log("WARM UP DAY");
AssessMetric();
}
return;
}
// Abandon method if this is the first time the OnData() method is called
if (_firstondatacall)
{
_firstondatacall = false;
_enabletrading = true;
return;
}
// Assess interval rules
if (IsEvaluationTime())
{
Log("TRADING DAY");
_enabletrading = false;
AssessMetric();
TakeAction();
}
}
// Rebalance Rules Methods
public void AssessMetric()
{
Log(String.Format("PrevClose: {0}\tLNStd: {1}", _metricprevclose, _lnstd));
}
public void TakeAction()
{
if (Portfolio[_metricsymbol].HoldStock == false)
{
SetHoldings(_metricsymbol, 0.95m);
Log(String.Format("ACTION: Setting holdings to 100% {0}.", _metricsymbol));
}
else
{
Log(String.Format("ACTION: We are already 100% on {0}. No action taken.", _metricsymbol));
}
}
// Helper Methods
public void UpdateLNStd(TradeBars data)
{
if (_metricconsolidator.Update(data[_metricsymbol]))
{
try
{
if(_metricprevclose != 0.0m)
{
_metricdelta = (decimal)Math.Log((double)data[_metricsymbol].Close/(double)_metricprevclose);
}
TradeBar bar;
if (data.TryGetValue(_metricsymbol, out bar))
{
_lnstd.Update(bar.Time, _metricdelta);
}
_metricprevclose = data[_metricsymbol].Close;
}
catch(Exception e)
{
Debug(e.Message);
}
}
}
public bool IsEvaluationTime()
{
bool satisfied = false;
if (this.Time.Hour == 23 && this.Time.Minute == 30 && _enabletrading == true) // Afternoon
satisfied = true;
else
satisfied = false;
return satisfied;
}
}
}namespace QuantConnect
{
public class QuandlVixContract : Quandl
{
public QuandlVixContract() : base(valueColumnName: "S&P 500 VIX Short-Term Index MCAP")
{
}
}
}using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;
namespace QuantConnect
{
public class Consolidator
{
private TradeBar _resultBar;
private TradeBar _workingBar;
private DateTime _start;
private TimeSpan _period;
//Result:
public TradeBar Bar
{
get
{
return _resultBar;
}
}
//Constructor: Set the period we'd like to scan
public Consolidator(TimeSpan span)
{
this._period = span;
this._resultBar = new TradeBar();
this._workingBar = new TradeBar(new DateTime(), "", Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
}
//Submit this bar, return true if we've started a new one.
public bool Update(TradeBar newBar)
{
//Intialize:
if (_start == new DateTime())
{
_start = newBar.Time;
}
//While we're less than end date, keep adding to this bar:
if (newBar.Time < (_start + _period))
{
//Building bar:
AddToBar(newBar);
return false;
}
else
{
//Completed bar: start new one:
_resultBar = _workingBar;
//Create a new bar:
_workingBar = new TradeBar(newBar.Time, newBar.Symbol, Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
//Start of this bar:
_start = newBar.Time;
AddToBar(newBar);
return true;
}
}
//Add to a tradebar
private void AddToBar(TradeBar newBar)
{
//Add this data to working bar:
if (_workingBar.Time == new DateTime()) _workingBar.Time = newBar.Time;
if (_workingBar.Symbol == "") _workingBar.Symbol = newBar.Symbol;
if (_workingBar.Open == Decimal.Zero) _workingBar.Open = newBar.Open;
if (newBar.High > _workingBar.High) _workingBar.High = newBar.High;
if (newBar.Low < _workingBar.Low) _workingBar.Low = newBar.Low;
_workingBar.Close = newBar.Close;
_workingBar.Volume = newBar.Volume;
}
}
}