finbrain-python 0.1.6__tar.gz → 0.1.8__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 (65) hide show
  1. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.github/workflows/ci.yml +1 -1
  2. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/CHANGELOG.md +26 -1
  3. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/PKG-INFO +42 -1
  4. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/README.md +41 -0
  5. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/RELEASE.md +3 -2
  6. finbrain_python-0.1.8/examples/transactions_plotting_example.py +143 -0
  7. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/client.py +2 -0
  8. finbrain_python-0.1.8/src/finbrain/aio/endpoints/senate_trades.py +48 -0
  9. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/client.py +2 -0
  10. finbrain_python-0.1.8/src/finbrain/endpoints/senate_trades.py +76 -0
  11. finbrain_python-0.1.8/src/finbrain/plotting.py +971 -0
  12. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/PKG-INFO +42 -1
  13. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/SOURCES.txt +4 -0
  14. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_async_client.py +1 -0
  15. finbrain_python-0.1.8/tests/test_plotting.py +138 -0
  16. finbrain_python-0.1.8/tests/test_senate_trades.py +76 -0
  17. finbrain_python-0.1.6/src/finbrain/plotting.py +0 -506
  18. finbrain_python-0.1.6/tests/test_plotting.py +0 -27
  19. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.gitattributes +0 -0
  20. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.github/workflows/release.yml +0 -0
  21. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.gitignore +0 -0
  22. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/LICENSE +0 -0
  23. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/examples/async_example.py +0 -0
  24. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/pyproject.toml +0 -0
  25. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/setup.cfg +0 -0
  26. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/__init__.py +0 -0
  27. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/__init__.py +0 -0
  28. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/__init__.py +0 -0
  29. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/_utils.py +0 -0
  30. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/analyst_ratings.py +0 -0
  31. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/app_ratings.py +0 -0
  32. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/available.py +0 -0
  33. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/house_trades.py +0 -0
  34. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/insider_transactions.py +0 -0
  35. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/linkedin_data.py +0 -0
  36. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/options.py +0 -0
  37. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/predictions.py +0 -0
  38. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/sentiments.py +0 -0
  39. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/__init__.py +0 -0
  40. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/_utils.py +0 -0
  41. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/analyst_ratings.py +0 -0
  42. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/app_ratings.py +0 -0
  43. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/available.py +0 -0
  44. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/house_trades.py +0 -0
  45. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/insider_transactions.py +0 -0
  46. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/linkedin_data.py +0 -0
  47. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/options.py +0 -0
  48. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/predictions.py +0 -0
  49. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/sentiments.py +0 -0
  50. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/exceptions.py +0 -0
  51. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/py.typed +0 -0
  52. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/dependency_links.txt +0 -0
  53. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/requires.txt +0 -0
  54. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/top_level.txt +0 -0
  55. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/__init__.py +0 -0
  56. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/conftest.py +0 -0
  57. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_analyst_ratings.py +0 -0
  58. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_app_ratings.py +0 -0
  59. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_available.py +0 -0
  60. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_house_trades.py +0 -0
  61. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_insider_transactions.py +0 -0
  62. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_linkedin_data.py +0 -0
  63. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_options.py +0 -0
  64. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_predictions.py +0 -0
  65. {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_sentiments.py +0 -0
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- python: ['3.9', '3.10', '3.11', '3.12', '3.13']
10
+ python: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
11
11
  steps:
12
12
  - uses: actions/checkout@v4
13
13
  with:
@@ -7,9 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.7] - 2025-10-02
11
+
12
+ ### Added
13
+
14
+ - **Insider Transactions Plotting**: `fb.plot.insider_transactions()` - Overlay insider buy/sell markers on user-provided price charts
15
+ - **House Trades Plotting**: `fb.plot.house_trades()` - Visualize U.S. House member trades on price charts
16
+ - **Transaction Plotting Example**: `examples/transactions_plotting_example.py` demonstrating integration with various price data sources
17
+ - **Plotting Tests**: Extended `tests/test_plotting.py` with 8 new test cases for transaction plotting
18
+
19
+ ### Changed
20
+
21
+ - **Price Data Flexibility**: Plotting methods now auto-detect multiple price column formats (`close`, `Close`, `price`, `Price`, `adj_close`, `Adj Close`)
22
+ - **MultiIndex Support**: Transaction plotting methods now handle yfinance's MultiIndex column format (from `yf.download()`)
23
+ - **Timezone Handling**: Automatic timezone normalization to handle timezone-aware price data (e.g., from yfinance)
24
+
25
+ ### Fixed
26
+
27
+ - **Column Detection**: Fixed `KeyError` when house trades API returns `type` column instead of `transaction`
28
+ - **yfinance Compatibility**: Fixed price line not displaying when using `yf.download()` due to MultiIndex columns
29
+
10
30
  ## [0.1.6] - 2025-10-02
