bdshare 1.2.0__tar.gz → 1.2.2__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 (38) hide show
  1. {bdshare-1.2.0 → bdshare-1.2.2}/CHANGELOG.md +25 -0
  2. {bdshare-1.2.0/bdshare.egg-info → bdshare-1.2.2}/PKG-INFO +140 -25
  3. {bdshare-1.2.0 → bdshare-1.2.2}/README.md +109 -24
  4. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/__init__.py +10 -32
  5. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/_version.py +1 -1
  6. bdshare-1.2.2/bdshare/mcp_server.py +197 -0
  7. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/stock/market.py +151 -123
  8. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/stock/news.py +79 -73
  9. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/stock/trading.py +85 -94
  10. bdshare-1.2.2/bdshare/util/helper.py +356 -0
  11. bdshare-1.2.2/bdshare/util/sectigo_dv_r36.pem +36 -0
  12. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/vars.py +4 -3
  13. {bdshare-1.2.0 → bdshare-1.2.2/bdshare.egg-info}/PKG-INFO +140 -25
  14. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare.egg-info/SOURCES.txt +4 -0
  15. bdshare-1.2.2/bdshare.egg-info/entry_points.txt +2 -0
  16. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare.egg-info/requires.txt +7 -0
  17. {bdshare-1.2.0 → bdshare-1.2.2}/setup.cfg +13 -2
  18. bdshare-1.2.2/tests/test_market.py +172 -0
  19. bdshare-1.2.2/tests/test_polars.py +351 -0
  20. {bdshare-1.2.0 → bdshare-1.2.2}/tests/test_trading.py +1 -1
  21. bdshare-1.2.0/bdshare/util/helper.py +0 -236
  22. bdshare-1.2.0/tests/test_market.py +0 -214
  23. {bdshare-1.2.0 → bdshare-1.2.2}/LICENSE +0 -0
  24. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/stock/__init__.py +0 -0
  25. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/__init__.py +0 -0
  26. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/cache.py +0 -0
  27. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/cons.py +0 -0
  28. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/proxy.py +0 -0
  29. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/session.py +0 -0
  30. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/store.py +0 -0
  31. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/tickers.py +0 -0
  32. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare/util/upass.py +0 -0
  33. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare.egg-info/dependency_links.txt +0 -0
  34. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare.egg-info/not-zip-safe +0 -0
  35. {bdshare-1.2.0 → bdshare-1.2.2}/bdshare.egg-info/top_level.txt +0 -0
  36. {bdshare-1.2.0 → bdshare-1.2.2}/pyproject.toml +0 -0
  37. {bdshare-1.2.0 → bdshare-1.2.2}/tests/__init__.py +0 -0
  38. {bdshare-1.2.0 → bdshare-1.2.2}/tests/test_news.py +0 -0
@@ -6,6 +6,31 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
  Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
