roboquant 2.4.0__tar.gz → 2.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {roboquant-2.4.0 → roboquant-2.4.2}/PKG-INFO +17 -29
- {roboquant-2.4.0 → roboquant-2.4.2}/README.md +15 -28
- {roboquant-2.4.0 → roboquant-2.4.2}/pyproject.toml +7 -2
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/account.py +31 -57
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ai/features.py +4 -4
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ai/rl.py +4 -4
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ai/strategies.py +3 -3
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/asset.py +78 -103
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/brokers/broker.py +11 -11
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/brokers/simbroker.py +28 -51
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/crypto/cryptobroker.py +8 -8
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/crypto/cryptofeed.py +9 -9
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/event.py +6 -6
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/__init__.py +1 -5
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/feed.py +8 -7
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/historic.py +5 -5
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/live.py +3 -3
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/parquet.py +6 -6
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ibkr/broker.py +2 -1
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/metric.py +11 -1
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/metricsjournal.py +9 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/scorecard.py +1 -1
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/tensorboard.py +2 -2
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/monetary.py +54 -36
- roboquant-2.4.2/roboquant/order.py +153 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/run.py +2 -10
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/buffer.py +4 -3
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ta/__init__.py +1 -1
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/timeframe.py +2 -2
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/timeseries.py +23 -13
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/traders/flextrader.py +2 -2
- roboquant-2.4.0/roboquant/order.py +0 -201
- {roboquant-2.4.0 → roboquant-2.4.2}/LICENSE +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ai/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/alpaca/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/alpaca/broker.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/alpaca/feed.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/brokers/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/crypto/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/csvfeed.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/randomwalk.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/resources/us10.parquet +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/sql.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/util.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/feeds/yahoo.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ibkr/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/ibkr/types.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/alphabeta.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/basicjournal.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/feedmetric.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/journal.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/marketmetric.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/pnlmetric.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/pricemetric.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/journals/runmetric.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/signal.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/cachedstrategy.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/emacrossover.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/ibsstrategy.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/multistrategy.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/strategy.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/strategies/tastrategy.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/traders/__init__.py +0 -0
- {roboquant-2.4.0 → roboquant-2.4.2}/roboquant/traders/trader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roboquant
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: A fast algorithmic trading platform with support for AI based strategies
|
|
5
5
|
Keywords: algorithmic,trading,machine learning,AI,investment,finance,crypto,stocks,exchange,forex
|
|
6
6
|
Author: roboquant team
|
|
@@ -23,6 +23,7 @@ Requires-Dist: requests>2.30.0
|
|
|
23
23
|
Requires-Dist: yfinance>1.5.0
|
|
24
24
|
Requires-Dist: pyarrow>24.0.0
|
|
25
25
|
Requires-Dist: ta-lib==0.6.5
|
|
26
|
+
Requires-Dist: pandas>=2.2.0
|
|
26
27
|
Requires-Dist: torch>=2.9.0 ; extra == 'ai'
|
|
27
28
|
Requires-Dist: tensorboard>=2.21.0 ; extra == 'ai'
|
|
28
29
|
Requires-Dist: stable-baselines3>=2.9.0 ; extra == 'ai'
|
|
@@ -46,16 +47,15 @@ Description-Content-Type: text/markdown
|
|
|
46
47
|

|
|
47
48
|

|
|
48
49
|

|
|
49
|
-

|
|
50
50
|