11
31
 
12
32
  ### Added
33
+
13
34
  - **Async Support**: Full async/await implementation using `httpx`
14
35
  - `AsyncFinBrainClient` with context manager support
15
36
  - All 9 endpoints have async equivalents
@@ -23,15 +44,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
44
  - **Release guide**: `RELEASE.md` with tag conventions
24
45
 
25
46
  ### Changed
47
+
26
48
  - **Tag Convention**: Now using `v` prefix (e.g., `v0.1.6` instead of `0.1.6`)
27
49
  - **GitHub Actions**: Updated to trigger on `v[0-9]*` tags
28
50
  - **Code Deduplication**: Consolidated 12 duplicate `_to_datestr()` helpers into 2 utility modules
29
51
  - **README**: Added async usage section with examples
30
52
 
31
53
  ### Fixed
54
+
32
55
  - **Plotting Error Handling**: `options()` method now raises clear `ValueError` for invalid `kind` parameter instead of `NameError`
33
56
 
34
57
  ### Dependencies
58
+
35
59
  - Added `httpx>=0.24` as optional dependency for async support
36
60
  - Added `pytest-asyncio` as dev dependency
37
61
 
@@ -55,7 +79,8 @@ Previous releases...
55
79
 
56
80
  Previous releases...
57
81
 
58
- [Unreleased]: https://github.com/ahmetsbilgin/finbrain-python/compare/v0.1.6...HEAD
82
+ [Unreleased]: https://github.com/ahmetsbilgin/finbrain-python/compare/v0.1.7...HEAD
83
+ [0.1.7]: https://github.com/ahmetsbilgin/finbrain-python/compare/v0.1.6...v0.1.7
59
84
  [0.1.6]: https://github.com/ahmetsbilgin/finbrain-python/compare/0.1.5...v0.1.6
60
85
  [0.1.5]: https://github.com/ahmetsbilgin/finbrain-python/compare/0.1.4...0.1.5
61
86
  [0.1.4]: https://github.com/ahmetsbilgin/finbrain-python/compare/0.1.3...0.1.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: finbrain-python
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Official Python client for the FinBrain API
5
5
  Author-email: Ahmet Salim Bilgin <ahmet@finbrain.tech>
6
6
  License-Expression: MIT
@@ -86,6 +86,12 @@ fb.house_trades.ticker("S&P 500", "AMZN",
86
86
  date_to="2025-06-30",
87
87
  as_dataframe=True)
88
88
 
89
+ # ---------- senate trades ----------
90
+ fb.senate_trades.ticker("NASDAQ", "META",
91
+ date_from="2025-01-01",
92
+ date_to="2025-06-30",
93
+ as_dataframe=True)
94
+
89
95
  # ---------- insider transactions ----------
90
96
  fb.insider_transactions.ticker("S&P 500", "AMZN", as_dataframe=True)
91
97
 
@@ -184,8 +190,42 @@ fb.plot.predictions("AMZN") # prediction_type="monthly" for monthly pred
184
190
  fb.plot.sentiments("S&P 500", "AMZN",
185
191
  date_from="2025-01-01",
186
192
  date_to="2025-06-30")
