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.
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.github/workflows/ci.yml +1 -1
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/CHANGELOG.md +26 -1
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/PKG-INFO +42 -1
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/README.md +41 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/RELEASE.md +3 -2
- finbrain_python-0.1.8/examples/transactions_plotting_example.py +143 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/client.py +2 -0
- finbrain_python-0.1.8/src/finbrain/aio/endpoints/senate_trades.py +48 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/client.py +2 -0
- finbrain_python-0.1.8/src/finbrain/endpoints/senate_trades.py +76 -0
- finbrain_python-0.1.8/src/finbrain/plotting.py +971 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/PKG-INFO +42 -1
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/SOURCES.txt +4 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_async_client.py +1 -0
- finbrain_python-0.1.8/tests/test_plotting.py +138 -0
- finbrain_python-0.1.8/tests/test_senate_trades.py +76 -0
- finbrain_python-0.1.6/src/finbrain/plotting.py +0 -506
- finbrain_python-0.1.6/tests/test_plotting.py +0 -27
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.gitattributes +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.github/workflows/release.yml +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/.gitignore +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/LICENSE +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/examples/async_example.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/pyproject.toml +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/setup.cfg +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/__init__.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/__init__.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/__init__.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/_utils.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/analyst_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/app_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/available.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/house_trades.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/insider_transactions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/linkedin_data.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/options.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/predictions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/aio/endpoints/sentiments.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/__init__.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/_utils.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/analyst_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/app_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/available.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/house_trades.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/insider_transactions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/linkedin_data.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/options.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/predictions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/endpoints/sentiments.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/exceptions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain/py.typed +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/dependency_links.txt +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/requires.txt +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/src/finbrain_python.egg-info/top_level.txt +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/__init__.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/conftest.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_analyst_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_app_ratings.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_available.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_house_trades.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_insider_transactions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_linkedin_data.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_options.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_predictions.py +0 -0
- {finbrain_python-0.1.6 → finbrain_python-0.1.8}/tests/test_sentiments.py +0 -0
|
@@ -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.
|
|
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.
|
|
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
|