avanza-mcp 1.1.0__tar.gz → 1.3.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.
Files changed (71) hide show
  1. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/PKG-INFO +56 -1
  2. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/README.md +55 -0
  3. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/justfile +1 -1
  4. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/__init__.py +3 -1
  5. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/client/endpoints.py +28 -0
  6. avanza_mcp-1.3.0/src/avanza_mcp/models/__init__.py +121 -0
  7. avanza_mcp-1.3.0/src/avanza_mcp/models/certificate.py +87 -0
  8. avanza_mcp-1.3.0/src/avanza_mcp/models/chart.py +51 -0
  9. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/models/common.py +15 -0
  10. avanza_mcp-1.3.0/src/avanza_mcp/models/etf.py +92 -0
  11. avanza_mcp-1.3.0/src/avanza_mcp/models/filter.py +51 -0
  12. avanza_mcp-1.3.0/src/avanza_mcp/models/future_forward.py +63 -0
  13. avanza_mcp-1.3.0/src/avanza_mcp/models/instrument_data.py +26 -0
  14. avanza_mcp-1.3.0/src/avanza_mcp/models/warrant.py +88 -0
  15. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/prompts/__init__.py +2 -1
  16. avanza_mcp-1.3.0/src/avanza_mcp/prompts/workflows.py +488 -0
  17. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/resources/__init__.py +2 -1
  18. avanza_mcp-1.3.0/src/avanza_mcp/resources/usage.py +503 -0
  19. avanza_mcp-1.3.0/src/avanza_mcp/services/market_data_service.py +611 -0
  20. avanza_mcp-1.3.0/src/avanza_mcp/tools/__init__.py +22 -0
  21. avanza_mcp-1.3.0/src/avanza_mcp/tools/certificates.py +156 -0
  22. avanza_mcp-1.3.0/src/avanza_mcp/tools/etfs.py +151 -0
  23. avanza_mcp-1.3.0/src/avanza_mcp/tools/futures_forwards.py +174 -0
  24. avanza_mcp-1.3.0/src/avanza_mcp/tools/instrument_data.py +135 -0
  25. avanza_mcp-1.3.0/src/avanza_mcp/tools/warrants.py +139 -0
  26. avanza_mcp-1.3.0/tests/integration/test_certificates_integration.py +111 -0
  27. avanza_mcp-1.3.0/tests/integration/test_chart_integration.py +107 -0
  28. avanza_mcp-1.3.0/tests/integration/test_etfs_integration.py +80 -0
  29. avanza_mcp-1.3.0/tests/integration/test_futures_forwards_integration.py +64 -0
  30. avanza_mcp-1.3.0/tests/integration/test_instrument_data_integration.py +42 -0
  31. avanza_mcp-1.3.0/tests/integration/test_warrants_integration.py +59 -0
  32. avanza_mcp-1.3.0/tests/unit/test_certificate_models.py +118 -0
  33. avanza_mcp-1.3.0/tests/unit/test_chart_models.py +131 -0
  34. avanza_mcp-1.3.0/tests/unit/test_etf_models.py +54 -0
  35. avanza_mcp-1.3.0/tests/unit/test_filter_models.py +30 -0
  36. avanza_mcp-1.3.0/tests/unit/test_future_forward_models.py +67 -0
  37. avanza_mcp-1.3.0/tests/unit/test_instrument_data_models.py +26 -0
  38. avanza_mcp-1.3.0/tests/unit/test_warrant_models.py +60 -0
  39. avanza_mcp-1.1.0/src/avanza_mcp/models/__init__.py +0 -41
  40. avanza_mcp-1.1.0/src/avanza_mcp/services/market_data_service.py +0 -298
  41. avanza_mcp-1.1.0/src/avanza_mcp/tools/__init__.py +0 -8
  42. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/.github/PUBLISHING.md +0 -0
  43. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/.github/workflows/ci.yml +0 -0
  44. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/.github/workflows/publish.yml +0 -0
  45. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/.gitignore +0 -0
  46. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/.python-version +0 -0
  47. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/CLAUDE.md +0 -0
  48. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/DEVELOPMENT.md +0 -0
  49. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/LICENSE.md +0 -0
  50. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/pyproject.toml +0 -0
  51. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/client/__init__.py +0 -0
  52. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/client/base.py +0 -0
  53. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/client/exceptions.py +0 -0
  54. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/models/fund.py +0 -0
  55. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/models/search.py +0 -0
  56. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/models/stock.py +0 -0
  57. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/prompts/analysis.py +0 -0
  58. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/resources/instruments.py +0 -0
  59. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/services/__init__.py +0 -0
  60. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/services/search_service.py +0 -0
  61. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/tools/funds.py +0 -0
  62. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/tools/market_data.py +0 -0
  63. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/src/avanza_mcp/tools/search.py +0 -0
  64. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/__init__.py +0 -0
  65. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/conftest.py +0 -0
  66. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/integration/__init__.py +0 -0
  67. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/integration/test_tools.py +0 -0
  68. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/unit/__init__.py +0 -0
  69. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/unit/test_client.py +0 -0
  70. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/tests/unit/test_models.py +0 -0
  71. {avanza_mcp-1.1.0 → avanza_mcp-1.3.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: avanza-mcp
3
- Version: 1.1.0
3
+ Version: 1.3.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
@@ -57,12 +57,67 @@ The author of this software is not responsible for any indirect damages (foresee
57
57
  | `get_fund_description` | Detailed fund description |
58
58
  | `get_fund_holdings` | Portfolio allocation (country, sector, top holdings) |
59
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
+
60
96
  ## 💡 MCP Prompts
61
97
 
98
+ ### Analysis Prompts
62
99
  - `analyze_stock` - Comprehensive stock analysis workflow
63
100
  - `compare_funds` - Multi-fund comparison template
64
101
  - `screen_dividend_stocks` - Dividend stock screening
65
102
 
103
+ ### Workflow Prompts (Teach AI Efficient Data Fetching)
104
+ - `search_and_analyze_instrument` - Guide for finding and analyzing instruments efficiently
105
+ - `filter_instruments_efficiently` - Guide for filtering large datasets with pagination
106
+ - `compare_multiple_instruments` - Guide for comparing instruments efficiently
107
+ - `explore_market_segment` - Guide for exploring market segments
108
+ - `get_historical_analysis` - Guide for analyzing historical data
109
+ - `screen_by_criteria` - Guide for screening by custom criteria
110
+
111
+ ## 📚 MCP Resources
112
+
113
+ ### Documentation Resources
114
+ - `avanza://docs/usage` - Comprehensive usage guide for AI assistants
115
+ - `avanza://docs/quick-start` - Quick reference for common tasks
116
+
117
+ ### Instrument Resources
118
+ - `avanza://stock/{instrument_id}` - Get stock information as markdown
119
+ - `avanza://fund/{instrument_id}` - Get fund information as markdown
120
+
66
121
 
67
122
  ### Configuration for MCP Clients
68
123
 
@@ -40,12 +40,67 @@ 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
 
81
+ ### Analysis Prompts
45
82
  - `analyze_stock` - Comprehensive stock analysis workflow
46
83
  - `compare_funds` - Multi-fund comparison template
47
84
  - `screen_dividend_stocks` - Dividend stock screening
48
85
 
86
+ ### Workflow Prompts (Teach AI Efficient Data Fetching)
87
+ - `search_and_analyze_instrument` - Guide for finding and analyzing instruments efficiently
88
+ - `filter_instruments_efficiently` - Guide for filtering large datasets with pagination
89
+ - `compare_multiple_instruments` - Guide for comparing instruments efficiently
90
+ - `explore_market_segment` - Guide for exploring market segments
91
+ - `get_historical_analysis` - Guide for analyzing historical data
92
+ - `screen_by_criteria` - Guide for screening by custom criteria
93
+
94
+ ## 📚 MCP Resources
95
+
96
+ ### Documentation Resources
97
+ - `avanza://docs/usage` - Comprehensive usage guide for AI assistants
98
+ - `avanza://docs/quick-start` - Quick reference for common tasks
99
+
100
+ ### Instrument Resources
101
+ - `avanza://stock/{instrument_id}` - Get stock information as markdown
102
+ - `avanza://fund/{instrument_id}` - Get fund information as markdown
103
+
49
104
 
50
105
  ### Configuration for MCP Clients
51
106
 
@@ -63,7 +63,7 @@ release version_part="patch":
63
63
  git add src/avanza_mcp/__init__.py
64
64
  git commit -m "Bump version to $new_version"
65
65
  git tag "v$new_version"
66
- git push origin master
66
+ git push origin main
67
67
  git push origin "v$new_version"
68
68
 
69
69
  echo ""
@@ -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.1.0"
15
+ __version__ = "1.3.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
@@ -0,0 +1,63 @@
1
+ """Future and forward contract models."""
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from .filter import SortBy
6
+ from .stock import MODEL_CONFIG, HistoricalClosingPrices, Listing, Quote
7
+
8
+
9
+ class FutureForwardInfo(BaseModel):
10
+ """Detailed future/forward information."""
11
+
12
+ model_config = MODEL_CONFIG
13
+
14
+ orderbookId: str
15
+ name: str
16
+ isin: str | None = None
17
+ tradable: str | None = None
18
+ listing: Listing | None = None
19
+ historicalClosingPrices: HistoricalClosingPrices | None = None
20
+ keyIndicators: dict | None = None
21
+ quote: Quote | None = None
22
+ type: str | None = None
23
+ underlying: dict | None = None
24
+
25
+
26
+ class FutureForwardDetails(BaseModel):
27
+ """Detailed future/forward extended information."""
28
+
29
+ model_config = MODEL_CONFIG
30
+
31
+ # Flexible structure to handle various response formats
32
+ pass
33
+
34
+
35
+ class FutureForwardMatrixFilter(BaseModel):
36
+ """Filter criteria for futures/forwards matrix."""
37
+
38
+ model_config = MODEL_CONFIG
39
+
40
+ underlyingInstruments: list[str] = []
41
+ optionTypes: list[str] = []
42
+ endDates: list[str] = []
43
+ callIndicators: list[str] = []
44
+
45
+
46
+ class FutureForwardMatrixRequest(BaseModel):
47
+ """Request for futures/forwards matrix list."""
48
+
49
+ model_config = MODEL_CONFIG
50
+
51
+ filter: FutureForwardMatrixFilter
52
+ offset: int = 0
53
+ limit: int = 20
54
+ sortBy: SortBy
55
+
56
+
57
+ class FutureForwardMatrixResponse(BaseModel):
58
+ """Response from futures/forwards matrix endpoint."""
59
+
60
+ model_config = MODEL_CONFIG
61
+
62
+ # Flexible structure to handle matrix response
63
+ # The actual structure will be preserved via extra="allow"