193
+
194
+ # ---------- Insider Transactions, House & Senate Trades (requires user price data) ----------
195
+ # These plots overlay transaction markers on a price chart.
196
+ # Since FinBrain doesn't provide historical prices, you must provide your own:
197
+
198
+ import pandas as pd
199
+
200
+ # Example: Load your price data from any legal source
201
+ # (broker API, licensed data provider, CSV file, etc.)
202
+ price_df = pd.DataFrame({
203
+ "close": [150.25, 151.30, 149.80], # Your price data
204
+ "date": pd.date_range("2025-01-01", periods=3)
205
+ }).set_index("date")
206
+
207
+ # Plot insider transactions on your price chart
208
+ fb.plot.insider_transactions("S&P 500", "AAPL", price_data=price_df)
209
+
210
+ # Plot House member trades on your price chart
211
+ fb.plot.house_trades("S&P 500", "NVDA",
212
+ price_data=price_df,
213
+ date_from="2025-01-01",
214
+ date_to="2025-06-30")
215
+
216
+ # Plot Senate member trades on your price chart
217
+ fb.plot.senate_trades("NASDAQ", "META",
218
+ price_data=price_df,
219
+ date_from="2025-01-01",
220
+ date_to="2025-06-30")
187
221
  ```
188
222
 
223
+ **Price Data Requirements:**
224
+
225
+ - DataFrame with DatetimeIndex
226
+ - Must contain a price column: `close`, `Close`, `price`, `Price`, `adj_close`, or `Adj Close`
227
+ - Obtain from legal sources: broker API, Bloomberg, Alpha Vantage, FMP, etc.
228
+
189
229
  ## 🔑 Authentication
190
230
 
191
231
  To call the API you need an **API key**, obtained by purchasing a **FinBrain API subscription**.
@@ -214,6 +254,7 @@ fb = FinBrainClient(api_key="YOUR_KEY")
214
254
  | App ratings | `client.app_ratings.ticker()` | `/appratings/{MARKET}/{TICKER}` |
215
255
  | Analyst ratings | `client.analyst_ratings.ticker()` | `/analystratings/{MARKET}/{TICKER}` |
216
256
  | House trades | `client.house_trades.ticker()` | `/housetrades/{MARKET}/{TICKER}` |
257
+ | Senate trades | `client.senate_trades.ticker()` | `/senatetrades/{MARKET}/{TICKER}` |
217
258
  | Insider transactions | `client.insider_transactions.ticker()` | `/insidertransactions/{MARKET}/{TICKER}` |
218
259
  | LinkedIn | `client.linkedin_data.ticker()` | `/linkedindata/{MARKET}/{TICKER}` |
219
260
  | Options – Put/Call | `client.options.put_call()` | `/putcalldata/{MARKET}/{TICKER}` |
@@ -60,6 +60,12 @@ fb.house_trades.ticker("S&P 500", "AMZN",
60
60
  date_to="2025-06-30",
61
61
  as_dataframe=True)
62
62
 
63
+ # ---------- senate trades ----------
64
+ fb.senate_trades.ticker("NASDAQ", "META",
65
+ date_from="2025-01-01",
66
+ date_to="2025-06-30",
67
+ as_dataframe=True)
68
+
63
69
  # ---------- insider transactions ----------
64
70
  fb.insider_transactions.ticker("S&P 500", "AMZN", as_dataframe=True)
65
71
 
@@ -158,8 +164,42 @@ fb.plot.predictions("AMZN") # prediction_type="monthly" for monthly pred
158
164
  fb.plot.sentiments("S&P 500", "AMZN",
159
165
  date_from="2025-01-01",
160
166
  date_to="2025-06-30")
167
+
168
+ # ---------- Insider Transactions, House & Senate Trades (requires user price data) ----------
169
+ # These plots overlay transaction markers on a price chart.
170
+ # Since FinBrain doesn't provide historical prices, you must provide your own:
171
+
172
+ import pandas as pd
173
+
174
+ # Example: Load your price data from any legal source
175
+ # (broker API, licensed data provider, CSV file, etc.)
176
+ price_df = pd.DataFrame({
177
+ "close": [150.25, 151.30, 149.80], # Your price data
178
+ "date": pd.date_range("2025-01-01", periods=3)
179
+ }).set_index("date")
180
+
181
+ # Plot insider transactions on your price chart
182
+ fb.plot.insider_transactions("S&P 500", "AAPL", price_data=price_df)
183
+
184
+ # Plot House member trades on your price chart
185
+ fb.plot.house_trades("S&P 500", "NVDA",
186
+ price_data=price_df,
187
+ date_from="2025-01-01",
188
+ date_to="2025-06-30")
189
+
190
+ # Plot Senate member trades on your price chart
191
+ fb.plot.senate_trades("NASDAQ", "META",
192
+ price_data=price_df,
193
+ date_from="2025-01-01",
194
+ date_to="2025-06-30")
161
195
  ```
