axionquant-sdk 0.1.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.
axion/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ from .axion import Axion
2
+ from . import ta
3
+ from . import models
4
+ from . import utils
5
+ from . import visualize
6
+
7
+
8
+ __all__ = ['Axion', 'visualize', 'ta', 'utils', 'models']
axion/axion.py ADDED
@@ -0,0 +1,612 @@
1
+ import requests
2
+ import json
3
+
4
+ BASE_URL = "http://localhost:3001"
5
+
6
+
7
+ def normalize(obj):
8
+ if isinstance(obj, dict):
9
+ return {k: normalize(v) for k, v in obj.items()}
10
+ if isinstance(obj, list):
11
+ return [normalize(v) for v in obj]
12
+ return coerce(obj)
13
+
14
+
15
+ def coerce(value):
16
+ if isinstance(value, str):
17
+ if value.isdigit():
18
+ return int(value)
19
+ try:
20
+ return float(value)
21
+ except ValueError:
22
+ if value.lower() == 'true':
23
+ return True
24
+ if value.lower() == 'false':
25
+ return False
26
+ return value
27
+
28
+
29
+ class Axion:
30
+ def __init__(self, api_key: str = None):
31
+ self.base_url = BASE_URL
32
+ self.session = requests.Session()
33
+ self.session.headers.update({
34
+ "Content-Type": "application/json"
35
+ })
36
+ if api_key:
37
+ self.session.headers.update({"Authorization": f"Bearer {api_key}"})
38
+
39
+ def _request(self, method: str, path: str, params: dict = None, json_data: dict = None, auth_required: bool = True):
40
+ url = f"{self.base_url}/{path}"
41
+ headers = self.session.headers.copy()
42
+
43
+ if not auth_required and "Authorization" in headers:
44
+ del headers["Authorization"]
45
+ elif auth_required and "Authorization" not in headers:
46
+ raise Exception("Authentication required but no API key provided to client.")
47
+
48
+ try:
49
+ response = self.session.request(method, url, params=params, json=json_data, headers=headers)
50
+ response.raise_for_status()
51
+
52
+ data = response.json()
53
+ r = normalize(data)
54
+ return r
55
+ except requests.exceptions.HTTPError as e:
56
+ try:
57
+ error_data = e.response.json()
58
+ raise Exception(f"HTTP Error {e.response.status_code}: {error_data.get('message', 'Unknown HTTP error')}") from e
59
+ except json.JSONDecodeError:
60
+ raise Exception(f"HTTP Error {e.response.status_code}: {e.response.text}") from e
61
+ except requests.exceptions.ConnectionError as e:
62
+ raise Exception(f"Connection Error: Could not connect to {self.base_url}") from e
63
+ except requests.exceptions.Timeout as e:
64
+ raise Exception(f"Timeout Error: Request to {self.base_url} timed out") from e
65
+ except requests.exceptions.RequestException as e:
66
+ raise Exception(f"Request Error: {e}") from e
67
+
68
+ # --- Credit API ---
69
+ def search_credit(self, query: str):
70
+ """
71
+ Search for credit entities.
72
+ Authentication required.
73
+ :param query: The search term for credit entities.
74
+ """
75
+ params = {"query": query}
76
+ return self._request("GET", "credit/search", params=params)
77
+
78
+ def get_credit_ratings(self, entity_id: str):
79
+ """
80
+ Get ratings for a specific credit entity.
81
+ Authentication required.
82
+ :param entity_id: The ID of the credit entity.
83
+ """
84
+ return self._request("GET", f"credit/ratings/{entity_id}")
85
+
86
+ # --- ESG API ---
87
+ def get_esg_data(self, ticker: str):
88
+ """
89
+ Get ESG data for a given ticker.
90
+ Authentication required.
91
+ :param ticker: The stock ticker symbol.
92
+ """
93
+ return self._request("GET", f"esg/{ticker}")
94
+
95
+ # --- ETF API ---
96
+ def get_etf_fund_data(self, ticker: str):
97
+ """
98
+ Get detailed fund data for an ETF.
99
+ Authentication required.
100
+ :param ticker: The ETF ticker symbol.
101
+ """
102
+ return self._request("GET", f"etfs/{ticker}/fund")
103
+
104
+ def get_etf_holdings(self, ticker: str):
105
+ """
106
+ Get holdings data for an ETF.
107
+ Authentication required.
108
+ :param ticker: The ETF ticker symbol.
109
+ """
110
+ return self._request("GET", f"etfs/{ticker}/holdings")
111
+
112
+ def get_etf_exposure(self, ticker: str):
113
+ """
114
+ Get exposure data for an ETF holding.
115
+ Authentication required.
116
+ :param ticker: The ETF holding ticker symbol.
117
+ """
118
+ return self._request("GET", f"etfs/{ticker}/exposure")
119
+
120
+ # --- Supply Chain API ---
121
+ def get_supply_chain_customers(self, ticker: str):
122
+ """
123
+ Get customer data for a given ticker.
124
+ Authentication required.
125
+ :param ticker: The stock ticker symbol.
126
+ """
127
+ return self._request("GET", f"supply-chain/{ticker}/customers")
128
+
129
+ def get_supply_chain_peers(self, ticker: str):
130
+ """
131
+ Get peer data for a given ticker.
132
+ Authentication required.
133
+ :param ticker: The stock ticker symbol.
134
+ """
135
+ return self._request("GET", f"supply-chain/{ticker}/peers")
136
+
137
+ def get_supply_chain_suppliers(self, ticker: str):
138
+ """
139
+ Get supplier data for a given ticker.
140
+ Authentication required.
141
+ :param ticker: The stock ticker symbol.
142
+ """
143
+ return self._request("GET", f"supply-chain/{ticker}/suppliers")
144
+
145
+ # --- Stocks API ---
146
+ def get_stock_tickers(self, country: str = None, exchange: str = None):
147
+ """
148
+ Get all stock tickers with optional filtering.
149
+ Authentication required. Free tier restricted to 'america' country.
150
+ :param country: Optional country to filter by.
151
+ :param exchange: Optional exchange to filter by.
152
+ """
153
+ params = {}
154
+ if country is not None:
155
+ params["country"] = country
156
+ if exchange is not None:
157
+ params["exchange"] = exchange
158
+ return self._request("GET", "stocks/tickers", params=params)
159
+
160
+ def get_stock_ticker_by_symbol(self, ticker: str):
161
+ """
162
+ Get a single stock ticker by its ticker symbol.
163
+ Authentication required. Free tier restricted to 'america' country.
164
+ :param ticker: The stock ticker symbol.
165
+ """
166
+ return self._request("GET", f"stocks/{ticker}")
167
+
168
+ def get_stock_prices(self, ticker: str, from_date: str = None, to_date: str = None, frame: str = 'daily'):
169
+ """
170
+ Get prices for a specific stock ticker.
171
+ Authentication required. Free tier restricted to 'america' country.
172
+ :param ticker: The stock ticker symbol.
173
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
174
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
175
+ :param frame: Time frame for aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly'). Default: 'daily'.
176
+ """
177
+ params = {}
178
+ if from_date is not None:
179
+ params["from"] = from_date
180
+ if to_date is not None:
181
+ params["to"] = to_date
182
+ if frame != 'daily':
183
+ params["frame"] = frame
184
+ return self._request("GET", f"stocks/{ticker}/prices", params=params)
185
+
186
+ # --- Crypto API ---
187
+ def get_crypto_tickers(self, type: str = None):
188
+ """
189
+ Get all cryptocurrency tickers with optional filtering.
190
+ Authentication required.
191
+ :param type: Optional type to filter by (e.g., 'coin', 'token').
192
+ """
193
+ params = {}
194
+ if type is not None:
195
+ params["type"] = type
196
+ return self._request("GET", "crypto/tickers", params=params)
197
+
198
+ def get_crypto_ticker_by_symbol(self, ticker: str):
199
+ """
200
+ Get a single cryptocurrency ticker by its ticker symbol.
201
+ Authentication required.
202
+ :param ticker: The cryptocurrency ticker symbol.
203
+ """
204
+ return self._request("GET", f"crypto/{ticker}")
205
+
206
+ def get_crypto_prices(self, ticker: str, from_date: str = None, to_date: str = None, frame: str = 'daily'):
207
+ """
208
+ Get prices for a specific cryptocurrency ticker.
209
+ Authentication required.
210
+ :param ticker: The cryptocurrency ticker symbol.
211
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
212
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
213
+ :param frame: Time frame for aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly'). Default: 'daily'.
214
+ """
215
+ params = {}
216
+ if from_date is not None:
217
+ params["from"] = from_date
218
+ if to_date is not None:
219
+ params["to"] = to_date
220
+ if frame != 'daily':
221
+ params["frame"] = frame
222
+ return self._request("GET", f"crypto/{ticker}/prices", params=params)
223
+
224
+ # --- Forex API ---
225
+ def get_forex_tickers(self, country: str = None, exchange: str = None):
226
+ """
227
+ Get all forex tickers with optional filtering.
228
+ Authentication required.
229
+ :param country: Optional country to filter by.
230
+ :param exchange: Optional exchange to filter by.
231
+ """
232
+ params = {}
233
+ if country is not None:
234
+ params["country"] = country
235
+ if exchange is not None:
236
+ params["exchange"] = exchange
237
+ return self._request("GET", "forex/tickers", params=params)
238
+
239
+ def get_forex_ticker_by_symbol(self, ticker: str):
240
+ """
241
+ Get a single forex ticker by its ticker symbol.
242
+ Authentication required.
243
+ :param ticker: The forex ticker symbol.
244
+ """
245
+ return self._request("GET", f"forex/{ticker}")
246
+
247
+ def get_forex_prices(self, ticker: str, from_date: str = None, to_date: str = None, frame: str = 'daily'):
248
+ """
249
+ Get prices for a specific forex ticker.
250
+ Authentication required.
251
+ :param ticker: The forex ticker symbol.
252
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
253
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
254
+ :param frame: Time frame for aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly'). Default: 'daily'.
255
+ """
256
+ params = {}
257
+ if from_date is not None:
258
+ params["from"] = from_date
259
+ if to_date is not None:
260
+ params["to"] = to_date
261
+ if frame != 'daily':
262
+ params["frame"] = frame
263
+ return self._request("GET", f"forex/{ticker}/prices", params=params)
264
+
265
+ # --- Futures API ---
266
+ def get_futures_tickers(self, exchange: str = None):
267
+ """
268
+ Get all futures tickers with optional filtering.
269
+ Authentication required.
270
+ :param exchange: Optional exchange to filter by.
271
+ """
272
+ params = {}
273
+ if exchange is not None:
274
+ params["exchange"] = exchange
275
+ return self._request("GET", "futures/tickers", params=params)
276
+
277
+ def get_futures_ticker_by_symbol(self, ticker: str):
278
+ """
279
+ Get a single futures ticker by its ticker symbol.
280
+ Authentication required.
281
+ :param ticker: The futures ticker symbol.
282
+ """
283
+ return self._request("GET", f"futures/{ticker}")
284
+
285
+ def get_futures_prices(self, ticker: str, from_date: str = None, to_date: str = None, frame: str = 'daily'):
286
+ """
287
+ Get prices for a specific futures ticker.
288
+ Authentication required.
289
+ :param ticker: The futures ticker symbol.
290
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
291
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
292
+ :param frame: Time frame for aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly'). Default: 'daily'.
293
+ """
294
+ params = {}
295
+ if from_date is not None:
296
+ params["from"] = from_date
297
+ if to_date is not None:
298
+ params["to"] = to_date
299
+ if frame != 'daily':
300
+ params["frame"] = frame
301
+ return self._request("GET", f"futures/{ticker}/prices", params=params)
302
+
303
+ # --- Indices API ---
304
+ def get_index_tickers(self, exchange: str = None):
305
+ """
306
+ Get all index tickers with optional filtering.
307
+ Authentication required.
308
+ :param exchange: Optional exchange to filter by.
309
+ """
310
+ params = {}
311
+ if exchange is not None:
312
+ params["exchange"] = exchange
313
+ return self._request("GET", "indices/tickers", params=params)
314
+
315
+ def get_index_ticker_by_symbol(self, ticker: str):
316
+ """
317
+ Get a single index ticker by its ticker symbol.
318
+ Authentication required.
319
+ :param ticker: The index ticker symbol.
320
+ """
321
+ return self._request("GET", f"indices/{ticker}")
322
+
323
+ def get_index_prices(self, ticker: str, from_date: str = None, to_date: str = None, frame: str = 'daily'):
324
+ """
325
+ Get prices for a specific index ticker.
326
+ Authentication required.
327
+ :param ticker: The index ticker symbol.
328
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
329
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
330
+ :param frame: Time frame for aggregation ('daily', 'weekly', 'monthly', 'quarterly', 'yearly'). Default: 'daily'.
331
+ """
332
+ params = {}
333
+ if from_date is not None:
334
+ params["from"] = from_date
335
+ if to_date is not None:
336
+ params["to"] = to_date
337
+ if frame != 'daily':
338
+ params["frame"] = frame
339
+ return self._request("GET", f"indices/{ticker}/prices", params=params)
340
+
341
+ # --- Economic API ---
342
+ def search_econ(self, query: str):
343
+ """
344
+ Search for economic series.
345
+ Authentication required.
346
+ :param query: The search term for economic series.
347
+ """
348
+ params = {"query": query}
349
+ return self._request("GET", "econ/search", params=params)
350
+
351
+ def get_econ_dataset(self, series_id: str):
352
+ """
353
+ Get economic series observations (all releases).
354
+ Authentication required.
355
+ :param series_id: The ID of the economic series.
356
+ """
357
+ return self._request("GET", f"econ/dataset/{series_id}")
358
+
359
+
360
+ def get_econ_calendar(self, from_date: str = None, to_date: str = None, country: str = None, min_importance: int = None, currency: str = None, category: str = None):
361
+ """
362
+ Get economic calendar data with optional filters.
363
+ Authentication required.
364
+ :param from_date: Start date for filtering (format: YYYY-MM-DD).
365
+ :param to_date: End date for filtering (format: YYYY-MM-DD).
366
+ :param country: Single country code or comma-separated list (e.g., 'US' or 'US,UK,CA').
367
+ :param min_importance: Minimum importance level (numeric value).
368
+ :param currency: Single currency code or comma-separated list (e.g., 'USD' or 'USD,EUR').
369
+ :param category: Single category or comma-separated list (e.g., 'employment' or 'employment,inflation').
370
+ """
371
+ params = {}
372
+ if from_date is not None:
373
+ params["from"] = from_date
374
+ if to_date is not None:
375
+ params["to"] = to_date
376
+ if country is not None:
377
+ params["country"] = country
378
+ if min_importance is not None:
379
+ params["minImportance"] = min_importance
380
+ if currency is not None:
381
+ params["currency"] = currency
382
+ if category is not None:
383
+ params["category"] = category
384
+ return self._request("GET", "econ/calendar", params=params)
385
+
386
+ # --- News API ---
387
+ def get_news(self):
388
+ """
389
+ Get general news articles.
390
+ Authentication required.
391
+ """
392
+ return self._request("GET", "news")
393
+
394
+ def get_company_news(self, ticker: str):
395
+ """
396
+ Get news articles for a specific company.
397
+ Authentication required.
398
+ :param ticker: The stock ticker symbol.
399
+ """
400
+ return self._request("GET", f"news/{ticker}")
401
+
402
+ def get_country_news(self, country: str):
403
+ """
404
+ Get news articles for a specific country.
405
+ Authentication required.
406
+ :param country: The country code or name.
407
+ """
408
+ return self._request("GET", f"news/country/{country}")
409
+
410
+ def get_category_news(self, category: str):
411
+ """
412
+ Get news articles for a specific category.
413
+ Authentication required.
414
+ :param category: The news category.
415
+ """
416
+ return self._request("GET", f"news/category/{category}")
417
+
418
+ # --- Sentiment API ---
419
+ def get_sentiment_all(self, ticker: str):
420
+ """
421
+ Get all sentiment data (social, news, and analyst) for a ticker.
422
+ Authentication required.
423
+ :param ticker: The stock ticker symbol.
424
+ """
425
+ return self._request("GET", f"sentiment/{ticker}/all")
426
+
427
+ def get_sentiment_social(self, ticker: str):
428
+ """
429
+ Get social sentiment data for a ticker.
430
+ Authentication required.
431
+ :param ticker: The stock ticker symbol.
432
+ """
433
+ return self._request("GET", f"sentiment/{ticker}/social")
434
+
435
+ def get_sentiment_news(self, ticker: str):
436
+ """
437
+ Get news sentiment data for a ticker.
438
+ Authentication required.
439
+ :param ticker: The stock ticker symbol.
440
+ """
441
+ return self._request("GET", f"sentiment/{ticker}/news")
442
+
443
+ def get_sentiment_analyst(self, ticker: str):
444
+ """
445
+ Get analyst sentiment data for a ticker.
446
+ Authentication required.
447
+ :param ticker: The stock ticker symbol.
448
+ """
449
+ return self._request("GET", f"sentiment/{ticker}/analyst")
450
+
451
+ # --- Company Profile API ---
452
+
453
+ def get_company_asset_profile(self, ticker: str):
454
+ """
455
+ Get company asset profile and business summary.
456
+ Authentication required.
457
+ :param ticker: The stock ticker symbol.
458
+ """
459
+ return self._request("GET", f"profiles/{ticker}/asset")
460
+
461
+ def get_company_recommendation_trend(self, ticker: str):
462
+ """
463
+ Get analyst recommendation trends.
464
+ Authentication required.
465
+ :param ticker: The stock ticker symbol.
466
+ """
467
+ return self._request("GET", f"profiles/{ticker}/recommendation")
468
+
469
+ def get_company_cashflow(self, ticker: str):
470
+ """
471
+ Get cash flow statement history.
472
+ Authentication required.
473
+ :param ticker: The stock ticker symbol.
474
+ """
475
+ return self._request("GET", f"profiles/{ticker}/cashflow")
476
+
477
+ def get_company_index_trend(self, ticker: str):
478
+ """
479
+ Get index trend estimates.
480
+ Authentication required.
481
+ :param ticker: The stock ticker symbol.
482
+ """
483
+ return self._request("GET", f"profiles/{ticker}/trend/index")
484
+
485
+ def get_company_statistics(self, ticker: str):
486
+ """
487
+ Get key statistics and financial ratios.
488
+ Authentication required.
489
+ :param ticker: The stock ticker symbol.
490
+ """
491
+ return self._request("GET", f"profiles/{ticker}/statistics")
492
+
493
+ def get_company_income_statement(self, ticker: str):
494
+ """
495
+ Get income statement history.
496
+ Authentication required.
497
+ :param ticker: The stock ticker symbol.
498
+ """
499
+ return self._request("GET", f"profiles/{ticker}/income")
500
+
501
+ def get_company_fund_ownership(self, ticker: str):
502
+ """
503
+ Get fund ownership data.
504
+ Authentication required.
505
+ :param ticker: The stock ticker symbol.
506
+ """
507
+ return self._request("GET", f"profiles/{ticker}/fund")
508
+
509
+ def get_company_summary(self, ticker: str):
510
+ """
511
+ Get summary detail including prices, volumes, and market data.
512
+ Authentication required.
513
+ :param ticker: The stock ticker symbol.
514
+ """
515
+ return self._request("GET", f"profiles/{ticker}/summary")
516
+
517
+ def get_company_insider_holders(self, ticker: str):
518
+ """
519
+ Get insider holders and their positions.
520
+ Authentication required.
521
+ :param ticker: The stock ticker symbol.
522
+ """
523
+ return self._request("GET", f"profiles/{ticker}/insiders")
524
+
525
+ def get_company_calendar_events(self, ticker: str):
526
+ """
527
+ Get calendar events including earnings dates and dividends.
528
+ Authentication required.
529
+ :param ticker: The stock ticker symbol.
530
+ """
531
+ return self._request("GET", f"profiles/{ticker}/calendar")
532
+
533
+ def get_company_balance_sheet(self, ticker: str):
534
+ """
535
+ Get balance sheet history.
536
+ Authentication required.
537
+ :param ticker: The stock ticker symbol.
538
+ """
539
+ return self._request("GET", f"profiles/{ticker}/balancesheet")
540
+
541
+ def get_company_earnings_trend(self, ticker: str):
542
+ """
543
+ Get earnings trend and estimates.
544
+ Authentication required.
545
+ :param ticker: The stock ticker symbol.
546
+ """
547
+ return self._request("GET", f"profiles/{ticker}/trend/earnings")
548
+
549
+ def get_company_institution_ownership(self, ticker: str):
550
+ """
551
+ Get institutional ownership data.
552
+ Authentication required.
553
+ :param ticker: The stock ticker symbol.
554
+ """
555
+ return self._request("GET", f"profiles/{ticker}/institution")
556
+
557
+ def get_company_major_holders(self, ticker: str):
558
+ """
559
+ Get major holders breakdown.
560
+ Authentication required.
561
+ :param ticker: The stock ticker symbol.
562
+ """
563
+ return self._request("GET", f"profiles/{ticker}/ownership")
564
+
565
+ def get_company_earnings_history(self, ticker: str):
566
+ """
567
+ Get historical earnings data.
568
+ Authentication required.
569
+ :param ticker: The stock ticker symbol.
570
+ """
571
+ return self._request("GET", f"profiles/{ticker}/earnings")
572
+
573
+ def get_company_profile_info(self, ticker: str):
574
+ """
575
+ Get company profile information.
576
+ Authentication required.
577
+ :param ticker: The stock ticker symbol.
578
+ """
579
+ return self._request("GET", f"profiles/{ticker}/info")
580
+
581
+ def get_company_share_activity(self, ticker: str):
582
+ """
583
+ Get net share purchase activity.
584
+ Authentication required.
585
+ :param ticker: The stock ticker symbol.
586
+ """
587
+ return self._request("GET", f"profiles/{ticker}/activity")
588
+
589
+ def get_company_insider_transactions(self, ticker: str):
590
+ """
591
+ Get insider transactions.
592
+ Authentication required.
593
+ :param ticker: The stock ticker symbol.
594
+ """
595
+ return self._request("GET", f"profiles/{ticker}/transactions")
596
+
597
+ def get_company_financial_data(self, ticker: str):
598
+ """
599
+ Get comprehensive financial data.
600
+ Authentication required.
601
+ :param ticker: The stock ticker symbol.
602
+ """
603
+ return self._request("GET", f"profiles/{ticker}/financials")
604
+
605
+ def get_company_website_traffic(self, ticker: str):
606
+ """
607
+ Get website traffic and analytics data.
608
+ Authentication required.
609
+ :param ticker: The stock ticker symbol.
610
+ """
611
+ return self._request("GET", f"profiles/{ticker}/traffic")
612
+