Overall Statistics |
Total Trades 20 Average Win 0.02% Average Loss -0.01% Compounding Annual Return -0.740% Drawdown 2.800% Expectancy 0.539 Net Profit -0.062% Sharpe Ratio -0.046 Loss Rate 64% Win Rate 36% Profit-Loss Ratio 3.23 Alpha -0.033 Beta -0.251 Annual Standard Deviation 0.083 Annual Variance 0.007 Information Ratio 0.889 Tracking Error 0.126 Treynor Ratio 0.015 Total Fees $20.00 |
namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Alpha Generation Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Alpha Generator Module: /// </summary> public class ModuleAlpha { /******************************************************** * PRIVATE VARIABLES *********************************************************/ //Strategy Settings: private decimal _vix = 20m; private decimal _vixLowerBound = 10m; private decimal _vixUpperBound = 32m; private int _rebalancePeriod = 4; private decimal _cashTolerance = 0.01m; private decimal _minimumDeployedCapital = -0.25m; private string _cashAsset = "AGG"; //Working Variables: private DateTime _lastRebalance = new DateTime(2004, 1, 2); private decimal _activePortfolioFraction = 0.3333m; private decimal _deployedCapital = 1m; private QCUQuantFramework _algorithm; private List<string> _assets = new List<string>(); private decimal _safeCapital = 0m; private decimal _adjustLeverageToOne = 0.5m; private Dictionary<string, decimal> _historicalPrices = new Dictionary<string, decimal>(); private Dictionary<string, decimal> _activeFractionsBySymbol = new Dictionary<string, decimal>(); private Dictionary<string, decimal> _relativePrices = new Dictionary<string, decimal>(); /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Alpha Manager: /// </summary> /// <param name="algorithm">Algorithm instance</param> public ModuleAlpha(QCUQuantFramework algorithm, List<string> assetList, string cashAsset = "AGG") { this._algorithm = algorithm; this._assets = assetList; _cashAsset = cashAsset; //Remove the cash asset from the active portfolio. _assets.Remove(_cashAsset); //Find default fraction of assets _activePortfolioFraction = 1m / ((decimal)assetList.Count); foreach (var symbol in _assets) { _activeFractionsBySymbol.Add(symbol, _activePortfolioFraction); _relativePrices.Add(symbol, 1); } } /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Generate the Alpha Signal. Create a Symbol with a Strength of Conviction Indicator: /// </summary> /// <param name="prices">Latest prices data</param> /// <returns>List of commands to trade</returns> public Dictionary<string, PortfolioTarget> Scan(TradeBars prices, List<string> universe) { var targets = new Dictionary<string, PortfolioTarget>(); try { if (_algorithm.Time > _lastRebalance.Date.AddDays(_rebalancePeriod)) { //_vix = prices["VIX"].Close; _lastRebalance = _algorithm.Time; //Scale VIX fractionally 0-1 for 10-30. _deployedCapital = 1; //- ((_vix - _vixLowerBound) / (_vixUpperBound - _vixLowerBound)); //Set minimum deployed (set min to negative to allow shorts) if (_deployedCapital < _minimumDeployedCapital) _deployedCapital = _minimumDeployedCapital; //Fraction of capital preserved for bonds: _safeCapital = 0;// - _deployedCapital - _cashTolerance; targets.Add(_cashAsset, new PortfolioTarget(_cashAsset, _safeCapital * _adjustLeverageToOne)); //Use rotational logic to reduce allocation to poorly performing stocks: foreach(var symbol in _assets) { var price = prices[symbol].Close; //Find the relative prices of each stock sinc rebalance. e.g. 0.97, 1.03, 0.80 if (!_historicalPrices.ContainsKey(symbol)) _historicalPrices.Add(symbol, price); _relativePrices[symbol] = (price / _historicalPrices[symbol]); } // Baseline of all asset performance var sum = _relativePrices.Values.Sum(); foreach(var symbol in _assets) { if (sum > 0) { _activeFractionsBySymbol[symbol] = (_relativePrices[symbol] / sum); } else { _activeFractionsBySymbol[symbol] = 0; } if (symbol != _cashAsset) { targets.Add(symbol, new PortfolioTarget(symbol, _deployedCapital * _activeFractionsBySymbol[symbol] * _adjustLeverageToOne)); } //Save to calculate the rotational fraction. _historicalPrices[symbol] = prices[symbol].Close; } } } catch (Exception err) { _algorithm.Error("AlphaModule.Scan: Error -" + err.Message); } return targets; } } } // End of QCU QuantFramework } // End of QuantConnect Namespace
namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Asset/Universe Selection Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Asset Screening Module: /// </summary> public partial class ModuleAssets { /******************************************************** * PRIVATE VARIABLES *********************************************************/ //Strategy Variables: public string _cashAsset = "AGG"; //Working Variables: private QCUQuantFramework _algorithm; private Dictionary<string, Asset> _assets; private int _daysAnalysed; private List<string> _universe; /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /// <summary> /// Public access to the asset properties: /// </summary> public Dictionary<string, Asset> Assets { get { return _assets; } } /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Asset Manager: /// </summary> /// <param name="algorithm">Instance of the algorithm required</param> public ModuleAssets(QCUQuantFramework algorithm, string cashAsset = "AGG") { _daysAnalysed = 0; _algorithm = algorithm; _cashAsset = cashAsset; _universe = new List<string>(); _assets = new Dictionary<string, Asset>() { { "IBM", new Asset("IBM", Industry.Energy, 0, 0) }, { "AAPL", new Asset("AAPL", Industry.All, 0, 0) }, { "MSFT", new Asset("MSFT", Industry.All, 0, 0) }, { "SPY", new Asset("SPY", Industry.All, 0, 0) }, { _cashAsset, new Asset(_cashAsset, Industry.Bonds, 0, 0) } // Cash Equivalent / Bonds ETF. }; } /******************************************************** * PUBLIC METHODS *********************************************************/ public void LoadAssets() { //Load the assets: foreach (var symbol in _assets.Keys) { _algorithm.AddSecurity(SecurityType.Equity, symbol, Resolution.Minute, fillDataForward:true, leverage:2, extendedMarketHours:false); } } /// <summary> /// At the start of end of each trading day, select the stock universe for next day: /// </summary> /// <returns></returns> public List<string> UpdateUniverse() { _universe.Clear(); try { //Perform any math / filtering / data search required to select the algorithm symbols for this next period. foreach (var symbol in _assets.Keys) { _universe.Add(symbol); } } catch (Exception err) { _algorithm.Error("AssetModule.ScreenUniverse(): Error - " + err.Message); } return _universe; } /// <summary> /// Update the asset properties where possible /// </summary> /// <param name="symbol">Symbol of the asset we're setting.</param> /// <param name="volume"></param> public void UpdateAssetProperties(string symbol, decimal close, decimal volume) { Asset asset; if (!_assets.TryGetValue(symbol, out asset)) return; if (asset.Price == 0) asset.Price = close; if (asset.Volume == 0) asset.Volume = close; //E10 Exponential moving average prices: asset.Price = 0.1m * close + 0.9m * asset.Price; asset.Volume = 0.1m * volume + 0.9m * asset.Volume; // Update the end of day count of days counted: _daysAnalysed++; } } } // End of QCU QuantFramework } // End of QuantConnect Namespace
using MathNet.Numerics; using MathNet.Numerics.Statistics; namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Execution Management Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Trading Execution Module: with two execution style out of the box: /// -> ImmediateExecution - Send to market now. /// -> StandardDeviation - Send to market later. /// </summary> public class ModuleExecute { /******************************************************** * PRIVATE VARIABLES *********************************************************/ private QCUQuantFramework _algorithm; private Dictionary<string, decimal> _target; private ExecutionTechnique _technique; private TradeBars _prices; //Standard deviation strategy variable: private int _devWindowPeriod = 60; private double _buyPoint = -2; private double _sellPoint = 2; private double _extremePoint = 3.6; //Standard deviation working varibles private Dictionary<string, RunningStatistics> _deviationsStatistics; private Dictionary<string, double> _deviations; private Dictionary<string, FixedLengthQueue<double>> _priceQueue; private int _devSampleCount = 0; /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Execution Manager: /// </summary> /// <param name="algorithm">Algorithm instance</param> public ModuleExecute(QCUQuantFramework algorithm, ExecutionTechnique technique = ExecutionTechnique.Immediate) { //Common Execution Parameters this._algorithm = algorithm; this._target = new Dictionary<string, decimal>(); this._technique = technique; //StdDev Working Parameters this._deviations = new Dictionary<string, double>(); this._deviationsStatistics = new Dictionary<string, RunningStatistics>(); this._priceQueue = new Dictionary<string, FixedLengthQueue<double>>(); } /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Set the target quantity for a symbol. Let the risk manager processing get us to this target: /// </summary> /// <param name="symbol">Desired asset</param> /// <param name="quantity">Desired quantity</param> public void SetPortfolioTarget(Dictionary<string, PortfolioTarget> targets) { try { foreach (var symbol in targets.Keys) { if (!_target.ContainsKey(symbol)) { _target.Add(symbol, targets[symbol].Signal); } else { _target[symbol] = targets[symbol].Signal; } } } catch (Exception err) { _algorithm.Error("ModuleExecute.SetPortfolioTarget(): " + err.Message); } } /// <summary> /// Manage the execution of the algorithm delta of desired -> actual portfolio holdings: /// </summary> public void Execute(TradeBars prices) { try { _prices = prices; switch (_technique) { //Send the order to market immediate: case ExecutionTechnique.Immediate: ExecuteImmediate(); break; //Execute with at favourable standard deviations: // - Use online stdDev techinque to track prices, when significantly better than mean purchase. case ExecutionTechnique.StandardDeviation: ExecuteStandardDeviation(); break; } } catch (Exception err) { _algorithm.Error("ModuleExecute.Analyse(): " + err.Message); } } /// <summary> /// Execute the trade immediately /// </summary> private void ExecuteImmediate() { int orderId = 0; decimal deltaQuantity = 0; var delta = new Dictionary<string, decimal>(); var remove = new List<string>(); //Find the difference in number target to holdings: foreach (string symbol in _target.Keys) { decimal total = _algorithm.Portfolio.TotalHoldingsValue + _algorithm.Portfolio.Cash * _algorithm.Securities[symbol].Leverage; //2. Difference between our target % and our current holdings: (relative +- number). decimal deltaValue = (total * _target[symbol]) - _algorithm.Portfolio[symbol].HoldingsValue; //Potential divide by zero error for zero prices assets. if (Math.Abs(_algorithm.Securities[symbol].Price) > 0) { //3. Now rebalance the symbol requested: deltaQuantity = Math.Floor(deltaValue / _algorithm.Securities[symbol].Price); } //Determine if we need to place an order: if (Math.Abs(deltaQuantity) > 0) { delta.Add(symbol, deltaQuantity); } else { //Remove the targets which have 0-more stocks to fill. remove.Add(symbol); } } //If there are any decrease holdings order process them first: foreach (var symbol in delta.Keys) { deltaQuantity = delta[symbol]; if (!IncreaseHoldings(symbol, delta[symbol])) { orderId = _algorithm.MarketOrder(symbol, (int)deltaQuantity, false, "Decrease: " + symbol + " " + deltaQuantity); if (orderId < 0) { //Error placing order: adjust execution... _algorithm.Error("DECREASE Order Error: " + orderId + " " + symbol + " Quantity:" + deltaQuantity); } } } //After processed the decrease of holdings, send the increase of holdings: foreach (var symbol in delta.Keys) { deltaQuantity = delta[symbol]; if (IncreaseHoldings(symbol, delta[symbol])) { orderId = _algorithm.MarketOrder(symbol, (int)deltaQuantity, false, "Increase: " + symbol + " " + deltaQuantity); if (orderId < 0) { //Error placing order: adjust execution... _algorithm.Error("INCREASE Order Error: " + orderId + " " + symbol + " Quantity:" + deltaQuantity); } } } //Strip the stocks already filled: foreach (var symbol in remove) { _target.Remove(symbol); } } /// <summary> /// Using the supplied portfolio targets execute the trades when stddeviation is ideal. /// </summary> private void ExecuteStandardDeviation() { var badTick = false; decimal deltaQuantity = 0; var delta = new Dictionary<string, decimal>(); var remove = new List<string>(); var decreaseHoldings = false; //Update standard deviation queue: foreach (var kvp in _prices) { var symbol = kvp.Key; var price = Convert.ToDouble(kvp.Value.Close); if (!_priceQueue.ContainsKey(symbol)) { _priceQueue.Add(symbol, new FixedLengthQueue<double>(_devWindowPeriod)); } //Enqueue new data: _priceQueue[symbol].Enqueue(price); } //Only do analysis once we have sufficient data: if (_devSampleCount < _devWindowPeriod) { _devSampleCount++; return; } //Calculate current deviations from mean: foreach (var kvp in _prices) { var symbol = kvp.Key; var price = Convert.ToDouble(kvp.Value.Close); if (!_deviations.ContainsKey(symbol)) { _deviations.Add(symbol, 0); _deviationsStatistics.Add(symbol, new RunningStatistics()); } _deviationsStatistics[symbol] = new RunningStatistics(_priceQueue[symbol].ToList()); //Update the standard deviation for this symbol: filter anything too extreme as fake tick. var deviation = (price - _deviationsStatistics[symbol].Mean) / _deviationsStatistics[symbol].StandardDeviation; if (Math.Abs(deviation) < _extremePoint) { _deviations[symbol] = deviation; } else { badTick = true; } } //Filter out bad ticks: if (badTick) return; //Find the difference in number target to holdings: foreach (string symbol in _target.Keys) { var total = _algorithm.Portfolio.TotalHoldingsValue + _algorithm.Portfolio.Cash * _algorithm.Securities[symbol].Leverage; var price = _algorithm.Securities[symbol].Price; //2. Difference between our target % and our current holdings: (relative +- number). decimal deltaValue = (total * _target[symbol]) - _algorithm.Portfolio[symbol].HoldingsValue; //Potential divide by zero error for zero prices assets. if (Math.Abs(_algorithm.Securities[symbol].Price) > 0) { //3. Now rebalance the symbol requested: deltaQuantity = Math.Floor(deltaValue / _algorithm.Securities[symbol].Price); } //Determine if we need to place an order: if transaction volume more than $500. $1 fee on 1 share @ $25 trade is silly. if (Math.Abs(deltaQuantity) > 0 && (price * Math.Abs(deltaQuantity) > 500)) { delta.Add(symbol, deltaQuantity); if (!IncreaseHoldings(symbol, deltaQuantity)) decreaseHoldings = true; } else { //Remove the targets which have 0-more stocks to fill. remove.Add(symbol); } } //If there are any decrease holdings order process them first: foreach (var symbol in delta.Keys) { deltaQuantity = delta[symbol]; if (!IncreaseHoldings(symbol, deltaQuantity)) { if ( (deltaQuantity > 0 && _deviations[symbol] < _buyPoint) || (deltaQuantity < 0 && _deviations[symbol] > _sellPoint) ) { _algorithm.MarketOrder(symbol, (int)deltaQuantity, false, "Decrease: " + symbol + " " + deltaQuantity); } } } //If there are any decrease holdings commands outstanding, process them first; don't run increase holdings. if (!decreaseHoldings) { //After processed the decrease of holdings, send the increase of holdings: foreach (var symbol in delta.Keys) { deltaQuantity = delta[symbol]; if (IncreaseHoldings(symbol, deltaQuantity)) { if ( (deltaQuantity > 0 && _deviations[symbol] < _buyPoint) || (deltaQuantity < 0 && _deviations[symbol] > _sellPoint) ) { _algorithm.MarketOrder(symbol, (int)deltaQuantity, false, "Increase: " + symbol + " " + deltaQuantity); } } } } } /// <summary> /// Return true if the order would increase the holdings (long/short) of the symbol. /// </summary> private bool IncreaseHoldings(string symbol, decimal deltaQuantity) { var increaseHoldings = false; if (_algorithm.Portfolio.ContainsKey(symbol)) { if ( (_algorithm.Portfolio[symbol].IsLong && deltaQuantity > 0) || (_algorithm.Portfolio[symbol].IsShort && deltaQuantity < 0) ) { increaseHoldings = true; } if (_algorithm.Portfolio[symbol].Quantity == 0) { increaseHoldings = true; } } else { _algorithm.Error("IncreaseHoldings(): Symbol not found in portfolio"); } return increaseHoldings; } } } // End of RV Fund: }
namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Exit Management Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Exit Management Module: /// </summary> public class ModuleExit { /******************************************************** * PRIVATE VARIABLES *********************************************************/ private QCUQuantFramework _algorithm; private ExitTechnique _technique; /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Exit Strategy Manager: /// </summary> /// <param name="algorithm">Algorithm instance</param> public ModuleExit(QCUQuantFramework algorithm, ExitTechnique technique = ExitTechnique.Momentum) { this._algorithm = algorithm; this._technique = technique; } /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Scan the portfolio holdings for exit opportunities: /// </summary> public void Scan(TradeBars prices, Dictionary<string, PortfolioTarget> targets) { try { //Based on set exit technique, scan and apply switch(_technique) { //No exit system (portfolio algorithms) case ExitTechnique.None: break; } } catch (Exception err) { _algorithm.Error("ExitManager.Scan(): " + err.Message); } } } } // End of QCU QuantFramework } // End of QuantConnect Namespace
namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Notification Management Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Notification Module: /// </summary> public class ModuleNotify { /******************************************************** * PRIVATE VARIABLES *********************************************************/ private QCUQuantFramework _algorithm; private string _defaultToEmail = ""; private string _defaultPhoneNumber = ""; /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Notification Manager: /// </summary> /// <param name="algorithm">Algorithm instance</param> public ModuleNotify(QCUQuantFramework algorithm, string toEmail, string phoneNumber) { this._algorithm = algorithm; this._defaultToEmail = toEmail; this._defaultPhoneNumber = phoneNumber; } /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Send an email to the notification addresses /// </summary> /// <param name="message"></param> public void Send(string message, string toEmail = "", string ccEmail = "") { try { //Send Email if (toEmail == "") toEmail = _defaultToEmail; } catch (Exception err) { _algorithm.Error("ModuleNotify.Send(): " + err.Message); } } /// <summary> /// Send a SMS to this phone number /// </summary> /// <param name="phoneNumber"></param> public void SMS(string message, string phoneNumber = "") { try { //Send SMS if (phoneNumber == "") phoneNumber = _defaultPhoneNumber; } catch (Exception err) { _algorithm.Error("ModuleNotify.SMS(): " + err.Message); } } } } // End of QCU QuantFramework } // End of QuantConnect Namespace
namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Risk Management Module: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Risk Management Module: /// </summary> public class ModuleRisk { /******************************************************** * PRIVATE VARIABLES *********************************************************/ private QCUQuantFramework _algorithm; /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /******************************************************** * PUBLIC CONSTRUCTOR *********************************************************/ /// <summary> /// Initialize the Risk Manager: /// </summary> /// <param name="algorithm">Algorithm instance</param> public ModuleRisk(QCUQuantFramework algorithm) { this._algorithm = algorithm; } /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Analyse the list of directives, generate a quantity position size adjusting for market volatility /// </summary> /// <param name="directives">Directives to transfor.</param> public void Analyse(TradeBars prices, Dictionary<string, PortfolioTarget> targets) { try { //Control the total exposure: // // NOP. // } catch (Exception err) { _algorithm.Error("RiskModule.Analyse(): " + err.Message); } } } } // End of QCU QuantFramework } // End of QuantConnect Namespace
using System.Globalization; using System.Collections.Concurrent; namespace QuantConnect { /// <summary> /// QuantConnect QuantFramework Algorithm /// /// Initialization and Parameters: /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /// <summary> /// Algorithm Parameters: /// </summary> public static class FundParameters { /// Total Assets Under Management: public static decimal TotalFundAssets = 250000; /// Maximum Allocation Per Algorithm public static decimal AlgorithmMaximumAllocation = 50000; } /// <summary> /// Strategy Risk Parameters: /// </summary> public static class RiskParameters { /// Any position we take, set the maximum allowable risk. public static decimal RiskPerTrade = 0.18m; // 15% } /// <summary> /// Universe Selection Criteria /// </summary> public static class UniverseSelection { //10 Days Analysis Before Filtering Universe: public static decimal MinimumAnalysisPeriod = 10; //Other ideal parameters if we had data: //public static decimal MinimumMarketCapitalization = 0; etc } /// <summary> /// Contact Settings for the Algorithm Notifier /// </summary> public static class Contacts { /// Primary Contact Email Addresses public static string ToEmail = "contact@quantconnect.com"; /// Primary SMS Notification public static string PhoneNumber = "555-5555-55"; } /// <summary> /// Portfolio Target from a signal decision: /// </summary> public class PortfolioTarget { /// Symbol to Trade: public string Symbol; /// Direction Signal: -1 to +1 public decimal Signal; public PortfolioTarget(string symbol, decimal signal = 1) { this.Symbol = symbol; this.Signal = signal; } } /// <summary> /// Asset industry categories: /// </summary> public enum Industry { All, Bonds, BasicMaterials, CapitalGoods, Consumer, Energy, Financial, Services, Transportation, Technology, Healthcare, RealEstate, Utilities } /// <summary> /// Property group of an asset - Symbol, Volume, Industry, PE.. etc. For expansion later: /// </summary> public class Asset { /// Symbol of this asset: public string Symbol; /// Asset Industry Catgegory: public Industry Industry; ///Volume of the asset in millions: public decimal Volume; /// 20 Day Average Closing Price of the Asset: public decimal Price; /// Initialise the Asset Property Group: public Asset(string symbol, Industry industry, decimal price, decimal volume) { this.Symbol = symbol; this.Industry = industry; this.Volume = 0; this.Price = 0; } } /// <summary> /// Stoploss / exit technique to apply /// </summary> public enum ExitTechnique { /// No exit technique. Do not interfere. None, //Mebane Faber 10 Month Average Exit. Momentum, /// Exit immediately after achieving a prefixed gain FixedGain, /// Use a rolling stoploss immediately after taking position. FixedRollingStoploss, /// Rolling stoploss which increases closing speed exponentially. ParabolicRollingStoploss, /// Sell 20% of holdings with each 0.1% return achieved. FractionalProfitTaking } /// <summary> /// Determine execution technique for the algorithm: /// </summary> public enum ExecutionTechnique { /// Execute immediately, as fast as possible. Immediate, /// Volume weighted average price execution, wait for VWAP price or better before executing. VWAP, /// Wait for negative stddev before ordering (price favourable). StandardDeviation } } // End of RV Fund: /// <summary> /// Queue which automatically dequeues old data. /// </summary> public class FixedLengthQueue<T> : ConcurrentQueue<T> { public int Size { get; private set; } public FixedLengthQueue(int size) { Size = size; } public new void Enqueue(T obj) { base.Enqueue(obj); lock (this) { while (base.Count > Size) { T outObj; base.TryDequeue(out outObj); } } } } /// <summary> /// Custom imported data -- VIX indicator: /// </summary> public class VIX : BaseData { public decimal Open = 0; public decimal High = 0; public decimal Low = 0; public decimal Close = 0; public VIX() { this.Symbol = "VIX"; } public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive) { return new SubscriptionDataSource("https://www.quandl.com/api/v1/datasets/YAHOO/INDEX_VIX.csv?trim_start=2000-01-01&trim_end=2014-10-27&sort_order=asc&exclude_headers=true", SubscriptionTransportMedium.RemoteFile); } public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive) { VIX fear = new VIX(); //try //{ //Date Open High Low Close Volume Adjusted Close //10/27/2014 17.24 17.87 16 16.04 0 16.04 string[] data = line.Split(','); fear.Time = DateTime.ParseExact(data[0], "yyyy-MM-dd", CultureInfo.InvariantCulture); fear.Open = Convert.ToDecimal(data[1]); fear.High = Convert.ToDecimal(data[2]); fear.Low = Convert.ToDecimal(data[3]); fear.Close = Convert.ToDecimal(data[4]); fear.Symbol = "VIX"; fear.Value = fear.Close; //} //catch //{ } return fear; } } // End of VIX } // End of QuantConnect Namespace
namespace QuantConnect { /// <summary> /// /// QuantConnect University - Quant-Framework Implementation /// /// Basic algorithm framework implementation to design a robust, thorough and /// thoughtful algorithm which can meet the challenges of live trading /// /// </summary> public partial class QCUQuantFramework : QCAlgorithm { /******************************************************** * PRIVATE VARIABLES *********************************************************/ /// <summary> /// Prices of all Assets Stores Rolling Forward: /// </summary> private TradeBars _prices = new TradeBars(); /// <summary> /// Universe of symbols for today: /// </summary> private List<string> _universe = new List<string>(); /******************************************************** * PUBLIC PROPERTIES *********************************************************/ /// <summary> /// Module 1: Screen assets daily to match criteria; generate list of matching assets. /// </summary> public ModuleAssets AssetManager; /// <summary> /// Module 2: Generate alpha / signals based on desired behaviour. Signals from -1 to +1. /// </summary> public ModuleAlpha AlphaManager; /// <summary> /// Module 3: Manage Net Portfolio Cash Risk to ensure maximum 1% Exposed. /// </summary> public ModuleRisk RiskManager; /// <summary> /// Module 4: Factoring in the signal strength, apply stop loss techniques to control the position exit. /// </summary> public ModuleExit ExitManager; /// <summary> /// Module 5: Given a Desired Portfolio; Execute trades to reach this portfolio in the optimial manner possible /// </summary> public ModuleExecute ExecutionManager; /// <summary> /// Module 6: Send instant email/SMS notifications on issuing trades. /// </summary> public ModuleNotify NotificationManager; /******************************************************** * PUBLIC METHODS *********************************************************/ /// <summary> /// Initialize algorithm and create instances of all the portfolio modules /// </summary> public override void Initialize() { //Cash Asset: (asset for when market is volatile and we go to cash, using AAPL is fun) string cashAsset = "AGG"; //Backtest Range: // Make sure you check the start dates of the assets you trade. SetStartDate(2015, 5, 10); SetEndDate(2015, 6, 10); //Set Cash to $250k SetCash(FundParameters.AlgorithmMaximumAllocation); //Initalize Algorithm-A Modules: AssetManager = new ModuleAssets(this, cashAsset); // Analyse Generation of New Positions: AlphaManager = new ModuleAlpha(this, AssetManager.Assets.Keys.ToList(), cashAsset); // Monitor the Risk Profile RiskManager = new ModuleRisk(this); // Analysis of Exit Positions: ExitManager = new ModuleExit(this); // Time and Split the Orders: ExecutionManager = new ModuleExecute(this, ExecutionTechnique.StandardDeviation); // Send Notifications of Positions: NotificationManager = new ModuleNotify(this, Contacts.ToEmail, Contacts.PhoneNumber); //Load the assets universe we're trading AssetManager.LoadAssets(); //Add custom data: //AddData<VIX>("VIX", Resolution.Minute); //Get the universe for the first analysis: //_universe = AssetManager.UpdateUniverse(); } /// <summary> /// New Data Event: Process new data signal into the modules: /// </summary> /// <param name="data"></param> public void OnData(TradeBars bars) { //1. Initialize: only continue when prices completely full: if (!UpdatePrices(bars)) return; // 2. Update the Modules: var targets = AlphaManager.Scan(_prices, _universe); // 3. Quantify directives into risk-adjusted positions: RiskManager.Analyse(_prices, targets); // 4. Before Sending to Execution Manager, Scan for Exit Signal: ExitManager.Scan(_prices, targets); // 5. Issue Quantified Directives to Execution Manager: ExecutionManager.SetPortfolioTarget(targets); // 6. Issue Trade Orders to Actually Create Portfolio ExecutionManager.Execute(_prices); } /// <summary> /// New Data Event: VIX daily pricing: /// </summary> /* public void OnData(VIX data) { TradeBar vixBar = new TradeBar(); vixBar.Open = data.Open; vixBar.High = data.High; vixBar.Low = data.Low; vixBar.Close = data.Close; vixBar.Value = data.Value; vixBar.Time = data.Time; _prices["VIX"] = vixBar; } */ /// <summary> /// End of Day Scan to Update Algorithm Parameters /// </summary> /// <param name="symbol"></param> public override void OnEndOfDay(string symbol) { //Ignore non-tradeable symbols if (Securities[symbol].Type == SecurityType.Base) return; //Update the asset moving average price and volumes: AssetManager.UpdateAssetProperties(symbol, _prices[symbol].Close, Convert.ToDecimal(_prices[symbol].Volume)); //Update the universe for tomorrow. _universe = AssetManager.UpdateUniverse(); } /// <summary> /// Update the price store: /// </summary> private bool UpdatePrices(TradeBars bars) { foreach (var bar in bars.Values) { // 1.1 Record the prices for future reference: _prices[bar.Symbol] = bar; } return (_prices.Count == Portfolio.Count); } } // End of QCU QuantFramework } // End of QuantConnect Namespace