162
196
 
197
+ **Price Data Requirements:**
198
+
199
+ - DataFrame with DatetimeIndex
200
+ - Must contain a price column: `close`, `Close`, `price`, `Price`, `adj_close`, or `Adj Close`
201
+ - Obtain from legal sources: broker API, Bloomberg, Alpha Vantage, FMP, etc.
202
+
163
203
  ## 🔑 Authentication
164
204
 
165
205
  To call the API you need an **API key**, obtained by purchasing a **FinBrain API subscription**.
@@ -188,6 +228,7 @@ fb = FinBrainClient(api_key="YOUR_KEY")
188
228
  | App ratings | `client.app_ratings.ticker()` | `/appratings/{MARKET}/{TICKER}` |
189
229
  | Analyst ratings | `client.analyst_ratings.ticker()` | `/analystratings/{MARKET}/{TICKER}` |
190
230
  | House trades | `client.house_trades.ticker()` | `/housetrades/{MARKET}/{TICKER}` |
231
+ | Senate trades | `client.senate_trades.ticker()` | `/senatetrades/{MARKET}/{TICKER}` |
191
232
  | Insider transactions | `client.insider_transactions.ticker()` | `/insidertransactions/{MARKET}/{TICKER}` |
192
233
  | LinkedIn | `client.linkedin_data.ticker()` | `/linkedindata/{MARKET}/{TICKER}` |
193
234
  | Options – Put/Call | `client.options.put_call()` | `/putcalldata/{MARKET}/{TICKER}` |
@@ -35,13 +35,14 @@ git push origin v0.1.6
35
35
  ### 3. GitHub Actions (Automated)
36
36
 
37
37
  GitHub Actions will automatically:
38
+
38
39
  - Build the wheel and source distribution
39
40
  - Upload to TestPyPI first
40
41
  - Upload to production PyPI
41
42
 
42
43
  ### 4. Create GitHub Release (Manual)
43
44
 
44
- 1. Go to: https://github.com/ahmetsbilgin/finbrain-python/releases/new
45
+ 1. Go to: <https://github.com/ahmetsbilgin/finbrain-python/releases/new>
45
46
  2. Select tag: `v0.1.6`
46
47
  3. Title: `v0.1.6 - Brief Description`
47
48
  4. Copy the relevant section from `CHANGELOG.md` into the description
@@ -49,7 +50,7 @@ GitHub Actions will automatically:
49
50
 
50
51
  ### 5. Verify
51
52
 
52
- - Check PyPI: https://pypi.org/project/finbrain-python/
53
+ - Check PyPI: <https://pypi.org/project/finbrain-python/>
53
54
  - Test installation: `pip install finbrain-python==0.1.6`
54
55
 
55
56
  ## How setuptools-scm Works
