eetc-utils 1.9.0__tar.gz → 2.0.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 (20) hide show
  1. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/PKG-INFO +3 -3
  2. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/README.md +2 -2
  3. eetc_utils-2.0.0/pyproject.toml +64 -0
  4. eetc_utils-1.9.0/pyproject.toml → eetc_utils-2.0.0/pyproject.toml.orig +1 -1
  5. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/clients/eetc_data.py +28 -22
  6. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/backtesting/engine.py +1 -1
  7. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/engine.py +1 -3
  8. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/LICENSE +0 -0
  9. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/__init__.py +0 -0
  10. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/clients/__init__.py +0 -0
  11. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/clients/claude.py +0 -0
  12. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/clients/eetc_notifications.py +0 -0
  13. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/finance.py +0 -0
  14. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/options.py +0 -0
  15. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/__init__.py +0 -0
  16. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/backtesting/__init__.py +0 -0
  17. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/backtesting/broker_sim.py +0 -0
  18. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/backtesting/metrics.py +0 -0
  19. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/backtesting/strategy.py +0 -0
  20. {eetc_utils-1.9.0 → eetc_utils-2.0.0}/src/eetc_utils/strategy/strategy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eetc-utils
3
- Version: 1.9.0
3
+ Version: 2.0.0
4
4
  Summary: EETC Utils Library
5
5
  Author: East Empire Trading Company, Stefan Delic, Milos Dovedan
6
6
  Author-email: East Empire Trading Company <eastempiretradingcompany2019@gmail.com>, Stefan Delic <einfach.jung1@gmail.com>, Milos Dovedan <dovedanmilosh@gmail.com>
@@ -147,8 +147,8 @@ import os
147
147
  # Initialize client (requires EETC_API_KEY environment variable)
148
148
  client = EETCDataClient(api_key=os.getenv("EETC_API_KEY"))
149
149
 
150
- # Fetch price data
151
- price_data = client.get_price_data(symbol="AAPL", start_date="2024-01-01")
150
+ # Fetch price data (one symbol or a list, batched into few requests)
151
+ price_data = client.get_price_data(["AAPL", "MSFT"], from_date="2024-01-01")
152
152
 
153
153
  # Get fundamentals
154
154
  fundamentals = client.get_fundamentals(symbol="AAPL")
@@ -124,8 +124,8 @@ import os
124
124
  # Initialize client (requires EETC_API_KEY environment variable)
125
125
  client = EETCDataClient(api_key=os.getenv("EETC_API_KEY"))
126
126
 
127
- # Fetch price data
128
- price_data = client.get_price_data(symbol="AAPL", start_date="2024-01-01")
127
+ # Fetch price data (one symbol or a list, batched into few requests)
128
+ price_data = client.get_price_data(["AAPL", "MSFT"], from_date="2024-01-01")
129
129
 
130
130
  # Get fundamentals
131
131
  fundamentals = client.get_fundamentals(symbol="AAPL")
@@ -0,0 +1,64 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11.6,<0.12.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "eetc-utils"
7
+ version = "2.0.0"
8
+ description = "EETC Utils Library"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.12,<4.0"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ dependencies = [
18
+ "pandas>=2.3.3,<3.0.0",
19
+ "numpy>=2.3.4,<3.0.0",
20
+ "arch>=8.0.0,<9.0.0",
21
+ "requests>=2.28.0,<3.0.0",
22
+ "anthropic>=1.6.0,<2.0.0",
23
+ ]
24
+
25
+ [[project.authors]]
26
+ name = "East Empire Trading Company"
27
+ email = "eastempiretradingcompany2019@gmail.com"
28
+
29
+ [[project.authors]]
30
+ name = "Stefan Delic"
31
+ email = "einfach.jung1@gmail.com"
32
+
33
+ [[project.authors]]
34
+ name = "Milos Dovedan"
35
+ email = "dovedanmilosh@gmail.com"
36
+
37
+ [[project.maintainers]]
38
+ name = "East Empire Trading Company"
39
+ email = "eastempiretradingcompany2019@gmail.com"
40
+
41
+ [[project.maintainers]]
42
+ name = "Stefan Delic"
43
+ email = "einfach.jung1@gmail.com"
44
+
45
+ [[project.maintainers]]
46
+ name = "Milos Dovedan"
47
+ email = "dovedanmilosh@gmail.com"
48
+
49
+ [project.urls]
50
+ Homepage = "https://github.com/east-empire-trading-company/eetc-utils"
51
+ Repository = "https://github.com/east-empire-trading-company/eetc-utils"
52
+ "Bug Tracker" = "https://github.com/east-empire-trading-company/eetc-utils/issues"
53
+
54
+ [dependency-groups]
55
+ dev = [
56
+ "black>=25.9.0,<26.0.0",
57
+ "pytest>=9.0.1,<10.0.0",
58
+ ]
59
+
60
+ [[tool.uv.index]]
61
+ name = "testpypi"
62
+ url = "https://test.pypi.org/simple/"
63
+ publish-url = "https://test.pypi.org/legacy/"
64
+ explicit = true
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "eetc-utils"
7
- version = "1.9.0"
7
+ version = "2.0.0"
8
8
  description = "EETC Utils Library"
