avanza-mcp 1.0.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
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/__init__.py +3 -1
- avanza_mcp/client/endpoints.py +28 -0
- avanza_mcp/models/__init__.py +87 -7
- avanza_mcp/models/certificate.py +87 -0
- avanza_mcp/models/chart.py +51 -0
- avanza_mcp/models/common.py +15 -0
- avanza_mcp/models/etf.py +92 -0
- avanza_mcp/models/filter.py +51 -0
- avanza_mcp/models/future_forward.py +63 -0
- avanza_mcp/models/instrument_data.py +26 -0
- avanza_mcp/models/warrant.py +88 -0
- avanza_mcp/services/market_data_service.py +313 -0
- avanza_mcp/tools/__init__.py +15 -1
- avanza_mcp/tools/certificates.py +156 -0
- avanza_mcp/tools/etfs.py +151 -0
- avanza_mcp/tools/futures_forwards.py +174 -0
- avanza_mcp/tools/instrument_data.py +135 -0
- avanza_mcp/tools/warrants.py +139 -0
- {avanza_mcp-1.0.0.dist-info → avanza_mcp-1.2.0.dist-info}/METADATA +42 -3
- avanza_mcp-1.2.0.dist-info/RECORD +38 -0
- avanza_mcp-1.0.0.dist-info/RECORD +0 -26
- {avanza_mcp-1.0.0.dist-info → avanza_mcp-1.2.0.dist-info}/WHEEL +0 -0
- {avanza_mcp-1.0.0.dist-info → avanza_mcp-1.2.0.dist-info}/entry_points.txt +0 -0
- {avanza_mcp-1.0.0.dist-info → avanza_mcp-1.2.0.dist-info}/licenses/LICENSE.md +0 -0
avanza_mcp/__init__.py
CHANGED
|
@@ -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
|
|
avanza_mcp/client/endpoints.py
CHANGED
|
@@ -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
|
|
avanza_mcp/models/__init__.py
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
"""Pydantic models for Avanza API responses."""
|
|
2
2
|
|
|
3
|
-
from .
|
|
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
|
|
4
22
|
from .fund import (
|
|
5
23
|
FundChart,
|
|
6
24
|
FundChartPeriod,
|
|
@@ -9,7 +27,15 @@ from .fund import (
|
|
|
9
27
|
FundPerformance,
|
|
10
28
|
FundSustainability,
|
|
11
29
|
)
|
|
12
|
-
from .
|
|
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
|
|
13
39
|
from .stock import (
|
|
14
40
|
BrokerTradeSummary,
|
|
15
41
|
MarketplaceInfo,
|
|
@@ -19,23 +45,77 @@ from .stock import (
|
|
|
19
45
|
StockInfo,
|
|
20
46
|
Trade,
|
|
21
47
|
)
|
|
48
|
+
from .warrant import (
|
|
49
|
+
WarrantDetails,
|
|
50
|
+
WarrantFilter,
|
|
51
|
+
WarrantFilterRequest,
|
|
52
|
+
WarrantFilterResponse,
|
|
53
|
+
WarrantInfo,
|
|
54
|
+
WarrantListItem,
|
|
55
|
+
)
|
|
22
56
|
|
|
23
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
|
|
24
71
|
"InstrumentType",
|
|
25
72
|
"TimePeriod",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
"
|
|
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
|
|
30
88
|
"FundInfo",
|
|
31
89
|
"FundPerformance",
|
|
90
|
+
"FundSustainability",
|
|
32
91
|
"FundChart",
|
|
33
92
|
"FundChartPeriod",
|
|
34
93
|
"FundDescription",
|
|
35
|
-
|
|
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",
|
|
36
109
|
"StockChart",
|
|
37
110
|
"MarketplaceInfo",
|
|
38
111
|
"BrokerTradeSummary",
|
|
39
112
|
"Trade",
|
|
40
113
|
"OrderDepth",
|
|
114
|
+
# Warrant models
|
|
115
|
+
"WarrantInfo",
|
|
116
|
+
"WarrantDetails",
|
|
117
|
+
"WarrantListItem",
|
|
118
|
+
"WarrantFilter",
|
|
119
|
+
"WarrantFilterRequest",
|
|
120
|
+
"WarrantFilterResponse",
|
|
41
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
|
avanza_mcp/models/common.py
CHANGED
|
@@ -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"
|
avanza_mcp/models/etf.py
ADDED
|
@@ -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"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Additional instrument data models."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
from .stock import MODEL_CONFIG
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NumberOfOwners(BaseModel):
|
|
9
|
+
"""Number of owners for an instrument."""
|
|
10
|
+
|
|
11
|
+
model_config = MODEL_CONFIG
|
|
12
|
+
|
|
13
|
+
orderbookId: str | None = None
|
|
14
|
+
numberOfOwners: int | None = None
|
|
15
|
+
timestamp: int | None = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ShortSellingData(BaseModel):
|
|
19
|
+
"""Short selling data for an instrument."""
|
|
20
|
+
|
|
21
|
+
model_config = MODEL_CONFIG
|
|
22
|
+
|
|
23
|
+
orderbookId: str | None = None
|
|
24
|
+
shortSellingVolume: float | None = None
|
|
25
|
+
shortSellingPercentage: float | None = None
|
|
26
|
+
date: str | None = None
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Warrant-related Pydantic models."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from .filter import SortBy, FilterResponse, UnderlyingInstrument
|
|
6
|
+
from .stock import MODEL_CONFIG, Listing, Quote, HistoricalClosingPrices
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WarrantListItem(BaseModel):
|
|
10
|
+
"""Warrant in filter/list results."""
|
|
11
|
+
|
|
12
|
+
model_config = MODEL_CONFIG
|
|
13
|
+
|
|
14
|
+
orderbookId: str
|
|
15
|
+
countryCode: str
|
|
16
|
+
name: str
|
|
17
|
+
direction: str
|
|
18
|
+
issuer: str
|
|
19
|
+
subType: str
|
|
20
|
+
hasPosition: bool
|
|
21
|
+
underlyingInstrument: UnderlyingInstrument | None = None
|
|
22
|
+
totalValueTraded: float | None = None
|
|
23
|
+
stopLoss: float | None = None
|
|
24
|
+
oneDayChangePercent: float | None = None
|
|
25
|
+
spread: float | None = None
|
|
26
|
+
buyPrice: float | None = None
|
|
27
|
+
sellPrice: float | None = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class WarrantInfo(BaseModel):
|
|
31
|
+
"""Detailed warrant information."""
|
|
32
|
+
|
|
33
|
+
model_config = MODEL_CONFIG
|
|
34
|
+
|
|
35
|
+
orderbookId: str
|
|
36
|
+
name: str
|
|
37
|
+
isin: str | None = None
|
|
38
|
+
tradable: str | None = None
|
|
39
|
+
listing: Listing | None = None
|
|
40
|
+
historicalClosingPrices: HistoricalClosingPrices | None = None
|
|
41
|
+
keyIndicators: dict | None = None # Different structure than stock
|
|
42
|
+
quote: Quote | None = None
|
|
43
|
+
type: str | None = None
|
|
44
|
+
underlying: dict | None = None # Nested underlying instrument info
|
|
45
|
+
assetCategory: str | None = None
|
|
46
|
+
category: str | None = None
|
|
47
|
+
subCategory: str | None = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class WarrantDetails(BaseModel):
|
|
51
|
+
"""Detailed warrant extended information."""
|
|
52
|
+
|
|
53
|
+
model_config = MODEL_CONFIG
|
|
54
|
+
|
|
55
|
+
# Flexible structure to handle various response formats
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class WarrantFilter(BaseModel):
|
|
60
|
+
"""Filter criteria for warrants."""
|
|
61
|
+
|
|
62
|
+
model_config = MODEL_CONFIG
|
|
63
|
+
|
|
64
|
+
directions: list[str] = Field(default_factory=list)
|
|
65
|
+
subTypes: list[str] = Field(default_factory=list)
|
|
66
|
+
issuers: list[str] = Field(default_factory=list)
|
|
67
|
+
underlyingInstruments: list[str] = Field(default_factory=list)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class WarrantFilterRequest(BaseModel):
|
|
71
|
+
"""Complete filter request for warrants."""
|
|
72
|
+
|
|
73
|
+
model_config = MODEL_CONFIG
|
|
74
|
+
|
|
75
|
+
filter: WarrantFilter
|
|
76
|
+
offset: int = 0
|
|
77
|
+
limit: int = 20
|
|
78
|
+
sortBy: SortBy
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class WarrantFilterResponse(FilterResponse):
|
|
82
|
+
"""Response from warrant filter endpoint."""
|
|
83
|
+
|
|
84
|
+
model_config = MODEL_CONFIG
|
|
85
|
+
|
|
86
|
+
warrants: list[WarrantListItem]
|
|
87
|
+
filter: WarrantFilter | None = None
|
|
88
|
+
sortBy: SortBy | None = None
|