@@ -0,0 +1,143 @@
1
+ """
2
+ Example: Plotting Insider Transactions and House Trades with User-Provided Price Data
3
+
4
+ This example demonstrates how to visualize insider transactions and House member trades
5
+ on a price chart. Since FinBrain doesn't provide historical price data, users must
6
+ bring their own price data from legal sources (e.g., their broker, Bloomberg, etc.).
7
+ """
8
+
9
+ import os
10
+ import pandas as pd
11
+ from finbrain import FinBrainClient
12
+
13
+ # Initialize client
14
+ api_key = os.environ.get("FINBRAIN_API_KEY")
15
+ if not api_key:
16
+ raise ValueError("Please set FINBRAIN_API_KEY environment variable")
17
+
18
+ fb = FinBrainClient(api_key=api_key)
19
+
20
+ # ============================================================================
21
+ # Example 1: Mock price data for demonstration
22
+ # ============================================================================
23
+ # In production, replace this with real price data from your legal source
24
+ # (broker API, Bloomberg, Alpha Vantage, yfinance with proper licensing, etc.)
25
+
26
+ mock_prices = pd.DataFrame({
27
+ "date": pd.date_range("2024-01-01", "2024-12-31", freq="D"),
28
+ "close": [150 + i * 0.5 for i in range(366)], # Simulated price trend
29
+ })
30
+ mock_prices.set_index("date", inplace=True)
31
+
32
+ print("=" * 70)
33
+ print("Example 1: Insider Transactions with Mock Price Data")
34
+ print("=" * 70)
35
+
36
+ # Plot insider transactions for AAPL
37
+ # This will fetch real transaction data from FinBrain and overlay on your price data
38
+ fig_insider = fb.plot.insider_transactions(
39
+ market="S&P 500",
40
+ ticker="AAPL",
41
+ price_data=mock_prices,
42
+ show=False, # Don't display immediately for this example
43
+ )
44
+
45
+ print(f"Created insider transactions plot with {len(fig_insider.data)} traces")
46
+ print("Green triangles (▲) = Buys | Red triangles (▼) = Sells")
47
+
48
+ # Uncomment to display the figure:
49
+ # fig_insider.show()
50
+
51
+ # ============================================================================
52
+ # Example 2: House Trades with Date Filtering
53
+ # ============================================================================
54
+ print("\n" + "=" * 70)
55
+ print("Example 2: House Trades with Date Filtering")
56
+ print("=" * 70)
57
+
58
+ # Plot House member trades for a specific date range
59
+ fig_house = fb.plot.house_trades(
60
+ market="S&P 500",
61
+ ticker="NVDA",
62
+ price_data=mock_prices,
63
+ date_from="2024-06-01",
64
+ date_to="2024-12-31",
65
+ show=False,
66
+ )
67
+
68
+ print(f"Created House trades plot with {len(fig_house.data)} traces")
69
+
70
+ # Uncomment to display the figure:
71
+ # fig_house.show()
72
+
73
+ # ============================================================================
74
+ # Example 3: Using Real Price Data (conceptual - adjust to your source)
75
+ # ============================================================================
76
+ print("\n" + "=" * 70)
77
+ print("Example 3: Integration with Real Price Data (Conceptual)")
78
+ print("=" * 70)
79
+
80
+ # Example pattern for integrating with real data sources:
81
+
82
+ # Option A: If you have CSV files from your broker
83
+ # real_prices = pd.read_csv("path/to/your/price_data.csv", parse_dates=["date"], index_col="date")
84
+
85
+ # Option B: If you have access to a licensed API (e.g., Alpha Vantage)
86
+ # import requests
87
+ # api_key = "your_alpha_vantage_key"
88
+ # response = requests.get(f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=AAPL&apikey={api_key}")
89
+ # # ... parse and create DataFrame ...
90
+
91
+ # Option C: If you have a Bloomberg Terminal subscription
92
+ # from blpapi import Session
93
+ # # ... Bloomberg API code ...
94
+
95
+ # Then use it with FinBrain plotting:
96
+ # fb.plot.insider_transactions("S&P 500", "AAPL", price_data=real_prices)
97
+
98
+ print("""
99
+ To use real price data, replace mock_prices with data from your legal source:
100
+ - Broker API (Interactive Brokers, TD Ameritrade, etc.)
101
+ - Licensed data provider (Bloomberg, Refinitiv, Alpha Vantage, etc.)
102
+ - Your own database/warehouse
103
+
104
+ Required DataFrame format:
105
+ - DatetimeIndex with dates
106
+ - Column named 'close', 'Close', 'price', or 'Price'
107
+
108
+ Example:
109
+ close
110
+ date
111
+ 2024-01-01 150.25
112
+ 2024-01-02 151.30
113
+ 2024-01-03 149.80
114
+ """)
115
+
116
+ # ============================================================================
117
+ # Example 4: Exporting to JSON for web applications
118
+ # ============================================================================
119
+ print("\n" + "=" * 70)
120
+ print("Example 4: Export to JSON for Web Applications")
121
+ print("=" * 70)
122
+
123
+ # Get the plot as JSON (useful for web apps, dashboards, etc.)
124
+ json_plot = fb.plot.insider_transactions(
125
+ market="S&P 500",
126
+ ticker="TSLA",
127
+ price_data=mock_prices,
128
+ as_json=True,
129
+ show=False,
130
+ )
131
+
132
+ print(f"Generated JSON plot (length: {len(json_plot)} characters)")
133
+ print("This can be sent to a web frontend using Plotly.js")
134
+
135
+ # Example: Save to file for web app
136
+ # with open("insider_plot.json", "w") as f:
137
+ # f.write(json_plot)
138
+
139
+ print("\n" + "=" * 70)
140
+ print("Examples completed!")
141
+ print("=" * 70)
142
+ print("\nNote: To actually display the plots, uncomment the fig.show() lines above.")
143
+ print("Make sure you have real price data from a legal source for production use.")
@@ -15,6 +15,7 @@ from .endpoints.sentiments import AsyncSentimentsAPI
15
15
  from .endpoints.app_ratings import AsyncAppRatingsAPI
