Skip to content

Commit

Permalink
Improve quickstart tutorials
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdsellers committed Jun 24, 2024
1 parent de39e69 commit 20f1513
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 40 deletions.
84 changes: 64 additions & 20 deletions docs/getting_started/backtest_high_level.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
"id": "8",
"metadata": {},
"source": [
"## Loading data into the Data Catalog\n",
"## Loading data into the Parquet data catalog\n",
"\n",
"The FX data from `histdata` is stored in CSV/text format, with fields `timestamp, bid_price, ask_price`.\n",
"Firstly, we need to load this raw data into a `pandas.DataFrame` which has a compatible schema for Nautilus quote ticks.\n",
Expand Down Expand Up @@ -207,21 +207,17 @@
"start = dt_to_unix_nanos(pd.Timestamp(\"2020-01-03\", tz=\"UTC\"))\n",
"end = dt_to_unix_nanos(pd.Timestamp(\"2020-01-04\", tz=\"UTC\"))\n",
"\n",
"catalog.quote_ticks(instrument_ids=[EURUSD.id.value], start=start, end=end)[:10]"
"catalog.quote_ticks(instrument_ids=[EURUSD.id.value], start=start, end=end)[:10]\n",
"\n",
"instrument = catalog.instruments()[0]"
]
},
{
"cell_type": "markdown",
"id": "15",
"metadata": {},
"source": [
"## Configuring backtests\n",
"\n",
"Nautilus uses a `BacktestRunConfig` object, which enables backtest configuration in one place. It is a `Partialable` object (which means it can be configured in stages); the benefits of which are reduced boilerplate code when creating multiple backtest runs (for example when doing some sort of grid search over parameters).\n",
"\n",
"### Adding data and venues\n",
"\n",
"We can now use configuration objects to build up our final run configuration."
"## Add venues"
]
},
{
Expand All @@ -231,8 +227,6 @@
"metadata": {},
"outputs": [],
"source": [
"instrument = catalog.instruments()[0]\n",
"\n",
"venue_configs = [\n",
" BacktestVenueConfig(\n",
" name=\"SIM\",\n",
Expand All @@ -241,8 +235,24 @@
" base_currency=\"USD\",\n",
" starting_balances=[\"1_000_000 USD\"],\n",
" ),\n",
"]\n",
"\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "17",
"metadata": {},
"source": [
"## Add data"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "18",
"metadata": {},
"outputs": [],
"source": [
"data_configs = [\n",
" BacktestDataConfig(\n",
" catalog_path=str(ParquetDataCatalog.from_env().path),\n",
Expand All @@ -251,8 +261,24 @@
" start_time=start,\n",
" end_time=end,\n",
" ),\n",
"]\n",
"\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "19",
"metadata": {},
"source": [
"## Add strategies"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "20",
"metadata": {},
"outputs": [],
"source": [
"strategies = [\n",
" ImportableStrategyConfig(\n",
" strategy_path=\"nautilus_trader.examples.strategies.ema_cross:EMACross\",\n",
Expand All @@ -265,8 +291,26 @@
" trade_size=Decimal(1_000_000),\n",
" ),\n",
" ),\n",
"]\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "21",
"metadata": {},
"source": [
"## Configure backtest\n",
"\n",
"Nautilus uses a `BacktestRunConfig` object, which enables backtest configuration in one place. It is a `Partialable` object (which means it can be configured in stages); the benefits of which are reduced boilerplate code when creating multiple backtest runs (for example when doing some sort of grid search over parameters)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "22",
"metadata": {},
"outputs": [],
"source": [
"config = BacktestRunConfig(\n",
" engine=BacktestEngineConfig(strategies=strategies),\n",
" data=data_configs,\n",
Expand All @@ -276,18 +320,18 @@
},
{
"cell_type": "markdown",
"id": "17",
"id": "23",
"metadata": {},
"source": [
"## Run the backtest\n",
"## Run backtest\n",
"\n",
"Now we can simply run the backtest node, which will simulate trading across the entire data stream."
"Now we can run the backtest node, which will simulate trading across the entire data stream."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "18",
"id": "24",
"metadata": {},
"outputs": [],
"source": [
Expand Down
10 changes: 5 additions & 5 deletions docs/getting_started/backtest_low_level.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
"id": "10",
"metadata": {},
"source": [
"## Adding venues\n",
"## Add venues\n",
"\n",
"We'll need a venue to trade on, which should match the *market* data being added to the engine.\n",
"\n",
Expand Down Expand Up @@ -190,7 +190,7 @@
"id": "12",
"metadata": {},
"source": [
"## Adding data\n",
"## Add data\n",
"\n",
"Now we can add data to the backtest engine. First add the `Instrument` object we previously initialized, which matches our data.\n",
"\n",
Expand Down Expand Up @@ -227,7 +227,7 @@
"id": "15",
"metadata": {},
"source": [
"## Adding strategies\n",
"## Add strategies\n",
"\n",
"Now we can add the trading strategies we’d like to run as part of our system.\n",
"\n",
Expand Down Expand Up @@ -270,7 +270,7 @@
"This is because we can flexibly use different parameters per order submit, we still need to initialize\n",
"and add the actual `ExecAlgorithm` component which will execute the algorithm - which we'll do now.\n",
"\n",
"## Adding execution algorithms\n",
"## Add execution algorithms\n",
"\n",
"NautilusTrader enables us to build up very complex systems of custom components. Here we show just one of the custom components\n",
"available, in this case a built-in TWAP execution algorithm. It is configured and added to the engine in generally the same pattern as for strategies:\n",
Expand All @@ -297,7 +297,7 @@
"id": "19",
"metadata": {},
"source": [
"## Running backtests\n",
"## Run backtest\n",
"\n",
"Now that we have our data, venues and trading system configured - we can run a backtest\n",
"Simply call the `.run(...)` method which will run a backtest over all available data by default.\n",
Expand Down
36 changes: 21 additions & 15 deletions docs/getting_started/quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"id": "3",
"metadata": {},
"source": [
"## Getting the sample data\n",
"## 1. Get sample data\n",
"\n",
"To save time, we have prepared a script to load sample data into the Nautilus format for use with this example. \n",
"First, download and load the data by running the next cell (this should take ~ 1-2 mins):\n",
Expand Down Expand Up @@ -88,7 +88,7 @@
"id": "5",
"metadata": {},
"source": [
"## Connecting to the ParquetDataCatalog\n",
"## 2. Set up a Parquet data catalog\n",
"\n",
"If everything worked correctly, you should be able to see a single EUR/USD instrument in the catalog."
]
Expand All @@ -114,7 +114,7 @@
"id": "7",
"metadata": {},
"source": [
"## Writing a trading strategy\n",
"## 3. Write a trading strategy\n",
"\n",
"NautilusTrader includes many indicators built-in, in this example we will use the MACD indicator to \n",
"build a simple trading strategy.\n",
Expand Down Expand Up @@ -235,9 +235,9 @@
"id": "9",
"metadata": {},
"source": [
"## Configuring Backtests\n",
"## Configuring backtests\n",
"\n",
"Now that we have a trading strategy and data, we can begin to configure a backtest run! Nautilus uses a `BacktestNode` \n",
"Now that we have a trading strategy and data, we can begin to configure a backtest run. Nautilus uses a `BacktestNode` \n",
"to orchestrate backtest runs, which requires some setup. This may seem a little complex at first, \n",
"however this is necessary for the capabilities that Nautilus strives for.\n",
"\n",
Expand All @@ -250,7 +250,7 @@
"\n",
"There are many more configurable features which will be described later in the docs, for now this will get us up and running.\n",
"\n",
"## Venue\n",
"## 4. Configure venue\n",
"\n",
"First, we create a venue configuration. For this example we will create a simulated FX ECN. \n",
"A venue needs a name which acts as an ID (in this case `SIM`), as well as some basic configuration, e.g. \n",
Expand Down Expand Up @@ -284,9 +284,9 @@
"id": "11",
"metadata": {},
"source": [
"## Instruments\n",
"## 5. Configure data\n",
"\n",
"Second, we need to know about the instruments that we would like to load data for, we can use the `ParquetDataCatalog` for this."
"We need to know about the instruments that we would like to load data for, we can use the `ParquetDataCatalog` for this."
]
},
{
Expand All @@ -305,8 +305,6 @@
"id": "13",
"metadata": {},
"source": [
"## Data\n",
"\n",
"Next, we need to configure the data for the backtest. Nautilus is built to be very flexible when it \n",
"comes to loading data for backtests, however this also means some configuration is required.\n",
"\n",
Expand Down Expand Up @@ -337,7 +335,7 @@
"id": "15",
"metadata": {},
"source": [
"## Engine\n",
"## 6. Configure engine\n",
"\n",
"Then, we need a `BacktestEngineConfig` which represents the configuration of our core trading system.\n",
"Here we need to pass our trading strategies, we can also adjust the log level \n",
Expand Down Expand Up @@ -386,7 +384,7 @@
"id": "17",
"metadata": {},
"source": [
"## Running a backtest\n",
"## 7. Run backtest\n",
"\n",
"We can now pass our various config pieces to the `BacktestRunConfig`. This object now contains the \n",
"full configuration for our backtest."
Expand Down Expand Up @@ -440,6 +438,14 @@
"cell_type": "markdown",
"id": "21",
"metadata": {},
"source": [
"## 8. Analyze results"
]
},
{
"cell_type": "markdown",
"id": "22",
"metadata": {},
"source": [
"Now that the run is complete, we can also directly query for the `BacktestEngine`(s) used internally by the `BacktestNode`\n",
"by using the run configs ID. \n",
Expand All @@ -450,7 +456,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "22",
"id": "23",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -465,7 +471,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "23",
"id": "24",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -475,7 +481,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "24",
"id": "25",
"metadata": {},
"outputs": [],
"source": [
Expand Down

0 comments on commit 20f1513

Please sign in to comment.