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 { /// <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 = 1; 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)) { _algorithm.Debug("alpha"); _algorithm.Log("Alpha3"); //_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;//1 - _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)); targets.Add(symbol, new PortfolioTarget(symbol, (decimal)0.25)); } //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
using System; using System.Linq; using QuantConnect.Indicators; using QuantConnect.Models; using System.Net; 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"; //string[] initial_universe = new string[110] {"ABM","ABTL","ACAT","ADSK","AEO","AIR","AMBA","AMD","AMID","ANH","ASCMA","ASNA","ASPS","ATI","AXGN","AZZ","BCPC","BDN","BFAM","BGFV","BGG","BNFT","BOFI","BOX","BSQR","BWS","CAKE","CBL","CEMP","CHKE","CMRX","CNBKA","CONN","CPAH","CPHD","CPSS","CSII","CYH","DEPO","DGI","DHF","DM","EGBN","EGHT","ELGX","ENTA","ENV","ERI","FCFS","FCH","FIVE","FIX","FMO","FOLD","FPRX","FRAN","FSFR","FSP","GABC","GCO","GHL","GNMK","GTT","HEI","HWAY","IBP","IMGN","IPI","IRET","IRWD","ISIL","JVA","KAR","KMG","KRO","LAYN","LDRH","LJPC","LPSN","MEP","MGNX","MNR","MTG","NEWP","NKTR","OHRP","OMED","ONB","PEB","PN","POZN","PSG","REGI","REXR","RHP","RLYP","SCSS","SHLD","SMRT","SPNC","SSP","TCAP","TCPC","TCS","THC","TTPH","UNT","VAC","YORW","SPY"}; //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>(); //string[] initial_universe = new string[109] {"ABM","ABTL","ACAT","ADSK","AEO","AIR","AMBA","AMD","AMID","ANH","ASCMA","ASNA","ASPS","ATI","AXGN","AZZ","BCPC","BDN","BFAM","BGFV","BGG","BNFT","BOFI","BOX","BSQR","BWS","CAKE","CBL","CEMP","CHKE","CMRX","CNBKA","CONN","CPAH","CPHD","CPSS","CSII","CYH","DEPO","DGI","DHF","DM","EGBN","EGHT","ELGX","ENTA","ENV","ERI","FCFS","FCH","FIVE","FIX","FMO","FOLD","FPRX","FRAN","FSFR","FSP","GABC","GCO","GHL","GNMK","GTT","HEI","HWAY","IBP","IMGN","IPI","IRET","IRWD","ISIL","JVA","KAR","KMG","KRO","LAYN","LDRH","LJPC","LPSN","MEP","MGNX","MNR","MTG","NEWP","NKTR","OHRP","OMED","ONB","PEB","PN","POZN","PSG","REGI","REXR","RHP","RLYP","SCSS","SHLD","SMRT","SPNC","SSP","TCAP","TCPC","TCS","THC","TTPH","UNT","VAC","YORW"}; _assets = new Dictionary<string, Asset>() { { "ABM", new Asset("ABM", Industry.All, 0, 0) }, { "ABTL", new Asset("ABTL", Industry.All, 0, 0) }, { "ACAT", new Asset("ACAT", Industry.All, 0, 0) }, { "ADSK", new Asset("ADSK", Industry.All, 0, 0) }, { "AEO", new Asset("AEO", Industry.All, 0, 0) }, { "AIR", new Asset("AIR", Industry.All, 0, 0) }, { "AMBA", new Asset("AMBA", Industry.All, 0, 0) }, { "AMD", new Asset("AMD", Industry.All, 0, 0) }, { "AMID", new Asset("AMID", Industry.All, 0, 0) }, { "ANH", new Asset("ANH", Industry.All, 0, 0) }, { "ASCMA", new Asset("ASCMA", Industry.All, 0, 0) }, { "ASNA", new Asset("ASNA", Industry.All, 0, 0) }, { "ASPS", new Asset("ASPS", Industry.All, 0, 0) }, { "ATI", new Asset("ATI", Industry.All, 0, 0) }, { "AXGN", new Asset("AXGN", Industry.All, 0, 0) }, { "AZZ", new Asset("AZZ", Industry.All, 0, 0) }, { "BCPC", new Asset("BCPC", Industry.All, 0, 0) }, { "BDN", new Asset("BDN", Industry.All, 0, 0) }, { "BFAM", new Asset("BFAM", Industry.All, 0, 0) }, { "BGFV", new Asset("BGFV", Industry.All, 0, 0) }, { "BGG", new Asset("BGG", Industry.All, 0, 0) }, { "BNFT", new Asset("BNFT", Industry.All, 0, 0) }, { "BOFI", new Asset("BOFI", Industry.All, 0, 0) }, { "BOX", new Asset("BOX", Industry.All, 0, 0) }, { "BSQR", new Asset("BSQR", Industry.All, 0, 0) }, //{ "BWS", new Asset("BWS", Industry.All, 0, 0) }, { "CAKE", new Asset("CAKE", Industry.All, 0, 0) }, { "CBL", new Asset("CBL", Industry.All, 0, 0) }, { "CEMP", new Asset("CEMP", Industry.All, 0, 0) }, { "CHKE", new Asset("CHKE", Industry.All, 0, 0) }, { "CMRX", new Asset("CMRX", Industry.All, 0, 0) }, { "CNBKA", new Asset("CNBKA", Industry.All, 0, 0) }, { "CONN", new Asset("CONN", Industry.All, 0, 0) }, { "CPAH", new Asset("CPAH", Industry.All, 0, 0) }, { "CPHD", new Asset("CPHD", Industry.All, 0, 0) }, { "CPSS", new Asset("CPSS", Industry.All, 0, 0) }, { "CSII", new Asset("CSII", Industry.All, 0, 0) }, { "CYH", new Asset("CYH", Industry.All, 0, 0) }, { "DEPO", new Asset("DEPO", Industry.All, 0, 0) }, { "DGI", new Asset("DGI", Industry.All, 0, 0) }, { "DHF", new Asset("DHF", Industry.All, 0, 0) }, { "DM", new Asset("DM", Industry.All, 0, 0) }, { "EGBN", new Asset("EGBN", Industry.All, 0, 0) }, { "EGHT", new Asset("EGHT", Industry.All, 0, 0) }, { "ELGX", new Asset("ELGX", Industry.All, 0, 0) }, { "ENTA", new Asset("ENTA", Industry.All, 0, 0) }, { "ENV", new Asset("ENV", Industry.All, 0, 0) }, //{ "ERI", new Asset("ERI", Industry.All, 0, 0) }, { "FCFS", new Asset("FCFS", Industry.All, 0, 0) }, { "FCH", new Asset("FCH", Industry.All, 0, 0) }, { "FIVE", new Asset("FIVE", Industry.All, 0, 0) }, { "FIX", new Asset("FIX", Industry.All, 0, 0) }, { "FMO", new Asset("FMO", Industry.All, 0, 0) }, { "FOLD", new Asset("FOLD", Industry.All, 0, 0) }, { "FPRX", new Asset("FPRX", Industry.All, 0, 0) }, { "FRAN", new Asset("FRAN", Industry.All, 0, 0) }, { "FSFR", new Asset("FSFR", Industry.All, 0, 0) }, { "FSP", new Asset("FSP", Industry.All, 0, 0) }, { "GABC", new Asset("GABC", Industry.All, 0, 0) }, { "GCO", new Asset("GCO", Industry.All, 0, 0) }, { "GHL", new Asset("GHL", Industry.All, 0, 0) }, { "GNMK", new Asset("GNMK", Industry.All, 0, 0) }, { "GTT", new Asset("GTT", Industry.All, 0, 0) }, { "HEI", new Asset("HEI", Industry.All, 0, 0) }, { "HWAY", new Asset("HWAY", Industry.All, 0, 0) }, { "IBP", new Asset("IBP", Industry.All, 0, 0) }, { "IMGN", new Asset("IMGN", Industry.All, 0, 0) }, { "IPI", new Asset("IPI", Industry.All, 0, 0) }, { "IRET", new Asset("IRET", Industry.All, 0, 0) }, { "IRWD", new Asset("IRWD", Industry.All, 0, 0) }, { "ISIL", new Asset("ISIL", Industry.All, 0, 0) }, { "JVA", new Asset("JVA", Industry.All, 0, 0) }, { "KAR", new Asset("KAR", Industry.All, 0, 0) }, { "KMG", new Asset("KMG", Industry.All, 0, 0) }, { "KRO", new Asset("KRO", Industry.All, 0, 0) }, { "LAYN", new Asset("LAYN", Industry.All, 0, 0) }, { "LDRH", new Asset("LDRH", Industry.All, 0, 0) }, //{ "LJPC", new Asset("LJPC", Industry.All, 0, 0) }, { "LPSN", new Asset("LPSN", Industry.All, 0, 0) }, { "MEP", new Asset("MEP", Industry.All, 0, 0) }, { "MGNX", new Asset("MGNX", Industry.All, 0, 0) }, { "MNR", new Asset("MNR", Industry.All, 0, 0) }, { "MTG", new Asset("MTG", Industry.All, 0, 0) }, { "NEWP", new Asset("NEWP", Industry.All, 0, 0) }, { "NKTR", new Asset("NKTR", Industry.All, 0, 0) }, { "OHRP", new Asset("OHRP", Industry.All, 0, 0) }, { "OMED", new Asset("OMED", Industry.All, 0, 0) }, { "ONB", new Asset("ONB", Industry.All, 0, 0) }, { "PEB", new Asset("PEB", Industry.All, 0, 0) }, { "PN", new Asset("PN", Industry.All, 0, 0) }, { "POZN", new Asset("POZN", Industry.All, 0, 0) }, { "PSG", new Asset("PSG", Industry.All, 0, 0) }, { "REGI", new Asset("REGI", Industry.All, 0, 0) }, { "REXR", new Asset("REXR", Industry.All, 0, 0) }, //{ "RHP", new Asset("RHP", Industry.All, 0, 0) }, { "RLYP", new Asset("RLYP", Industry.All, 0, 0) }, { "SCSS", new Asset("SCSS", Industry.All, 0, 0) }, { "SHLD", new Asset("SHLD", Industry.All, 0, 0) }, { "SMRT", new Asset("SMRT", Industry.All, 0, 0) }, { "SPNC", new Asset("SPNC", Industry.All, 0, 0) }, { "SSP", new Asset("SSP", Industry.All, 0, 0) }, { "TCAP", new Asset("TCAP", Industry.All, 0, 0) }, { "TCPC", new Asset("TCPC", Industry.All, 0, 0) }, { "TCS", new Asset("TCS", Industry.All, 0, 0) }, { "THC", new Asset("THC", Industry.All, 0, 0) }, { "TTPH", new Asset("TTPH", Industry.All, 0, 0) }, { "UNT", new Asset("UNT", Industry.All, 0, 0) }, { "VAC", new Asset("VAC", Industry.All, 0, 0) }, { "YORW", new Asset("YORW", Industry.All, 0, 0) }, { "SPY", new Asset("SPY", Industry.All, 0, 0) }, { _cashAsset, new Asset(_cashAsset, Industry.Bonds, 0, 0) } // Cash Equivalent / Bonds ETF. }; //foreach (var symbol in initial_universe) //{ // _assets.Add(symbol, new Asset(symbol, Industry.All, 0, 0)); //} } /******************************************************** * PUBLIC METHODS *********************************************************/ public void LoadAssets() { //Load the assets: foreach (var symbol in _assets.Keys) { _algorithm.AddSecurity(SecurityType.Equity, symbol, Resolution.Minute, fillDataForward:false, 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("SPY"); //} } catch (Exception err) { _algorithm.Error("AssetModule.ScreenUniverse(): Error - " + err.Message); } return _universe; } public List<string> UpdateUniverse2(String[] today_picks) { _universe.Clear(); try { _universe.Add("SPY"); //Perform any math / filtering / data search required to select the algorithm symbols for this next period. //foreach (var symbol in today_picks) //{ // _universe.Add(symbol); // _algorithm.Log("Pick: " + 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 { public string[] new_universe = new string[4]; public ImportPicks PicksData; public DateTime current_date; /******************************************************** * 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() { /* string[] initial_universe = new string[109] {"ABM","ABTL","ACAT","ADSK","AEO","AIR","AMBA","AMD","AMID","ANH","ASCMA","ASNA","ASPS","ATI","AXGN","AZZ","BCPC","BDN","BFAM","BGFV","BGG","BNFT","BOFI","BOX","BSQR","BWS","CAKE","CBL","CEMP","CHKE","CMRX","CNBKA","CONN","CPAH","CPHD","CPSS","CSII","CYH","DEPO","DGI","DHF","DM","EGBN","EGHT","ELGX","ENTA","ENV","ERI","FCFS","FCH","FIVE","FIX","FMO","FOLD","FPRX","FRAN","FSFR","FSP","GABC","GCO","GHL","GNMK","GTT","HEI","HWAY","IBP","IMGN","IPI","IRET","IRWD","ISIL","JVA","KAR","KMG","KRO","LAYN","LDRH","LJPC","LPSN","MEP","MGNX","MNR","MTG","NEWP","NKTR","OHRP","OMED","ONB","PEB","PN","POZN","PSG","REGI","REXR","RHP","RLYP","SCSS","SHLD","SMRT","SPNC","SSP","TCAP","TCPC","TCS","THC","TTPH","UNT","VAC","YORW"}; foreach (var symbol in initial_universe) { AddSecurity(SecurityType.Equity, symbol, Resolution.Minute); } */ AddData<ImportPicks>("Picks_Data", Resolution.Minute); //imports picks data //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, 9, 18); SetEndDate(2015, 9, 25); //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.Immediate); // 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(); } public void OnData(ImportPicks data) { PicksData = data; new_universe[0] = PicksData.ticker1; new_universe[1] = PicksData.ticker2; new_universe[2] = PicksData.ticker3; new_universe[3] = PicksData.ticker4; } /// <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. if (current_date.Date != PicksData.Time.Date){ _universe = AssetManager.UpdateUniverse2(new_universe); } current_date = PicksData.Time.Date; } /// <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); } public class ImportPicks : BaseData { public string ticker1; public string ticker2; public string ticker3; public string ticker4; public ImportPicks() { this.Symbol = "Picks_Data"; } public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive) { return new SubscriptionDataSource("https://www.dropbox.com/s/kzo2kdu2v7q7qc1/dataforqc.csv?dl=1", SubscriptionTransportMedium.RemoteFile); } public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive) { ImportPicks importpicks = new ImportPicks(); string[] data = line.Split(','); importpicks.Time = DateTime.Parse(data[0]).AddHours(0); // Make sure we only get this data AFTER trading day - don't want forward bias. importpicks.ticker1 = Convert.ToString(data[1]); importpicks.ticker2 = Convert.ToString(data[2]); importpicks.ticker3 = Convert.ToString(data[3]); importpicks.ticker4 = Convert.ToString(data[4]); return importpicks; } } } // End of QCU QuantFramework } // End of QuantConnect Namespace