+ ## [1.2.2] - 2026-07-22
10
+
11
+ ### Added
12
+ - Optional `as_polars=True` parameter across all data-fetching functions to return `polars.DataFrame` instead of `pandas.DataFrame` (requires `pip install bdshare[polars]`)
13
+ - `get_market_status()` — current market status (Open, Closed, Holiday, etc.)
14
+ - `get_top_twenty_shares()` — top twenty shares by traded volume
15
+ - MCP ([Model Context Protocol](https://modelcontextprotocol.io/)) server (`bdshare/mcp_server.py`) exposing 15 tools so AI agents (Claude Desktop, Claude Code, etc.) can call live DSE data directly; install with `pip install bdshare[mcp]`, run with `bdshare-mcp`
16
+
17
+ ### Changed
18
+ - Renamed `get_top_gainers_losers()` → `get_top_ten_gainers_losers()`; returned columns changed from `symbol, ltp, change` to `symbol, close, high, low, ycp, change`
19
+
20
+ ### Removed
21
+ - `get_sector_performance()` (module function and `BDShare.get_sector_performance()`) — no aliased replacement; use `get_top_twenty_shares()` instead
22
+
23
+ ### Fixed
24
+ - Bundled the missing Sectigo DV R36 intermediate certificate so requests to dsebd.org verify correctly instead of relying on an incomplete chain
25
+ - Corrected `DSE_ALT_URL` fallback domain to `dse.com.bd`
26
+ - `get_corporate_announcements()` and `get_price_sensitive_news()` always raised `BDShareError` — the row parser assumed each news item was one `<tr>` with 4 `<td>`s, but DSE renders each field (`Trading Code:`, `News Title:`, `News:`, `Post Date:`) as its own `<th>`/`<td>` row pair
27
+ - `as_polars=True` could crash with `unexpected value while building Series of type String; found value of type Float64: NaN` on tables mixing strings and missing values (e.g. `get_company_info()`); NaN now converts to a proper polars null instead
28
+ - Corrected `usage.rst`/README documentation that had `get_historical_data()`/`get_basic_historical_data()` mislabeled as the deprecated aliases — `get_hist_data()`/`get_basic_hist_data()` are the deprecated ones
29
+
30
+ ## [1.2.1] - 2026-02-22
31
+
32
+ ### Added
33
+ - Added code filter on market index
9
34
 
10
35
  ## [1.2.0] - 2026-02-21
11
36
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bdshare
3
- Version: 1.2.0
3
+ Version: 1.2.2
4
4
  Summary: A utility for crawling historical and Real-time Quotes of DSE(Dhaka Stock Exchange)
5
5
  Author: Raisul Islam
6
6
  Author-email: raisul.me@gmail.com
@@ -11,10 +11,15 @@ Requires-Python: >=3.9
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
  Requires-Dist: requests
14
+ Requires-Dist: certifi
14
15
  Requires-Dist: beautifulsoup4
15
16
  Requires-Dist: html5lib
16
17
  Requires-Dist: pandas
17
18
  Requires-Dist: lxml
19
+ Provides-Extra: polars
20
+ Requires-Dist: polars; extra == "polars"
21
+ Provides-Extra: mcp
22
+ Requires-Dist: mcp>=1.0.0; extra == "mcp"
18
23
  Dynamic: license-file
19
24
 
20
25
  # bdshare
@@ -44,6 +49,7 @@ Dynamic: license-file
44
49
  - [Error Handling](#error-handling)
45
50
  - [API Reference](#api-reference)
46
51
  - [Examples](#examples)
52
+ - [Using bdshare with AI Agents (MCP Server)](#using-bdshare-with-ai-agents-mcp-server)
47
53
  - [Contributing](#contributing)
48
54
  - [Roadmap](#roadmap)
49
55
  - [Disclaimer](#disclaimer)
@@ -71,14 +77,14 @@ Dependencies installed automatically: `pandas`, `requests`, `beautifulsoup4`, `l
71
77
  ## Quick Start
72
78
 
73
79
  ```python
74
- from bdshare import get_current_trade_data, get_hist_data
80
+ from bdshare import get_current_trade_data, get_historical_data
75
81
 
76
82
  # Live prices for all instruments
77
83
  df = get_current_trade_data()
78
84
  print(df.head())
79
85
 
80
86
  # Historical data for a specific symbol
81
- df = get_hist_data('2024-01-01', '2024-01-31', 'GP')
87
+ df = get_historical_data('2024-01-01', '2024-01-31', 'GP')
82
88
  print(df.head())
83
89
  ```
84
90
 
@@ -130,7 +136,7 @@ print(codes['symbol'].tolist())
130
136
  ### Historical Data
131
137
 
132
138
  ```python
133
- from bdshare import get_hist_data, get_basic_hist_data, get_close_price_data
139
+ from bdshare import get_historical_data, get_basic_historical_data, get_close_price_data
134
140
  import datetime as dt
135
141
 
136
142
  start = '2024-01-01'
@@ -138,39 +144,46 @@ end = '2024-03-31'
138
144
 
139
145
  # Full historical data (ltp, open, high, low, close, volume, trade, value…)
140
146
  # Indexed by date, sorted newest-first
141
- df = get_hist_data(start, end, 'ACI')
147
+ df = get_historical_data(start, end, 'ACI')
142
148
 
143
149
  # Simplified OHLCV — sorted oldest-first, ready for TA libraries
144
- df = get_basic_hist_data(start, end, 'ACI')
150
+ df = get_basic_historical_data(start, end, 'ACI')
145
151
 
146
152
  # Set date as index explicitly
147
- df = get_basic_hist_data(start, end, 'ACI', index='date')
153
+ df = get_basic_historical_data(start, end, 'ACI', index='date')
148
154
 
149
155
  # Rolling 2-year window
150
156
  end = dt.date.today()
151
157
  start = end - dt.timedelta(days=2 * 365)
152
- df = get_basic_hist_data(str(start), str(end), 'GP')
158
+ df = get_basic_historical_data(str(start), str(end), 'GP')
153
159
 
154
160
  # Close prices only
155
161
  df = get_close_price_data(start, end, 'ACI')
156
162
  ```
157
163
 
158
- > **Column order note:** `get_basic_hist_data` intentionally returns OHLCV in standard order
164
+ > **Column order note:** `get_basic_historical_data` intentionally returns OHLCV in standard order
159
165
  > (`open`, `high`, `low`, `close`, `volume`) to be compatible with libraries like `ta`, `pandas-ta`, and `backtrader`.
166
+ >
167
+ > **Deprecated aliases:** `get_hist_data()` and `get_basic_hist_data()` still work but emit a
168
+ > `DeprecationWarning` — migrate to `get_historical_data()` / `get_basic_historical_data()`.
160
169
 
161
170
  ### Market & Index Data
162
171
 
163
172
  ```python
164
173
  from bdshare import (
174
+ get_market_status,
165
175
  get_market_info,
166
176
  get_market_info_more_data,
167
177
  get_market_depth_data,
168
178
  get_latest_pe,
169
- get_sector_performance,
170
- get_top_gainers_losers,
179
+ get_top_ten_gainers_losers,
180
+ get_top_twenty_shares,
171
181
  get_company_info,
172
182
  )
173
183
 
184
+ # Current market status: Open, Closed, Holiday, etc.
185
+ status = get_market_status()
186
+
174
187
  # Last 30 days of market summary (DSEX, DSES, DS30, DGEN, volumes, market cap)
175
188
  df = get_market_info()
176
189
 
@@ -183,11 +196,11 @@ df = get_market_depth_data('ACI')
183
196
  # P/E ratios for all listed companies
184
197
  df = get_latest_pe()
185
198
 
186
- # Sector-wise performance
187
- df = get_sector_performance()
188
-
189
199
  # Top 10 gainers and losers (adjust limit as needed)
190
- df = get_top_gainers_losers(limit=10)
200
+ df = get_top_ten_gainers_losers(limit=10)
201
+
202
+ # Top 20 shares by traded volume (adjust limit as needed)
203
+ df = get_top_twenty_shares(limit=20)
191
204
 
192
205
  # Detailed company profile
193
206
  tables = get_company_info('GP')
@@ -213,13 +226,13 @@ df = get_all_news('2024-01-01', '2024-03-31', 'GP') # Filtered by date + symbol
213
226
  ### Saving to CSV
214
227
 
215
228
  ```python
216
- from bdshare import get_basic_hist_data, Store
229
+ from bdshare import get_basic_historical_data, Store
217
230
  import datetime as dt
218
231
 
219
232
  end = dt.date.today()
220
233
  start = end - dt.timedelta(days=365)
221
234
 
222
- df = get_basic_hist_data(str(start), str(end), 'GP')
235
+ df = get_basic_historical_data(str(start), str(end), 'GP')
223
236
  Store(df).save() # saves to current directory as a CSV
224
237
  ```
225
238
 
@@ -249,9 +262,11 @@ bd.get_market_summary() # DSEX/DSES/DS30 indices + stats (1-
249
262
  bd.get_company_profile('ACI') # Company profile (1-hr TTL)
250
263
  bd.get_latest_pe_ratios() # All P/E ratios (1-hr TTL)
251
264
  bd.get_top_movers(limit=10) # Top gainers/losers (5-min TTL)
252
- bd.get_sector_performance() # Sector breakdown (5-min TTL)
253
265
  ```
254
266
 
267
+ `get_market_status()` and `get_top_twenty_shares()` don't have `BDShare` wrapper methods yet —
268
+ call the module-level functions directly (see [API Reference](#api-reference)).
269
+
255
270
  ### Trading methods
256
271
 
257
272
  ```python
@@ -313,22 +328,26 @@ Common causes of `BDShareError`:
313
328
  | `get_current_trade_data(symbol?)` | `symbol: str` | DataFrame | Live prices (all or one symbol) |
314
329
  | `get_dsex_data(symbol?)` | `symbol: str` | DataFrame | DSEX index entries |
315
330
  | `get_current_trading_code()` | — | DataFrame | All tradeable symbols |
316
- | `get_hist_data(start, end, code?)` | `str, str, str` | DataFrame | Full historical OHLCV |
317
- | `get_basic_hist_data(start, end, code?, index?)` | `str, str, str, str` | DataFrame | Simplified OHLCV (TA-ready) |
331
+ | `get_historical_data(start, end, code?)` | `str, str, str` | DataFrame | Full historical OHLCV |
332
+ | `get_basic_historical_data(start, end, code?, index?)` | `str, str, str, str` | DataFrame | Simplified OHLCV (TA-ready) |
318
333
  | `get_close_price_data(start, end, code?)` | `str, str, str` | DataFrame | Close + prior close |
319
334
  | `get_last_trade_price_data()` | — | DataFrame | Last trade from DSE text file |
320
335
 
336
+ Deprecated aliases (removed in 2.0.0): `get_hist_data()` → `get_historical_data()`,
337
+ `get_basic_hist_data()` → `get_basic_historical_data()`.
338
+
321
339
  ### Market Functions
322
340
 
323
341
  | Function | Parameters | Returns | Description |
324
342
  |---|---|---|---|
343
+ | `get_market_status()` | — | str | Current market status (Open, Closed, Holiday, etc.) |
325
344
  | `get_market_info()` | — | DataFrame | 30-day market summary |
326
345
  | `get_market_info_more_data(start, end)` | `str, str` | DataFrame | Historical market summary |
327
346
  | `get_market_depth_data(symbol)` | `str` | DataFrame | Order book (buy/sell depth) |
328
347
  | `get_latest_pe()` | — | DataFrame | P/E ratios for all companies |
329
348
  | `get_company_info(symbol)` | `str` | list[DataFrame] | Detailed company tables |
330
- | `get_sector_performance()` | — | DataFrame | Sector-wise performance |
331
- | `get_top_gainers_losers(limit?)` | `int` (default 10) | DataFrame | Top movers |
349
+ | `get_top_ten_gainers_losers(limit?)` | `int` (default 10) | DataFrame | Top movers by price change |
350
+ | `get_top_twenty_shares(limit?)` | `int` (default 20) | DataFrame | Top shares by traded volume |
332
351
 
333
352
  ### News Functions
334
353
 
@@ -420,13 +439,83 @@ with BDShare() as bd:
420
439
  ### Fetch and screen top gainers above 5 %
421
440
 
422
441
  ```python
423
- from bdshare import get_top_gainers_losers
442
+ from bdshare import get_top_ten_gainers_losers
424
443
 
425
- df = get_top_gainers_losers(limit=20)
444
+ df = get_top_ten_gainers_losers(limit=20)
426
445
  big_movers = df[df['change'] > 5]
427
- print(big_movers[['symbol', 'ltp', 'change']])
446
+ print(big_movers[['symbol', 'close', 'change']])
447
+ ```
448
+
449
+ ---
450
+
451
+ ## Using bdshare with AI Agents (MCP Server)
452
+
453
+ bdshare ships an [MCP](https://modelcontextprotocol.io/) server so AI agents running in
454
+ **another program** — Claude Desktop, Claude Code, or any other MCP-compatible client —
455
+ can call live DSE data as tools, without you writing any glue code.
456
+
457
+ ### Install
458
+
459
+ ```bash
460
+ pip install "bdshare[mcp]"
461
+ ```
462
+
463
+ ### Run
464
+
465
+ ```bash
466
+ bdshare-mcp
467
+ # or
468
+ python -m bdshare.mcp_server
469
+ ```
470
+
471
+ By default it speaks MCP over stdio, which is what desktop/CLI agent clients expect.
472
+
473
+ ### Connect it to a client
474
+
475
+ **Claude Code:**
476
+
477
+ ```bash
478
+ claude mcp add bdshare -- bdshare-mcp
479
+ ```
480
+
481
+ **Claude Desktop** (`claude_desktop_config.json`):
482
+
483
+ ```json
484
+ {
485
+ "mcpServers": {
486
+ "bdshare": {
487
+ "command": "bdshare-mcp"
488
+ }
489
+ }
490
+ }
428
491
  ```
429
492
 
493
+ Any other MCP client is configured the same way — point it at the `bdshare-mcp` command
494
+ (or `python -m bdshare.mcp_server`), stdio transport.
495
+
496
+ ### What the agent gets
497
+
498
+ 15 tools covering the same data this README documents — `market_status`,
499
+ `market_summary`, `market_summary_range`, `market_depth`, `latest_pe_ratios`,
500
+ `top_ten_gainers_losers`, `top_twenty_shares`, `company_info`, `current_trades`,
501
+ `dsex_index`, `trading_codes`, `historical_data`, `basic_historical_data`, `news`,
502
+ `agm_news`. Each tool returns JSON — `DataFrame`s are converted to lists of row
503
+ records — and a `BDShareError` (bad symbol, DSE outage, parse failure) surfaces as a
504
+ clean tool error message instead of a raw traceback.
505
+
506
+ ### Notes for agent use
507
+
508
+ - **No caching in the MCP server itself.** Every tool call scrapes dsebd.org live. If
509
+ your agent calls the same tool repeatedly in one turn (e.g. checking a price several
510
+ times), consider fronting it with the `BDShare` client's caching in a custom
511
+ wrapper — the bundled server intentionally stays stateless and simple.
512
+ - **Rate limits are the agent's responsibility.** The `BDShare` OOP client has a
513
+ built-in 5 calls/second limiter; the MCP tools call the plain module-level functions,
514
+ which don't. Avoid tight loops of tool calls.
515
+ - Source: [`bdshare/mcp_server.py`](bdshare/mcp_server.py) — a plain
516
+ [`FastMCP`](https://github.com/modelcontextprotocol/python-sdk) server, easy to fork
517
+ if you want a different tool surface.
518
+
430
519
  ---
431
520
 
432
521
  ## Contributing
@@ -456,6 +545,7 @@ Please open an issue before submitting a pull request for significant changes. S
456
545
  - [x] `BDShareError` for clean error handling
457
546
  - [x] Unified `get_news()` dispatcher
458
547
  - [x] Rate limiter and response caching
548
+ - [x] MCP server for AI agent integration
459
549
 
460
550
  ---
461
551
 
@@ -482,6 +572,31 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
482
572
  Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
483
573
 
484
574
  ---
575
+ ## [1.2.2] - 2026-07-22
576
+
577
+ ### Added
578
+ - Optional `as_polars=True` parameter across all data-fetching functions to return `polars.DataFrame` instead of `pandas.DataFrame` (requires `pip install bdshare[polars]`)
579
+ - `get_market_status()` — current market status (Open, Closed, Holiday, etc.)
580
+ - `get_top_twenty_shares()` — top twenty shares by traded volume
581
+ - MCP ([Model Context Protocol](https://modelcontextprotocol.io/)) server (`bdshare/mcp_server.py`) exposing 15 tools so AI agents (Claude Desktop, Claude Code, etc.) can call live DSE data directly; install with `pip install bdshare[mcp]`, run with `bdshare-mcp`
582
+
583
+ ### Changed
584
+ - Renamed `get_top_gainers_losers()` → `get_top_ten_gainers_losers()`; returned columns changed from `symbol, ltp, change` to `symbol, close, high, low, ycp, change`
585
+
586
+ ### Removed
587
+ - `get_sector_performance()` (module function and `BDShare.get_sector_performance()`) — no aliased replacement; use `get_top_twenty_shares()` instead
588
+
589
+ ### Fixed
590
+ - Bundled the missing Sectigo DV R36 intermediate certificate so requests to dsebd.org verify correctly instead of relying on an incomplete chain
591
+ - Corrected `DSE_ALT_URL` fallback domain to `dse.com.bd`
592
+ - `get_corporate_announcements()` and `get_price_sensitive_news()` always raised `BDShareError` — the row parser assumed each news item was one `<tr>` with 4 `<td>`s, but DSE renders each field (`Trading Code:`, `News Title:`, `News:`, `Post Date:`) as its own `<th>`/`<td>` row pair
593
+ - `as_polars=True` could crash with `unexpected value while building Series of type String; found value of type Float64: NaN` on tables mixing strings and missing values (e.g. `get_company_info()`); NaN now converts to a proper polars null instead
594
+ - Corrected `usage.rst`/README documentation that had `get_historical_data()`/`get_basic_historical_data()` mislabeled as the deprecated aliases — `get_hist_data()`/`get_basic_hist_data()` are the deprecated ones
595
+
596
+ ## [1.2.1] - 2026-02-22
597
+
598
+ ### Added
599
+ - Added code filter on market index
485
600
 
486
601
  ## [1.2.0] - 2026-02-21
487
602
 
@@ -25,6 +25,7 @@
25
25
  - [Error Handling](#error-handling)
26
26
  - [API Reference](#api-reference)
27
27
  - [Examples](#examples)
28
+ - [Using bdshare with AI Agents (MCP Server)](#using-bdshare-with-ai-agents-mcp-server)
28
29
  - [Contributing](#contributing)
29
30
  - [Roadmap](#roadmap)
30
31
  - [Disclaimer](#disclaimer)
@@ -52,14 +53,14 @@ Dependencies installed automatically: `pandas`, `requests`, `beautifulsoup4`, `l
52
53
  ## Quick Start
53
54
 
54
55
  ```python
55
- from bdshare import get_current_trade_data, get_hist_data
56
+ from bdshare import get_current_trade_data, get_historical_data
56
57
 
57
58
  # Live prices for all instruments
58
59
  df = get_current_trade_data()
59
60
  print(df.head())
60
61
 
61
62
  # Historical data for a specific symbol
62
- df = get_hist_data('2024-01-01', '2024-01-31', 'GP')
63
+ df = get_historical_data('2024-01-01', '2024-01-31', 'GP')
63
64
  print(df.head())
64
65
  ```
65
66
 
@@ -111,7 +112,7 @@ print(codes['symbol'].tolist())
111
112
  ### Historical Data
112
113
 
113
114
  ```python
114
- from bdshare import get_hist_data, get_basic_hist_data, get_close_price_data
115
+ from bdshare import get_historical_data, get_basic_historical_data, get_close_price_data
115
116
  import datetime as dt
116
117
 
117
118
  start = '2024-01-01'
@@ -119,39 +120,46 @@ end = '2024-03-31'
119
120
 
120
121
  # Full historical data (ltp, open, high, low, close, volume, trade, value…)
121
122
  # Indexed by date, sorted newest-first
122
- df = get_hist_data(start, end, 'ACI')
123
+ df = get_historical_data(start, end, 'ACI')
123
124
 
124
125
  # Simplified OHLCV — sorted oldest-first, ready for TA libraries
125
- df = get_basic_hist_data(start, end, 'ACI')
126
+ df = get_basic_historical_data(start, end, 'ACI')
126
127
 
127
128
  # Set date as index explicitly
128
- df = get_basic_hist_data(start, end, 'ACI', index='date')
129
+ df = get_basic_historical_data(start, end, 'ACI', index='date')
129
130
 
130
131
  # Rolling 2-year window
131
132
  end = dt.date.today()
132
133
  start = end - dt.timedelta(days=2 * 365)
133
- df = get_basic_hist_data(str(start), str(end), 'GP')
134
+ df = get_basic_historical_data(str(start), str(end), 'GP')
134
135
 
135
136
  # Close prices only
136
137
  df = get_close_price_data(start, end, 'ACI')
137
138
  ```
138
139
 
139
- > **Column order note:** `get_basic_hist_data` intentionally returns OHLCV in standard order
140
+ > **Column order note:** `get_basic_historical_data` intentionally returns OHLCV in standard order
140
141
  > (`open`, `high`, `low`, `close`, `volume`) to be compatible with libraries like `ta`, `pandas-ta`, and `backtrader`.
142
+ >
143
+ > **Deprecated aliases:** `get_hist_data()` and `get_basic_hist_data()` still work but emit a
144
+ > `DeprecationWarning` — migrate to `get_historical_data()` / `get_basic_historical_data()`.
141
145
 
142
146
  ### Market & Index Data
143
147
 
144
148
  ```python
145
149
  from bdshare import (
150
+ get_market_status,
146
151
  get_market_info,
147
152
  get_market_info_more_data,
148
153
  get_market_depth_data,
149
154
  get_latest_pe,
150
- get_sector_performance,
151
- get_top_gainers_losers,
155
+ get_top_ten_gainers_losers,
156
+ get_top_twenty_shares,
152
157
  get_company_info,
153
158
  )
154
159
 
160
+ # Current market status: Open, Closed, Holiday, etc.
161
+ status = get_market_status()
162
+
155
163
  # Last 30 days of market summary (DSEX, DSES, DS30, DGEN, volumes, market cap)
156
164
  df = get_market_info()
157
165
 
@@ -164,11 +172,11 @@ df = get_market_depth_data('ACI')
164
172
  # P/E ratios for all listed companies
165
173
  df = get_latest_pe()
166
174
 
167
- # Sector-wise performance
168
- df = get_sector_performance()
169
-
170
175
  # Top 10 gainers and losers (adjust limit as needed)
171
- df = get_top_gainers_losers(limit=10)
176
+ df = get_top_ten_gainers_losers(limit=10)
177
+
178
+ # Top 20 shares by traded volume (adjust limit as needed)
179
+ df = get_top_twenty_shares(limit=20)
172
180
 
173
181
  # Detailed company profile
174
182
  tables = get_company_info('GP')
@@ -194,13 +202,13 @@ df = get_all_news('2024-01-01', '2024-03-31', 'GP') # Filtered by date + symbol
194
202
  ### Saving to CSV
195
203
 
196
204
  ```python
197
- from bdshare import get_basic_hist_data, Store
205
+ from bdshare import get_basic_historical_data, Store
198
206
  import datetime as dt
199
207
 
200
208
  end = dt.date.today()
201
209
  start = end - dt.timedelta(days=365)
202
210
 
203
- df = get_basic_hist_data(str(start), str(end), 'GP')
211
+ df = get_basic_historical_data(str(start), str(end), 'GP')
204
212
  Store(df).save() # saves to current directory as a CSV
205
213
  ```
206
214
 
@@ -230,9 +238,11 @@ bd.get_market_summary() # DSEX/DSES/DS30 indices + stats (1-
230
238
  bd.get_company_profile('ACI') # Company profile (1-hr TTL)
231
239
  bd.get_latest_pe_ratios() # All P/E ratios (1-hr TTL)
232
240
  bd.get_top_movers(limit=10) # Top gainers/losers (5-min TTL)
233
- bd.get_sector_performance() # Sector breakdown (5-min TTL)
234
241
  ```
235
242
 
243
+ `get_market_status()` and `get_top_twenty_shares()` don't have `BDShare` wrapper methods yet —
244
+ call the module-level functions directly (see [API Reference](#api-reference)).
245
+
236
246
  ### Trading methods
237
247
 
238
248
  ```python
@@ -294,22 +304,26 @@ Common causes of `BDShareError`:
294
304
  | `get_current_trade_data(symbol?)` | `symbol: str` | DataFrame | Live prices (all or one symbol) |
295
305
  | `get_dsex_data(symbol?)` | `symbol: str` | DataFrame | DSEX index entries |
296
306
  | `get_current_trading_code()` | — | DataFrame | All tradeable symbols |
297
- | `get_hist_data(start, end, code?)` | `str, str, str` | DataFrame | Full historical OHLCV |
298
- | `get_basic_hist_data(start, end, code?, index?)` | `str, str, str, str` | DataFrame | Simplified OHLCV (TA-ready) |
307
+ | `get_historical_data(start, end, code?)` | `str, str, str` | DataFrame | Full historical OHLCV |
308
+ | `get_basic_historical_data(start, end, code?, index?)` | `str, str, str, str` | DataFrame | Simplified OHLCV (TA-ready) |
299
309
  | `get_close_price_data(start, end, code?)` | `str, str, str` | DataFrame | Close + prior close |
300
310
  | `get_last_trade_price_data()` | — | DataFrame | Last trade from DSE text file |
301
311
 
312
+ Deprecated aliases (removed in 2.0.0): `get_hist_data()` → `get_historical_data()`,
313
+ `get_basic_hist_data()` → `get_basic_historical_data()`.
314
+
302
315
  ### Market Functions
303
316
 
304
317
  | Function | Parameters | Returns | Description |
305
318
  |---|---|---|---|
319
+ | `get_market_status()` | — | str | Current market status (Open, Closed, Holiday, etc.) |
306
320
  | `get_market_info()` | — | DataFrame | 30-day market summary |
307
321
  | `get_market_info_more_data(start, end)` | `str, str` | DataFrame | Historical market summary |
308
322
  | `get_market_depth_data(symbol)` | `str` | DataFrame | Order book (buy/sell depth) |
309
323
  | `get_latest_pe()` | — | DataFrame | P/E ratios for all companies |
310
324
  | `get_company_info(symbol)` | `str` | list[DataFrame] | Detailed company tables |
311
- | `get_sector_performance()` | — | DataFrame | Sector-wise performance |
312
- | `get_top_gainers_losers(limit?)` | `int` (default 10) | DataFrame | Top movers |
325
+ | `get_top_ten_gainers_losers(limit?)` | `int` (default 10) | DataFrame | Top movers by price change |
326
+ | `get_top_twenty_shares(limit?)` | `int` (default 20) | DataFrame | Top shares by traded volume |
313
327
 
314
328
  ### News Functions
315
329
 
@@ -401,13 +415,83 @@ with BDShare() as bd:
401
415
  ### Fetch and screen top gainers above 5 %
402
416
 
403
417
  ```python
404
- from bdshare import get_top_gainers_losers
418
+ from bdshare import get_top_ten_gainers_losers
405
419
 
406
- df = get_top_gainers_losers(limit=20)
420
+ df = get_top_ten_gainers_losers(limit=20)
407
421
  big_movers = df[df['change'] > 5]
408
- print(big_movers[['symbol', 'ltp', 'change']])
422
+ print(big_movers[['symbol', 'close', 'change']])
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Using bdshare with AI Agents (MCP Server)
428
+
429
+ bdshare ships an [MCP](https://modelcontextprotocol.io/) server so AI agents running in
430
+ **another program** — Claude Desktop, Claude Code, or any other MCP-compatible client —
431
+ can call live DSE data as tools, without you writing any glue code.
432
+
433
+ ### Install
434
+
435
+ ```bash
436
+ pip install "bdshare[mcp]"
437
+ ```
438
+
439
+ ### Run
440
+
441
+ ```bash
442
+ bdshare-mcp
443
+ # or
444
+ python -m bdshare.mcp_server
409
445
  ```
410
446
 
447
+ By default it speaks MCP over stdio, which is what desktop/CLI agent clients expect.
448
+
449
+ ### Connect it to a client
450
+
451
+ **Claude Code:**
452
+
453
+ ```bash
454
+ claude mcp add bdshare -- bdshare-mcp
455
+ ```
456
+
457
+ **Claude Desktop** (`claude_desktop_config.json`):
458
+
459
+ ```json
460
+ {
461
+ "mcpServers": {
462
+ "bdshare": {
463
+ "command": "bdshare-mcp"
464
+ }
465
+ }
466
+ }
467
+ ```
468
+
469
+ Any other MCP client is configured the same way — point it at the `bdshare-mcp` command
470
+ (or `python -m bdshare.mcp_server`), stdio transport.
471
+
472
+ ### What the agent gets
473
+
474
+ 15 tools covering the same data this README documents — `market_status`,
475
+ `market_summary`, `market_summary_range`, `market_depth`, `latest_pe_ratios`,
476
+ `top_ten_gainers_losers`, `top_twenty_shares`, `company_info`, `current_trades`,
477
+ `dsex_index`, `trading_codes`, `historical_data`, `basic_historical_data`, `news`,
478
+ `agm_news`. Each tool returns JSON — `DataFrame`s are converted to lists of row
479
+ records — and a `BDShareError` (bad symbol, DSE outage, parse failure) surfaces as a
480
+ clean tool error message instead of a raw traceback.
481
+
482
+ ### Notes for agent use
483
+
484
+ - **No caching in the MCP server itself.** Every tool call scrapes dsebd.org live. If
485
+ your agent calls the same tool repeatedly in one turn (e.g. checking a price several
486
+ times), consider fronting it with the `BDShare` client's caching in a custom
487
+ wrapper — the bundled server intentionally stays stateless and simple.
488
+ - **Rate limits are the agent's responsibility.** The `BDShare` OOP client has a
489
+ built-in 5 calls/second limiter; the MCP tools call the plain module-level functions,
490
+ which don't. Avoid tight loops of tool calls.
491
+ - Source: [`bdshare/mcp_server.py`](bdshare/mcp_server.py) — a plain
492
+ [`FastMCP`](https://github.com/modelcontextprotocol/python-sdk) server, easy to fork
493
+ if you want a different tool surface.
494
+
411
495
  ---
412
496
 
413
497
  ## Contributing
@@ -437,6 +521,7 @@ Please open an issue before submitting a pull request for significant changes. S
437
521
  - [x] `BDShareError` for clean error handling
438
522
  - [x] Unified `get_news()` dispatcher
439
523
  - [x] Rate limiter and response caching
524
+ - [x] MCP server for AI agent integration
440
525
 
441
526
  ---
442
527