9
9
  authors = [
10
10
  { name = "East Empire Trading Company", email = "eastempiretradingcompany2019@gmail.com" },
@@ -4,6 +4,9 @@ import pandas as pd
4
4
  import requests
5
5
  from requests import Response
6
6
 
7
+ # max number of symbols the /price/ endpoint accepts per request
8
+ PRICE_BATCH_SIZE = 500
9
+
7
10
 
8
11
  class EETCDataClient:
9
12
  """
@@ -55,44 +58,47 @@ class EETCDataClient:
55
58
 
56
59
  def get_price_data(
57
60
  self,
58
- symbol: str,
61
+ symbols: Union[str, List[str]],
59
62
  date: Optional[str] = None,
60
63
  from_date: Optional[str] = None,
61
64
  to_date: Optional[str] = None,
62
65
  as_json: bool = False,
63
66
  ) -> Union[pd.DataFrame, List[Dict]]:
64
67
  """
65
- Get historical price data from EETC Data Hub via REST API.
68
+ Get historical price data for one or more symbols from EETC Data
69
+ Hub via REST API.
66
70
 
67
- :param symbol: Ticker symbol of the instrument (e.g., "AAPL").
71
+ Symbols are fetched in alphabetically sorted batches of
72
+ PRICE_BATCH_SIZE, since each request costs about the same in
73
+ BigQuery whether it reads one symbol or hundreds.
74
+
75
+ :param symbols: Ticker symbol (e.g., "AAPL") or list of ticker
76
+ symbols.
68
77
  :param date: Specific date in format "yyyy-mm-dd".
69
78
  :param from_date: Earliest date in format "yyyy-mm-dd".
70
79
  :param to_date: Latest date in format "yyyy-mm-dd".
71
80
  :param as_json: If True, returns raw JSON list; if False
72
81
  (default), returns pandas DataFrame.
73
- :return: Historical price data as pandas DataFrame (default) or
74
- list of dicts (if as_json=True).
82
+ :return: Historical price data as pandas DataFrame sorted by
83
+ symbol and date (default) or list of dicts (if as_json=True).
75
84
  :raises requests.HTTPError: If the API request fails.
76
85
  """
77
86
 
78
- url = f"{self.base_url}/price/?symbol={symbol}"
79
- params = {}
80
-
81
- # add optional query params
82
- if date:
83
- params["date"] = date
84
-
85
- if from_date:
86
- params["from_date"] = from_date
87
+ if isinstance(symbols, str):
88
+ symbols = [symbols]
87
89
 
88
- if to_date:
89
- params["to_date"] = to_date
90
-
91
- # send the HTTP request to EETC Data Hub
92
- response = self._send_http_request(url, params)
90
+ symbols = sorted(set(symbols))
91
+ url = f"{self.base_url}/price/"
92
+ params = {"date": date, "from_date": from_date, "to_date": to_date}
93
+ params = {k: v for k, v in params.items() if v is not None}
93
94
 
94
- # process and return response data
95
- response_data = response.json()
95
+ response_data = []
96
+ for i in range(0, len(symbols), PRICE_BATCH_SIZE):
97
+ batch = symbols[i : i + PRICE_BATCH_SIZE]
98
+ response = self._send_http_request(
99
+ url, {**params, "symbols": ",".join(batch)}
100
+ )
101
+ response_data.extend(response.json())
96
102
 
97
103
  if as_json:
98
104
  return response_data
@@ -101,7 +107,7 @@ class EETCDataClient:
101
107
  return pd.DataFrame()
102
108
 
103
109
  df = pd.json_normalize(response_data)
104
- df = df.sort_values(by=["date"])
110
+ df = df.sort_values(by=["symbol", "date"], ignore_index=True)
105
111
 
106
112
  return df
107
113
 
@@ -22,7 +22,7 @@ class BacktestEngine:
22
22
 
23
23
  # fetch input data
24
24
  price_df = self.eetc_data_client.get_price_data(
25
- symbol=symbol, from_date=start, to_date=end
25
+ symbol, from_date=start, to_date=end
26
26
  )
27
27
  context = {
28
28
  "engine": self,
@@ -21,9 +21,7 @@ class Engine:
21
21
  } # output
22
22
 
23
23
  # fetch input data
24
- price_df = self.client.get_price_data(
25
- symbol=symbol, from_date=start, to_date=end
26
- )
24
+ price_df = self.client.get_price_data(symbol, from_date=start, to_date=end)
27
25
  context = {
28
26
  "engine": self,
29
27
  "symbol": symbol,
File without changes