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 Probabilistic 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 |
# Just because QC requires a main.py file to build correctly. # Launch example_usage.ipynb and inspect notebook_graphing_modules.py! class non(QCAlgorithm): def Initialize(self): # Set Start Date so that backtest has 5+ years of data self.SetStartDate(2015, 1, 6) # No need to set End Date as the final submission will be tested # up until the review date # Set $1m Strategy Cash to trade significant AUM self.SetCash(1000000) # Add a relevant benchmark, with the default being SPY self.AddEquity('SPY') self.SetBenchmark('SPY') # Use the Alpha Streams Brokerage Model, developed in conjunction with # funds to model their actual fees, costs, etc. # Please do not add any additional reality modelling, such as Slippage, Fees, Buying Power, etc. self.SetBrokerageModel(AlphaStreamsBrokerageModel()) def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' # if not self.Portfolio.Invested: # self.SetHoldings("SPY", 1)
''' Created January 2020 by Ian Rolin Larson | www.ianrlarson.com ----released for unlimited modification and distribution---- Usage: from notebook_graphing_modules import g Pass g a string ticker, eg. "GOOG", and it will output a bokeh plot in notebook using its default analysis module, included in this file. Pass it a list of tickers and it will output a column of full-sized plots--so you can check your trading logic on multiple symbols simultaneously. g takes 2 important arguments, the symbol or list of symbols and the name of a function--without parentheses. (There are 2 optional keyword arguments, 'bars' and resolution. Defaults to 360 and 'd'.) This analysis function is what you're supposed to create. Each dataframe passes this function (open,high,low,close) prices. You can use objects or global variables to store previous values for more complex analysis. You return either a start price (whichever price) and an end price (whichever extreme you want to draw to) or (None,None). These prices can be anywhere on the chart, but but I recommend drawing from the top or bottom of a candlestick to the high or low respectively. This will highlight a wick--the highlight is rectangular and as wide as a candle body By default the chart candles are black and white for clarity and the drawing is in red to stand out. Multiple colors could be used by modifying the functions herein to add another column to the dataframe (hence the analyze module would have 3 outputs) so you can select different colors to indicate various types of data. d takes the same inputs g does but outputs the dataframes instead of a complete unit plot takes a dataframe or list of dfs with start, end, date columns and outputs plot(s) These functions exist so you have direct access to all the important functionality in a modularly testable way. Most of the dependencies at the beginning are necessary so that we can initiazlize the quantbook and get data as in module 1 from quantconnect so we can generate dataframes. They came from the research environment documentation...we need to populate the namespace to use research environment commands. Also, this makes it so we can just import the function of interest, primarily g, but still get data. It keeps things under wraps so you can concentrate on your analysis functions. analyze -- takes OHLC values and outputs (start, end) drawing prices or (None,None) mod1 -- takes the symbol(s) and generates dataframes mod2 -- takes the dataframe(s), adds a date column, and uses a function--analyze by default--to add start and end columns d -- puts all the above together in an easy-to-use module plot -- takes the modified dataframe(s) from the "d" pipeline and generates plot(s) from them g -- packages d and plot for a truly seamless 1-call experience ''' #import jupyter dependencies so this file will build and not run into 'not found' errors from clr import AddReference AddReference("System") AddReference("QuantConnect.Common") AddReference("QuantConnect.Jupyter") AddReference("QuantConnect.Indicators") from System import * from QuantConnect import * from QuantConnect.Data.Market import TradeBar, QuoteBar from QuantConnect.Jupyter import * from QuantConnect.Indicators import * from datetime import datetime, timedelta import matplotlib.pyplot as plt import pandas as pd #initialize quantbook so don't have to do it in the notebook qb = QuantBook() ##----------CUSTOM MODULE AND GRAPHING CODE FOLLOWS:-------------- ##EXAMPLE, DEFAULT WICK ANALYZE MODULE--DOES NOT DO ANYTHING USEFUL #global variables needed for your analyze function: count = -1 #analyze each candle in a dataframe def analyze(o,h,l,c): ''' input: open, high, low, close output: start, end -- these will either be price values, or there will be nothing returned ''' global count #declare global variables to keep track of values to persist from one candle to the next count += 1 #count starts at -1 to compensate for advanced position #test implimentation logic -- does nothing useful, for illustrative purposes only if count % 5 == 0: e=h if c>o: s = c else: s = o return (s, e) else: return (None, None) ##module 1 as above: def mod1(symbol,bars,resolution): '''Requires qb to be set up already, subscribes to new asset data input: string or list of strings, where these are tickers; optional int "bars="; optional "resolution="'d','h','m'" Output: Pandas dataframe or list of dataframes of the OHLC series(s) requested''' def action(i): sym = qb.AddEquity(i) return qb.History([i], bars, res[resolution]) res = { 'd' : Resolution.Daily, 'h' : Resolution.Hour, 'm' : Resolution.Minute } if type(symbol) == str: return action(symbol) else: assert type(symbol) == list, 'Symbol(s)--tickers--need to be passed in either as a single string or list of strings. \ If you get an error from the quant connect modules it\'s likely your symbol(s) are invalid.' return [action(e)for e in symbol] ##module 2 as above: def mod2(data,func): def action(df): '''takes in dataframe, then feeds OHLC to ANALYSIS module "analyze", then returns dataframe(s)''' # iterating over multiple columns #call analyze in a loop, pass it row values, update new columns #doing list comprehension instead as from here: https://stackoverflow.com/questions/16476924/how-to-iterate-over-rows-in-a-dataframe-in-pandas/55557758#55557758 #result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].values] # add date column so can graph it better df['date']=[pd.to_datetime(e[1]) for e in df.index] #apply analysis function to OHLC values result = [func(row[3],row[1],row[2],row[0]) for row in df[['close','high','low','open']].values] #add columns to dataframe with NA's df['start'] = [e[0] for e in result] df['end'] = [e[1] for e in result] return df if type(data) == list: return [action(e)for e in data] else: return action(data) #package them all together for easy usage in the notebook def d(symbol,func=analyze, bars=360, resolution='d'): '''Takes all the modules contained in this file as input, assembles the graphing pipeline, shows the plot''' return mod2(mod1(symbol,bars,resolution),func) ##MULTI PLOTTING MODULE '''input list of dfs or df with date, start, end columns specifying wicks to highlight, output plot or multiple plots''' def plot(df): from bokeh.plotting import figure, show from bokeh.io import output_notebook from bokeh.layouts import column w = 12*60*60*1000 # half day in ms TOOLS = "pan,wheel_zoom,box_zoom,reset,save" def pl(df): inc = df.close > df.open dec = df.open > df.close #Plot width of 963 was the maximum fit in my QC jupyter notebook without having to scroll p = figure(x_axis_type="datetime", tools=TOOLS, plot_width=963, title = (df.index[0][0]).split()[0], toolbar_location = "above", active_scroll = 'wheel_zoom') p.xaxis.major_label_orientation = .7 #use this instead of Pi/4...why have an additional import? p.grid.grid_line_alpha=0.3 #candles p.segment(df.date, df.high, df.date, df.low, color="black") p.vbar(df.date[inc], w, df.open[inc], df.close[inc], fill_color='white', line_color="black") p.vbar(df.date[dec], w, df.open[dec], df.close[dec], fill_color='black', line_color="black") #highlight wicks #p.circle(df.date, df.target, color="red", fill_alpha=0.2, size=df.radius) p.vbar(df.date, w, df.start, df.end, fill_color="red", line_color="red", fill_alpha=0.2) return p if type(df) == list: p = [pl(i) for i in df] else: p = pl(df) output_notebook() show(column(p)) #put it ALL together...including the graphing!! def g(symbol,func=analyze, bars=360, resolution='d'): plot(d(symbol,func,bars,resolution))