16
16
  from .endpoints.analyst_ratings import AsyncAnalystRatingsAPI
17
17
  from .endpoints.house_trades import AsyncHouseTradesAPI
18
+ from .endpoints.senate_trades import AsyncSenateTradesAPI
18
19
  from .endpoints.insider_transactions import AsyncInsiderTransactionsAPI
19
20
  from .endpoints.linkedin_data import AsyncLinkedInDataAPI
20
21
  from .endpoints.options import AsyncOptionsAPI
@@ -68,6 +69,7 @@ class AsyncFinBrainClient:
68
69
  self.app_ratings = AsyncAppRatingsAPI(self)
69
70
  self.analyst_ratings = AsyncAnalystRatingsAPI(self)
70
71
  self.house_trades = AsyncHouseTradesAPI(self)
72
+ self.senate_trades = AsyncSenateTradesAPI(self)
71
73
  self.insider_transactions = AsyncInsiderTransactionsAPI(self)
72
74
  self.linkedin_data = AsyncLinkedInDataAPI(self)
73
75
  self.options = AsyncOptionsAPI(self)
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+ import pandas as pd
3
+ from urllib.parse import quote
4
+ import datetime as _dt
5
+ from typing import TYPE_CHECKING, Dict, Any
6
+
7
+ from ._utils import to_datestr
8
+
9
+ if TYPE_CHECKING:
10
+ from ..client import AsyncFinBrainClient
11
+
12
+
13
+ class AsyncSenateTradesAPI:
14
+ """Async wrapper for /senatetrades endpoints."""
15
+
16
+ def __init__(self, client: "AsyncFinBrainClient") -> None:
17
+ self._c = client
18
+
19
+ async def ticker(
20
+ self,
21
+ market: str,
22
+ symbol: str,
23
+ *,
24
+ date_from: _dt.date | str | None = None,
25
+ date_to: _dt.date | str | None = None,
26
+ as_dataframe: bool = False,
27
+ ) -> Dict[str, Any] | pd.DataFrame:
28
+ """Fetch Senate-member trades for symbol in market (async)."""
29
+ params: Dict[str, str] = {}
30
+ if date_from:
31
+ params["dateFrom"] = to_datestr(date_from)
32
+ if date_to:
33
+ params["dateTo"] = to_datestr(date_to)
34
+
35
+ market_slug = quote(market, safe="")
36
+ path = f"senatetrades/{market_slug}/{symbol.upper()}"
37
+
38
+ data: Dict[str, Any] = await self._c._request("GET", path, params=params)
39
+
40
+ if as_dataframe:
41
+ rows = data.get("senateTrades", [])
42
+ df = pd.DataFrame(rows)
43
+ if not df.empty and "date" in df.columns:
44
+ df["date"] = pd.to_datetime(df["date"])
45
+ df.set_index("date", inplace=True)
46
+ return df
47
+
48
+ return data
@@ -16,6 +16,7 @@ from .endpoints.sentiments import SentimentsAPI
16
16
  from .endpoints.app_ratings import AppRatingsAPI
