Skip to content

Commit

Permalink
Updated notebooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Dekkers committed Jun 22, 2023
1 parent c5c2b1c commit b8a33a5
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dockerx.yml
Expand Up @@ -26,4 +26,4 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: roboquant/jupyter:1.5.0,roboquant/jupyter:latest
tags: roboquant/jupyter:1.6.0,roboquant/jupyter:latest
2 changes: 1 addition & 1 deletion Dockerfile
Expand Up @@ -15,7 +15,7 @@ USER 1000

# Install the Kotlin kernel in the Jupyter environment
# RUN pip install kotlin-jupyter-kernel==0.11.0.255
RUN pip install -i https://test.pypi.org/simple/ kotlin-jupyter-kernel==0.11.0.393
RUN pip install -i https://test.pypi.org/simple/ kotlin-jupyter-kernel==0.12.0.5

# Make additional Kotlin kernels available with different memory profiles
RUN python -m kotlin_kernel add-kernel --name "Small_0.5GB" --jvm-arg=-Xmx512M
Expand Down
38 changes: 19 additions & 19 deletions README.adoc
Expand Up @@ -17,7 +17,7 @@ image:https://img.shields.io/docker/image-size/roboquant/jupyter[Docker Image Si
image:https://img.shields.io/docker/v/roboquant/jupyter[Docker Image Version (latest by date)]
image:https://img.shields.io/docker/pulls/roboquant/jupyter[Docker Pulls]

This repository contains a number of Jupyter notebooks that demonstrate howto use _roboquant_. The focus of each notebook is on a specific task, like howto visualize results or create technical analysis based strategies.
This repository contains a number of Jupyter notebooks that demonstrate how to use _roboquant_. The focus of each notebook is on a specific task, like how to visualize results or create technical-analysis based strategies.

image:http://roboquant.org/img/jupyter-lab.png[Jupyter Lab]

Expand All @@ -30,7 +30,7 @@ If you prefer, you can run the notebooks without installing anything on your loc

NOTE: It might take some time before the MyBinder environment is set up, and you can run the notebooks. This is mainly due to the limited resources that these free environments have available and the fact that the Kotlin kernel isn't included by default and needs to be build first.

Alternatively you can run a Docker container on your local machine that has all the notebooks included and will automatically spin-up a Jupyter notebook environment:
Alternatively, you can run a Docker container on your local machine that has all the notebooks included and will automatically spin-up a Jupyter notebook environment:

[source,shell]
----
Expand All @@ -48,22 +48,22 @@ If you don't want to install anything on your local machine, you can try any of

These are the how-to notebooks that are included:

* backtest.ipynb - How to run a different types of back tests. This is also a good starting place if you are new to _roboquant_
* charts.ipynb - Shows the charting capabilities of roboquant
* alpaca.ipynb - Shows the integration with Alpaca broker
* binance.ipynb - Shows the integration with Binance crypto exchange
* crypto.ipynb - Shows the integration with many crypto exchanges using the XChange library
* strategies.ipynb - How to develop your own strategies
* policies.ipynb - How to develop a custom policy
* discord.ipynb - ow to develop a Discord bot
* talib.ipynb - How to develop technical analysis based strategies using the `TaLib` library
* ta4j.ipynb - How to develop technical analysis based strategies using teh `Ta4j` library
* xgboost.ipynb - How to develop a machine learning based strategy using XGBoost
* forex.ipynb - How to run back-tests for Forex trading
* empty.ipynb - Empty notebook that just includes the `%use` statement
* basic.ipynb - Notebook with a simple custom strategy that can serve as a starting point for developing your own strategy
* dotenv - Not a notebook but an example environment file that can hold the keys and secrets which are often required to connect to third party data providers and brokers.
* ibkr.ipynb - Shows how to integrate with Interactive Brokers
* backtest.ipynb How to run a different types of back tests. This is also a good starting place if you are new to _roboquant_
* charts.ipynb Shows the charting capabilities of roboquant
* alpaca.ipynb Shows the integration with Alpaca broker
* binance.ipynb Shows the integration with Binance crypto exchange
* crypto.ipynb Shows the integration with many crypto exchanges using the XChange library
* strategies.ipynb How to develop your own strategies
* policies.ipynb How to develop a custom policy
* discord.ipynb ow to develop a Discord bot
* talib.ipynb How to develop technical analysis based strategies using the `TaLib` library
* ta4j.ipynb How to develop technical analysis based strategies using teh `Ta4j` library
* xgboost.ipynb How to develop a machine learning based strategy using XGBoost
* forex.ipynb How to run back-tests for Forex trading
* empty.ipynb Empty notebook that just includes the `%use` statement
* basic.ipynb Notebook with a simple custom strategy that can serve as a starting point for developing your own strategy
* dotenv Not a notebook but an example environment file that can hold the keys and secrets which are often required to connect to third party data providers and brokers.
* ibkr.ipynb Shows how to integrate with Interactive Brokers
+
NOTE: the `ibkr` notebook cannot be run on MyBinder.org since it requires access to a (local) running Trader Workstation or IB Gateway. You can, however, run it on a local installed Jupyter Notebook.

