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 { /* * 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/Lean/tree/master/Algorithm */ public class BollingerAlgo : QCAlgorithm { private List<Symbol> toTradeLong = new List<Symbol>(); private List<Symbol> toTradeShort = new List<Symbol>(); public override void Initialize() { //Start and End Date range for the backtest: SetStartDate(2014, 1, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash SetCash(25000); UniverseSettings.Resolution = Resolution.Hour; UniverseSettings.Leverage = 0; //screen universe based on if the price is above/below bollinger bands AddUniverse(coarse => { return (from c in coarse let bb = BB(c.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour) where (c.Price > bb.UpperBand || c.Price < bb.LowerBand) orderby c.DollarVolume descending select c.Symbol).Take(500); }); } //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) { //list to put stocks to trade toTradeLong.Clear(); toTradeShort.Clear(); //check which type of order to make (short or long) foreach(Symbol Key in data.Keys) { int check = checkBollinger(Key, data[Key]); if(check == 1){ toTradeLong.Add(Key); }else if(check == -1){ toTradeShort.Add(Key); } } makeTrades(); } //check whether a stock is above/below upper/lower bands. public int checkBollinger(Symbol sym, TradeBar data){ var bb = BB(sym, 20, 2, MovingAverageType.Exponential, Resolution.Hour); if (bb.UpperBand > data.Close){ //above return 1; }else if(bb.UpperBand < data.Close){ //below return -1; }else{ //within both return 0; } } public void makeTrades(){ if(Portfolio.HoldStock){ Liquidate(); } //wait until all positions are closed do { // nothing } while (Portfolio.HoldStock); int lengthLong = toTradeLong.Count; int lengthShort = toTradeShort.Count; //set each list to contain no more than 3 items if(lengthLong > 3){ lengthLong = 3; } if(lengthShort > 3){ lengthShort = 3; } //divide the cash to long and short allocations decimal cash = Portfolio.Cash; if(lengthLong != 0){ //half to long, dive the half up decimal cashLong = (cash / 2 ) / lengthLong; //iterate through and place orders for(int i = 0; i < lengthLong; i ++){ Symbol sym = toTradeLong[i]; double weight = 0.5 / lengthLong; SetHoldings(sym.Value, weight); } } if(lengthShort != 0){ //half to short, dive the half up decimal cashShort = (cash / 2 ) / lengthShort; //iterate through and place orders for(int i = 0; i < lengthShort; i ++){ Symbol sym = toTradeShort[i]; double weight = 0.5 / lengthShort; SetHoldings(sym.Value, weight * -1); } } } } }