17
17
  from .endpoints.analyst_ratings import AnalystRatingsAPI
18
18
  from .endpoints.house_trades import HouseTradesAPI
19
+ from .endpoints.senate_trades import SenateTradesAPI
19
20
  from .endpoints.insider_transactions import InsiderTransactionsAPI
20
21
  from .endpoints.linkedin_data import LinkedInDataAPI
21
22
  from .endpoints.options import OptionsAPI
@@ -63,6 +64,7 @@ class FinBrainClient:
63
64
  self.app_ratings = AppRatingsAPI(self)
64
65
  self.analyst_ratings = AnalystRatingsAPI(self)
65
66
  self.house_trades = HouseTradesAPI(self)
67
+ self.senate_trades = SenateTradesAPI(self)
66
68
  self.insider_transactions = InsiderTransactionsAPI(self)
67
69
  self.linkedin_data = LinkedInDataAPI(self)
68
70
  self.options = OptionsAPI(self)
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+ import pandas as pd
3
+ from urllib.parse import quote
4
+ import datetime as _dt
5
+ from typing import TYPE_CHECKING, Dict, Any
6
+
7
+ from ._utils import to_datestr
8
+
9
+ if TYPE_CHECKING: # imported only by type-checkers
10
+ from ..client import FinBrainClient
11
+
12
+
13
+ class SenateTradesAPI:
14
+ """
15
+ Endpoint
16
+ --------
17
+ ``/senatetrades/<MARKET>/<TICKER>`` - trading activity of U.S. Senators
18
+ for the selected ticker.
19
+ """
20
+
21
+ # ------------------------------------------------------------------ #
22
+ def __init__(self, client: "FinBrainClient") -> None:
23
+ self._c = client # reference to the parent client
24
+
25
+ # ------------------------------------------------------------------ #
26
+ def ticker(
27
+ self,
28
+ market: str,
29
+ symbol: str,
30
+ *,
31
+ date_from: _dt.date | str | None = None,
32
+ date_to: _dt.date | str | None = None,
33
+ as_dataframe: bool = False,
34
+ ) -> Dict[str, Any] | pd.DataFrame:
35
+ """
36
+ Fetch Senate-member trades for *symbol* in *market*.
37
+
38
+ Parameters
39
+ ----------
40
+ market :
41
+ Market name **exactly as FinBrain lists it**
42
+ (e.g. ``"NASDAQ"``, ``"NYSE"``, ``"S&P 500"``).
43
+ Spaces and special characters are accepted; they are URL-encoded
44
+ automatically.
45
+ symbol :
46
+ Ticker symbol; auto-upper-cased.
47
+ date_from, date_to :
48
+ Optional ISO dates (``YYYY-MM-DD``) bounding the returned rows.
49
+ as_dataframe :
50
+ If *True*, return a **pandas.DataFrame** indexed by ``date``;
51
+ otherwise return the raw JSON dict.
52
+
53
+ Returns
54
+ -------
55
+ dict | pandas.DataFrame
56
+ """
57
+ params: Dict[str, str] = {}
58
+ if date_from:
59
+ params["dateFrom"] = to_datestr(date_from)
60
+ if date_to:
61
+ params["dateTo"] = to_datestr(date_to)
62
+
63
+ market_slug = quote(market, safe="")
64
+ path = f"senatetrades/{market_slug}/{symbol.upper()}"
65
+
66
+ data: Dict[str, Any] = self._c._request("GET", path, params=params)
67
+
68
+ if as_dataframe:
69
+ rows = data.get("senateTrades", [])
70
+ df = pd.DataFrame(rows)
71
+ if not df.empty and "date" in df.columns:
72
+ df["date"] = pd.to_datetime(df["date"])
73
+ df.set_index("date", inplace=True)
74
+ return df
75
+
76
+ return data