diff --git a/notebooks/tutorials/1_getting_started_follow_along_notebook/notebook.ipynb b/notebooks/tutorials/1_getting_started_follow_along_notebook/notebook.ipynb new file mode 100644 index 00000000..2ebaccab --- /dev/null +++ b/notebooks/tutorials/1_getting_started_follow_along_notebook/notebook.ipynb @@ -0,0 +1,420 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Getting Started Tutorial Companion Notebook\n", + "\n", + "Fill in the relevant parts of this notebook after reading each lesson in [Quantopian's Getting Started Tutorial](https://www.quantopian.com/tutorials/getting-started). \n", + "\n", + "For example, read the entirety of lesson 1, then fill in the cells under the Lesson 1 Header in this notebook.\n", + "\n", + "Also, check out this notebook's [follow along video.](youtube.com)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 1\n", + "##### Welcome!\n", + "# ***\n", + "\n", + "To see what is possible with Quantopian, copy, paste, and run the code from the intro lesson of the getting started tutorial in the code cell below. Don't worry if you don't understand what any of the code means, we're going to cover that next.\n", + "\n", + "Run a code block by selecting it, then holding Shift and pressing Enter. It takes around a minute to run." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 2 - The Quant Equity Workflow\n", + "##### How to use the Quantopian platform effectively.\n", + "# ***\n", + "The Quantopian platform was designed to be used in the following steps:\n", + "1. Express your investment idea as an alpha factor using Pipeline and inpsect the data.\n", + "2. Analyze the predictiveness of the alpha factor with Alphalens.\n", + "3. If the alpha factor is predictive, define logic to construct a portfolio from the alpha factor data with Optimize.\n", + "4. Design a trading algorithm that uses your portfolio construction logic with the Algorithm API.\n", + "5. Backtest the trading algorithm and analyze the results with Pyfolio." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Advice from the author of this tutorial :-)\n", + "\n", + "The rest of this notebook will ask you to recreate code from the tutorial to solidify your understanding of key concepts. \n", + "\n", + "You can copy and paste code if you want, but in my experience, actually typing out the code helps you remember better. \n", + "\n", + "That being said, if you get stuck, don't feel bad about copying and pasting. Just come back to that part later." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 3 - Expressing Alpha Factors with Pipeline\n", + "##### Step 1 of the Quant Equity Workflow.\n", + "# ***" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Import `Pipeline`, the `run_pipeline` function, the `QTradableStocksUS` filter, and the `factset` dataset.\n", + "\n", + "Hint: There should be four import statements. Each import statement starts with `from quantopian`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Define a function that returns a pipeline object.\n", + "\n", + "In lesson 3, we defined a trading universe and expressed an alpha factor with a pipeline. \n", + "\n", + "Try recreating that pipeline in the code cell below by:\n", + "\n", + "1. Defining a function named `make_pipeline()`\n", + "2. Creating a filter term that uses the built in `QTradableStocksUS()` universe. \n", + "3. Create a factor term that returns a company's net income using the `factset.Fundamentals.net_inc_af.latest` field.\n", + "4. Construct a pipeline by passing your factor term as a `columns` argument, and the filter term as a `screen` argument.\n", + "5. Return the pipeline from the function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Run the pipeline and inspect the data.\n", + "Pass the `make_pipeline()` function, a `start_date` and `end_date` argument to `run_pipeline()`. \n", + "\n", + "Then, use the `.head()` function to view the contents of the variable holding the output of the pipeline. By the way, we recommend naming that variable `pipeline_output`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 4 - Determine if the alpha factor is predictive.\n", + "##### Step 2 of the Quant Equity Workflow\n", + "# ***" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Query pricing data.\n", + "\n", + "The `get_pricing()` function is an easy way to get pricing data for a list of assets over a given time frame.\n", + "\n", + "Create a variable named `pricing_data` to hold the output of `get_pricing()`. Pass `get_pricing()` these arguments:\n", + "\n", + "1. A list of all assets that appear in `pipeline_output` at least once.\n", + "2. A start date\n", + "3. An end date\n", + "4. Specify with a string whether you want open, high, low, or close pricing. `open_price` is recommended." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Import Alphalens, as `al` here." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Use `get_clean_factor_and_forward_returns()` to align the pricing data from `get_pricing()` with the factor data contained in `pipeline_output`.\n", + "\n", + "`get_clean_factor_and_forward_returns()` only requires two arguments:\n", + "1. Factor data from a pipeline.\n", + "2. Pricing data from `get_pricing()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create a tear sheet.\n", + "\n", + "All you have to do to create a tear sheet is pass `create_full_tear_sheet()` the output of `get_clean_factor_and_forward_returns()`. This will take a little less than a minute to run." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 5 - Use your pipeline's output to construct a portfolio.\n", + "##### Step 3 of the Quant Equity Workflow\n", + "# ***" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Re-run our pipeline on a single day" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Convert to weight space here.\n", + "\n", + "Before we pass a column from our `pipeline_output` dataframe to the Optimize API, we need to convert it to weight space.\n", + "\n", + "For a column of a dataframe to be in weight space, the absolute value of every number in the column must add up to one. There are two lines of Pandas code in this lesson that does this for us. Execute that code below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import Optimize, as `opt` here." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Define TargetWeights as an objective object.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Define a list of constraints.\n", + "The constraints should be as follows:\n", + "1. We don't want any one position to be larger than 1% of our portfolio.\n", + "2. We don't want to have higher gross exposure than 1 (as in, we won't spend more money than we have).\n", + "3. We want our strategy to be dollar neutral (which means we will have equal exposure to long and short positions)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import, define and run Quantopian's risk model pipeline\n", + "\n", + "The pipeline should run " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Calculate an optimal portfolio with `calculate_optimal_portfolio()`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 6 - Write A Trading Algorithm\n", + "##### Step 4 of the Quant Equity Workflow\n", + "# ***\n", + "\n", + "Time to backtest our trading algorithm. [Click this link to clone our getting started template algorithm](link).\n", + "\n", + "You must change the make_pipeline() function to match the make_pipeline() function we recreated from lesson 3." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ***\n", + "### Lesson 7- Analyze Backtest Results\n", + "##### Step 5 of the Quant Equity Workflow\n", + "# ***\n", + "\n", + "There are two ways to analyze a backtest. When the backtest is finished, the \"full backtest results\" page will present itself. This page offers a ton of useful information. \n", + "\n", + "For a more in depth look at an algorithm's performance, you can run the backtest through Pyfolio. To do so, click the \"Notebook\" tab at the top of the backtest results page. This will present you with two lines of code that will look like this:\n", + "```\n", + "bt = get_backtest('A_BIG_LONG_ID_STRING')\n", + "bt.create_full_tear_sheet()\n", + "```\n", + "\n", + "You can run the code right there or copy and paste that code into another notebook. That's it!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/template_algorithms/getting_started_template.py b/template_algorithms/getting_started_template.py new file mode 100644 index 00000000..b3f3815e --- /dev/null +++ b/template_algorithms/getting_started_template.py @@ -0,0 +1,65 @@ +import quantopian.optimize as opt +import quantopian.algorithm as algo +from quantopian.pipeline import Pipeline +from quantopian.pipeline.data import factset +from quantopian.pipeline.filters import QTradableStocksUS +from quantopian.pipeline.experimental import risk_loading_pipeline + + +def initialize(context): + # A pipeline that produces alpha factor values which we will use to rebalance our portfolio + algo.attach_pipeline(make_pipeline(), 'alpha_factors_pipeline') + + # A special pipline provided by Quantopian that helps us avoid key risk factors + algo.attach_pipeline(risk_loading_pipeline(), 'risk_factors_pipeline') + + # Schedules a function called rebalance to be called once a day, at market open + algo.schedule_function( + func=rebalance, + date_rule=algo.date_rules.every_day(), + time_rule=algo.time_rules.market_open(), + ) + + +def make_pipeline(): + # A pipelione "filter term" that defines a trading universe + universe = QTradableStocksUS() + + # A pipeline "factor term" which specifies data we want about assets in our trading universe + sales_growth = factset.Fundamentals.sales_gr_qf.latest.winsorize(.2, .98).zscore() + + return Pipeline( + # Pipeline columns usually consists of factor terms + columns={'sales_growth': sales_growth}, + # Pipeline screens always consists of filter terms + screen=universe & sales_growth.notnull() + ) + + +def rebalance(context, data): + # Get the output of our pipelines. + pipeline_output = algo.pipeline_output('alpha_factors_pipeline') + risk_loadings = algo.pipeline_output('risk_factors_pipeline') + + # Convert a column of our dataframe into weight space + pipeline_column = pipeline_output['sales_growth'] + weights = pipeline_column/pipeline_column.abs().sum() + + # Match the target weights calculated in before_trading_start + objective = opt.TargetWeights(weights) + + # All of our constraints + constraints = [ + opt.DollarNeutral(), + opt.MaxGrossExposure(1), + opt.PositionConcentration.with_equal_bounds(-.005, .005), + opt.experimental.RiskModelExposure( + risk_model_loadings=risk_loadings, + version=opt.Newest + ) + ] + + algo.order_optimal_portfolio( + objective=objective, + constraints=constraints + ) \ No newline at end of file