|
|
51
51
|
[](https://discord.com/channels/954650958300856340/954650958300856343)
|
|
52
52
|
|
|
53
|
-
Roboquant is an open-source algorithmic trading platform. It is flexible, user-friendly and completely free to use. It is designed for anyone serious about algo-trading.
|
|
53
|
+
Roboquant is an open-source algorithmic trading platform written in Python. It is flexible, user-friendly and completely free to use. It is designed for anyone serious about algo-trading.
|
|
54
54
|
|
|
55
55
|
So whether you are a beginning retail trader or an established trading firm, roboquant can help you to develop robust and fully automated trading strategies. You can find out more at [roboquant.org](https://roboquant.org).
|
|
56
56
|
|
|
57
57
|
## Usage
|
|
58
|
-
The following code snippet shows the steps
|
|
58
|
+
The following code snippet shows the required steps to run a full back-test on a number of stocks.
|
|
59
59
|
|
|
60
60
|
```python
|
|
61
61
|
import roboquant as rq
|
|
@@ -66,6 +66,18 @@ account = rq.run(feed, strategy)
|
|
|
66
66
|
print(account)
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## Features
|
|
70
|
+
Below are some of the key features of *roboquant*:
|
|
71
|
+
- [x] fast back testing and live trading
|
|
72
|
+
- [x] AI/ML based strategies
|
|
73
|
+
- [x] market data feeds from CSV files, Yahoo Finance, Alpaca and many crypto exchanges
|
|
74
|
+
- [x] multi-currency trading
|
|
75
|
+
- [x] multi-asset trading, stocks, options, forex and crypto out of the box
|
|
76
|
+
- [x] larger-than-memory data feeds
|
|
77
|
+
- [x] TaLib based indicators and strategies
|
|
78
|
+
- [x] plotting of prices and metrics
|
|
79
|
+
- [x] modulair and extensible
|
|
80
|
+
|
|
69
81
|
## Install
|
|
70
82
|
Roboquant can be installed like most other Python packages, using tools like `uv`, `pip` or `conda`.
|
|
71
83
|
Make sure you have Python version 3.12 or higher installed.
|
|
@@ -74,7 +86,7 @@ Make sure you have Python version 3.12 or higher installed.
|
|
|
74
86
|
python3 -m pip install --upgrade roboquant
|
|
75
87
|
```
|
|
76
88
|
|
|
77
|
-
The core of roboquant limits the number of dependencies. But you can install roboquant including one or more of the optional dependencies if you require certain additional functionality:
|
|
89
|
+
The core installation of roboquant limits the number of dependencies. But you can install roboquant including one or more of the optional dependencies if you require certain additional functionality:
|
|
78
90
|
|
|
79
91
|
```shell
|
|
80
92
|
# AI based strategies using PyTorch and SB3
|
|
@@ -90,30 +102,6 @@ python3 -m pip install --upgrade "roboquant[alpaca]"
|
|
|
90
102
|
python3 -m pip install --upgrade "roboquant[crypto]"
|
|
91
103
|
```
|
|
92
104
|
|
|
93
|
-
## Building from source
|
|
94
|
-
Roboquant.py uses `uv` as the main tool for handling package dependencies.
|
|
95
|
-
|
|
96
|
-
```shell
|
|
97
|
-
uv sync --all-extras --dev
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
You should now be in the virtual environment and ready to build/install roboquant:
|
|
101
|
-
|
|
102
|
-
```shell
|
|
103
|
-
uv build
|
|
104
|
-
uv pip install .
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Some other useful commands:
|
|
108
|
-
|
|
109
|
-
```shell
|
|
110
|
-
# build & validate the code
|
|
111
|
-
./bin/verify.sh
|
|
112
|
-
|
|
113
|
-
# publish, only works if UV_PUBLISH_TOKEN is set
|
|
114
|
-
./bin/publish.sh
|
|
115
|
-
```
|
|
116
|
-
|
|
117
105
|
## License
|
|
118
106
|
Roboquant is made available under the Apache 2.0 license. You can read more about the Apache 2.0 license on this page: https://www.apache.org/licenses/LICENSE-2.0.html
|
|
119
107
|
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|

|
|
7
|
-

|
|
8
7
|

|
|
9
8
|
[](https://discord.com/channels/954650958300856340/954650958300856343)
|
|
10
9
|
|
|
11
|
-
Roboquant is an open-source algorithmic trading platform. It is flexible, user-friendly and completely free to use. It is designed for anyone serious about algo-trading.
|
|
10
|
+
Roboquant is an open-source algorithmic trading platform written in Python. It is flexible, user-friendly and completely free to use. It is designed for anyone serious about algo-trading.
|
|
12
11
|
|
|
13
12
|
So whether you are a beginning retail trader or an established trading firm, roboquant can help you to develop robust and fully automated trading strategies. You can find out more at [roboquant.org](https://roboquant.org).
|
|
14
13
|
|
|
15
14
|
## Usage
|
|
16
|
-
The following code snippet shows the steps
|
|
15
|
+
The following code snippet shows the required steps to run a full back-test on a number of stocks.
|
|
17
16
|
|
|
18
17
|
```python
|
|
19
18
|
import roboquant as rq
|
|
@@ -24,6 +23,18 @@ account = rq.run(feed, strategy)
|
|
|
24
23
|
print(account)
|
|
25
24
|
```
|
|
26
25
|
|
|
26
|
+
## Features
|
|
27
|
+
Below are some of the key features of *roboquant*:
|
|
28
|
+
- [x] fast back testing and live trading
|
|
29
|
+
- [x] AI/ML based strategies
|
|
30
|
+
- [x] market data feeds from CSV files, Yahoo Finance, Alpaca and many crypto exchanges
|
|
31
|
+
- [x] multi-currency trading
|
|
32
|
+
- [x] multi-asset trading, stocks, options, forex and crypto out of the box
|
|
33
|
+
- [x] larger-than-memory data feeds
|
|
34
|
+
- [x] TaLib based indicators and strategies
|
|
35
|
+
- [x] plotting of prices and metrics
|
|
36
|
+
- [x] modulair and extensible
|
|
37
|
+
|
|
27
38
|
## Install
|
|
28
39
|
Roboquant can be installed like most other Python packages, using tools like `uv`, `pip` or `conda`.
|
|
29
40
|
Make sure you have Python version 3.12 or higher installed.
|
|
@@ -32,7 +43,7 @@ Make sure you have Python version 3.12 or higher installed.
|
|
|
32
43
|
python3 -m pip install --upgrade roboquant
|
|
33
44
|
```
|
|
34
45
|
|
|
35
|
-
The core of roboquant limits the number of dependencies. But you can install roboquant including one or more of the optional dependencies if you require certain additional functionality:
|
|
46
|
+
The core installation of roboquant limits the number of dependencies. But you can install roboquant including one or more of the optional dependencies if you require certain additional functionality:
|
|
36
47
|
|
|
37
48
|
```shell
|
|
38
49
|
# AI based strategies using PyTorch and SB3
|
|
@@ -48,30 +59,6 @@ python3 -m pip install --upgrade "roboquant[alpaca]"
|
|
|
48
59
|
python3 -m pip install --upgrade "roboquant[crypto]"
|
|
49
60
|
```
|
|
50
61
|
|
|
51
|
-
## Building from source
|
|
52
|
-
Roboquant.py uses `uv` as the main tool for handling package dependencies.
|
|
53
|
-
|
|
54
|
-
```shell
|
|
55
|
-
uv sync --all-extras --dev
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
You should now be in the virtual environment and ready to build/install roboquant:
|
|
59
|
-
|
|
60
|
-
```shell
|
|
61
|
-
uv build
|
|
62
|
-
uv pip install .
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Some other useful commands:
|
|
66
|
-
|
|
67
|
-
```shell
|
|
68
|
-
# build & validate the code
|
|
69
|
-
./bin/verify.sh
|
|
70
|
-
|
|
71
|
-
# publish, only works if UV_PUBLISH_TOKEN is set
|
|
72
|
-
./bin/publish.sh
|
|
73
|
-
```
|
|
74
|
-
|
|
75
62
|
## License
|
|
76
63
|
Roboquant is made available under the Apache 2.0 license. You can read more about the Apache 2.0 license on this page: https://www.apache.org/licenses/LICENSE-2.0.html
|
|
77
64
|
|
|
@@ -8,6 +8,9 @@ build-backend = "uv_build"
|
|
|
8
8
|
[tool.ruff.lint]
|
|
9
9
|
select = ["E", "F", "W"]
|
|
10
10
|
|
|
11
|
+
[tool.ty.rules]
|
|
12
|
+
unused-type-ignore-comment = "ignore"
|
|
13
|
+
|
|
11
14
|
[tool.pyright]
|
|
12
15
|
typeCheckingMode = "standard"
|
|
13
16
|
reportPrivateImportUsage = "none"
|
|
@@ -19,7 +22,7 @@ module-name = "roboquant"
|
|
|
19
22
|
|
|
20
23
|
[project]
|
|
21
24
|
name = "roboquant"
|
|
22
|
-
version = "2.4.
|
|
25
|
+
version = "2.4.2"
|
|
23
26
|
authors = [{ name = "roboquant team", email = "info@roboquant.org" }]
|
|
24
27
|
description = "A fast algorithmic trading platform with support for AI based strategies"
|
|
25
28
|
readme = "README.md"
|
|
@@ -56,7 +59,8 @@ dependencies = [
|
|
|
56
59
|
"requests>2.30.0",
|
|
57
60
|
"yfinance>1.5.0",
|
|
58
61
|
"pyarrow>24.0.0",
|
|
59
|
-
"ta-lib==0.6.5"
|
|
62
|
+
"ta-lib==0.6.5",
|
|
63
|
+
"pandas>=2.2.0"
|
|
60
64
|
]
|
|
61
65
|
|
|
62
66
|
[project.optional-dependencies]
|
|
@@ -83,4 +87,5 @@ dev = [
|
|
|
83
87
|
"ipykernel>=7.3.0",
|
|
84
88
|
"ipywidgets>=8.1.6",
|
|
85
89
|
"chronos-forecasting>=2.3.1",
|
|
90
|
+
"ty>=0.0.62",
|
|
86
91
|
]
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
1
|
+
from dataclasses import dataclass, asdict
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
from decimal import Decimal
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
5
6
|
|
|
6
7
|
from roboquant.asset import Asset
|
|
7
8
|
from roboquant.monetary import USD, Amount, Currency, Wallet
|
|
@@ -25,8 +26,8 @@ class Trade:
|
|
|
25
26
|
asset: Asset
|
|
26
27
|
time: datetime
|
|
27
28
|
size: Decimal
|
|
28
|
-
price: float
|
|
29
|
-
pnl: float
|
|
29
|
+
price: float = float("nan")
|
|
30
|
+
pnl: float = float("nan")
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
@dataclass(slots=True)
|
|
@@ -41,9 +42,12 @@ class Position:
|
|
|
41
42
|
avg_price: float
|
|
42
43
|
"""Average price paid denoted in the currency of the asset"""
|
|
43
44
|
|
|
44
|
-
mkt_price: float
|
|
45
|
+
mkt_price: float = float("nan")
|
|
45
46
|
"""Latest market price denoted in the currency of the asset"""
|
|
46
47
|
|
|
48
|
+
pnl: float = float("nan")
|
|
49
|
+
"""The pnl for this position"""
|
|
50
|
+
|
|
47
51
|
@property
|
|
48
52
|
def is_short(self):
|
|
49
53
|
"""Return True if this is a short position, False otherwise"""
|
|
@@ -59,17 +63,17 @@ class Position:
|
|
|
59
63
|
"""Return a zero position size with no known prices"""
|
|
60
64
|
return Position(Decimal(), float("nan"), float("nan"))
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
@dataclass
|
|
63
67
|
class Account:
|
|
64
68
|
"""Represents a trading account. The account maintains the following state during a run:
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
Attributes:
|
|
71
|
+
buying_power (Amount): Available buying power for orders in the base currency of the account.
|
|
72
|
+
cash (Wallet): The cash available in the account.
|
|
73
|
+
positions (Dict[Asset, Position]): the open positions, each denoted in the currency of the asset.
|
|
74
|
+
orders (list[Order]): the open orders, each denoted in the currency of the asset.
|
|
75
|
+
trades (list[Trade]): the trades that have been executed, each denoted in the currency of the asset.
|
|
76
|
+
last_update (datetime): The last time the account was updated.
|
|
73
77
|
|
|
74
78
|
Only the `broker` updates the account and does this only during its `sync` method.
|
|
75
79
|
"""
|
|
@@ -242,50 +246,6 @@ class Account:
|
|
|
242
246
|
pos = self.positions.get(asset)
|
|
243
247
|
return pos.size if pos else Decimal()
|
|
244
248
|
|
|
245
|
-
def get_position_list(self) -> list[dict[str, Any]]:
|
|
246
|
-
"""Return all open positions including their pnl as a list of dicts.
|
|
247
|
-
This comes in handy for further processing, like converting
|
|
248
|
-
them to a dataframe.
|
|
249
|
-
"""
|
|
250
|
-
result: list[dict[str, Any]] = []
|
|
251
|
-
for asset, pos in self.positions.items():
|
|
252
|
-
result.append(
|
|
253
|
-
{
|
|
254
|
-
"asset class": asset.asset_class(),
|
|
255
|
-
"symbol": asset.symbol,
|
|
256
|
-
"currency": asset.currency,
|
|
257
|
-
"size": pos.size,
|
|
258
|
-
"type": "LONG" if pos.is_long else "SHORT",
|
|
259
|
-
"avg price": pos.avg_price,
|
|
260
|
-
"mkt price": pos.mkt_price,
|
|
261
|
-
"value": asset.contract_value(pos.size, pos.mkt_price),
|
|
262
|
-
"pnl": asset.contract_value(pos.size, pos.mkt_price - pos.avg_price),
|
|
263
|
-
}
|
|
264
|
-
)
|
|
265
|
-
return result
|
|
266
|
-
|
|
267
|
-
def get_order_list(self) -> list[dict[str, Any]]:
|
|
268
|
-
"""Return all open orders as a list of dicts.
|
|
269
|
-
This comes in handy for further processing, like converting
|
|
270
|
-
them to a dataframe."""
|
|
271
|
-
result: list[dict[str, Any]] = []
|
|
272
|
-
for order in self.orders:
|
|
273
|
-
result.append(
|
|
274
|
-
{
|
|
275
|
-
"id": order.id,
|
|
276
|
-
"asset class": order.asset.asset_class(),
|
|
277
|
-
"symbol": order.asset.symbol,
|
|
278
|
-
"currency": order.asset.currency,
|
|
279
|
-
"size": order.size,
|
|
280
|
-
"type": "BUY" if order.is_buy else "SELL",
|
|
281
|
-
"value": order.value(),
|
|
282
|
-
"fill": order.fill,
|
|
283
|
-
"tif": order.tif,
|
|
284
|
-
"info": str(order.info) if order.info else "-",
|
|
285
|
-
}
|
|
286
|
-
)
|
|
287
|
-
return result
|
|
288
|
-
|
|
289
249
|
def get_order(self, order_id: str) -> Order | None:
|
|
290
250
|
"""Return an order by its id, or None if no matching order can be found"""
|
|
291
251
|
for order in self.orders:
|
|
@@ -327,3 +287,17 @@ class Account:
|
|
|
327
287
|
f"last update : {self.last_update}"
|
|
328
288
|
)
|
|
329
289
|
return result
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def trades_to_dataframe(self) -> pd.DataFrame:
|
|
293
|
+
"""Return the trades as a dataframe"""
|
|
294
|
+
return pd.json_normalize([asdict(trade) for trade in self.trades])
|
|
295
|
+
|
|
296
|
+
def orders_to_dataframe(self)-> pd.DataFrame:
|
|
297
|
+
"""Return the orders as a dataframe"""
|
|
298
|
+
return pd.json_normalize([asdict(order) for order in self.orders])
|
|
299
|
+
|
|
300
|
+
def positions_to_dataframe(self)-> pd.DataFrame:
|
|
301
|
+
"""Return the positions as a dataframe"""
|
|
302
|
+
return pd.json_normalize([asdict(asset) | asdict(pos) for asset, pos in self.positions.items()])
|
|
303
|
+
|
|
@@ -21,7 +21,7 @@ class Feature(Generic[T]):
|
|
|
21
21
|
roboquant machine learning models and can be used to extract relevant information.
|
|
22
22
|
|
|
23
23
|
The ones included by default are either based on an `Event` or an `Account`.
|
|
24
|
-
Typically Event features are used for input data and Account features are used for
|
|
24
|
+
Typically, Event features are used for input data and Account features are used for
|
|
25
25
|
reward/label/output data.
|
|
26
26
|
|
|
27
27
|
Features can be combined, sliced, nested, normalized and cached to create more
|
|
@@ -197,7 +197,7 @@ class NormalizeFeature(Feature[T]):
|
|
|
197
197
|
(count, mean, m2) = self.existing_aggregate
|
|
198
198
|
stdev = self._full_nan()
|
|
199
199
|
mask = count >= self.min_count
|
|
200
|
-
stdev[mask] = np.sqrt(m2[mask] / count[mask]) + 1e-12
|
|
200
|
+
stdev[mask] = np.sqrt(m2[mask] / count[mask]) + 1e-12
|
|
201
201
|
return (values - mean) / stdev
|
|
202
202
|
|
|
203
203
|
def calc(self, value: T) -> NPFloatArray:
|
|
@@ -269,7 +269,7 @@ class ReturnFeature(Feature[T]):
|
|
|
269
269
|
|
|
270
270
|
def calc(self, value: T) -> NPFloatArray:
|
|
271
271
|
values = self.feature.calc(value)
|
|
272
|
-
r: NPFloatArray = values / self.history - np.float32(1.0)
|
|
272
|
+
r: NPFloatArray = values / self.history - np.float32(1.0)
|
|
273
273
|
self.history = values
|
|
274
274
|
return r
|
|
275
275
|
|
|
@@ -566,7 +566,7 @@ class TaFeature(Feature[Event]):
|
|
|
566
566
|
if asset not in self._data:
|
|
567
567
|
self._data[asset] = OHLCVBuffer(self.period)
|
|
568
568
|
ohlcv = self._data[asset]
|
|
569
|
-
if ohlcv.append(item.ohlcv):
|
|
569
|
+
if ohlcv.append(item.ohlcv):
|
|
570
570
|
v = self._calc(asset, ohlcv)
|
|
571
571
|
|
|
572
572
|
result.append(v)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Callable,
|
|
2
|
+
from typing import Callable, Iterator
|
|
3
3
|
import gymnasium as gym
|
|
4
4
|
from gymnasium import spaces
|
|
5
5
|
from gymnasium.envs.registration import register
|
|
@@ -55,9 +55,9 @@ class TradingEnv(gym.Env):
|
|
|
55
55
|
self.broker: SimBroker = broker or SimBroker()
|
|
56
56
|
self.feed = feed
|
|
57
57
|
|
|
58
|
-
self._event_gen:
|
|
58
|
+
self._event_gen: Iterator[Event]
|
|
59
59
|
self.event: Event | None = None
|
|
60
|
-
self.account: Account
|
|
60
|
+
self.account: Account
|
|
61
61
|
self.obs_feature = obs_feature
|
|
62
62
|
self.reward_feature = reward_feature
|
|
63
63
|
self.timefame = timeframe
|
|
@@ -170,7 +170,7 @@ class SB3PolicyStrategy(Strategy):
|
|
|
170
170
|
env: TradingEnv = model.env # type: ignore
|
|
171
171
|
return cls(env.obs_feature, env.assets, model.policy)
|
|
172
172
|
|
|
173
|
-
def create_signals(self, event) -> list[Signal]:
|
|
173
|
+
def create_signals(self, event: Event) -> list[Signal]:
|
|
174
174
|
obs = self.obs_feature.calc(event)
|
|
175
175
|
if np.any(np.isnan(obs)):
|
|
176
176
|
return []
|
|
@@ -87,10 +87,10 @@ class SequenceDataset(Dataset):
|
|
|
87
87
|
calc_l = len(self.target_data) - self.input_sequences - self.output_sequences - self.gap + 1
|
|
88
88
|
return max(0, calc_l)
|
|
89
89
|
|
|
90
|
-
def __getitem__(self,
|
|
90
|
+
def __getitem__(self, index):
|
|
91
91
|
"""Get a sample from the dataset."""
|
|
92
|
-
end =
|
|
93
|
-
features = self.input_data[
|
|
92
|
+
end = index + self.input_sequences
|
|
93
|
+
features = self.input_data[index:end]
|
|
94
94
|
start = end + self.gap
|
|
95
95
|
target = self.target_data[start: start + self.output_sequences]
|
|
96
96
|
if self.transform:
|