Expand All @@ -73,7 +73,7 @@ Check the instructions in the link:/bin/README.adoc[README] in the bin directory
== Contributions
Contributions are greatly appreciated. This can be a fix or enhancement to one of the existing notebooks or a completely new notebook. The best way to do so is to raise an issue on GitHub and afterwards a PR.

Before checking-in, make sure the notebooks don't have any cell output, for example by running the following command from the project root directory.
Before checking-in, make sure the notebooks don't have any cell output, for example, by running the following command from the project root directory.

[source,shell]
----
Expand Down
2 changes: 1 addition & 1 deletion binder/Dockerfile
@@ -1 +1 @@
FROM roboquant/jupyter:1.5.0
FROM roboquant/jupyter:1.6.0
60 changes: 28 additions & 32 deletions notebooks/charts.ipynb
Expand Up @@ -33,11 +33,13 @@
"tags": []
},
"source": [
"# Price Feeds\n",
"## Price Feeds\n",
"\n",
"A feed represents a stream of events you can use in your strategies. There are several type of feeds supported, like the one for Avro files used here. \n",
"\n",
"The file we are using in this notebook contains few years of S&P 500 daily prices (OHLCV). The Avro file format allows to store, access and compress data efficiently and works great for historic prices used in back-testing. This feed implementation also has low memory consumption since it only loads data when required. If you want to find out more about Avro files, check out their [documentation pages](https://avro.apache.org/docs/current/index.html)."
"The file we are using in this notebook contains few years of S&P 500 daily prices (OHLCV). The Avro file format allows to store, access and compress data efficiently and works great for historic prices used in back-testing. \n",
"\n",
"This feed implementation also has low memory consumption since it only loads data when required. If you want to find out more about Avro files, check out their [documentation pages](https://avro.apache.org/docs/current/index.html)."
]
},
{
Expand All @@ -48,6 +50,11 @@
"source": [
"val feed = AvroFeed.sp500()\n",
"\n",
"// We define some assets we are going to use\n",
"val apple = feed.assets.getBySymbol(\"AAPL\")\n",
"val tesla = feed.assets.getBySymbol(\"TSLA\")\n",
"val popularAssets = feed.assets.findBySymbols(\"AAPL\", \"GOOGL\", \"F\", \"BAC\", \"T\", \"MSFT\", \"CAT\", \"JPM\", \"IBM\", \"PFE\")\n",
"\n",
"// Show the first 10 assets in this feed\n",
"feed.assets.take(10).summary()"
]
Expand All @@ -56,7 +63,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Asset Performance Chart\n",
"## Performance Chart\n",
"This chart enables you to see which assets got most traded and how they performed:\n",
"\n",
"1. The volume decides how big the asset is plotted. The volume = (price of the asset denoted in the base currency) x (the number unit traded).\n",
Expand All @@ -80,7 +87,17 @@
"metadata": {},
"source": [
"## Price Chart\n",
"The PriceChart replay the stream of events found in a feed and plots the prices it finds for a particular asset. In this example we'll find Apple stock (symbol name is \"AAPL\") and plot it with the same timeframe as we use in the above chart. If we omit the timeframe, all available prices will be plotted. "
"Roboquant charts aren't designed to be a tool where you manually draw support lines on price charts to make trading decisions. \n",
"\n",
"But that doesn't mean price charts cannot come in handy. For example to validate if the data in a feed is not corrupted or has some other strange anomalies. \n",
"\n",
"There are two type of price charts:\n",
"\n",
"1. PriceChart, this one support any type of pricing info\n",
"\n",
"2. PriecBarChart, that only support price-bars (candlestick) data\n",
"\n",
"A price chart will always plot the prices for a single asset. If we don't supply a timeframe, so all prices in the feed will be displayed. In the top right part of the plotted graph there is a toolbox that you can use to zoom into a particular area of interest."
]
},
{
Expand All @@ -94,30 +111,13 @@
"PriceChart(feed, \"AAPL\", timeframe = timeframe)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Price Chart\n",
"Roboquant charts aren't designed to be a tool where you manually draw support lines on price charts to make trading decisions. But that doesn't mean price charts cannot come in handy. For example to validate if the data in a feed is not corrupted or has some other strange anomalies. \n",
"\n",
"There are two type of price charts:\n",
"\n",
"1. PriceChart, this one support any type of pricing info\n",
"2. PriecBarChart, that only support price-bars (candlestick) data\n",
"\n",
"\n",
"If we don't supply a timeframe, so all prices in the feed will be displayed. In the top right part of the plotted graph there is a toolbox that you can use to zoom into a particular area of interest."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"val ind = TaLibIndicator.bbands()\n",
"val tesla = feed.assets.getBySymbol(\"TSLA\") \n",
"val chart = PriceChart(feed, tesla, priceType = \"CLOSE\", indicators = arrayOf(ind))\n",
"chart.height = 900\n",
"chart"
Expand All @@ -133,16 +133,15 @@
"source": [
"val ema26 = TaLibIndicator.ema(26)\n",
"val ema12 = TaLibIndicator.ema(12)\n",
"val apple = feed.assets.getBySymbol(\"AAPL\") \n",
"PriceBarChart(feed, apple, indicators = arrayOf(ema12, ema26))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Price Correlation Chart\n",
"This chart shows the correlation matrix of the prices of a number of assets within a feed. In this example we select some well known stocks and see how these are correlated."
"### Correlation Chart\n",
"This chart shows the correlation matrix of the prices of a number of assets within a feed. In this example we select some well popular stocks from different sectors and see how these are correlated."
]
},
{
Expand All @@ -151,15 +150,14 @@
"metadata": {},
"outputs": [],
"source": [
"val assets = feed.assets.findBySymbols(\"AAPL\", \"GOOGL\", \"F\", \"BAC\", \"T\", \"MSFT\", \"CAT\", \"JPM\", \"IBM\", \"PFE\")\n",
"PriceCorrelationChart(feed, assets)"
"CorrelationChart(feed, popularAssets)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Indicators\n",
"### Indicators\n",
"To get further insights into the price behavior of assets, you can use indicators. You can define your own, use one of the prebuilt ones like the `rsi` indicator in the example below."
]
},
Expand All @@ -170,8 +168,6 @@
"outputs": [],
"source": [
"val rsi = TaLibIndicator.rsi(10)\n",
"val apple = feed.assets.getBySymbol(\"AAPL\")\n",
"val tesla = feed.assets.getBySymbol(\"TSLA\")\n",
"val data = feed.apply(rsi, apple, tesla)\n",
"TimeSeriesChart(data)"
]
Expand All @@ -180,7 +176,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Strategy & Signals\n",
"### Strategy & Signals\n",
"\n",
"Before running a back-test, you might want to validate the type of signals that your strategy is producing. You can do so, using the SignalChart. This chart plots the signals and the rating (value from -2 to 2) over time.\n",
"For this notebook we'll use the EMA crossover strategy with its default settings"
Expand All @@ -200,7 +196,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Account\n",
"### Account\n",
"We run a simple strategy over the feed we just created to get some results to use for the charts. We'll also capture the AccountMetric metrics. After the run has finished, the account contains the latest state. There are several charts that provide some insights into this. "
]
},
Expand Down Expand Up @@ -533,7 +529,7 @@
},
"outputs": [],
"source": [
"for (asset in assets.take(2)) PriceBarChart(feed, asset).render()"
"for (asset in popularAssets.take(2)) PriceBarChart(feed, asset).render()"
]
},
{
Expand Down
10 changes: 1 addition & 9 deletions notebooks/dataframes.ipynb
Expand Up @@ -126,16 +126,8 @@
"metadata": {},
"outputs": [],
"source": [
"df.describe(\"value\")"
"df.describe(\"run-0\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dac50c81-aac0-418b-8a95-e8380292fe25",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
7 changes: 4 additions & 3 deletions notebooks/forex.ipynb
Expand Up @@ -71,7 +71,8 @@
" /**\n",
" * We want to create brack orders\n",
" */\n",
" override fun createOrder(signal: Signal, size: Size, price: Double): Order? {\n",
" override fun createOrder(signal: Signal, size: Size, priceAction: PriceAction): Order? {\n",
" val price = priceAction.getPrice(priceType)\n",
" val asset = signal.asset\n",
" val trailPercentage = 0.02\n",
" val stopPercentage = 0.005\n",
Expand Down Expand Up @@ -200,7 +201,7 @@
},
"outputs": [],
"source": [
"MetricCalendarChart(data.flatten().diff())"
"CalendarChart(data.flatten().diff())"
]
},
{
Expand Down Expand Up @@ -253,7 +254,7 @@
"name": "kotlin",
"nbconvert_exporter": "",
"pygments_lexer": "kotlin",
"version": "1.8.20-Beta"
"version": "1.8.20"
}
},
"nbformat": 4,
Expand Down
10 changes: 9 additions & 1 deletion notebooks/policies.ipynb
Expand Up @@ -39,12 +39,13 @@
"class MyPolicy(val trailPercentage: Double = 0.02, val stopPercentage: Double = 0.01) : FlexPolicy() {\n",
" \n",
" \n",
" override fun createOrder(signal: Signal, size: Size, price: Double): Order? {\n",
" override fun createOrder(signal: Signal, size: Size, priceAction: PriceAction): Order? {\n",
" \n",
" // In this example we don't short and exit orders are covered by the initial bracket order.\n",
" if (size < 0) return null\n",
" \n",
" val asset = signal.asset\n",
" val price = priceAction.getPrice()\n",
" \n",
" return BracketOrder(\n",
" MarketOrder(asset, size), // Entry Order\n",
Expand Down Expand Up @@ -155,6 +156,13 @@
"TimeSeriesChart(data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
2 changes: 1 addition & 1 deletion notebooks/strategies.ipynb
Expand Up @@ -184,7 +184,7 @@
"name": "kotlin",
"nbconvert_exporter": "",
"pygments_lexer": "kotlin",
"version": "1.8.20-Beta"
"version": "1.8.20"
}
},
"nbformat": 4,
Expand Down
18 changes: 15 additions & 3 deletions notebooks/talib.ipynb
Expand Up @@ -80,8 +80,8 @@
"metadata": {},
"outputs": [],
"source": [
"val mfiMetric = TaLibMetric(\"mfi\") {\n",
" mfi(it) \n",
"val mfiMetric = TaLibMetric {\n",
" mapOf(\"mfi\" to mfi(it)) \n",
"}"
]
},
Expand Down Expand Up @@ -238,6 +238,18 @@
"TimeSeriesChart(data1 + data2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"// Plot an indicator on a PriceBarChart\n",
"val tesla = feed.assets.getBySymbol(\"TSLA\")\n",
"val indicators = arrayOf(TaLibIndicator.bbands(20))\n",
"PriceBarChart(feed, tesla, indicators = indicators)"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -259,7 +271,7 @@
"name": "kotlin",
"nbconvert_exporter": "",
"pygments_lexer": "kotlin",
"version": "1.8.20-Beta"
"version": "1.8.20"
}
},
"nbformat": 4,
Expand Down

0 comments on commit b8a33a5

Please sign in to comment.