fmp-data 0.0.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.
- fmp_data/__init__.py +138 -0
- fmp_data/alternative/__init__.py +34 -0
- fmp_data/alternative/client.py +150 -0
- fmp_data/alternative/endpoints.py +533 -0
- fmp_data/alternative/mapping.py +737 -0
- fmp_data/alternative/models.py +296 -0
- fmp_data/alternative/schema.py +165 -0
- fmp_data/base.py +316 -0
- fmp_data/client.py +269 -0
- fmp_data/company/__init__.py +40 -0
- fmp_data/company/client.py +238 -0
- fmp_data/company/endpoints.py +711 -0
- fmp_data/company/hints.py +77 -0
- fmp_data/company/mapping.py +1361 -0
- fmp_data/company/models.py +543 -0
- fmp_data/company/schema.py +132 -0
- fmp_data/config.py +207 -0
- fmp_data/economics/__init__.py +16 -0
- fmp_data/economics/client.py +52 -0
- fmp_data/economics/endpoints.py +164 -0
- fmp_data/economics/mapping.py +641 -0
- fmp_data/economics/models.py +75 -0
- fmp_data/economics/schema.py +91 -0
- fmp_data/exceptions.py +54 -0
- fmp_data/fundamental/__init__.py +40 -0
- fmp_data/fundamental/client.py +87 -0
- fmp_data/fundamental/endpoints.py +403 -0
- fmp_data/fundamental/mapping.py +867 -0
- fmp_data/fundamental/models.py +913 -0
- fmp_data/fundamental/schema.py +40 -0
- fmp_data/institutional/__init__.py +26 -0
- fmp_data/institutional/client.py +141 -0
- fmp_data/institutional/endpoints.py +321 -0
- fmp_data/institutional/mapping.py +749 -0
- fmp_data/institutional/models.py +301 -0
- fmp_data/institutional/schema.py +99 -0
- fmp_data/intelligence/__init__.py +58 -0
- fmp_data/intelligence/client.py +331 -0
- fmp_data/intelligence/endpoints.py +788 -0
- fmp_data/intelligence/mapping.py +1677 -0
- fmp_data/intelligence/models.py +707 -0
- fmp_data/intelligence/schema.py +57 -0
- fmp_data/investment/__init__.py +24 -0
- fmp_data/investment/client.py +104 -0
- fmp_data/investment/endpoints.py +241 -0
- fmp_data/investment/mapping.py +658 -0
- fmp_data/investment/models.py +220 -0
- fmp_data/investment/schema.py +106 -0
- fmp_data/lc/__init__.py +256 -0
- fmp_data/lc/config.py +88 -0
- fmp_data/lc/embedding.py +140 -0
- fmp_data/lc/hints.py +66 -0
- fmp_data/lc/mapping.py +107 -0
- fmp_data/lc/models.py +98 -0
- fmp_data/lc/registry.py +693 -0
- fmp_data/lc/utils.py +35 -0
- fmp_data/lc/validation.py +267 -0
- fmp_data/lc/vector_store.py +592 -0
- fmp_data/logger.py +358 -0
- fmp_data/market/__init__.py +18 -0
- fmp_data/market/client.py +106 -0
- fmp_data/market/endpoints.py +358 -0
- fmp_data/market/hints.py +22 -0
- fmp_data/market/mapping.py +854 -0
- fmp_data/market/models.py +310 -0
- fmp_data/market/schema.py +186 -0
- fmp_data/mcp/__init__.py +0 -0
- fmp_data/mcp/server.py +101 -0
- fmp_data/mcp/tool_loader.py +74 -0
- fmp_data/mcp/tools_manifest.py +17 -0
- fmp_data/models.py +265 -0
- fmp_data/rate_limit.py +136 -0
- fmp_data/schema.py +158 -0
- fmp_data/technical/__init__.py +28 -0
- fmp_data/technical/client.py +214 -0
- fmp_data/technical/endpoints.py +102 -0
- fmp_data/technical/mapping.py +452 -0
- fmp_data/technical/models.py +87 -0
- fmp_data/technical/schema.py +261 -0
- fmp_data-0.0.0.dist-info/METADATA +732 -0
- fmp_data-0.0.0.dist-info/RECORD +84 -0
- fmp_data-0.0.0.dist-info/WHEEL +4 -0
- fmp_data-0.0.0.dist-info/entry_points.txt +10 -0
- fmp_data-0.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# fmp_data/alternative/models.py
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
import warnings
|
|
5
|
+
from datetime import date
|
|
6
|
+
from typing import Any
|
|
7
|
+
from zoneinfo import ZoneInfo
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
10
|
+
from pydantic.alias_generators import to_camel
|
|
11
|
+
|
|
12
|
+
UTC = ZoneInfo("UTC")
|
|
13
|
+
|
|
14
|
+
default_model_config = ConfigDict(
|
|
15
|
+
populate_by_name=True,
|
|
16
|
+
validate_assignment=True,
|
|
17
|
+
str_strip_whitespace=True,
|
|
18
|
+
extra="allow",
|
|
19
|
+
alias_generator=to_camel,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Base Models
|
|
24
|
+
class PriceQuote(BaseModel):
|
|
25
|
+
"""Base model for price quotes"""
|
|
26
|
+
|
|
27
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
28
|
+
|
|
29
|
+
# Required fields
|
|
30
|
+
symbol: str = Field(description="Trading symbol")
|
|
31
|
+
price: float | None = Field(None, description="Current price")
|
|
32
|
+
change: float | None = Field(None, description="Price change")
|
|
33
|
+
change_percent: float | None = Field(
|
|
34
|
+
alias="changesPercentage", description="Percent change"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Optional fields
|
|
38
|
+
name: str | None = Field(None, description="Symbol name or pair name")
|
|
39
|
+
|
|
40
|
+
# Day range
|
|
41
|
+
day_low: float | None = Field(None, alias="dayLow", description="Day low price")
|
|
42
|
+
day_high: float | None = Field(None, alias="dayHigh", description="Day high price")
|
|
43
|
+
|
|
44
|
+
# Year range
|
|
45
|
+
year_high: float | None = Field(None, alias="yearHigh", description="52-week high")
|
|
46
|
+
year_low: float | None = Field(None, alias="yearLow", description="52-week low")
|
|
47
|
+
|
|
48
|
+
# Moving averages
|
|
49
|
+
price_avg_50: float | None = Field(
|
|
50
|
+
None, alias="priceAvg50", description="50-day average"
|
|
51
|
+
)
|
|
52
|
+
price_avg_200: float | None = Field(
|
|
53
|
+
None, alias="priceAvg200", description="200-day average"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Volume
|
|
57
|
+
volume: float | None = Field(None, description="Trading volume")
|
|
58
|
+
avg_volume: float | None = Field(
|
|
59
|
+
None, alias="avgVolume", description="Average volume"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Other price points
|
|
63
|
+
open: float | None = Field(None, description="Opening price")
|
|
64
|
+
previous_close: float | None = Field(
|
|
65
|
+
None, alias="previousClose", description="Previous close"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Market data
|
|
69
|
+
market_cap: float | None = Field(
|
|
70
|
+
None, alias="marketCap", description="Market capitalization"
|
|
71
|
+
)
|
|
72
|
+
eps: float | None = Field(None, description="Earnings per share")
|
|
73
|
+
pe: float | None = Field(None, description="Price to earnings ratio")
|
|
74
|
+
shares_outstanding: float | None = Field(
|
|
75
|
+
None, alias="sharesOutstanding", description="Shares outstanding"
|
|
76
|
+
)
|
|
77
|
+
earnings_announcement: datetime.datetime | None = Field(
|
|
78
|
+
None, alias="earningsAnnouncement", description="Next earnings date"
|
|
79
|
+
)
|
|
80
|
+
exchange: str | None = Field(None, description="Exchange name")
|
|
81
|
+
|
|
82
|
+
timestamp: datetime.datetime | None = Field(
|
|
83
|
+
None,
|
|
84
|
+
description="Quote timestamp",
|
|
85
|
+
json_schema_extra={"format": "unix-timestamp"},
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
@field_validator("timestamp", mode="before")
|
|
89
|
+
def parse_timestamp(cls, value: Any) -> datetime.datetime | None:
|
|
90
|
+
if value is None:
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
if isinstance(value, str | int | float):
|
|
95
|
+
timestamp = float(value)
|
|
96
|
+
else:
|
|
97
|
+
raise ValueError(f"Unexpected type for timestamp: {type(value)}")
|
|
98
|
+
|
|
99
|
+
return datetime.datetime.fromtimestamp(timestamp, tz=UTC)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
warnings.warn(f"Failed to parse timestamp {value}: {e}", stacklevel=2)
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class HistoricalPrice(BaseModel):
|
|
106
|
+
"""Base model for historical price data"""
|
|
107
|
+
|
|
108
|
+
price_date: date = Field(
|
|
109
|
+
description="The date of the historical record", alias="date"
|
|
110
|
+
)
|
|
111
|
+
open: float = Field(description="Opening price")
|
|
112
|
+
high: float = Field(description="Highest price of the day")
|
|
113
|
+
low: float = Field(description="Lowest price of the day")
|
|
114
|
+
close: float = Field(description="Closing price")
|
|
115
|
+
adj_close: float = Field(alias="adjClose", description="Adjusted closing price")
|
|
116
|
+
volume: int = Field(description="Volume traded")
|
|
117
|
+
unadjusted_volume: int = Field(
|
|
118
|
+
alias="unadjustedVolume", description="Unadjusted trading volume"
|
|
119
|
+
)
|
|
120
|
+
change: float = Field(description="Price change")
|
|
121
|
+
change_percent: float | None = Field(
|
|
122
|
+
None, alias="changePercent", description="Percentage change in price"
|
|
123
|
+
)
|
|
124
|
+
vwap: float | None = Field(None, description="Volume-weighted average price")
|
|
125
|
+
label: str | None = Field(None, description="Formatted label for the date")
|
|
126
|
+
change_over_time: float | None = Field(
|
|
127
|
+
None, alias="changeOverTime", description="Change over time as a percentage"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class IntradayPrice(BaseModel):
|
|
132
|
+
"""Base model for intraday prices"""
|
|
133
|
+
|
|
134
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
135
|
+
|
|
136
|
+
date: datetime.datetime = Field(description="Price date and time")
|
|
137
|
+
open: float = Field(description="Opening price")
|
|
138
|
+
high: float = Field(description="High price")
|
|
139
|
+
low: float = Field(description="Low price")
|
|
140
|
+
close: float = Field(description="Closing price")
|
|
141
|
+
volume: float | None = Field(None, description="Trading volume") # Changed to float
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# Cryptocurrency Models
|
|
145
|
+
class CryptoPair(BaseModel):
|
|
146
|
+
"""Cryptocurrency trading pair information"""
|
|
147
|
+
|
|
148
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
149
|
+
|
|
150
|
+
symbol: str = Field(description="Trading symbol")
|
|
151
|
+
name: str = Field(description="Cryptocurrency name")
|
|
152
|
+
currency: str = Field(description="Quote currency")
|
|
153
|
+
stock_exchange: str = Field(
|
|
154
|
+
alias="stockExchange", description="Full name of the stock exchange"
|
|
155
|
+
)
|
|
156
|
+
exchange_short_name: str = Field(
|
|
157
|
+
alias="exchangeShortName", description="Short name of the exchange"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class CryptoQuote(PriceQuote):
|
|
162
|
+
"""Cryptocurrency price quote"""
|
|
163
|
+
|
|
164
|
+
model_config = ConfigDict(
|
|
165
|
+
populate_by_name=True,
|
|
166
|
+
validate_assignment=True,
|
|
167
|
+
extra="ignore", # Allow extra fields from API
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Override the base class field to make it optional
|
|
171
|
+
change_percent: float | None = Field(
|
|
172
|
+
None, alias="changesPercentage", description="Percent change"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
@field_validator("timestamp", mode="before")
|
|
176
|
+
def parse_timestamp(cls, value: Any) -> datetime.datetime | None:
|
|
177
|
+
"""Parse Unix timestamp (int, float, str) into a TZ-aware UTC datetime."""
|
|
178
|
+
if value is None:
|
|
179
|
+
return None
|
|
180
|
+
try:
|
|
181
|
+
ts_float = float(value) # handles int, float, str transparently
|
|
182
|
+
return datetime.datetime.fromtimestamp(ts_float, tz=UTC)
|
|
183
|
+
except (ValueError, TypeError) as exc:
|
|
184
|
+
warnings.warn(f"Failed to parse timestamp {value!r}: {exc}", stacklevel=2)
|
|
185
|
+
return None
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class CryptoHistoricalPrice(HistoricalPrice):
|
|
189
|
+
"""Cryptocurrency historical price"""
|
|
190
|
+
|
|
191
|
+
pass
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class CryptoHistoricalData(BaseModel):
|
|
195
|
+
"""Historical price data wrapper"""
|
|
196
|
+
|
|
197
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
198
|
+
|
|
199
|
+
symbol: str = Field(description="Trading symbol")
|
|
200
|
+
historical: list[CryptoHistoricalPrice] = Field(
|
|
201
|
+
description="Historical price records"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class CryptoIntradayPrice(IntradayPrice):
|
|
206
|
+
"""Cryptocurrency intraday price"""
|
|
207
|
+
|
|
208
|
+
pass
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# Forex Models
|
|
212
|
+
class ForexPair(BaseModel):
|
|
213
|
+
"""Forex trading pair information"""
|
|
214
|
+
|
|
215
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
216
|
+
|
|
217
|
+
symbol: str = Field(description="Trading symbol")
|
|
218
|
+
name: str = Field(description="Pair name")
|
|
219
|
+
currency: str = Field(description="Quote currency")
|
|
220
|
+
stock_exchange: str = Field(
|
|
221
|
+
alias="stockExchange", description="Stock exchange code"
|
|
222
|
+
)
|
|
223
|
+
exchange_short_name: str = Field(
|
|
224
|
+
alias="exchangeShortName", description="Exchange short name"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class ForexQuote(PriceQuote):
|
|
229
|
+
"""Forex price quote"""
|
|
230
|
+
|
|
231
|
+
pass
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class ForexHistoricalPrice(HistoricalPrice):
|
|
235
|
+
"""Forex historical price"""
|
|
236
|
+
|
|
237
|
+
pass
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class ForexPriceHistory(BaseModel):
|
|
241
|
+
"""Full forex price history"""
|
|
242
|
+
|
|
243
|
+
symbol: str = Field(description="Symbol for the currency pair")
|
|
244
|
+
historical: list[ForexHistoricalPrice] = Field(
|
|
245
|
+
description="List of historical price data for the forex pair"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class ForexIntradayPrice(IntradayPrice):
|
|
250
|
+
"""Forex intraday price"""
|
|
251
|
+
|
|
252
|
+
pass
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# Commodities Models
|
|
256
|
+
class Commodity(BaseModel):
|
|
257
|
+
"""Commodity information"""
|
|
258
|
+
|
|
259
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
260
|
+
|
|
261
|
+
symbol: str = Field(description="Trading symbol")
|
|
262
|
+
name: str = Field(description="Commodity name")
|
|
263
|
+
currency: str = Field(description="Trading currency")
|
|
264
|
+
stock_exchange: str = Field(
|
|
265
|
+
alias="stockExchange", description="Full name of the stock exchange"
|
|
266
|
+
)
|
|
267
|
+
exchange_short_name: str = Field(
|
|
268
|
+
alias="exchangeShortName", description="Short name of the exchange category"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class CommodityQuote(PriceQuote):
|
|
273
|
+
"""Commodity price quote"""
|
|
274
|
+
|
|
275
|
+
pass
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class CommodityHistoricalPrice(HistoricalPrice):
|
|
279
|
+
"""Commodity historical price"""
|
|
280
|
+
|
|
281
|
+
pass
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class CommodityPriceHistory(BaseModel):
|
|
285
|
+
"""Full commodity price history"""
|
|
286
|
+
|
|
287
|
+
symbol: str = Field(description="Symbol for the commodity")
|
|
288
|
+
historical: list[CommodityHistoricalPrice] = Field(
|
|
289
|
+
description="List of historical price data"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class CommodityIntradayPrice(IntradayPrice):
|
|
294
|
+
"""Commodity intraday price"""
|
|
295
|
+
|
|
296
|
+
pass
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# fmp_data/alternative/schema.py
|
|
2
|
+
from datetime import date
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field, field_validator
|
|
6
|
+
|
|
7
|
+
# Constants
|
|
8
|
+
VALID_INTERVALS = Literal["1min", "5min", "15min", "30min", "1hour", "4hour"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseListArgs(BaseModel):
|
|
12
|
+
"""Base class for list endpoints that take no arguments"""
|
|
13
|
+
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseQuoteArgs(BaseModel):
|
|
18
|
+
"""Base class for quote endpoints"""
|
|
19
|
+
|
|
20
|
+
symbol: str = Field(description="Trading symbol for the instrument")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BaseHistoricalArgs(BaseQuoteArgs):
|
|
24
|
+
"""Base class for historical data endpoints"""
|
|
25
|
+
|
|
26
|
+
start_date: date | None = Field( # Changed from from_date
|
|
27
|
+
None,
|
|
28
|
+
description="Start date for historical data (format: YYYY-MM-DD)",
|
|
29
|
+
)
|
|
30
|
+
end_date: date | None = Field( # Changed from to_date
|
|
31
|
+
None,
|
|
32
|
+
description="End date for historical data (format: YYYY-MM-DD)",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class BaseIntradayArgs(BaseQuoteArgs):
|
|
37
|
+
"""Base class for intraday data endpoints"""
|
|
38
|
+
|
|
39
|
+
interval: VALID_INTERVALS = Field(
|
|
40
|
+
description="Time interval between price points",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
@field_validator("interval")
|
|
44
|
+
def validate_interval(cls, v: str) -> str:
|
|
45
|
+
valid_intervals = ["1min", "5min", "15min", "30min", "1hour", "4hour"]
|
|
46
|
+
if v not in valid_intervals:
|
|
47
|
+
raise ValueError(f"Interval must be one of: {valid_intervals}")
|
|
48
|
+
return v
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Crypto Arguments
|
|
52
|
+
class CryptoListArgs(BaseListArgs):
|
|
53
|
+
"""Arguments for listing available cryptocurrencies"""
|
|
54
|
+
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class CryptoQuotesArgs(BaseListArgs):
|
|
59
|
+
"""Arguments for getting cryptocurrency quotes"""
|
|
60
|
+
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class CryptoQuoteArgs(BaseQuoteArgs):
|
|
65
|
+
"""Arguments for getting a specific cryptocurrency quote"""
|
|
66
|
+
|
|
67
|
+
symbol: str = Field(
|
|
68
|
+
description=(
|
|
69
|
+
"Trading symbol for the cryptocurrency" " (e.g., 'BTCUSD' for Bitcoin/USD)"
|
|
70
|
+
),
|
|
71
|
+
pattern=r"^[A-Z]{3,4}USD$",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class CryptoHistoricalArgs(BaseHistoricalArgs):
|
|
76
|
+
"""Arguments for getting historical cryptocurrency prices"""
|
|
77
|
+
|
|
78
|
+
symbol: str = Field(
|
|
79
|
+
description="Trading symbol for the cryptocurrency (e.g., 'BTCUSD')",
|
|
80
|
+
pattern=r"^[A-Z]{3,4}USD$",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class CryptoIntradayArgs(BaseIntradayArgs):
|
|
85
|
+
"""Arguments for getting intraday cryptocurrency prices"""
|
|
86
|
+
|
|
87
|
+
symbol: str = Field(
|
|
88
|
+
description="Trading symbol for the cryptocurrency", pattern=r"^[A-Z]{3,4}USD$"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Forex Arguments
|
|
93
|
+
class ForexListArgs(BaseListArgs):
|
|
94
|
+
"""Arguments for listing available forex pairs"""
|
|
95
|
+
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class ForexQuotesArgs(BaseListArgs):
|
|
100
|
+
"""Arguments for getting forex quotes"""
|
|
101
|
+
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ForexQuoteArgs(BaseQuoteArgs):
|
|
106
|
+
"""Arguments for getting a specific forex quote"""
|
|
107
|
+
|
|
108
|
+
symbol: str = Field(
|
|
109
|
+
description="Trading symbol for the forex pair (e.g., 'EURUSD')",
|
|
110
|
+
pattern=r"^[A-Z]{6}$",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ForexHistoricalArgs(BaseHistoricalArgs):
|
|
115
|
+
"""Arguments for getting historical forex prices"""
|
|
116
|
+
|
|
117
|
+
symbol: str = Field(
|
|
118
|
+
description="Trading symbol for the forex pair", pattern=r"^[A-Z]{6}$"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ForexIntradayArgs(BaseIntradayArgs):
|
|
123
|
+
"""Arguments for getting intraday forex prices"""
|
|
124
|
+
|
|
125
|
+
symbol: str = Field(
|
|
126
|
+
description="Trading symbol for the forex pair", pattern=r"^[A-Z]{6}$"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Commodity Arguments
|
|
131
|
+
class CommoditiesListArgs(BaseListArgs):
|
|
132
|
+
"""Arguments for listing available commodities"""
|
|
133
|
+
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class CommoditiesQuotesArgs(BaseListArgs):
|
|
138
|
+
"""Arguments for getting commodities quotes"""
|
|
139
|
+
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class CommodityQuoteArgs(BaseQuoteArgs):
|
|
144
|
+
"""Arguments for getting a specific commodity quote"""
|
|
145
|
+
|
|
146
|
+
symbol: str = Field(
|
|
147
|
+
description="Trading symbol for the commodity (e.g., 'GC' for Gold)",
|
|
148
|
+
pattern=r"^[A-Z]{2,3}$",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class CommodityHistoricalArgs(BaseHistoricalArgs):
|
|
153
|
+
"""Arguments for getting historical commodity prices"""
|
|
154
|
+
|
|
155
|
+
symbol: str = Field(
|
|
156
|
+
description="Trading symbol for the commodity", pattern=r"^[A-Z]{2,3}$"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class CommodityIntradayArgs(BaseIntradayArgs):
|
|
161
|
+
"""Arguments for getting intraday commodity prices"""
|
|
162
|
+
|
|
163
|
+
symbol: str = Field(
|
|
164
|
+
description="Trading symbol for the commodity", pattern=r"^[A-Z]{2,3}$"
|
|
165
|
+
)
|