avanza-mcp 1.0.0__tar.gz → 1.2.0__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.
- avanza_mcp-1.2.0/CHANGELOG.md +60 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/PKG-INFO +42 -3
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/README.md +39 -1
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/pyproject.toml +2 -1
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/__init__.py +3 -1
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/client/endpoints.py +28 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/__init__.py +121 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/certificate.py +87 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/chart.py +51 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/models/common.py +15 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/etf.py +92 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/filter.py +51 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/future_forward.py +63 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/instrument_data.py +26 -0
- avanza_mcp-1.2.0/src/avanza_mcp/models/warrant.py +88 -0
- avanza_mcp-1.2.0/src/avanza_mcp/services/market_data_service.py +611 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/__init__.py +22 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/certificates.py +156 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/etfs.py +151 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/futures_forwards.py +174 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/instrument_data.py +135 -0
- avanza_mcp-1.2.0/src/avanza_mcp/tools/warrants.py +139 -0
- avanza_mcp-1.2.0/tests/integration/test_certificates_integration.py +111 -0
- avanza_mcp-1.2.0/tests/integration/test_chart_integration.py +107 -0
- avanza_mcp-1.2.0/tests/integration/test_etfs_integration.py +80 -0
- avanza_mcp-1.2.0/tests/integration/test_futures_forwards_integration.py +64 -0
- avanza_mcp-1.2.0/tests/integration/test_instrument_data_integration.py +42 -0
- avanza_mcp-1.2.0/tests/integration/test_warrants_integration.py +59 -0
- avanza_mcp-1.2.0/tests/unit/test_certificate_models.py +118 -0
- avanza_mcp-1.2.0/tests/unit/test_chart_models.py +131 -0
- avanza_mcp-1.2.0/tests/unit/test_etf_models.py +54 -0
- avanza_mcp-1.2.0/tests/unit/test_filter_models.py +30 -0
- avanza_mcp-1.2.0/tests/unit/test_future_forward_models.py +67 -0
- avanza_mcp-1.2.0/tests/unit/test_instrument_data_models.py +26 -0
- avanza_mcp-1.2.0/tests/unit/test_warrant_models.py +60 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/uv.lock +3 -1
- avanza_mcp-1.0.0/src/avanza_mcp/models/__init__.py +0 -41
- avanza_mcp-1.0.0/src/avanza_mcp/services/market_data_service.py +0 -298
- avanza_mcp-1.0.0/src/avanza_mcp/tools/__init__.py +0 -8
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/.github/PUBLISHING.md +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/.github/workflows/ci.yml +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/.github/workflows/publish.yml +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/.gitignore +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/.python-version +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/CLAUDE.md +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/DEVELOPMENT.md +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/LICENSE.md +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/justfile +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/client/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/client/base.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/client/exceptions.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/models/fund.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/models/search.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/models/stock.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/prompts/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/prompts/analysis.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/resources/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/resources/instruments.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/services/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/services/search_service.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/tools/funds.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/tools/market_data.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/src/avanza_mcp/tools/search.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/conftest.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/integration/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/integration/test_tools.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/unit/__init__.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/unit/test_client.py +0 -0
- {avanza_mcp-1.0.0 → avanza_mcp-1.2.0}/tests/unit/test_models.py +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.2.0] - 2026-02-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Certificates Support** (3 tools)
|
|
9
|
+
- `filter_certificates` - Search and filter certificates with pagination
|
|
10
|
+
- `get_certificate_info` - Get detailed certificate information
|
|
11
|
+
- `get_certificate_details` - Get extended certificate details
|
|
12
|
+
|
|
13
|
+
- **Warrants Support** (3 tools)
|
|
14
|
+
- `filter_warrants` - Search and filter warrants (turbos, minis)
|
|
15
|
+
- `get_warrant_info` - Get detailed warrant information
|
|
16
|
+
- `get_warrant_details` - Get extended warrant details
|
|
17
|
+
|
|
18
|
+
- **ETFs Support** (3 tools)
|
|
19
|
+
- `filter_etfs` - Search and filter exchange-traded funds
|
|
20
|
+
- `get_etf_info` - Get detailed ETF information
|
|
21
|
+
- `get_etf_details` - Get extended ETF details
|
|
22
|
+
|
|
23
|
+
- **Futures/Forwards Support** (4 tools)
|
|
24
|
+
- `list_futures_forwards` - List available futures and forwards
|
|
25
|
+
- `get_future_forward_filter_options` - Get available filter options
|
|
26
|
+
- `get_future_forward_info` - Get contract information
|
|
27
|
+
- `get_future_forward_details` - Get extended contract details
|
|
28
|
+
|
|
29
|
+
- **Additional Data Tools** (3 tools)
|
|
30
|
+
- `get_number_of_owners` - Get owner count for any instrument
|
|
31
|
+
- `get_short_selling` - Get short selling data for instruments
|
|
32
|
+
- `get_marketmaker_chart` - Get OHLC price chart data for traded products (certificates, warrants, ETFs)
|
|
33
|
+
|
|
34
|
+
- **New Models**
|
|
35
|
+
- `models/chart.py` - Chart data models (ChartData, OHLCDataPoint, ChartMetadata)
|
|
36
|
+
- `models/filter.py` - Shared filter models (SortBy, UnderlyingInstrument)
|
|
37
|
+
- `models/certificate.py` - Certificate models
|
|
38
|
+
- `models/warrant.py` - Warrant models
|
|
39
|
+
- `models/etf.py` - ETF models
|
|
40
|
+
- `models/future_forward.py` - Future/Forward models
|
|
41
|
+
- `models/instrument_data.py` - Additional instrument data models
|
|
42
|
+
|
|
43
|
+
- **16 New API Endpoints**
|
|
44
|
+
- Certificate endpoints (filter, info, details)
|
|
45
|
+
- Warrant endpoints (filter, info, details)
|
|
46
|
+
- ETF endpoints (filter, info, details)
|
|
47
|
+
- Futures/Forwards endpoints (matrix, filter-options, info, details)
|
|
48
|
+
- Additional data endpoints (number_of_owners, short_selling)
|
|
49
|
+
- Chart endpoint (marketmaker)
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Tool count increased from 18 to 34 tools
|
|
53
|
+
- `MarketDataService` extended with 15 new methods
|
|
54
|
+
- **Test Structure Reorganized** - Split monolithic test files into domain-specific files following clean code practices:
|
|
55
|
+
- Unit tests: 7 separate files by domain (filter, certificate, warrant, ETF, futures/forwards, instrument data, chart models)
|
|
56
|
+
- Integration tests: 6 separate files by domain (certificates, warrants, ETFs, futures/forwards, instrument data, chart endpoints)
|
|
57
|
+
|
|
58
|
+
## [1.1.0] - Previous Release
|
|
59
|
+
|
|
60
|
+
(Previous changelog entries would go here)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: avanza-mcp
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: MCP server for Avanza public market data API - Swedish stocks, funds, and more
|
|
5
5
|
License-File: LICENSE.md
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
7
|
Requires-Dist: fastmcp==3.0.0b1
|
|
8
|
-
Requires-Dist: httpx>=0.
|
|
8
|
+
Requires-Dist: httpx-sse>=0.4.3
|
|
9
|
+
Requires-Dist: httpx<1.0,>=0.28.1
|
|
9
10
|
Requires-Dist: pydantic>=2.0.0
|
|
10
11
|
Requires-Dist: tenacity>=9.0.0
|
|
11
12
|
Provides-Extra: dev
|
|
@@ -56,6 +57,42 @@ The author of this software is not responsible for any indirect damages (foresee
|
|
|
56
57
|
| `get_fund_description` | Detailed fund description |
|
|
57
58
|
| `get_fund_holdings` | Portfolio allocation (country, sector, top holdings) |
|
|
58
59
|
|
|
60
|
+
### Certificates
|
|
61
|
+
| Tool | Description |
|
|
62
|
+
|------|-------------|
|
|
63
|
+
| `filter_certificates` | Search and filter certificates with pagination |
|
|
64
|
+
| `get_certificate_info` | Get detailed certificate information |
|
|
65
|
+
| `get_certificate_details` | Get extended certificate details |
|
|
66
|
+
|
|
67
|
+
### Warrants
|
|
68
|
+
| Tool | Description |
|
|
69
|
+
|------|-------------|
|
|
70
|
+
| `filter_warrants` | Search and filter warrants (turbos, minis) |
|
|
71
|
+
| `get_warrant_info` | Get detailed warrant information |
|
|
72
|
+
| `get_warrant_details` | Get extended warrant details |
|
|
73
|
+
|
|
74
|
+
### ETFs
|
|
75
|
+
| Tool | Description |
|
|
76
|
+
|------|-------------|
|
|
77
|
+
| `filter_etfs` | Search and filter exchange-traded funds |
|
|
78
|
+
| `get_etf_info` | Get detailed ETF information |
|
|
79
|
+
| `get_etf_details` | Get extended ETF details |
|
|
80
|
+
|
|
81
|
+
### Futures/Forwards
|
|
82
|
+
| Tool | Description |
|
|
83
|
+
|------|-------------|
|
|
84
|
+
| `list_futures_forwards` | List available futures and forwards |
|
|
85
|
+
| `get_future_forward_filter_options` | Get available filter options |
|
|
86
|
+
| `get_future_forward_info` | Get contract information |
|
|
87
|
+
| `get_future_forward_details` | Get extended contract details |
|
|
88
|
+
|
|
89
|
+
### Additional Data
|
|
90
|
+
| Tool | Description |
|
|
91
|
+
|------|-------------|
|
|
92
|
+
| `get_number_of_owners` | Get owner count for any instrument |
|
|
93
|
+
| `get_short_selling` | Get short selling data for instruments |
|
|
94
|
+
| `get_marketmaker_chart` | Get OHLC price chart data for traded products (certificates, warrants, ETFs) |
|
|
95
|
+
|
|
59
96
|
## 💡 MCP Prompts
|
|
60
97
|
|
|
61
98
|
- `analyze_stock` - Comprehensive stock analysis workflow
|
|
@@ -72,12 +109,14 @@ For Claude Desktop or other MCP clients, add to your configuration:
|
|
|
72
109
|
"mcpServers": {
|
|
73
110
|
"avanza": {
|
|
74
111
|
"command": "uvx",
|
|
75
|
-
"args": ["avanza-mcp"]
|
|
112
|
+
"args": ["--prerelease=allow", "avanza-mcp"]
|
|
76
113
|
}
|
|
77
114
|
}
|
|
78
115
|
}
|
|
79
116
|
```
|
|
80
117
|
|
|
118
|
+
> **Note:** The `--prerelease=allow` flag is required because this package depends on fastmcp 3.0 (currently in beta). This will no longer be needed once fastmcp 3.0 stable is released.
|
|
119
|
+
|
|
81
120
|
### Usage in Claude Desktop
|
|
82
121
|
|
|
83
122
|
Once configured, you can ask Claude:
|
|
@@ -40,6 +40,42 @@ The author of this software is not responsible for any indirect damages (foresee
|
|
|
40
40
|
| `get_fund_description` | Detailed fund description |
|
|
41
41
|
| `get_fund_holdings` | Portfolio allocation (country, sector, top holdings) |
|
|
42
42
|
|
|
43
|
+
### Certificates
|
|
44
|
+
| Tool | Description |
|
|
45
|
+
|------|-------------|
|
|
46
|
+
| `filter_certificates` | Search and filter certificates with pagination |
|
|
47
|
+
| `get_certificate_info` | Get detailed certificate information |
|
|
48
|
+
| `get_certificate_details` | Get extended certificate details |
|
|
49
|
+
|
|
50
|
+
### Warrants
|
|
51
|
+
| Tool | Description |
|
|
52
|
+
|------|-------------|
|
|
53
|
+
| `filter_warrants` | Search and filter warrants (turbos, minis) |
|
|
54
|
+
| `get_warrant_info` | Get detailed warrant information |
|
|
55
|
+
| `get_warrant_details` | Get extended warrant details |
|
|
56
|
+
|
|
57
|
+
### ETFs
|
|
58
|
+
| Tool | Description |
|
|
59
|
+
|------|-------------|
|
|
60
|
+
| `filter_etfs` | Search and filter exchange-traded funds |
|
|
61
|
+
| `get_etf_info` | Get detailed ETF information |
|
|
62
|
+
| `get_etf_details` | Get extended ETF details |
|
|
63
|
+
|
|
64
|
+
### Futures/Forwards
|
|
65
|
+
| Tool | Description |
|
|
66
|
+
|------|-------------|
|
|
67
|
+
| `list_futures_forwards` | List available futures and forwards |
|
|
68
|
+
| `get_future_forward_filter_options` | Get available filter options |
|
|
69
|
+
| `get_future_forward_info` | Get contract information |
|
|
70
|
+
| `get_future_forward_details` | Get extended contract details |
|
|
71
|
+
|
|
72
|
+
### Additional Data
|
|
73
|
+
| Tool | Description |
|
|
74
|
+
|------|-------------|
|
|
75
|
+
| `get_number_of_owners` | Get owner count for any instrument |
|
|
76
|
+
| `get_short_selling` | Get short selling data for instruments |
|
|
77
|
+
| `get_marketmaker_chart` | Get OHLC price chart data for traded products (certificates, warrants, ETFs) |
|
|
78
|
+
|
|
43
79
|
## 💡 MCP Prompts
|
|
44
80
|
|
|
45
81
|
- `analyze_stock` - Comprehensive stock analysis workflow
|
|
@@ -56,12 +92,14 @@ For Claude Desktop or other MCP clients, add to your configuration:
|
|
|
56
92
|
"mcpServers": {
|
|
57
93
|
"avanza": {
|
|
58
94
|
"command": "uvx",
|
|
59
|
-
"args": ["avanza-mcp"]
|
|
95
|
+
"args": ["--prerelease=allow", "avanza-mcp"]
|
|
60
96
|
}
|
|
61
97
|
}
|
|
62
98
|
}
|
|
63
99
|
```
|
|
64
100
|
|
|
101
|
+
> **Note:** The `--prerelease=allow` flag is required because this package depends on fastmcp 3.0 (currently in beta). This will no longer be needed once fastmcp 3.0 stable is released.
|
|
102
|
+
|
|
65
103
|
### Usage in Claude Desktop
|
|
66
104
|
|
|
67
105
|
Once configured, you can ask Claude:
|
|
@@ -6,11 +6,13 @@ No authentication required - all endpoints are publicly accessible.
|
|
|
6
6
|
Provides access to:
|
|
7
7
|
- Stock information, quotes, and charts
|
|
8
8
|
- Fund information, sustainability metrics, and performance
|
|
9
|
+
- Certificates, Warrants, ETFs, Futures/Forwards data
|
|
9
10
|
- Market data including order depth, trades, and broker activity
|
|
11
|
+
- Additional data (number of owners, short selling info)
|
|
10
12
|
- Real-time market status and trading hours
|
|
11
13
|
"""
|
|
12
14
|
|
|
13
|
-
__version__ = "1.
|
|
15
|
+
__version__ = "1.2.0"
|
|
14
16
|
|
|
15
17
|
from fastmcp import FastMCP
|
|
16
18
|
|
|
@@ -22,6 +22,9 @@ class PublicEndpoint(Enum):
|
|
|
22
22
|
STOCK_BROKER_TRADES = "/_api/market-guide/stock/{id}/broker-trade-summaries"
|
|
23
23
|
STOCK_CHART = "/_api/price-chart/stock/{id}" # Requires timePeriod param
|
|
24
24
|
|
|
25
|
+
# Market data - Charts (for traded products: certificates, warrants, ETFs)
|
|
26
|
+
MARKETMAKER_CHART = "/_api/price-chart/marketmaker/{id}" # Requires timePeriod param
|
|
27
|
+
|
|
25
28
|
# Market data - Funds
|
|
26
29
|
FUND_INFO = "/_api/fund-guide/guide/{id}"
|
|
27
30
|
FUND_SUSTAINABILITY = "/_api/fund-reference/sustainability/{id}"
|
|
@@ -29,6 +32,31 @@ class PublicEndpoint(Enum):
|
|
|
29
32
|
FUND_CHART_PERIODS = "/_api/fund-guide/chart/timeperiods/{id}"
|
|
30
33
|
FUND_DESCRIPTION = "/_api/fund-guide/description/{id}"
|
|
31
34
|
|
|
35
|
+
# Market data - Certificates
|
|
36
|
+
CERTIFICATE_FILTER = "/_api/market-certificate-filter/"
|
|
37
|
+
CERTIFICATE_INFO = "/_api/market-guide/certificate/{id}"
|
|
38
|
+
CERTIFICATE_DETAILS = "/_api/market-guide/certificate/{id}/details"
|
|
39
|
+
|
|
40
|
+
# Market data - Warrants
|
|
41
|
+
WARRANT_FILTER = "/_api/market-warrant-filter/"
|
|
42
|
+
WARRANT_INFO = "/_api/market-guide/warrant/{id}"
|
|
43
|
+
WARRANT_DETAILS = "/_api/market-guide/warrant/{id}/details"
|
|
44
|
+
|
|
45
|
+
# Market data - ETFs
|
|
46
|
+
ETF_FILTER = "/_api/market-etf-filter/"
|
|
47
|
+
ETF_INFO = "/_api/market-etf/{id}"
|
|
48
|
+
ETF_DETAILS = "/_api/market-etf/{id}/details"
|
|
49
|
+
|
|
50
|
+
# Market data - Futures/Forwards
|
|
51
|
+
FUTURE_FORWARD_MATRIX = "/_api/market-option-future-forward-list/matrix"
|
|
52
|
+
FUTURE_FORWARD_FILTER_OPTIONS = "/_api/market-option-future-forward-list/filter-options"
|
|
53
|
+
FUTURE_FORWARD_INFO = "/_api/market-guide/futureforward/{id}"
|
|
54
|
+
FUTURE_FORWARD_DETAILS = "/_api/market-guide/futureforward/{id}/details"
|
|
55
|
+
|
|
56
|
+
# Additional features
|
|
57
|
+
NUMBER_OF_OWNERS = "/_api/market-guide/number-of-owners/{id}"
|
|
58
|
+
SHORT_SELLING = "/_api/market-guide/short-selling/{id}"
|
|
59
|
+
|
|
32
60
|
def format(self, **kwargs: str | int) -> str:
|
|
33
61
|
"""Format endpoint path with variables.
|
|
34
62
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Pydantic models for Avanza API responses."""
|
|
2
|
+
|
|
3
|
+
from .certificate import (
|
|
4
|
+
CertificateDetails,
|
|
5
|
+
CertificateFilter,
|
|
6
|
+
CertificateFilterRequest,
|
|
7
|
+
CertificateFilterResponse,
|
|
8
|
+
CertificateInfo,
|
|
9
|
+
CertificateListItem,
|
|
10
|
+
)
|
|
11
|
+
from .chart import ChartData, ChartMetadata, ChartResolution, OHLCDataPoint
|
|
12
|
+
from .common import Direction, InstrumentType, SubType, TimePeriod
|
|
13
|
+
from .etf import (
|
|
14
|
+
ETFDetails,
|
|
15
|
+
ETFFilter,
|
|
16
|
+
ETFFilterRequest,
|
|
17
|
+
ETFFilterResponse,
|
|
18
|
+
ETFInfo,
|
|
19
|
+
ETFListItem,
|
|
20
|
+
)
|
|
21
|
+
from .filter import FilterResponse, PaginationRequest, SortBy, UnderlyingInstrument
|
|
22
|
+
from .fund import (
|
|
23
|
+
FundChart,
|
|
24
|
+
FundChartPeriod,
|
|
25
|
+
FundDescription,
|
|
26
|
+
FundInfo,
|
|
27
|
+
FundPerformance,
|
|
28
|
+
FundSustainability,
|
|
29
|
+
)
|
|
30
|
+
from .future_forward import (
|
|
31
|
+
FutureForwardDetails,
|
|
32
|
+
FutureForwardInfo,
|
|
33
|
+
FutureForwardMatrixFilter,
|
|
34
|
+
FutureForwardMatrixRequest,
|
|
35
|
+
FutureForwardMatrixResponse,
|
|
36
|
+
)
|
|
37
|
+
from .instrument_data import NumberOfOwners, ShortSellingData
|
|
38
|
+
from .search import SearchHit, SearchResponse
|
|
39
|
+
from .stock import (
|
|
40
|
+
BrokerTradeSummary,
|
|
41
|
+
MarketplaceInfo,
|
|
42
|
+
OrderDepth,
|
|
43
|
+
Quote,
|
|
44
|
+
StockChart,
|
|
45
|
+
StockInfo,
|
|
46
|
+
Trade,
|
|
47
|
+
)
|
|
48
|
+
from .warrant import (
|
|
49
|
+
WarrantDetails,
|
|
50
|
+
WarrantFilter,
|
|
51
|
+
WarrantFilterRequest,
|
|
52
|
+
WarrantFilterResponse,
|
|
53
|
+
WarrantInfo,
|
|
54
|
+
WarrantListItem,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
__all__ = [
|
|
58
|
+
# Certificate models
|
|
59
|
+
"CertificateInfo",
|
|
60
|
+
"CertificateDetails",
|
|
61
|
+
"CertificateListItem",
|
|
62
|
+
"CertificateFilter",
|
|
63
|
+
"CertificateFilterRequest",
|
|
64
|
+
"CertificateFilterResponse",
|
|
65
|
+
# Chart models
|
|
66
|
+
"ChartData",
|
|
67
|
+
"OHLCDataPoint",
|
|
68
|
+
"ChartMetadata",
|
|
69
|
+
"ChartResolution",
|
|
70
|
+
# Common
|
|
71
|
+
"InstrumentType",
|
|
72
|
+
"TimePeriod",
|
|
73
|
+
"Direction",
|
|
74
|
+
"SubType",
|
|
75
|
+
# ETF models
|
|
76
|
+
"ETFInfo",
|
|
77
|
+
"ETFDetails",
|
|
78
|
+
"ETFListItem",
|
|
79
|
+
"ETFFilter",
|
|
80
|
+
"ETFFilterRequest",
|
|
81
|
+
"ETFFilterResponse",
|
|
82
|
+
# Filter models
|
|
83
|
+
"SortBy",
|
|
84
|
+
"PaginationRequest",
|
|
85
|
+
"UnderlyingInstrument",
|
|
86
|
+
"FilterResponse",
|
|
87
|
+
# Fund models
|
|
88
|
+
"FundInfo",
|
|
89
|
+
"FundPerformance",
|
|
90
|
+
"FundSustainability",
|
|
91
|
+
"FundChart",
|
|
92
|
+
"FundChartPeriod",
|
|
93
|
+
"FundDescription",
|
|
94
|
+
# Future/Forward models
|
|
95
|
+
"FutureForwardInfo",
|
|
96
|
+
"FutureForwardDetails",
|
|
97
|
+
"FutureForwardMatrixFilter",
|
|
98
|
+
"FutureForwardMatrixRequest",
|
|
99
|
+
"FutureForwardMatrixResponse",
|
|
100
|
+
# Instrument data
|
|
101
|
+
"NumberOfOwners",
|
|
102
|
+
"ShortSellingData",
|
|
103
|
+
# Search models
|
|
104
|
+
"SearchResponse",
|
|
105
|
+
"SearchHit",
|
|
106
|
+
# Stock models
|
|
107
|
+
"StockInfo",
|
|
108
|
+
"Quote",
|
|
109
|
+
"StockChart",
|
|
110
|
+
"MarketplaceInfo",
|
|
111
|
+
"BrokerTradeSummary",
|
|
112
|
+
"Trade",
|
|
113
|
+
"OrderDepth",
|
|
114
|
+
# Warrant models
|
|
115
|
+
"WarrantInfo",
|
|
116
|
+
"WarrantDetails",
|
|
117
|
+
"WarrantListItem",
|
|
118
|
+
"WarrantFilter",
|
|
119
|
+
"WarrantFilterRequest",
|
|
120
|
+
"WarrantFilterResponse",
|
|
121
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Certificate-related Pydantic models."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from .stock import MODEL_CONFIG, Quote, Listing, HistoricalClosingPrices, KeyIndicators
|
|
5
|
+
from .filter import UnderlyingInstrument, SortBy, FilterResponse
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CertificateListItem(BaseModel):
|
|
9
|
+
"""Certificate in filter/list results."""
|
|
10
|
+
|
|
11
|
+
model_config = MODEL_CONFIG
|
|
12
|
+
|
|
13
|
+
orderbookId: str
|
|
14
|
+
countryCode: str
|
|
15
|
+
name: str
|
|
16
|
+
direction: str
|
|
17
|
+
marketplaceCode: str
|
|
18
|
+
issuer: str
|
|
19
|
+
hasPosition: bool
|
|
20
|
+
totalValueTraded: float | None = None
|
|
21
|
+
underlyingInstrument: UnderlyingInstrument | None = None
|
|
22
|
+
leverage: float | None = None
|
|
23
|
+
spread: float | None = None
|
|
24
|
+
buyPrice: float | None = None
|
|
25
|
+
sellPrice: float | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CertificateInfo(BaseModel):
|
|
29
|
+
"""Detailed certificate information."""
|
|
30
|
+
|
|
31
|
+
model_config = MODEL_CONFIG
|
|
32
|
+
|
|
33
|
+
orderbookId: str
|
|
34
|
+
name: str
|
|
35
|
+
isin: str | None = None
|
|
36
|
+
tradable: str | None = None
|
|
37
|
+
listing: Listing | None = None
|
|
38
|
+
historicalClosingPrices: HistoricalClosingPrices | None = None
|
|
39
|
+
keyIndicators: KeyIndicators | None = None
|
|
40
|
+
quote: Quote | None = None
|
|
41
|
+
type: str | None = None
|
|
42
|
+
assetCategory: str | None = None
|
|
43
|
+
category: str | None = None
|
|
44
|
+
subCategory: str | None = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CertificateDetails(BaseModel):
|
|
48
|
+
"""Detailed certificate extended information."""
|
|
49
|
+
|
|
50
|
+
model_config = MODEL_CONFIG
|
|
51
|
+
|
|
52
|
+
# Flexible structure to handle various response formats
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class CertificateFilter(BaseModel):
|
|
57
|
+
"""Filter criteria for certificates."""
|
|
58
|
+
|
|
59
|
+
model_config = MODEL_CONFIG
|
|
60
|
+
|
|
61
|
+
directions: list[str] = Field(default_factory=list)
|
|
62
|
+
leverages: list[float] = Field(default_factory=list)
|
|
63
|
+
underlyingInstruments: list[str] = Field(default_factory=list)
|
|
64
|
+
categories: list[str] = Field(default_factory=list)
|
|
65
|
+
exposures: list[str] = Field(default_factory=list)
|
|
66
|
+
issuers: list[str] = Field(default_factory=list)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class CertificateFilterRequest(BaseModel):
|
|
70
|
+
"""Complete filter request for certificates."""
|
|
71
|
+
|
|
72
|
+
model_config = MODEL_CONFIG
|
|
73
|
+
|
|
74
|
+
filter: CertificateFilter
|
|
75
|
+
offset: int = 0
|
|
76
|
+
limit: int = 20
|
|
77
|
+
sortBy: SortBy
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class CertificateFilterResponse(FilterResponse):
|
|
81
|
+
"""Response from certificate filter endpoint."""
|
|
82
|
+
|
|
83
|
+
model_config = MODEL_CONFIG
|
|
84
|
+
|
|
85
|
+
certificates: list[CertificateListItem]
|
|
86
|
+
filter: CertificateFilter | None = None
|
|
87
|
+
sortBy: SortBy | None = None
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Chart data models for price charts."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from .stock import MODEL_CONFIG
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OHLCDataPoint(BaseModel):
|
|
9
|
+
"""OHLC (Open-High-Low-Close) candlestick data point."""
|
|
10
|
+
|
|
11
|
+
model_config = MODEL_CONFIG
|
|
12
|
+
|
|
13
|
+
timestamp: int
|
|
14
|
+
open: float
|
|
15
|
+
close: float
|
|
16
|
+
low: float
|
|
17
|
+
high: float
|
|
18
|
+
totalVolumeTraded: int
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ChartResolution(BaseModel):
|
|
22
|
+
"""Chart resolution metadata."""
|
|
23
|
+
|
|
24
|
+
model_config = MODEL_CONFIG
|
|
25
|
+
|
|
26
|
+
chartResolution: str
|
|
27
|
+
availableResolutions: list[str]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ChartMetadata(BaseModel):
|
|
31
|
+
"""Chart metadata."""
|
|
32
|
+
|
|
33
|
+
model_config = MODEL_CONFIG
|
|
34
|
+
|
|
35
|
+
resolution: ChartResolution
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ChartData(BaseModel):
|
|
39
|
+
"""Price chart data response.
|
|
40
|
+
|
|
41
|
+
Used for both stock charts and marketmaker charts.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
model_config = MODEL_CONFIG
|
|
45
|
+
|
|
46
|
+
ohlc: list[OHLCDataPoint]
|
|
47
|
+
metadata: ChartMetadata
|
|
48
|
+
from_date: str | None = Field(default=None, alias="from") # 'from' is a Python keyword
|
|
49
|
+
to: str | None = None
|
|
50
|
+
marketMaker: list[dict] | None = None # Only present in marketmaker charts
|
|
51
|
+
previousClosingPrice: float | None = None # Only present in some charts
|
|
@@ -48,3 +48,18 @@ class Resolution(str, Enum):
|
|
|
48
48
|
DAY = "DAY"
|
|
49
49
|
WEEK = "WEEK"
|
|
50
50
|
MONTH = "MONTH"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class Direction(str, Enum):
|
|
54
|
+
"""Direction for leveraged instruments."""
|
|
55
|
+
|
|
56
|
+
LONG = "long"
|
|
57
|
+
SHORT = "short"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class SubType(str, Enum):
|
|
61
|
+
"""Sub-types for warrants and certificates."""
|
|
62
|
+
|
|
63
|
+
TURBO = "TURBO"
|
|
64
|
+
MINI = "MINI"
|
|
65
|
+
KNOCK_OUT = "KNOCK_OUT"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""ETF-related Pydantic models."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from .filter import FilterResponse, SortBy
|
|
6
|
+
from .stock import (
|
|
7
|
+
MODEL_CONFIG,
|
|
8
|
+
HistoricalClosingPrices,
|
|
9
|
+
Listing,
|
|
10
|
+
MarketPlace,
|
|
11
|
+
Quote,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ETFListItem(BaseModel):
|
|
16
|
+
"""ETF in filter/list results."""
|
|
17
|
+
|
|
18
|
+
model_config = MODEL_CONFIG
|
|
19
|
+
|
|
20
|
+
orderbookId: str
|
|
21
|
+
countryCode: str
|
|
22
|
+
name: str
|
|
23
|
+
directYield: float | None = None
|
|
24
|
+
oneDayChangePercent: float | None = None
|
|
25
|
+
threeYearsChangePercent: float | None = None
|
|
26
|
+
managementFee: float | None = None
|
|
27
|
+
productFee: float | None = None
|
|
28
|
+
numberOfOwners: int | None = None
|
|
29
|
+
riskScore: int | None = None
|
|
30
|
+
hasPosition: bool = False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ETFInfo(BaseModel):
|
|
34
|
+
"""Detailed ETF information."""
|
|
35
|
+
|
|
36
|
+
model_config = MODEL_CONFIG
|
|
37
|
+
|
|
38
|
+
orderbookId: str
|
|
39
|
+
name: str
|
|
40
|
+
isin: str | None = None
|
|
41
|
+
tradable: str | None = None
|
|
42
|
+
listing: Listing | None = None
|
|
43
|
+
marketPlace: MarketPlace | None = None
|
|
44
|
+
historicalClosingPrices: HistoricalClosingPrices | None = None
|
|
45
|
+
keyIndicators: dict | None = None
|
|
46
|
+
quote: Quote | None = None
|
|
47
|
+
type: str | None = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ETFDetails(BaseModel):
|
|
51
|
+
"""Detailed ETF extended information."""
|
|
52
|
+
|
|
53
|
+
model_config = MODEL_CONFIG
|
|
54
|
+
|
|
55
|
+
# Flexible structure to handle various response formats
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ETFFilter(BaseModel):
|
|
60
|
+
"""Filter criteria for ETFs."""
|
|
61
|
+
|
|
62
|
+
model_config = MODEL_CONFIG
|
|
63
|
+
|
|
64
|
+
assetCategories: list[str] = Field(default_factory=list)
|
|
65
|
+
subCategories: list[str] = Field(default_factory=list)
|
|
66
|
+
exposures: list[str] = Field(default_factory=list)
|
|
67
|
+
riskScores: list[str] = Field(default_factory=list)
|
|
68
|
+
directions: list[str] = Field(default_factory=list)
|
|
69
|
+
issuers: list[str] = Field(default_factory=list)
|
|
70
|
+
currencyCodes: list[str] = Field(default_factory=list)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ETFFilterRequest(BaseModel):
|
|
74
|
+
"""Complete filter request for ETFs."""
|
|
75
|
+
|
|
76
|
+
model_config = MODEL_CONFIG
|
|
77
|
+
|
|
78
|
+
filter: ETFFilter
|
|
79
|
+
offset: int = 0
|
|
80
|
+
limit: int = 20
|
|
81
|
+
sortBy: SortBy
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ETFFilterResponse(FilterResponse):
|
|
85
|
+
"""Response from ETF filter endpoint."""
|
|
86
|
+
|
|
87
|
+
model_config = MODEL_CONFIG
|
|
88
|
+
|
|
89
|
+
etfs: list[ETFListItem]
|
|
90
|
+
filter: ETFFilter | None = None
|
|
91
|
+
filterOptions: dict | None = None # Available filter options
|
|
92
|
+
sortBy: SortBy | None = None
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Shared filter models for list/filter endpoints."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Standard model config for all models
|
|
8
|
+
MODEL_CONFIG = ConfigDict(
|
|
9
|
+
populate_by_name=True,
|
|
10
|
+
str_strip_whitespace=True,
|
|
11
|
+
validate_assignment=True,
|
|
12
|
+
extra="allow", # Don't fail on extra fields from API
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SortBy(BaseModel):
|
|
17
|
+
"""Sort configuration for filter endpoints."""
|
|
18
|
+
|
|
19
|
+
model_config = MODEL_CONFIG
|
|
20
|
+
|
|
21
|
+
field: str
|
|
22
|
+
order: Literal["asc", "desc"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class PaginationRequest(BaseModel):
|
|
26
|
+
"""Pagination parameters for filter endpoints."""
|
|
27
|
+
|
|
28
|
+
model_config = MODEL_CONFIG
|
|
29
|
+
|
|
30
|
+
offset: int = Field(default=0, ge=0)
|
|
31
|
+
limit: int = Field(default=20, ge=1, le=100)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class UnderlyingInstrument(BaseModel):
|
|
35
|
+
"""Underlying instrument for derivatives."""
|
|
36
|
+
|
|
37
|
+
model_config = MODEL_CONFIG
|
|
38
|
+
|
|
39
|
+
name: str | None = None
|
|
40
|
+
orderbookId: str | None = None
|
|
41
|
+
instrumentType: str | None = None
|
|
42
|
+
countryCode: str | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class FilterResponse(BaseModel):
|
|
46
|
+
"""Base response for filter endpoints with pagination."""
|
|
47
|
+
|
|
48
|
+
model_config = MODEL_CONFIG
|
|
49
|
+
|
|
50
|
+
pagination: dict | None = None
|
|
51
|
+
totalNumberOfOrderbooks: int | None = None
|