/* * 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 System.Linq; using QuantConnect.Data; using QuantConnect.Indicators; using QuantConnect.Securities; namespace QuantConnect.Algorithm.CSharp { /// /// Example of custom volatility model /// /// /// /// public class CustomVolatilityModelAlgorithm : QCAlgorithm { private Security _equity; public override void Initialize() { SetStartDate(2013, 10, 7); //Set Start Date SetEndDate(2015, 7, 15); //Set End Date SetCash(100000); //Set Strategy Cash // Find more symbols here: http://quantconnect.com/data _equity = AddEquity("SPY", Resolution.Daily); _equity.SetVolatilityModel(new CustomVolatilityModel(10)); } public override void OnData(Slice slice) { if (!Portfolio.Invested && !(_equity.VolatilityModel.Volatility > 0)) SetHoldings("SPY", 1); } } public class CustomVolatilityModel : IVolatilityModel { private DateTime _lastUpdate = DateTime.MinValue; private decimal _lastPrice = 0m; private bool _needsUpdate = false; private TimeSpan _periodSpan = TimeSpan.FromDays(1); private RollingWindow _window; // Volatility is a mandatory field public decimal Volatility { get; set; } = 0m; public CustomVolatilityModel(int periods) { _window = new RollingWindow(periods); } // Updates this model using the new price information in the specified security instance // Update is a mandatory method public void Update(Security security, BaseData data) { var timeSinceLastUpdate = data.EndTime - _lastUpdate; if (timeSinceLastUpdate >= _periodSpan && data.Price > 0m) { if (_lastPrice > 0) { _window.Add(data.Price / _lastPrice - 1.0m); _needsUpdate = _window.IsReady; } _lastUpdate = data.EndTime; _lastPrice = data.Price; } if (_window.Count < 2) { Volatility = 0; return; } if (_needsUpdate) { _needsUpdate = false; var mean = _window.Average(); var std = Math.Sqrt((double)_window.Sum(x => (x - mean)*(x - mean)) / _window.Count); Volatility = (std * Math.Sqrt(252d)).SafeDecimalCast(); } } // Returns history requirements for the volatility model expressed in the form of history request // GetHistoryRequirements is a mandatory method public IEnumerable GetHistoryRequirements(Security security, DateTime utcTime) // For simplicity's sake, we will not set a history requirement { return Enumerable.Empty(); } } }