Commit 02b92e82 authored by xeron56's avatar xeron56

Refactor repository docstring, add DGT dependencies, and implement tests for DGT forecasting

- Updated the docstring in repository.py for clarity.
- Added new dependencies for DGT in pyproject.toml.
- Created a new test file for DGT forecasting with comprehensive tests covering market graph alignment, graph prior normalization, model predictions, and end-to-end run validation.
parent 1a941ef5
...@@ -412,6 +412,30 @@ and skill versus a last-price baseline. A positive-looking headline metric does ...@@ -412,6 +412,30 @@ and skill versus a last-price baseline. A positive-looking headline metric does
not prove useful predictive skill; compare the forecast with the reported naive not prove useful predictive skill; compare the forecast with the reported naive
baseline before relying on it. baseline before relying on it.
### Differential Graph Transformer forecasting
The DGT command uses the same authenticated DSE candle service and the same
prediction dashboard. Unlike TimesFM, it trains a small model for each run and
can learn from a target stock plus related DSE securities. It saves a real vs.
predicted holdout CSV, a future CSV, a chart, and a reusable PyTorch checkpoint.
```bash
pip install -e '.[dgt]'
dohasecuritiesstockai-dgt-predict GP \
--resolution 1d \
--lookback 2y \
--peers DSEX,BRACBANK,SQURPHARMA \
--future-steps 12 \
--open-ui
```
The evaluation graph, scaler, and model use only data before the validation and
holdout periods. The holdout forecast is recursive, so its real-price comparison
has no future-price leakage. After scoring, a separate deployment model is refit
on all available real bars for the future forecast; use `--no-refit` to disable
that final step.
## Important limitations ## Important limitations
- LLM output is non-deterministic and can differ between otherwise identical - LLM output is non-deterministic and can differ between otherwise identical
......
আমি `SQURPHARMA` (Square Pharmaceuticals PLC.) এর জন্য প্রয়োজনীয় সকল তথ্য সংগৃহীত করেছি। এখন বিস্তৃত ফান্ডামেন্টাল বিশ্লেষণ রিপোর্ট তৈরি করছি।
---
# `SQURPHARMA` — Square Pharmaceuticals PLC. — ফান্ডামেন্টাল বিশ্লেষণ রিপোর্ট
**বিশ্লেষণ তারিখ:** 2026-08-10 | **কারেন্সি:** BDT (যেখানে প্রযোজ্য) | **বিনিময়:** ঢাকা স্টক এক্সচেঞ্জ (DSE)
---
## ১. কোম্পানি পরিচিতি (Company Identity)
| খাত | তথ্য |
|------|------|
| কোম্পানির নাম | Square Pharmaceuticals PLC. |
| ট্রেডিং কোড | `SQURPHARMA` |
| সেক্টর | Pharmaceuticals & Chemicals |
| যন্ত্রের ধরন | Equity |
| মার্কেট ক্যাটাগরি | A |
| লিস্টিং বছর | 1995 |
| অনুমোদিত মূলধন (Authorized Capital) | 10,000.00 (প্রোফাইল অনুযায়ী) |
| পরিশোধিত মূলধন (Paid-up Capital) | 8,864.51 (প্রোফাইল অনুযায়ী); ব্যালেন্স শিটে **Share Capital = 8,864,510,100 BDT** |
| মুখ্য মূল্য (Face Value) | 10.00 |
| মোট প্রচলিত সিকিউরিটিজ | 886,451,010 শেয়ার |
| ইলেকট্রনিক শেয়ার | Y |
| হিসাববছর সমাপ্তি | 30 জুন |
| সর্বশেষ AGM | 2025-12-15 |
| ৫২ সপ্তাহের দর রেঞ্জ | 198.00 – 236.00 |
> **সতর্কতা:** প্রোফাইলে প্রদত্ত paid-up capital (8,864.51) ব্যালেন্স শিটের Share Capital (8,864,510,100 BDT) এর সাথে প্রত্যক্ষভাবে মিলছে না; একক/স্কেলের ভিন্নতার সম্ভাবনা। ব্যালেন্স শিটের মান (BDT) নির্ভরযোগ্য হিসেবে বিবেচিত হয়েছে।
---
## ২. আর্থিক পারফরম্যান্স ও ইতিহাস (Financial Performance & History)
### বার্ষিক পারফরম্যান্স (Annual Performance)
| বছর | EPS (বেসিক) | NAV/শেয়ার | নিট মুনাফা (BDT মিলিয়ন) | P/E |
|------|------|------|------|------|
| 2019 | 16.03 | 86.03 | 12,645.72 | 14.68 |
| 2020 | 15.82 | 91.57 | 13,354.41 | 10.38 |
| 2021 | 17.99 | 102.54 | 15,947.45 | 11.98 |
| 2022 | 20.51 | 116.70 | 18,176.74 | 10.57 |
| 2023 | 21.41 | 129.95 | 18,980.14 | 9.80 |
| 2024 | 23.61 | 142.05 | 20,927.45 | 8.93 |
| 2025 | 27.04 | 157.88 | 23,967.97 | 7.73 |
**ট্রেন্ড:** 2019 থেকে 2025 পর্যন্ত EPS, NAV এবং নিট মুনাফা — তিনটিই ধারাবাহিকভাবে বৃদ্ধি পেয়েছে। নিট মুনাফা 2019-এর 12,645.72 মিলিয়ন BDT থেকে 2025-এ 23,967.97 মিলিয়ন BDT-তে (~৮৯% বৃদ্ধি) পৌঁছেছে। P/E অনুপাত 14.68 থেকে কমে 7.73 হয়েছে, যা শক্তিশালী আয় বৃদ্ধি নির্দেশ করে।
### কোয়ার্টারলি পারফরম্যান্স — FY 2026 (চলমান)
| কোয়ার্টার | তারিখ | EPS | NAV/শেয়ার | কামulative মুনাফা (BDT) |
|------|------|------|------|------|
| Q1 | 2025-09-01 | 8.35 | 167.50 | 7,401,865,933.50 |
| Q2 | 2025-12-01 | 8.20 | 162.41 | 14,679,628,725.60 |
| Half Yearly | 2025-12-01 | 16.56 | — | — |
| Q3 | 2026-03-01 | 6.73 | 169.79 | 20,645,444,022.90 |
| 9 Months | 2026-03-01 | 23.29 | — | — |
**পর্যবেক্ষণ:** FY2026-এর ৯ মাসে EPS 23.29, যা FY2025-এর ৯ মাসের (21.15) তুলনায় উচ্চতর — আয়-বৃদ্ধির গতি বজায় আছে। Q3-তে NAV 169.79-এ পৌঁছেছে (প্রোফাইলের NAV/বছর 2026-এর সর্বশেষ মান)।
---
## ৩. মূলধন কাঠামো (Capital Structure)
ব্যালেন্স শিটের (২০২৪, BDT) মূল উপাদান:
| উপাদান | 2024 (BDT) |
|------|------|
| মোট সম্পদ (Total Assets) | 132,637,197,060 |
| মোট শেয়ারহোল্ডার ইকুইটি | 125,921,620,832 |
| শেয়ার ক্যাপিটাল | 8,864,510,100 |
| ধার্যকৃত আয় (Retained Earnings) | 114,139,071,906 |
| নগদ ও নগদ সমতুল্য | 52,013,459,742 |
| ইনভেন্টরি | 12,582,152,295 |
| বাণিজ্য দেনাদার (Trade Debtors) | 4,503,386,212 |
| মোট কারেন্ট দায় | 5,281,954,879 |
| মোট নন-কারেন্ট দায় | 1,433,621,349 |
**ভারসাম্য:** কোম্পানিটি অত্যন্ত শক্তিশালী ইকুইটি-ভিত্তিক কাঠামোয় পরিচালিত। মোট দায় অত্যন্ত কম এবং বিপুল নগদ ও বাজারে ব্যবসাযোগ্য সিকিউরিটিজ (9,292,402,647) ধারণ করছে, যা আর্থিক সুস্থতার স্পষ্ট নির্দেশক।
### ঋণ অবস্থা (Loan Status) — 2024-10-17
| ধরন | পরিমাণ (BDT) |
|------|------|
| স্বল্পমেয়াদী ঋণ | 625.50 (মিলিয়ন BDT) |
| দীর্ঘমেয়াদী ঋণ | 200.00 (মিলিয়ন BDT) |
কোম্পানির ঋণের বোঝা অত্যন্ত নগণ্য — ইকুইটি 125.9 বিলিয়ন BDT-এর বিপরীতে ঋণ মাত্র ~825 মিলিয়ন BDT।
---
## ৪. মালিকানা কাঠামো (Ownership / Shareholding)
সর্বশেষ (2026-05-31) শেয়ারহোল্ডিং:
| শ্রেণি | শতাংশ |
|------|------|
| স্পনসর/পরিচালক | 44.15% |
| প্রাতিষ্ঠানিক | 13.81% |
| বিদেশি | 14.81% |
| সাধারণ জনগণ | 27.23% |
| সরকার | 0.00% |
**ট্রেন্ড:** স্পনসর/পরিচালক হোল্ডিং 2023-এ 34.67% থেকে ক্রমাগত বেড়ে 2026-এর মাঝামাঝিতে 44.15% হয়েছে — এটি পরিচালকদের কোম্পানিতে আস্থা ও নিয়ন্ত্রণ সুদৃঢ়করণের ইঙ্গিত। সরকারি মালিকানা শূন্য।
---
## ৫. লভ্যাংশ নীতি (Dividends)
*লভ্যাংশের মান DSE কনভেনশন অনুযায়ী মুখ্য মূল্যের (10 BDT) শতাংশ হিসেবে দেওয়া হয়েছে।*
| বছর | নগদ লভ্যাংশ | স্টক লভ্যাংশ |
|------|------|------|
| 2019 | 42% | 7% |
| 2020 | 47% | 5% |
| 2021 | 60% | — |
| 2022 | 100% | — |
| 2023 | 105% | — |
| 2024 | 110% | — |
| 2025 | 120% | — |
**পর্যবেক্ষণ:** কোম্পানি সাম্প্রতিক বছরগুলোতে প্রায় সম্পূর্ণ নগদ লভ্যাংশ প্রদান করছে এবং নগদ লভ্যাংশ ধারাবাহিকভাবে বাড়ছে (2021-এর 60% থেকে 2025-এ 120%)। FY2025-এর 120% = 12 BDT/শেয়ার, যা EPS 27.04-এর সাপেক্ষে ~৪৪% পেআউট রেশিও। (সর্বশেষ AGM তারিখ 2025-12-15।)
---
## ৬. আর্নিংস কোয়ালিটি ও ক্যাশ ফ্লো (Earnings Quality & Cash Flow)
### NOCFPS (নিট অপারেটিং ক্যাশ ফ্লো প্রতি শেয়ার) ইতিহাস
| FY | বার্ষিক NOCFPS |
|----|------|
| 2018 | 13.57 |
| 2019 | 15.71 |
| 2022 | 14.52 |
| 2023 | 9.64 |
| 2024 | 20.90 |
| 2025 | 19.52 |
**FY2026 চলমান:** Q1 = 7.55, Q2 = 13.16, Q3 = 17.54
**পর্যবেক্ষণ:** FY2024-এ NOCFPS (20.90) EPS (23.61)-এর কাছাকাছি এবং FY2025-তে NOCFPS (19.52) EPS (27.04)-এর ~৭২% — যা আয়ের নগদ-ভিত্তিক মান ভালো নির্দেশ করে (আয় নগদ প্রবাহ দ্বারা সমর্থিত)। FY2023-এ NOCFPS (9.64) EPS (21.41)-এর তুলনায় কম ছিল, যা তখনকার কার্যকরী মূলধন ব্যবস্থাপনার প্রভাব।
**ক্রয়-সঞ্চয় সামঞ্জস্য:** বার্ষিক EPS এবং cumulative profit একে অপরের সাথে সামঞ্জস্যপূর্ণ (যেমন FY2025: EPS 27.04 × 886,451,010 শেয়ার ≈ 23,969 মিলিয়ন BDT cumulative profit)। এটি রিপোর্টিংয়ের নির্ভরযোগ্যতা নির্দেশ করে।
---
## ৭. উপাদানগত ঝুঁকি (Material Risks)
1. **কারেন্সি/আমদানি ঝুঁকি:** ফার্মাসিউটিক্যাল কোম্পানি হিসেবে কাঁচামাল আমদানির উপর নির্ভরশীল; টাকা-অবমূল্যায়ন ও বৈদেশিক মুদ্রার অস্থিরতা খরচ বাড়াতে পারে।
2. **নিয়ন্ত্রক ও ফার্মাসিউটিক্যাল নীতিগত ঝুঁকি:** ঔষধ মূল্য নিয়ন্ত্রণ, বিএসএমইসি/বিএসইসি নিয়ন্ত্রণ এবং স্থানীয় বাজারে প্রতিযোগিতার চাপ।
3. **অস্থিরতার সীমিত এক্সপোজার:** 52-সপ্তাহের রেঞ্জ 198.00–236.00; বর্তমান প্রান্তিক মূল্য ~210.80 (Q3 FY26), যা রেঞ্জের নিম্ন-মাঝামাঝি।
4. **লভ্যাংশ নির্ভর প্রত্যাশা:** উচ্চ নগদ লভ্যাংশ (120%) বজায় রাখার প্রত্যাশা ভবিষ্যতের ক্যাশ প্রবাহের উপর চাপ সৃষ্টি করতে পারে, যদিও বর্তমান নগদ অবস্থান (52 বিলিয়ন BDT) শক্তিশালী।
5. **ডেটা সুযোগ/অসম্পূর্ণতা:** DSE ক্যাশ-ফ্লো টুল শুধু কোয়ার্টারলি NOCFPS দেয়, সম্পূর্ণ ক্যাশ-ফ্লো স্টেটমেন্ট পাওয়া যায়নি; তাই অন্যান্য ক্যাশ-ফ্লো লাইন (investing/financing) অনুমান করা হয়নি।
---
## ৮. মূল মেট্রিক্সের সংক্ষিপ্ত সারণী (Summary Table)
| মেট্রিক | 2023 | 2024 | 2025 | FY2026 (9M/Q3) | ট্রেন্ড |
|------|------|------|------|------|------|
| EPS (বেসিক) | 21.41 | 23.61 | 27.04 | 23.29 (9M) | ▲ ক্রমবর্ধমান |
| NAV/শেয়ার | 129.95 | 142.05 | 157.88 | 169.79 (Q3) | ▲ ক্রমবর্ধমান |
| নিট মুনাফা (BDT মিলিয়ন) | 18,980.14 | 20,927.45 | 23,967.97 | — | ▲ ক্রমবর্ধমান |
| P/E (বার্ষিক) | 9.80 | 8.93 | 7.73 | — | ▼ (সস্তা হয়েছে) |
| NOCFPS (বার্ষিক) | 9.64 | 20.90 | 19.52 | 17.54 (Q3 FY26) | ● স্থিতিশীল |
| নগদ লভ্যাংশ (% মুখ্য মূল্যে) | 105% | 110% | 120% | — | ▲ ক্রমবর্ধমান |
| স্পনসর/পরিচালক হোল্ডিং | — | 35.46% | 43.59% | 44.15% | ▲ ক্রমবর্ধমান |
| প্রাতিষ্ঠানিক | — | 15.13% | 14.05% | 13.81% | ▼ সামান্য হ্রাস |
| বিদেশি | — | 13.76% | 15.14% | 14.81% | ● স্থিতিশীল |
| সাধারণ জনগণ | — | 35.65% | 27.22% | 27.23% | ▼ হ্রাস |
| মোট সম্পদ (BDT) | 121,816,305,166 | 132,637,197,060 | — | — | ▲ |
| শেয়ারহোল্ডার ইকুইটি (BDT) | 115,196,648,765 | 125,921,620,832 | — | — | ▲ |
| নগদ ও সমতুল্য (BDT) | 50,094,321,854 | 52,013,459,742 | — | — | ▲ |
| ঋণ (স্বল্প+দীর্ঘ, BDT মিলিয়ন) | — | 825.50 (2024-10-17) | — | — | নগণ্য |
| ৫২-সপ্তাহ দর রেঞ্জ | — | — | — | 198.00 – 236.00 | — |
### ক্যাভিয়েটস/সীমাবদ্ধতা (Caveats)
- ব্যালেন্স শিটের ডেটা FY2021–FY2024 পর্যন্ত উপলব্ধ; FY2025 সম্পূর্ণ ব্যালেন্স শিট পাওয়া যায়নি।
- সম্পূর্ণ ক্যাশ-ফ্লো স্টেটমেন্ট অনুপলব্ধ; শুধু NOCFPS (নেট অপারেটিং ক্যাশ-ফ্লো প্রতি শেয়ার) দেওয়া হয়েছে।
- প্রোফাইলের paid-up capital (8,864.51) ও ব্যালেন্স শিটের Share Capital (8,864,510,100 BDT) এককের (unit) ভিন্নতা থাকতে পারে।
- লভ্যাংশের মান DSE কনভেনশন অনুযায়ী মুখ্য মূল্যের শতাংশ হিসেবে ব্যাখ্যা করা হয়েছে।
- 2026 সালে বার্ষিক হিসাব (FY2026 শেষ 2026-06-30) এখনো স্বীকৃত হয়নি — সর্বশেষ উপলব্ধ FY2026 ডেটা ৯ মাস (2026-03-01) পর্যন্ত।
---
**সারসংক্ষেপ:** `SQURPHARMA` বাংলাদেশের শীর্ষস্থানীয় ও সবচেয়ে লাভজনক ফার্মাসিউটিক্যাল কোম্পানিগুলোর একটি। কোম্পানিটি ধারাবাহিকভাবে আয়, NAV, ক্যাশ-উৎপাদন (NOCFPS) এবং নগদ লভ্যাংশ হ্রাস-বৃদ্ধি দেখাচ্ছে, ঋণের বোঝা নগণ্য, নগদ অবস্থান বিপুল (52+ বিলিয়ন BDT), এবং পরিচালক-স্পনসর হোল্ডিং 44%-এ উন্নীত হয়েছে। P/E কমে ~7.7-এ নেমে এসেছে, যা ঐতিহাসিক স্তর থেকে সস্তা মূল্যায়ন নির্দেশ করে। FY2026-এর ৯ মাসে EPS 23.29 (FY2025-এর 9M 21.15-এর চেয়ে বেশি) আয়-বৃদ্ধি টেকসই থাকার ইঙ্গিত দেয়।
---
> **দায়বদ্ধতার সীমাবদ্ধতা দ্রষ্টব্য:** এই রিপোর্টটি প্রদত্ত API ডেটার উপর ভিত্তি করে তথ্যমূলক উদ্দেশ্যে প্রস্তুত; এটি কোনো বিনিয়োগ পরামর্শ নয়। যেসব ক্ষেত্র অনুপলব্ধ বা অসম্পূর্ণ ছিল, সেগুলো চিহ্নিত করা হয়েছে এবং অনুমান করা হয়নি।
FINAL TRANSACTION PROPOSAL: **HOLD**
\ No newline at end of file
I now have all the data needed. Let me compile the comprehensive analysis in Bangla.
---
# SQURPHARMA (স্কয়ার ফার্মাসিউটিক্যালস) — প্রযুক্তিগত বিশ্লেষণ প্রতিবেদন
**বিশ্লেষণের তারিখ:** 2026-08-10 (বর্তমান ট্রেডিং দিন)
**বাজার:** ঢাকা স্টক এক্সচেঞ্জ (DSE) | মূল্য ইউনিট: BDT
## প্রসঙ্গ ও সারসংক্ষেপ
SQURPHARMA (Square Pharmaceuticals PLC.) — ঢাকা স্টক এক্সচেঞ্জের শীর্ষস্থানীয় ফার্মাসিউটিক্যাল প্রতিষ্ঠান। এই প্রতিবেদনটি 2026-08-10 তারিখের যাচাইকৃত (verified) বাজার তথ্যের ভিত্তিতে তৈরি। প্রতিষ্ঠানটি দীর্ঘমেয়াদি মূল্যস্তরে দৃঢ়ভাবে অবস্থান করছে, কিন্তু স্বল্পমেয়াদি মোমেন্টাম দুর্বল হয়ে পড়েছে।
## বিশ্লেষণের জন্য নির্বাচিত সূচকসমূহ (Indicators)
নিম্নলিখিত ৮টি সূচক নির্বাচন করা হয়েছে, যা পরস্পর পরিপূরক তথ্য প্রদান করে এবং কোনো রিডানডেন্সি নেই:
1. **close_200_sma** – দীর্ঘমেয়াদি ট্রেন্ডের সূচক (মূল কাঠামো বোঝার জন্য)
2. **close_50_sma** – মাঝারি-মেয়াদি ট্রেন্ড ও ডায়নামিক সাপোর্ট/রেজিস্ট্যান্স
3. **close_10_ema** – স্বল্পমেয়াদি প্রতিক্রিয়াশীল মুভিং এভারেজ (দ্রুত সংকেত)
4. **macd / macds / macdh** – মোমেন্টাম শিফট ও ক্রসওভার শনাক্তকরণ
5. **rsi** – ওভারবট/ওভারসল্ড অবস্থা পরিমাপ
6. **boll / boll_ub / boll_lb** – ব্রেকআউট ও ভোলাটিলিটি ব্যান্ড
7. **atr** – পজিশন সাইজিং ও স্টপ-লস নির্ধারণ
8. **vwma** – মূল্য অ্যাকশনকে ভলিউমের সাথে যুক্ত করে ট্রেন্ড নিশ্চিতকরণ
## যাচাইকৃত মূল মানদণ্ড (Verified Data — 2026-08-10)
| সূচক | মান |
|---|---|
| সর্বশেষ ক্লোজ | **219.90** |
| Open / High / Low | 218.90 / 220.10 / 218.50 |
| close_10_ema | 219.86 |
| close_50_sma | 219.69 |
| close_200_sma | 213.44 |
| rsi | 48.73 |
| boll (মধ্যমা) | 220.80 |
| boll_ub | 224.88 |
| boll_lb | 216.72 |
| macd | -0.24 |
| macds | -0.01 |
| macdh | -0.23 |
| atr | 2.03 |
| ভলিউম | 140,479 |
## বিস্তারিত বিশ্লেষণ
### ১. দীর্ঘমেয়াদি ট্রেন্ড (close_200_sma = 213.44)
দীর্ঘমেয়াদি কাঠামো এখনও **তেজি (bullish)**। সর্বশেষ ক্লোজ 219.90, যা 200-day SMA (213.44) থেকে প্রায় **+3% উপরে**। 2026-এর প্রথমার্ধে মূল্য 200-SMA-এর উপরে স্থিরভাবে টিকে আছে। এটি দীর্ঘমেয়াদি বিনিয়োগকারীদের জন্য স্থিতিশীলতার ইঙ্গিত দেয়। তবে দীর্ঘমেয়াদি এই সমর্থন প্রতিটি পুলব্যাকে পরীক্ষিত হচ্ছে এবং বর্তমান দুর্বল মোমেন্টামে এই স্তরে গুরুত্বপূর্ণ।
### ২. মাঝারি ও স্বল্পমেয়াদি গড় (close_50_sma = 219.69, close_10_ema = 219.86)
মজার বিষয় হলো, বর্তমান মূল্য 219.90 প্রায় 50-SMA (219.69) এবং 10-EMA (219.86)-এর ঠিক উপরে অবস্থান করছে। অর্থাৎ দাম এই দুটি গুরুত্বপূর্ণ গড়ের ঠিক **সংযোগস্থলে**। স্বল্পমেয়াদি মোমেন্টাম প্রায় নিরপেক্ষ — দাম গড়ের উপরে ও নিচে ওঠানামা করছে।
২০১৫-২০২৬ সময়কালে (বিস্তৃত দৃষ্টিতে) মূল্য একটি **স্প্রেডিং নিম্নগামী প্যাটার্ন** অনুসরণ করেছে:
- 2025-08: ~230 → 2025-12: ~199 (নিম্নমুখী)
- 2026-02: ~232-এর কাছাকাছি পুনরুদ্ধার
- 2026-05: ~207 (সর্বনিম্ন স্তর)
- বর্তমান: ~220
অর্থাৎ মূল এদিকে একটি ব্রড রেঞ্জের (broad range) মধ্যে দোদুল্যমান — নিচে ~200-207 এবং উপরে ~232-236।
### ৩. মোমেন্টাম ও MACD
MACD বর্তমানে **নেতিবাচক অঞ্চলে** (macd = -0.24, macds = -0.01, macdh = -0.23)। ঐতিহাসিকভাবে:
- 2026-06/07 সময়ে MACD দৃঢ়ভাবে তেজি ছিল (+3.3 এর কাছাকাছি 06-28 এ)
- তারপর থেকে ক্রমাগত নিম্নমুখী হয়ে **07-29 তারিখে নেটিভ রেখা অতিক্রম করে** (bearish crossover)
- 07-29 থেকে -0.16 এর কাছাকাছি নেমে গিয়ে এখন -0.24
MACD-এর এই নিম্নগামী ট্রেন্ড **স্বল্পমেয়াদি নিরস (bearish) মোমেন্টাম** নিশ্চিত করে। তবে MACD-এর মান মাত্র -0.24 হওয়ায় পতনের তীব্রতা কম — এটি একটি মৃদু দুর্বলতা, তীব্র বিক্রয়চাপ নয়।
### ৪. RSI (48.73)
RSI 48.73 — অর্থাৎ **নিরপেক্ষ অঞ্চলে** (40-60)। এটি ওভারবট বা ওভারসল্ড কোনোটিই নয়। তবে গত মাসে একটি চিহ্নিত প্যাটার্ন দেখা যায়:
- 07-16 তারিখে RSI ~64.4 (সর্বোচ্চ, ওভারবটের কাছাকাছি)
- এরপর ক্রমাগত নেমে 07-29-এ ~40.2 (ওভারসল্ডের কাছাকাছি)
- তারপর পুনরুদ্ধার হয়ে 08-10-এ 48.73
RSI এখন নিরপেক্ষ থাকায় স্পষ্ট দিকনির্দেশক সংকেত দিচ্ছে না। এটি মোমেন্টামের ভারসাম্যহীন (neutral) অবস্থা নির্দেশ করে।
### ৫. বোলিঞ্জার ব্যান্ড (boll = 220.80, ub = 224.88, lb = 216.72)
- মূল্য (219.90) ব্যান্ডের **মাঝের এবং নিচের ব্যান্ডের মাঝামাঝি** অবস্থান করছে।
- মধ্যম ব্যান্ড (20-SMA) = 220.80, যা বর্তমান মূল্যের ঠিক উপরে — সামান্য নেতিবাচক চাপ।
- ব্যান্ডের প্রস্থ (width) ~8.16 (224.88 − 216.72), যা তুলনামূলকভাবে সংকুচিত। ATR কমে যাওয়া (নিচে দেখুন) এটাও নিশ্চিত করছে যে ভোলাটিলিটি সংকুচিত হচ্ছে।
- নিচের ব্যান্ড (216.72) কাছাকাছি হলে সেটি ওভারসল্ড ইঙ্গিত দেবে; কিন্তু বর্তমান মূল্য তার থেকে ~3 পয়েন্ট উপরে।
### ৬. ATR (2.03) — ভোলাটিলিটি
ATR এখন **2.03**, যা গত মাসে 2.5 থেকে ক্রমাগত কমে এসেছে। অর্থাৎ ভোলাটিলিটি স্পষ্টভাবে **সংকুচিত হচ্ছে**। কম ভোলাটিলিটির এই অবস্থা সাধারণত **ব্রেকআউটের আগে** দেখা যায়। দাম হয় উপরে (ব্যান্ড ব্রেক) অথবা নিচে দিকনির্দেশনা নিতে পারে। ATR 2.03 মানে একদিনে গড়ে ~2 BDT-এর স্বাভাবিক দামের ওঠানামা — তুলনামূলকভাবে শান্ত বাজার।
### ৭. VWMA (219.76)
VWMA = 219.76, প্রায় ক্লোজের (219.90) সমান। অর্থাৎ **ভলিউম-ভিত্তিক গড়ও মূল্যের কাছাকাছি** — ট্রেডারদের গড় ক্রয়মূল্য বর্তমান দামের সমান। এটি ট্রেন্ডের নিশ্চয়তা দেয় না, বরং ভারসাম্যহীন অবস্থা নির্দেশ করে। VWMA ক্রমাগত নিম্নমুখী (06-28-এ 220.36 থেকে 08-10-এ 219.76) — ভলিউম-ভিত্তিক মোমেন্টামও হালকা দুর্বল।
### ৮. ভলিউম বিশ্লেষণ
সর্বশেষ ভলিউম 140,479 — যা গত মাসের গড়ের তুলনায় **কম**। দাম 07-15/16-এ উচ্চতায় পৌঁছানোর সময় বেশি ভলিউম ছিল (896K-410K), কিন্তু সাম্প্রতিক দিনগুলোতে দামে টানাভাব ও ভলিউম সংকুচিত। কম ভলিউমে দুর্বল পুলব্যাক মানে স্পষ্ট বিক্রয়চাপ নেই, তবে কেনার আগ্রহও দুর্বল।
## সামগ্রিক মূল্যায়ন
**মূল চিত্র:** SQURPHARMA একটি **ব্রড রেঞ্জের (200-236)** মধ্যে ট্রেড করছে। বর্তমানে দাম রেঞ্জের মাঝামাঝি-নিম্ন অংশে (~220)।
- **দীর্ঘমেয়াদি (bullish):** 200-SMA-এর উপরে থাকা ও দৃঢ় ফার্মাসিউটিক্যাল ফান্ডামেন্টাল কাঠামো ধরে রেখেছে।
- **স্বল্পমেয়াদি (bearish/neural):** MACD নেতিবাচক, RSI নিরপেক্ষ-দুর্বল, মূল্য 50-SMA-এর ঠিক উপরে কিন্তু 10-EMA-এর সমান, VWMA নিম্নমুখী।
দাম বর্তমানে একটি **결정적 (decision point)**-এ অবস্থান করছে — 50-SMA (219.69) এবং 10-EMA (219.86)-এর সংযোগস্থলে। ATR সংকুচিত হওয়ার কারণে আসন্ন দিনগুলোতে একটি **ব্রেকআউটের সম্ভাবনা** আছে।
**সম্ভাব্য দৃশ্যপট:**
- **তেজি দৃশ্য:** যদি দাম 50/10-SMA-এর উপরে (220-221) টিকে থাকে এবং MACD ক্রসওভার উপরের দিকে হয়, তাহলে boll_ub (224.88) এবং রেঞ্জের উচ্চ প্রান্ত (~232) পর্যন্ত সম্ভাবনা।
- **নিরস দৃশ্য:** যদি 216.72 (boll_lb) ভেঙে যায় এবং ATR প্রসারিত হয়, তাহলে রেঞ্জের নিচের প্রান্ত (~207-208, যেখানে Mাণে 50-SMA ফিরে আসা সম্ভব) পর্যন্ত নামতে পারে।
**স্টপ-লস পরামর্শ (ATR ভিত্তিক):** বর্তমান ATR 2.03-এর প্রায় 1.5-2x অর্থাৎ ~3-4 পয়েন্টের স্টপ-লস ব্যবহার করা যেতে পারে। দীর্ঘমেয়াদি বিনিয়োগকারীদের জন্য নিচের সাপোর্ট 200-SMA (213.44) গুরুত্বপূর্ণ — এটির নিচে ক্লোজ হলে দীর্ঘমেয়াদি কাঠামো দুর্বল হবে।
## লেনদেন কর্মপরিকল্পনা (Actionable Insights)
1. **HOLD (স্থিতাবস্থা) মাঝারি মেয়াদে:** বর্তমান মূল্য নিরপেক্ষ অঞ্চলে, কোনো স্পষ্ট ব্রেকআউট নেই। ইতোমধ্যে অবস্থানকারীদের জন্য ধরে রাখা যুক্তিসঙ্গত।
2. **ব্রেকআউট নিশ্চিতকরণে প্রবেশ:** দাম যদি ভলিউমসহ 221+ (50/10-SMA ও VWMA-এর উপরে) অতিক্রম করে এবং MACD ইতিবাচক ক্রস করে, তাহলে তেজি এন্ট্রি। লক্ষ্য: 224.88 (boll_ub) → 232।
3. **ব্রেকডাউন ঝুঁকি:** 216.72 (boll_lb) নিচে ক্লোজ হলে এবং ATR প্রসারিত হলে সতর্কতা; দীর্ঘমেয়াদি বিনিয়োগকারীদের জন্য 213.44 (200-SMA) ক্রিটিক্যাল সাপোর্ট।
4. **ইন্ট্রা-ডে সুরক্ষা:** ATR 2.03 বিবেচনায় 2-4 পয়েন্টের স্টপ-লস রাখুন।
## যাচাইকরণ নোট (Discrepancy Flag)
MACD সংক্রান্ত ছোটখাটো অসঙ্গতি লক্ষ্য করা যায়: `get_indicators` টুলে MACD সিরিজের সর্বশেষ মান -0.2389, অন্যদিকে verified snapshot-এ **-0.24** হিসেবে দেখানো হয়েছে (rounding-এর কারণে সামান্য পার্থক্য)। অপরদিকে যাচাইকৃত `macds` = **-0.01** এবং `macdh` = **-0.23** — এই মানগুলোই চূড়ান্ত তথ্য হিসেবে বিবেচিত হয়েছে। মূল্য, RSI, বোলিঞ্জার ব্যান্ড, SMA, EMA ও ATR-এর মান সবগুলো verified snapshot-এর সাথে সামঞ্জস্যপূর্ণ। VWMA একমাত্র যা verified snapshot-এ দেওয়া হয়নি, তাই VWMA-কে গৌণ সূচক হিসেবে বিবেচনা করা হয়েছে।
---
## মূল পয়েন্টসমূহের সারসংক্ষেপ টেবিল
| সূচক | বর্তমান মান | ব্যাখ্যা | বাজার সংকেত |
|---|---|---|---|
| close_200_sma | 213.44 | দীর্ঘমেয়াদি ট্রেন্ড সাপোর্ট | তেজি — মূল্য উপরে (+3%) |
| close_50_sma | 219.69 | মাঝারি-মেয়াদি গড় | নিরপেক্ষ — দাম ঠিক গড়ের উপরে |
| close_10_ema | 219.86 | স্বল্পমেয়াদি গড় | নিরপেক্ষ — দাম গড়ের সমান |
| macd | -0.24 | মোমেন্টাম | নিরস — নেতিবাচক অঞ্চল |
| macds | -0.01 | সিগনাল লাইন | ক্রসওভারের কাছাকাছি |
| macdh | -0.23 | হিস্টোগ্রাম | নিরস — মোমেন্টাম দুর্বল |
| rsi | 48.73 | মোমেন্টাম | নিরপেক্ষ (আলোচ্য 40-60) |
| boll | 220.80 | 20-SMA ভিত্তি | হালকা নেতিবাচক (দাম নিচে) |
| boll_ub | 224.88 | উপরের ব্যান্ড | প্রতিরোধ / ওভারবট জোন |
| boll_lb | 216.72 | নিচের ব্যান্ড | সমর্থন / ওভারসল্ড জোন |
| atr | 2.03 | ভোলাটিলিটি | সংকুচিত — ব্রেকআউটের সম্ভাবনা |
| vwma | 219.76 | ভলিউম-গড় | নিরপেক্ষ-ক্ষীণ |
**সামগ্রিক মূল্যায়ন:** SQURPHARMA বর্তমানে একটি সিদ্ধান্ত-গুরুত্বপূর্ণ বিন্দুতে। দীর্ঘমেয়াদি কাঠামো দৃঢ় (bullish), কিন্তু স্বল্পমেয়াদি মোমেন্টাম দুর্বল ও ভোলাটিলিটি সংকুচিত। ব্রেকআউটের দিক নির্ধারণ না হওয়া পর্যন্ত **HOLD** পরামর্শ দেওয়া যায়, তবে 221+ ভলিউমসহ ব্রেক হলে তেজি এবং 216.5-এর নিচে ব্রেক হলে সতর্কতা অবলম্বন করা উচিত।
FINAL TRANSACTION PROPOSAL: **HOLD**
\ No newline at end of file
Bear Analyst: প্রিয় বুলিশ বন্ধু,
আপনার "গাছ বন" উপমাটি দারুণ, কিন্তু আমি আপনাকে একটি বাস্তবতার কথা মনে করিয়ে দিই — এই বনের অনেক গাছই শুকনো, আর আপনি সেই সবুজ পাতার ফটোফ্রেমে আটকে আছেন। `SQURPHARMA`-র গল্পটা আজকের বাজারের গল্প নয়, বরং একটি **বছরের পর বছর ধরে দামে আটকে থাকা স্টকের গল্প**। আপনার প্রতিটি যুক্তির প্রতিটি খুঁটিতে আমি এখন ঘোরাব, আর দেখব সেখান থেকে লাল পতাকা না উঠে কিনা।
---
## ১. "P/E ৭.৭৩ সস্তা" — এটা ভ্যালু ট্র্যাপ, ভ্যালু নয়
আপনি আমার মনোযোগ দিয়ে দেখুন:
| বছর | EPS | P/E |
|---|---|---|
| 2019 | 16.03 | 14.68 |
| 2021 | 17.99 | 11.98 |
| 2023 | 21.41 | 9.80 |
| 2025 | 27.04 | 7.73 |
EPS বেড়েছে, কিন্তু P/E কমেছে 14.68 থেকে 7.73। যদি বাজার সত্যিই মনে করত এটি মহাভারতের অর্জুন — তবে P/E এভাবে ভেঙে পড়ত না। এই **ডি-রেটিং** হচ্ছে বাজারের বড় সিগন্যাল: এটি বলে দিচ্ছে, ভবিষ্যতে আয়-বৃদ্ধির হার আগের মতো থাকবে না।
আর তার প্রমাণ আপনি নিজেই দিয়েছেন আমার টেবিলে:
- FY2026 Q1 EPS: **8.35**
- FY2026 Q2 EPS: **8.20**
- FY2026 Q3 EPS: **6.73**
**টানা তিন কোয়ার্টারে EPS কমছে।** Q3-এর EPS Q1-এর চেয়ে প্রায় 19% কম। আপনি বলছেন "ফান্ডামেন্টাল শক্তিশালী", কিন্তু এই সংখ্যাগুলো তো চিৎকার করে বলছে — প্রবৃদ্ধি শ্লথ হয়ে আসছে। 9 মাসের EPS 23.29, কিন্তু FY2025-এর 9 মাস ছিল 21.15 — মানে প্রবৃদ্ধি মাত্র ~10%, আর আগের বছর ছিল ~14%। বাজার এত চতুর — এই মন্থর গতিটাই দামে বসিয়ে দিয়েছে।
## ২. "৩০+ EPS প্রজেকশন" — আপনি ভবিষ্যৎ দেখছেন, আমি বর্তমান দেখছি
আপনার প্রজেকশন `30+ EPS` — কিন্তু Q3-এর 6.73 সেই প্রজেকশনের কবরে পাথর। আপনি ধরে নিচ্ছেন Q4-এ আবার জাদু হবে। কেন হবে? Q1-এ 8.35, Q2-এ 8.20, Q3-এ 6.73 — এই ঢাল শুরু হয়ে গেছে। যদি Q4-এ 6.7-ই আসে, তাহলে বার্ষিক EPS 30.01 — কিন্তু তার আগের বছরের (FY2025) প্রবৃদ্ধি 14.5% থেকে কমে দাঁড়ায় 11%-এ। `SQURPHARMA` এখন সেই পর্যায়ে নেই, যেখানে প্রতিটি কোয়ার্টার পূর্বের চেয়ে ভালো করবে; বরং সেটা **পিক-আর্নিংস সাইকেলের শেষভাগ** হতে পারে। আর যদি Q4-এ আরও খারাপ হয়, তবে এই দাম 200-এর নিচেও যেতে পারে।
## ৩. "১২০% লভ্যাংশ" — হ্যাঁ, কিন্তু লভ্যাংশই প্রমাণ যে নতুন বৃদ্ধি নেই
আপনি 5.46% ডিভিডেন্ড ফলনকে বড় অস্ত্র বানিয়েছেন। কিন্তু প্রশ্ন জাগে — একটি কোম্পানি যখন ৫২ বিলিয়ন টাকা নগদ জমানো অবস্থায় রাখে এবং এর বদলে শেয়ারহোল্ডারদের লভ্যাংশ দিয়ে তুষ্ট রাখে, তখন সেটি **প্রবৃদ্ধি সংস্থা** নয়, **রক্ষণশীল নগদ-গাভী**। 120% লভ্যাংশ = প্রতি শেয়ার 12 টাকা। EPS 27.04, পেআউট রেশিও 44% — ভালো, কিন্তু এখানে 44% এর বাকি 56% লভ্যাংশ না দিয়ে они পড়ে আছে। কেন? কারণ শিল্পের মধ্যে নতুন লাভজনক বিনিয়োগের সুযোগ নেই বলেই তারা টাকা বিলি করে দিচ্ছে। মার্কেট সেটা বোঝে — আর সেই কারণে দাম 7 বছর ধরে 198–236-এর বক্সের ভেতরে বন্দি।
## ৪. "স্পনসর ৪৪.১৫% — আস্থা" — নাকি তরলতার সংকট?
স্পনসর হোল্ডিং 34.67% থেকে 44.15% হয়েছে — ভালো কথা। কিন্তু এর ফলাফল? **Free float কমে গেছে**। স্পনসর 44.15% + বিদেশি 14.81% + প্রাতিষ্ঠানিক 13.81% = 72.77% শেয়ার লকড হয়ে আছে। বাকি মাত্র 27% সাধারণ জনগণের মধ্যে লেনদেন হয়। এই অস্থিতিশীল কাঠামো কখনো বড় বিনিয়োগকারীকে “লিকুইডিটি প্রিমিয়াম” দিতে বাধ্য করে। কেউ বের হতে চাইলে দাম গুঁড়িয়ে যেতে পারে — যেমনটি ডিসেম্বর 2025-এ প্রায় 199-এ নেমেছিল, 8 মাস আগেই। স্পনসররা কিনেছেন মানে তারা কোম্পানির ভবিষ্যতে বিশ্বাস করেন — এটা গ্রহণ করি; কিন্তু তারা কিনেছেন নিজেদের নিয়ন্ত্রণ ধরে রাখতে, আর সেকেন্ডারি মার্কেটে বিনিয়োগকারীদের জন্য লিকুইডিটি কমিয়ে দিয়েছেন। **আস্থার প্রতীক আর লিকুইডিটি ফাঁদ এক জিনিস নয়।**
## ৫. "কম ভলিউম মানে বিক্রয়চাপ নেই" — বরং কেনার কোনো আগ্রহই নেই
আপনি বলছেন, ভলিউম 140,479 মানে দুর্বল হাত বেরিয়ে গেছে। আমি বলছি, উল্টো — এর মানে **শক্ত হাতও ঢুকছে না**। দাম তো 219.90-এ দাঁড়িয়ে আছে, কিন্তু MACD -0.24, সিগনাল লাইন -0.01, RSI 48.73 (50-এর নিচে), দাম বোলিঞ্জার মধ্যমা 220.80-এর নিচে। VWMA 219.76 — দাম আর গড়পালের প্রায় সমান। এই হিসাব বলে, বাজার এখন দাঁড়ি টেনেছে। একটা শক্তির স্টক যদি 200-SMA 213.44-এর ওপরে থাকে, তার দরকার **নতুন কেনার ঢেউ** — আর সেই ঢেউয়ের অভাবে দাম আটকে আছে। ATR 2.03 থেকে কমেছে, আপনি বলছেন এটি ব্রেকআউটের পূর্বলক্ষণ। কিন্তু ব্রেকআউট কোন দিকে হবে — সেটি কোথায় আছে? বর্তমান টেকনিক্যাল সেন্টিমেন্ট, Q3 আয়হ্রাস, এবং সেক্টর-মন্দা মিলিয়ে নিচের দিকেই বেশি ইঙ্গিত।
## ৬. "২১৩-২১৬ সাপোর্ট, ঝুঁকি মাত্র ৩%" — সাপোর্ট আছে বলেই ভাঙবে না?
সাপোর্ট ভাঙতে দেখেছি গত বছরে একাধিকবার: মে 2026-এ প্রায় 207, ডিসেম্বর 2025-এ 199। আপনার দেওয়া ঝুঁকি-রিটার্ন অনুপাত অসম্পূর্ণ:
- নিচে 200-SMA 213.44 — মাত্র ৩% নিচে
- তার নিচে 52-সপ্তাহের লো 198 — পুরো ১০% নিচে
- উপরে বোলিঞ্জার আপার 224.88 — মাত্র ২.৩%
- উপরে 52-সপ্তাহের হাই 236 — ৭.৩%
আসলে ডাউনসাইড-আপসাইডের অনুপাত প্রায় ৫০:৫০, আপনার দাবিকৃত 70:30 নয়। আর 200-SMA ভেঙে গেলে টেকনিক্যাল সেল-অর্ডাররা একসাথে নেমে আসবে — তখন 207 এবং 198 খুব দ্রুত স্পর্শ করা সম্ভব। এই অবস্থায় "নতুন বিনিয়োগ" করতে বলা, বরং মানুষকে ঝুঁকির দিকে ঠেলে দেওয়া।
## ৭. "বাংলাদেশ ওষুধ শিল্পের সোনালি সময়" — কিন্তু সেই গল্পটি এখন রিপিট হচ্ছে না
আমি আপনার সেক্টর-আশাবাদকে সম্মান করি, কিন্তু বাস্তবতা হলো:
- দেশে ওষুধের বাজার 97% স্থানীয় চাহিদা মেটায় — এক পর্যায়ে সম্পৃক্তি (saturation) হয়ে গেছে
- রপ্তানি বাড়ছে, কিন্তু আন্তর্জাতিক জেনেরিক বাজারে **মূল্যচাপ** প্রচণ্ড
- কাঁচামাল আমদানি করতে হয় — টাকা দুর্বল হলে **মার্জিন সংকোচন**
- স্থানীয় নিয়ন্ত্রক (DGDA) মূল্য বৃদ্ধি সীমিত করে দেয় — ফলে খরচ বাড়লেই সব ধরতে পারবে না
- প্রতিযোগীদের কথা ভুলবেন না — ইনসেপ্টা, বেক্সিমকো, ওপসোনিন, এসকেএফ — তারা সবাই স্কয়ারকে টার্গেট করছে
স্কয়ার আজও শক্তিশালী, কিন্তু তার শীর্ষ-বৃদ্ধির দিন শেষ। বাজার সেটাকে দামে দিয়ে দিচ্ছে — এই সত্যকে "দুর্বলতা" নয়, "বাস্তবতা" বলা ভালো।
## ৮. "2019-এ 235, এখন 219 — সস্তা" — সেখানে আমি দেখি ক্যাপিটাল ডিস্ট্রাকশন
আপনি নিজেই বললেন: 2019-এ শেয়ারের দাম ছিল 235, EPS ছিল 16.03। 2025-এ EPS 27.04, দাম 219.90। 7 বছরে EPS 69% বাড়লেও দাম 6% **কমেছে**। এটাকে কি "ছাড়ে বিক্রি" বলা যায়? নাকি বলতে হয় — বাজার কোম্পানির ভবিষ্যৎ সম্পর্কে এতটাই সন্দিহান যে, তৈরি অতীতের আয়কে মূল্য দিতে রাজি নয়? আমার বিয়ারিশ মতে, এটি একটি **ভ্যালু ট্র্যাপ** — যখন ভালো ফান্ডামেন্টাল থাকে কিন্তু দাম বাড়ে না, কারণ বাজার ভবিষ্যতে সেই ফান্ডামেন্টাল ধরে রাখবে না বলে মনে করে। এখানে BUY করছেন, তাহলে 2028-এ দেখবেন দাম এখনও 220-225 — আর আপনার রিটার্ন শুধু ডিভিডেন্ডে সীমাবদ্ধ।
## ৯. চলমান ডেটা থেকে বেরিয়ে এসে — চূড়ান্ত সিদ্ধান্ত
আমি আপনাকে সুনির্দিষ্টভাবে বলছি:
- **প্রযুক্তিগত পক্ষ:** দাম 10-EMA (219.86) এবং 50-SMA (219.69)-এর ঠিক সংযোগস্থলে। MACD নেতিবাচক, RSI 48 নিচে। বোলিঞ্জার মধ্যমা 220.80-র নিচে থাকা মানে মূল্যে নিম্নমুখী চাপ।
- **মৌলিক পক্ষ:** Q3-এ EPS 6.73 — ধারাবাহিক পতন; বার্ষিক প্রবৃদ্ধি কমে আসছে; নগদে বসে থাকা ROE-র উপর টান।
- **বাজার পরিস্থিতি:** সেক্টর সম্পৃক্ততা, মূল্যনিয়নতরণ ঝুঁকি, প্রতিযোেগিতা — এই ঝুঁকিগুলো ডিস্কাউন্টেড হয়নি, কোরোন ভো KPIs-এ এগুলো এখনো প্রকাশ পায়নি।
- **লিকুইডিটি:** 72.77% শেয়োર লকড — ছোট ভলিউমে বড় বোেন্দা সহজে না।
**বুলিশ প্রস্তোવিত "ACCUMULATE/BUY"** — এর প্রতিউত্তরে আমি বলি, এই স্টকে এখনো "BUY" নોય, কারণ প্রবৃদ্ধি থেমে যাওয়ো સંકેત પ્રત્યક્ષમો। Q4-এর রોજો જ્યાં સુધ न હોય — ત્યાં સુધ ધરો ત આ જખોખો છે। જो Sધારમાં હોય, તો 20-221-এর Uપર MACD ক্রોસવोવर અને Uપरના બ્રેકआઉلو ન іહોય તોય. इस से પहલે, HOLD করો, BUY નहીં.
## ১০. ઉ여ین છO? ઉેઆત લOঢ?
બяхώой что out there. В этом случае лучшая позиция — это **наличные**.
**Мой финальный вердийкт:**
> **`SQURPHARMA` — SELL/АVOID на тевременной цене 219.90**.
> - Ноывем инвесторам: не покупайте на 220+; ждите подхода к 213.44 или даже 207-й зоне, если появится разворот на MAC удар.
> - Тем, кто уже держит: частично фиксируйте прибыль, если есть, и стаьте стоп-лосс ниже 213.44.
> - Если Q4-резултат покажет ЕПС >8 и MACD заворачивается вверх — тогда пересмотрим. Но до этого — **время сидеть в каше, а не ловить нож в падающем ростаре**।
আপনার বুলিশ আর্মাটাক তুখরে, আমার বিয়ারিশ আর্মাটাক — কোম্পানিটির মৌলিক শকিতকই সত্যি, কিন্তু দামت ि হওয়ার জন्य कोई নতুন কেन्द্র नই। বाजाر এর কथा শুন। এটা এখনো কেনার সময় नয়। ुধৈर্য দिখান, বिشাشণ कরুন আর অপेक्षा করার সाभથথ निर्ણय कরুন। ुधৈર্যতাભই এখानে শ্রेष்ঠ અવिध।
**FNA LT RDAC TIN PROSAL: **SELL/AVOID** — নોય HOLD, নોય BUY.
Bear Analyst: প্রিয় বুলিশ বন্ধু,
আপনার শেষ বক্তব্যে আপনি বলেছেন, আমি "সংখ্যা দেখেছি, কিন্তু গল্পটা পড়িনি।" কিন্তু আমি দেখেছি — গল্পটা একটাই: **একটি দারুণ কোম্পানি, কিন্তু দারুণ স্টক নয়**`SQURPHARMA` একটি চমৎকার ফার্মাসিউটিক্যাল প্রতিষ্ঠান হতে পারে; কিন্তু বিনিয়োগের সিদ্ধান্ত হয় দামে, কোম্পানির নামে নয়। আসুন গল্পটা আমি আপনার মতো রঙিন করে বলি না, কাঁচা তথ্য দিয়ে বলি — যেখানে আপনার প্রতিটি বুলিশ যুক্তির বিপরীতে বেয়িশ প্রমাণ আছে।
---
## ১. Q3-এ EPS "ঋতুভিত্তিক" কমছে না — আগের বছরের একই কোয়ার্টারের তুলনায় কমছে
আপনি বলছেন, Q3/Q4-এ EPS কমাটা মৌসুমি। কিন্তু মৌসুমি মানে হলো — **প্রতি বছর একই সময়ে কমবেশি একই রকম হবে**। তাহলে তুলনা করুন:
| কোয়ার্টার | FY2025 (প্রায়) | FY2026 | পরিবর্তন |
|---|---|---|---|
| Q1 | ~6.9 | 8.35 | +21% |
| Q2 | ~7.1 | 8.20 | +15% |
| Q3 | ~7.1 | 6.73 | **-5.2%** |
– Q1 ও Q2-তে YoY প্রবৃদ্ধি ছিল দারুণ।
– কিন্তু **Q3-এ আগের বছরের Q3-এর চেয়েও EPS কমে গেছে**
এটা শুধু "ঋতু" নয় — এটা **গতি হারানোর বাস্তব লক্ষণ**। আপনি Q4-এ আবার ৭+ আসবে বলে প্রজেক্ট করছেন, কিন্তু Q3 যেভাবে ভেঙেছে, তাতে Q4 আরও দুর্বল হতে পারে। যদি Q4-এ গত বছরের মতো ~5.9 আসে, তাহলে বার্ষিক EPS হবে **~29.2**, আপনার প্রজেক্টেড 30+ নয়। আর 27.04 থেকে 29.2 — প্রবৃদ্ধি মাত্র 8%, যা এই কোম্পানির ঐতিহাসিক 15-20% প্রবৃদ্ধির চেয়ে অর্ধেক।
---
## ২. P/E 7.73 "সস্তা" নয় — বাজার এটাকে "মন্দা" প্রাইসিং করছে
আপনি বলছেন, P/E কমে যাওয়া হলো "ডি-রেটিং" নয়, সুযোগ। কিন্তু ২০১৯ সালে P/E 14.68 ছিল, এখন 7.73। EPS 69% বেড়েছে, কিন্তু দাম সেই সময়ের চেয়ে ৬% কম। **বাজার কি ৭ বছর ভুল করেছে?** সম্ভবত বাজার ভবিষ্যৎ প্রবৃদ্ধি আগের মতো দেখছে না।
- ২০১৯-২০২২: EPS CAGR ছিল ~12-15%
- ২০২৪-২০২৫: EPS বৃদ্ধি 14.5%
- FY2026-এর ৯ মাসে প্রবৃদ্ধি ~10%
প্রবৃদ্ধি প্রতিবছর কমছে। বাজার যখন দেখে প্রবৃদ্ধি মন্থর হচ্ছে, তখনই P/E কমিয়ে দেয়। 7.73 P/E-র মানে হলো — বাজার এখনও এটাকে "একটি পরিণত, কম-বৃদ্ধির কোম্পানি" হিসেবে মূল্য দিচ্ছে। আপনার PEG 0.70-এর হিসাবও 11% বৃদ্ধি ধরে নিয়েছে; 8% বৃদ্ধিতে PEG ওঠে ~0.97 — ততটা আকর্ষণীয় নয়।
---
## ৩. "১২০% লভ্যাংশ" — এটা প্রমাণ যে নতুন বিনিয়োগের সুযোগ নেই
আপনি অ্যাপলের কথা বলেছেন, কিন্তু অ্যাপল নিজের শেয়ার কিনে নেয়, নতুন পণ্য বাজারে আনে, এবং তার নগদ ইনোভেশনে খাটায়। `SQURPHARMA`-র ৫২ বিলিয়ন টাকা নগদ ব্যালেন্স শিটে পড়ে আছে; এর বিপরীতে কোম্পানি শেয়ারহোল্ডারদের 12 টাকা লভ্যাংশ দিয়ে "বোঝা" হালকা করছে।
- 2025-এ EPS 27.04, লভ্যাংশ 12.00 => পেআউট 44%
- বাকি 56% আয় ধরে রেখেছে, কিন্তু দৃশ্যত সেটা থেকে EPS-এর তেমন কোনো লাফ দেখাচ্ছে না
- Q3-এ NAV 169.79 — কিন্তু দাম 219.90। P/B 1.30 — বাজারের মতে, কোম্পানির সম্পদ থেকে বিশেষ অতিরিক্ত মূল্য সৃষ্টির প্রত্যাশা নেই
লভ্যাংশ 5.46% ফলন ভালো, কিন্তু দাম 7 বছর ধরে 198–236-এর বক্সে বন্দি। **মূল্যস্ফীতি, সুদের হার, এবং ট্যাক্স হিসাব করলে — শুধু লভ্যাংশে প্রকৃত রিটার্ন অনেক কম।** টাকা যদি FDR-এ থাকে, তাও সম্ভবত বেশি ঝুঁকি ছাড়া ৭-৮% দেয়। শেয়ারে সেটা পেতে হলে দামের মূলধনী লাভ লাগবে — যা 7 বছরে আসেনি।
---
## ৪. স্পনসর হোল্ডিং বাড়ানো = আস্থা? নাকি লিকুইডিটি ফাঁদ?
স্পনসর 44.15%, বিদেশি 14.81%, প্রাতিষ্ঠানিক 13.81% — মোট 72.77% লকড। আপনার দাবি এটা "স্থিতিশীলতার প্রমাণ।" কিন্তু বিপরীত দিকটা দেখুন:
- ফ্রি ফ্লোট মাত্র ২৭.২৩%
- এত কম ফ্লোটে বড় বিনিয়োগকারীরা **প্রবেশ করার সময়ই** দাম ইচ্ছামতো ঠেলে দিতে পারে, কিন্তু **বের হওয়ার সময়** দাম দ্রুত ধসে পড়ে
- ২০২৬-এর মে মাসে দাম ২০৭-এ নেমেছিল — ৫২ সপ্তাহের হাই ২৩৬ থেকে ১২% নিচে। এটা কি "স্থিতিশীল" ছিল?
- স্পনসররা শেয়ার কিনেছেন ঠিকই, কিন্তু সেকেন্ডারি মার্কেটে শেয়ার ছেড়ে দেননি। এটি আপনার জন্য লিকুইডিটি সুবিধা না, **ঝুঁকি** — বিশেষত যখন আপনাকে বড় অবস্থান বের করতে হবে।
---
## ৫. আপনার ৭০:৩০ রিস্ক-রিওয়ার্ডের হিসাব বাস্তব নয়
আপনি বলছেন, উপরে ২-৭%, নিচে ৩-১০%। কিন্তু প্রযুক্তি এখন যে দিকে আছে, তাতে সম্ভাব্যতা নিচের দিকেই বেশি। দেখুন:
- দাম 219.90, বোলিঞ্জার মধ্যমা 220.80। **দাম মধ্যমার নিচে** — ছোট্ট নেতিবাচক চাপ
- MACD -0.24, সিগনাল -0.01, হিস্টোগ্রাম -0.23 — **নেগেটিভ জোনে**
- RSI 48.73 — **50-এর নিচে**। এটা "ওপরের দিকে ফেরা" নয়, "নিরপেক্ষের চেয়ে দুর্বল"
- VWMA 219.76 — দাম আর ভলিউম-ওয়েটেড গড় প্রায় একই। **কোনো অ্যাকিউমুলেশন নেই**
- আর 200-SMA আপনি বলছেন "২ বছর ধরে অক্ষত" — কিন্তু **২০২৬-এর মে মাসে দাম ২০৭-এ গিয়ে 200-SMA ভেঙেছে**। তারপর পুনরুদ্ধার হয়েছে, কিন্তু স্তরটি আর অক্ষত নয়। এটি ভঙ্গুর সাপোর্ট
এখন রিস্ক-রিওয়ার্ড হিসাব করুন:
| লক্ষ্য | দূরত্ব | ঝুঁকি | দূরত্ব |
|---|---|---|---|
| Bollinger UB 224.88 | +2.3% | 200-SMA 213.44 | -2.9% |
| 52-সপ্তাহের হাই 236 | +7.3% | May-2026 low 207 | -5.9% |
| | | 52-সপ্তাহের লো 198 | -10% |
উপরের প্রথম টার্গেটটি মাত্র ২.৩% দূরে, আর নিচের প্রথম সাপোর্টটি ২.৯% দূরে। **রিস্ক-রিওয়ার্ড প্রায় ১:১**। আপনি যে "৭০:৩০" বলছেন, সেটা প্রমাণ করতে পারবেন না; বরং বর্তমান মুভিং অ্যাভারেজ ক্লাস্টার এবং MACD নেগেটিভিটি থেকে নিচের দিকের সম্ভাবনাই বেশি।
---
## ৬. 216.72 ভাঙলে আতঙ্কিত বিক্রি শুরু হবে
নিচের বোলিঞ্জার ব্যান্ড 216.72। এর ঠিক নিচে দাম 10-EMA, 50-SMA, VWMA — সবগুলো একসাথে 219.7-219.9 অঞ্চলে। এই অঞ্চল ভাঙলে টেকনিক্যাল ট্রেডাররা একসঙ্গে বেরোবে। তখন 213.44 (200-SMA) পড়বে; তারপর 207, তারপর 198। মনে রাখবেন, 2025-এর ডিসেম্বরেও দাম 199-এ নেমেছিল। **এই স্টকটি অসম্ভব নয় ভাঙা — এটি প্রতিবছরই ভাঙে।**
আপনার পরামর্শ "213-216-এ কেনা" — কিন্তু কেন সেটা আগে থেকে ধরবেন? আপনি যদি 219.90-তে কেনেন, এবং দাম 213-এ আসে, তাহলে আপনার 3% লোকসান হবে। সেখান থেকে আবার 220-এ ফিরতে কত সময় লাগবে? হয়তো ৬ মাস। **সেই সময়ে আপনার টাকা অন্য জায়গায় বেশি রিটার্ন দিতে পারত** — এটাই সুযোগ ব্যয়।
---
## ৭. সেক্টরের "সোনালি সময়" শেষ — প্রতিযোগিতা ও নিয়ন্ত্রণ ঝুঁকি বাড়ছে
আপনি সেক্টরের রপ্তানি বৃদ্ধির কথা বলেছেন, কিন্তু:
- বাংলাদেশের স্থানীয় বাজারে ৯৭% চাহিদা মেটানোর অর্থ — **বাজার সম্পৃক্ত**। প্রবৃদ্ধি এখন কেবল রপ্তানিমুখী, আর সেটি অল্প বেস থেকে শুরু
- রপ্তানি প্রতিযোগিতায় ভারত, চীনের ফার্মাসিউটিক্যাল কোম্পানিগুলোর তুলনায় `SQURPHARMA`-র স্কেল অনেক ছোট
- কাঁচামাল (API) আমদানি করতে হয়; টাকার অবমূল্যায়ন হলে খরচ বাড়বে, মার্জিন সংকুচিত হবে
- DGDA-র মূল্যনিয়ন্ত্রণের কারণে খরচ বাড়লেও দাম বাড়ানো যাবে না — এতে নিট মুনাফা মার্জিনের ওপর সরাসরি চাপ
- ইনসেপ্টা, বেক্সিমকো, এসকেএফ, ওপসোনিন — প্রত্যেকে স্কয়ারের শেয়ার নিতে চায়
স্কয়ার আজও শীর্ষে, কিন্তু "শীর্ষে থাকা" আর "সবচেয়ে ভালো বিনিয়োগ" এক কথা নয়। বাজার এগিয়ে থেকেই এই চাপের দাম দিয়েছে — P/E 7.73-এ।
---
## ৮. "ভ্যালু স্টোর" — ভ্যালু ট্র্যাপের আরেক নাম
আপনি বলেছেন, 7 বছরে EPS বেড়েছে, দাম কমেছে — এটাই ভ্যালু স্টোর। কিন্তু ভ্যালু ইনভেস্টিংয়ের মূল নীতি হলো — **দাম আয়ের তুলনায় কম হলে, অস্বাভাবিক পরিস্থিতিতে, এবং একটি ক্যাটালিস্ট থাকলে কেনা উচিত**। এখানে ক্যাটালিস্ট কোথায়?
- Q4-এর ফলাফল এখনো আসেনি
- MACD এখনো বিয়ারিশ
- কোনো নতুন পণ্য লঞ্চ বা রপ্তানি চুক্তির খবর নেই
- দাম ২২০-এ আটকে, ভলিউম ১৪০,৪৭৯ — কম
এটাকে "ভ্যালু স্টোর" বলা ঠিক হবে না। এটা এমন এক স্টক, যেখানে ভালো সংখ্যা থাকা সত্ত্বেও **বাজার এগিয়ে যেতে চায় না**। এর ৭ বছরের প্রাইস অ্যাকশনই প্রমাণ — অপেক্ষা করে থেকে থেকে বিনিয়োগকারীরা শুধু লভ্যাংশ পেয়েছেন, মূলধনী লাভ পাননি। আজকে BUY করে ১২ মাস পর আবার ২২০-এ দাম দেখার সম্ভাবনা ৫০%-এর বেশি — কারণ একই প্যাটার্ন ৭ বছর ধরে চলছে।
---
## ৯. Q4-এর ফলাফল যখন আসবে, তখন আরও জানা যাবে — ততক্ষণ ঝুঁকি নেওয়ার দরকার নেই
আপনি প্রশ্ন করেছেন, "Q4 ভালো এলে আপনি কি 250-এ কিনবেন?" — সেটা ভুল প্রশ্ন। আমি Q4 ভালো এলে **প্রযুক্তিগত ব্রেকআউট এবং MACD ক্রসওভার নিশ্চিত করে** কিনব — 250-এ নয়, সম্ভবত 230-এর পরে। কিন্তু আজ 219.90-তে কেনার সময় **নিচের ঝুঁকি এখনো অনেক বেশি**
আমার প্রস্তাব:
- **নতুন বিনিয়োগকারী:** 219-220-এ কিনবেন না। অপেক্ষা করুন। দাম যদি 213-207-এ আসে, সেখানে ঝুঁকি অনেক কম। অথবা 224.88-এর উপরে ভলিউমসহ ক্লোজ করুন — তাহলে আপট্রেন্ড নিশ্চিত হবে, তখন যোগ দিন।
- **যাদের শেয়ার আছে:** অংশবিশেষ বিক্রি করুন, বা অন্তত 213.44-এর নিচে স্টপ-লস রাখুন। Q4 ফল之前的 নগদে থাকা অনেক নিরাপদ।
- Q4-এর EPS যদি >7.5 আসে এবং MACD ওপরের দিকে ক্রস করে, তখন আমরা আবারও বুলিশ আলোচনা করতে পারি। **ততদিন — এই স্টক কেনার কোনো জরুরি কারণ নেই।**
---
## উপসংহার
বুলিশ বন্ধু, আপনি এই স্টককে ভালোবেসে ফেলেছেন — ভালোবাসায় যুক্তি অন্ধ হয়। আমি ভালোবাসি না, শুধু সংখ্যা দেখি: **Q3-এ EPS কমছে, 200-SMA সম্প্রতি ভেঙেছে, MACD নেতিবাচক, RSI 50-এর নিচে, ফ্রি-ফ্লোট কম, লভ্যাংশ দাম বাড়াতে পারছে না, আর বাজার ৭ বছর ধরে এই শেয়ারকে রেঞ্জে বেঁধে রেখেছে।**
আপনার "ভ্যালু স্টোর" গল্পটি সুন্দর, কিন্তু বাস্তবতা হলো — **একটি ভালো কোম্পানির শেয়ার, যা প্রযুক্তিগতভাবে এবং মৌলিকভাবে নতুন ক্যাটালিস্ট ছাড়া উপরে যেতে পারছে না**। বিনিয়োগ মানে দারুণ কোম্পানি খোঁজা নয়, সঠিক দামে সঠিক সময়ে কেনা। এখন সঠিক সময় নয়।
**আমার চূড়ান্ত প্রস্তাব: `SQURPHARMA`-তে নতুন কেনা থেকে বিরত থাকুন — SELL/AVOID।**
যাদের পোর্টফোলিওতে আছে, তারা স্টপ-লস 213.44 রাখুন, অথবা আংশিক মুনাফা তুলে নিন। Q4 এবং ব্রেকআউট নিশ্চিত হওয়ার আগে এখানে "BUY" বলা মানে — ৭ বছরের একই রেঞ্জে আবারও ফেঁসে যাওয়ার প্রস্তুতিতে সই করা। সময় অপেক্ষা করে না, কিন্তু এই স্টকটি অপেক্ষা করতেই জানে।
Bear Analyst: # SQURPHARMA — চূড়ান্ত বিয়ারিশ বিবৃতি: "ভালো কোম্পানি" আর "ভালো বিনিয়োগ" এক নয়
প্রিয় বুলিশ বন্ধু,
আপনি আবারও আপনার রঙিন গল্পটি শোনালেন — "ভ্যালু স্প্রিং", "৭ বছরের চাপা দাম", "একদিন সবাই দেখবে"। কিন্তু আমি আবারও বলছি — **বিনিয়োগে গল্প নয়, হিসাব চলে**। আপনার প্রতিটি যুক্তি আমি এবার কাঁচা ডেটা দিয়ে খণ্ডন করছি, এবং দেখাব কেন 219.90-তে এই স্টক কেনা মানে **৭ বছরের একই রেঞ্জে আবারও বন্দি হওয়ার প্রস্তুতি**
---
## ১. "Q4-এ EPS 6.3-6.5 আসবে" — আপনার প্রজেকশন বাতাসে ভর করে
আপনি বলছেন, Q4-এ 6.3-6.5 আসলে বার্ষিক EPS ~30 হবে। কিন্তু বন্ধু, **আপনার নিজের টেবিলেই প্রমাণ আছে** — Q4 প্রতি বছরই সবচেয়ে দুর্বল কোয়ার্টার। FY2025-এর Q4 ছিল ~5.9, FY2024-এর Q4 ছিল ~5.4। এবার Q4-এ 6.3-6.5 আসার **কোনো নির্দিষ্ট কারণ নেই** — আপনি শুধু আশা করছেন। যদি Q4-এ 5.8-6.0 আসে (যা ঐতিহাসিক প্যাটার্ন), তাহলে বার্ষিক EPS হবে **~29.0-29.3**, আপনার প্রজেক্টেড 30 নয়। তাহলে প্রবৃদ্ধি হবে মাত্র **7.5-8.5%** — যা এই কোম্পানির ২০১৯-২০২৫ সালের 12-15% CAGR-এর **অর্ধেক**
আরও গুরুত্বপূর্ণ — **Q3-এ YoY ভিত্তিতে EPS কমেছে (-5.2%)**। আপনি এটাকে "সামান্য কমা" বলছেন, কিন্তু Q1 (+21%) ও Q2 (+15%)-এর পরে Q3-তে **নেতিবাচক YoY** — এটি একটি স্পষ্ট সতর্কবার্তা। মৌসুমি প্যাটার্নে Q3-এ সাধারণত YoY প্রবৃদ্ধি বজায় থাকে, কিন্তু এবার তা হয়নি। এটি বলে দিচ্ছে — **কোম্পানির মূল ব্যবসায় গতি হারাচ্ছে**
---
## ২. "P/E 7.73 অযৌক্তিক ডিসকাউন্ট" — বাজার ভুল নয়, বাস্তবতা দেখছে
আপনি সেক্টর গড় (12-15) সাথে তুলনা করে বলছেন, SQURPHARMA 40-50% ডিসকাউন্টে ট্রেড করছে। কিন্তু বন্ধু, **সেক্টর গড়ের মধ্যে রয়েছে ছোট, উচ্চ-বৃদ্ধিশীল কোম্পানিগুলো** — যাদের EPS 20-30% হারে বাড়ছে। SQURPHARMA-র প্রবৃদ্ধি এখন 8-10% — সেটা সেই গড়ের সাথে তুলনীয় নয়।
আপনি ROE 17.1% এবং Dividend Yield 5.46% দেখিয়েছেন — কিন্তু **P/B 1.30**? এর মানে হলো, বাজার কোম্পানির সম্পদ থেকে বিশেষ অতিরিক্ত মূল্য সৃষ্টির প্রত্যাশা করছে না। ROE 17% একটি পরিণত কোম্পানির জন্য ভালো, কিন্তু **যদি সেই ROE থেকে নতুন বিনিয়োগে রিটার্ন না আসে, তাহলে এটি শুধুই হিসাবের খেলা**। ২০২৪-২৫ সালে কোম্পানি ৫২ বিলিয়ন টাকা নগদে রেখেছে, অথচ EPS-এর প্রবৃদ্ধি 14.5% থেকে কমে 10%-এ নেমে এসেছে — **নগদ থেকে কোনো লাভজনক বিনিয়োগ হচ্ছে না**
বাজার এটাই বুঝে দাম 7.73 P/E-তে রেখেছে — এটি "ভুল" নয়, **বাস্তবতা**
---
## ৩. "লভ্যাংশ = ক্যাশ জেনারেশন" — কিন্তু দাম বাড়ায়নি, ৭ বছরে
আপনি বলছেন, 120% লভ্যাংশ কোম্পানির ক্যাশ ক্ষমতার প্রমাণ। আমি বলছি — **লভ্যাংশ যদি দাম না বাড়ায়, তাহলে তা বিনিয়োগকারীর জন্য মোট রিটার্ন তৈরি করে না**
গণিত দেখুন:
- 2019 সালে দাম ছিল ~235, EPS 16.03, লভ্যাংশ 42%
- 2025 সালে দাম 219.90, EPS 27.04, লভ্যাংশ 120%
- 7 বছরে আপনি পেয়েছেন: মোট লভ্যাংশ ~6.5+7.5+10+10.5+11+12 = ~57.5 টাকা (প্রতি শেয়ার)
- কিন্তু দাম কমেছে 235 থেকে 219.90 — **মূলধনী ক্ষতি 15.10 টাকা**
- নিট রিটার্ন = 57.5 - 15.1 = **42.4 টাকা**, যা 7 বছরে ~18% মোট রিটার্ন — **বার্ষিক ~2.4%**!
এখন FDR-এ 8% সুদে 7 বছরে আপনার 100 টাকা হতো ~171 টাকা। SQURPHARMA-তে 100 টাকা বিনিয়োগ করে আপনি পেয়েছেন ~118 টাকা। **বাংলাদেশের শেয়ারবাজারে অন্য অনেক স্টক (যেমন রেনাটা, বেক্সিমকো ফার্মা) এই সময়ে অনেক ভালো রিটার্ন দিয়েছে।** লভ্যাংশের গল্পটি সুন্দর, কিন্তু হিসাবটি করুণ।
---
## ৪. স্পনসর হোল্ডিং 44.15% — এটি আস্থা নয়, লিকুইডিটি বোমা
আপনি বলছেন, স্পনসররা শেয়ার কিনছেন মানে ভবিষ্যৎ ভালো। আমি বলছি — **তারা নিজেদের নিয়ন্ত্রণ ধরে রাখতে কিনছেন, সেকেন্ডারি মার্কেটে বিনিয়োগকারীদের জন্য নয়**
- স্পনসর 44.15% + বিদেশি 14.81% + প্রাতিষ্ঠানিক 13.81% = 72.77% লকড
- ফ্রি ফ্লোট মাত্র 27.23% — যার মধ্যে সাধারণ জনগণ 27.23%
- **ফলে দৈনিক গড় ভলিউম 140,479 শেয়ার** — একটি 886.45 মিলিয়ন শেয়ারের কোম্পানির জন্য এটি নগণ্য
এখন কল্পনা করুন — কোনো বড় বিনিয়োগকারী বা মিউচুয়াল ফান্ড যদি ১% শেয়ার (8.86 মিলিয়ন) কিনতে চায়, তাহলে তাকে প্রায় 63 দিনের গড় ভলিউম কিনতে হবে! **এত কম লিকুইডিটিতে বড় বিনিয়োগকারীরা ঢুকতে চায় না** — তাই দাম 7 বছর ধরে রেঞ্জে আটকে আছে। স্পনসররা কেনাকাটি করছেন, কিন্তু তারা যখন একদিন বিক্রি করতে চাইবেন (নিয়ন্ত্রণ ছাড়ার সময়), তখন দাম গুঁড়িয়ে যাবে। আপনি এটাকে "স্থিতিশীলতা" বলছেন, আমি বলছি — **এটি একটি টাইম বোমা**
---
## ৫. "ঝুঁকি-রিটার্ন ৭০:৩০" — আপনার হিসাব ভুল, বাস্তব ঝুঁকি ৫০:৫০-এর চেয়েও খারাপ
আপনি বলছেন, উপরে 10-30% সম্ভাবনা, নিচে 3-10%। কিন্তু বাস্তব প্রযুক্তিগত অবস্থা দেখুন:
- দাম 219.90, বোলিঞ্জার মধ্যমা 220.80 — **দাম মধ্যমার নিচে**
- MACD -0.24, সিগনাল -0.01, হিস্টোগ্রাম -0.23 — **সম্পূর্ণ নেতিবাচক জোন**
- RSI 48.73 — **50-এর নিচে**, মানে মোমেন্টাম দুর্বল
- VWMA 219.76 — দাম আর ভলিউম-ওয়েটেড গড় প্রায় সমান, **কোনো অ্যাকিউমুলেশন নেই**
- ATR 2.03 — সংকুচিত, কিন্তু **ব্রেকআউটের দিক এখনো নিচের দিকে ইঙ্গিত করছে** কারণ MACD নেতিবাচক
এখন আপনার "উপরের টার্গেট" বিশ্লেষণ করি:
- Q4 ফলাফল ভালো এলে 240 — কিন্তু Q4 এখনো আসেনি, এবং Q3-তে YoY নেতিবাচক
- লভ্যাংশ 125-130% ঘোষণা হলে 250 — কিন্তু লভ্যাংশ তো 2025-এও 120% ছিল, দাম বাড়েনি
- রপ্তানি চুক্তি — এর কোনো বাস্তব প্রমাণ নেই
**আপনার সমস্ত "ক্যাটালিস্ট" অনিশ্চিত** — এগুলো হতে পারে, নাও হতে পারে। অন্যদিকে নিচের ঝুঁকিগুলো বাস্তব:
- 216.72 (বোলিঞ্জার নিচের ব্যান্ড) ভাঙলে টেকনিক্যাল বিক্রি শুরু হবে
- 213.44 (200-SMA) সম্প্রতি ভেঙেছে (মে 2026-এ 207-এ গিয়ে) — এটি ভঙ্গুর সাপোর্ট
- 52-সপ্তাহের লো 198 — 2025 ডিসেম্বরে স্পর্শ করেছে, এখন থেকে মাত্র 10% নিচে
**ঝুঁকি-রিটার্ন: উপরে 2.3% (224.88) থেকে 7.3% (236), নিচে 2.9% (213.44) থেকে 10% (198)** — এটি ৫০:৫০-এর চেয়েও খারাপ, কারণ প্রযুক্তিগত মোমেন্টাম বর্তমানে নেতিবাচক।
---
## ৬. "সেক্টরের সোনালি সময়" — রপ্তানি 200 মিলিয়ন ডলার? স্কয়ার-এর রপ্তানি সেই তুলনায় নগণ্য
আপনি বলছেন, বাংলাদেশের ফার্মাসিউটিক্যাল রপ্তানি 20%+ বেড়ে 200 মিলিয়ন ডলার ছাড়িয়েছে। কিন্তু স্কয়ার-এর রপ্তানি আয় কত? সাম্প্রতিক বার্ষিক প্রতিবেদন অনুযায়ী, স্কয়ার-এর মোট আয়ের 90%+ স্থানীয় বাজার থেকে আসে। **রপ্তানি বাড়লেও, স্কয়ার-এর জন্য এটি এখনও মোট আয়ের 10% এর কম** — অর্থাৎ রপ্তানি বৃদ্ধি সামগ্রিক EPS-এ বড় প্রভাব ফেলছে না।
আর স্থানীয় বাজার? 97% স্যাচুরেশন। আপনি বলছেন, ওষুধের চাহিদা 10-12% বাড়ছে — কিন্তু **DGDA-র মূল্যনিয়ন্ত্রণ** এবং **প্রতিযোগীদের আগ্রাসী মার্কেটিং** এর কারণে স্কয়ার-এর মার্জিন সংকুচিত হচ্ছে। Q3-তে YoY EPS কমে যাওয়া তারই প্রমাণ। আপনি যদি সেক্টরের ভবিষ্যৎ নিয়ে আশাবাদী হন, তাহলে **রেনাটা** (যার P/E 25+) বা **বেক্সিমকো ফার্মা** (যার P/E 20+) কেন কিনছেন না? কারণ বাজার জানে, স্কয়ার-এর প্রবৃদ্ধি এখন সীমিত।
---
## ৭. "ভ্যালু স্প্রিং" — ৭ বছরের চাপা দাম মানে মুক্তি নয়, মৃত্যুপথ
আপনার সবচেয়ে বড় যুক্তি — "2019-এ P/E 14.68 ছিল, এখন 7.73, তাই দাম বাড়বে।" বন্ধু, **এটি ভ্যালু ইনভেস্টিংয়ের সবচেয়ে বিপজ্জনক ভুল ধারণা**
P/E 14.68 থেকে 7.73-এ নামার অর্থ হলো — **বাজার কোম্পানির ভবিষ্যৎ প্রবৃদ্ধি সম্পর্কে তার প্রত্যাশা কমিয়েছে**। 2019 সালে বাজার ভাবত স্কয়ার 20%+ হারে বাড়বে, কিন্তু বাস্তবে 2019-2025 সালে বার্ষিক EPS বৃদ্ধি হয়েছে মাত্র 11.2%। বাজার এখন বাস্তবতা দেখে দাম ঠিক করেছে।
এখন আপনি যদি VWAP-এর মতো প্রযুক্তিগত টুল দেখেন, তাহলে দেখবেন **VWMA 219.76, দাম 219.90 — অর্থাৎ গড় ক্রেতারা বর্তমান দামে লাভ/লোকসান উভয়ই সমান**। এটি একটি ভারসাম্যহীন অবস্থা, যেখানে বড় বিনিয়োগকারীরা অবস্থান নিচ্ছে না। আপনি "স্প্রিং" বলছেন, আমি বলছি — **এটি একটি সমতল, প্রাণহীন রেখা**
---
## ৮. "BUY না করলে পরে আফসোস করবেন" — উল্টো, এখন Buy করলে আফসোস হবে
আপনি বলছেন, Q4-এর ফলাফল ভালো এলে দাম 230-240-এ চলে যাবে, তখন আর 219.90-তে কিনতে পারবেন না। আমি বলছি — **যদি Q4-এর ফলাফল ভালো আসে, তাহলে প্রযুক্তিগত ব্রেকআউট নিশ্চিত হবে — MACD পজিটিভ ক্রস করবে, ভলিউম বাড়বে, দাম 224.88-এর উপরে ক্লোজ করবে। সেই সময় কেনা অনেক নিরাপদ**
আজ 219.90-তে কেনার ঝুঁকি:
- Q4 খারাপ হলে (EPS <6.0), দাম 213-207-এ নেমে যাবে — আপনার 3-6% লোকসান
- 200-SMA ভাঙলে টেকনিক্যাল সেল-অর্ডার শুরু হবে — 198-এ যেতে পারে — 10% লোকসান
- সেই লোকসান পুষিয়ে উঠতে 6-12 মাস লাগবে — **সুযোগ ব্যয়**
আপনি বলছেন, "অপেক্ষা করার মূল্যই সবচেয়ে বড়" — কিন্তু আমি বলি, **অপ্রয়োজনীয় ঝুঁকি নেওয়ার মূল্যই সবচেয়ে বড়**। বাজারে সবসময় সুযোগ আসে — Q4-এর পরে, ব্রেকআউটের পরে, অথবা 207-213-এ। তাহলে আজকের 219.90-তে কেনার জরুরি কী?
---
## ৯. "SELL/AVOID — ২০২০-এর পরামর্শ" — কিন্তু আমি ৭ বছর ধরে সঠিক ছিলাম
আপনি বলছেন, আমি প্রতি বছর SELL বলেছি, আর কোম্পানি প্রতি বছর EPS বাড়িয়েছে। কিন্তু দেখুন — **আমি SELL বলেছি, কারণ দাম বাড়েনি**। 2020 সালে P/E 10.38-এ কেনা শেয়ার 2025-এ 219.90 — অর্থাৎ 5 বছরে দাম বাড়েনি, শুধু লভ্যাংশ পেয়েছেন। আপনি যদি 2020 সালে Buy করতেন, তাহলে আজ আপনার রিটার্ন শুধু লভ্যাংশ — যা FDR-এর চেয়ে কম। **আমি সঠিক ছিলাম কারণ আমি দামের দিকে তাকিয়ে ছিলাম, EPS-এর দিকে নয়**
এখন 2026 সালে, যখন Q3-তে YoY EPS কমছে, MACD নেতিবাচক, এবং দাম 7 বছরের রেঞ্জের মাঝামাঝি — তখন Buy বলার অর্থ হলো **একই ভুল আবার করা**
---
## উপসংহার: "ভালো কোম্পানি" স্বীকার, "ভালো বিনিয়োগ" অস্বীকার
বুলিশ বন্ধু, আমি একমত — Square Pharmaceuticals একটি অসাধারণ কোম্পানি। ৫২ বিলিয়ন নগদ, ঋণ প্রায় নেই, ৪৪% স্পনসর হোল্ডিং, ১২০% লভ্যাংশ — সবই চিত্তাকর্ষক। **কিন্তু এই সবকিছু ৭ বছর ধরে জানা সত্ত্বেও দাম ১৯৮-২৩৬-এর রেঞ্জ ভাঙতে পারেনি**। বাজার এই তথ্যগুলো জানে, তবুও দাম বাড়ায় না — কারণ বাজার ভবিষ্যৎ প্রবৃদ্ধি নিয়ে সন্দিহান।
আমার চূড়ান্ত বিশ্লেষণ:
| বিষয় | বুলিশ দাবি | বাস্তবতা |
|---|---|---|
| Q3 EPS | "ঋতুভিত্তিক কমা" | YoY -5.2%, গতি হারানো |
| P/E 7.73 | "অযৌক্তিক ডিসকাউন্ট" | প্রবৃদ্ধি 8-10% হলে ন্যায্য মূল্যায়ন |
| লভ্যাংশ 120% | "ক্যাশ জেনারেশন" | ৭ বছরে মোট রিটার্ন FDR-এর চেয়ে কম |
| স্পনসর ৪৪% | "আস্থা" | লিকুইডিটি সংকট, টাইম বোমা |
| ঝুঁকি-রিটার্ন | "৭০:৩০" | ৫০:৫০, প্রযুক্তিগত মোমেন্টাম নেতিবাচক |
| ক্যাটালিস্ট | "Q4, লভ্যাংশ, রপ্তানি" | সব অনিশ্চিত, বাস্তব প্রমাণ নেই |
**আমার চূড়ান্ত প্রস্তাব:**
> **`SQURPHARMA` — SELL/AVOID বর্তমান মূল্য 219.90 BDT-তে**
> - **নতুন বিনিয়োগকারী:** 219-220-এ কিনবেন না। অপেক্ষা করুন। দাম 213-207-এ আসলে (যেখানে ঝুঁকি-রিটার্ন অনুকূল), অথবা 224.88-এর উপরে ভলিউমসহ ক্লোজ করলে (যেখানে আপট্রেন্ড নিশ্চিত), তখন কেনা বিবেচনা করুন।
> - **যাদের শেয়ার আছে:** 213.44 (200-SMA) নিচে স্টপ-লস রাখুন। Q4-এর ফলাফলের আগে আংশিক মুনাফা তুলে নেওয়াই বুদ্ধিমানের কাজ।
> - Q4-এর EPS >7.5 এবং MACD পজিটিভ ক্রস নিশ্চিত হলে — আমরা আবারও বুলিশ আলোচনা করতে পারি। **ততদিন — এই স্টকে নতুন টাকা ঢোকানোর কোনো জরুরি কারণ নেই**।
আপনি বলছেন, "যারা অপেক্ষা করে, তারা কখনো গাড়িতে ওঠে না" — আমি বলি, **যারা লাল বাতিতে গাড়ি চালায়, তারা দুর্ঘটনায় পড়ে**। বর্তমান প্রযুক্তিগত ও মৌলিক সংকেত লাল — অপেক্ষা করুন, নিরাপদ থাকুন। সময় এসেছে নগদে থাকার, না কেনার।
**FINAL RECOMMENDATION: SELL/AVOID `SQURPHARMA` @ 219.90 — স্টপ-লস 213.44, টার্গেট ডাউনসাইড 207-198।**
\ No newline at end of file
Bull Analyst: # SQURPHARMA — বুল কেস: কেন এই দুর্বলতা-ই হলো সেরা কেনার সুযোগ
আমার প্রিয় বেয়িশ বিশ্লেষক বন্ধু, আপনার উদ্বেগগুলো আমি মনোযোগ দিয়ে শুনেছি। আপনি বলছেন MACD নেতিবাচক, RSI নিরপেক্ষ, ভলিউম দুর্বল, আর দাম 50-SMA-এর ঠিক উপরে এসে আটকে আছে — তাই HOLD-এর পরামর্শ। আমি বলছি, **আপনি গাছের দিকে না তাকিয়ে পাতা নাড়াচ্ছেন**। আসুন, পুরো বনটা একবার দেখি।
---
## ১. "দুর্বল মোমেন্টাম" — এটা তো ৭ বছরের সেরা সুযোগ!
আপনি MACD -0.24 দেখে চিন্তিত। আমি দেখছি **P/E মাত্র 7.73** — যা এই কোম্পানির ইতিহাসে সবচেয়ে আকর্ষণীয় স্তরগুলোর একটি। 2019 সালে P/E ছিল 14.68, 2020-তে 10.38, 2021-এ 11.98। আজকে সেই P/E 7.73-এ নেমে এসেছে, অথচ কোম্পানির EPS 2019-এর 16.03 থেকে বেড়ে 2025-এ 27.04 হয়েছে — **প্রায় 69% আয় বৃদ্ধি**, আর শেয়ারের দাম সেই তুলনায় পিছিয়ে আছে। এটাকে কি "দুর্বলতা" বলা যায়, নাকি **গভীর ছাড়ে একটি মানসম্পদ কেনার সুযোগ**?
MACD -0.24 বলছে স্বল্পমেয়াদি মোমেন্টাম ম্লান। কিন্তু মোমেন্টাম ইন্ডিকেটররা পেছনে তাকায় — তারা ভবিষ্যৎ দেখে না, অতীতের দাম নিয়ে হিসাব করে। আমরা বিনিয়োগ করি ভবিষ্যতের জন্য।
---
## ২. ফান্ডামেন্টাল: যেখানে বেয়িশরা চোখ বন্ধ করে
আপনি 7,400 কোটি টাকার কোম্পানির দৈনিক 140,479 শেয়ার ভলিউম নিয়ে মাথা ঘামাচ্ছেন, কিন্তু এর পাশের ছবিটা দেখুন:
- **টানা ৭ বছর EPS বৃদ্ধি:** 16.03 → 15.82 → 17.99 → 20.51 → 21.41 → 23.61 → 27.04
- **FY2026-এর ৯ মাসে EPS 23.29**, যা FY2025-এর একই সময়ের (21.15) চেয়ে **10% বেশি**। অর্থাৎ প্রবৃদ্ধির গতি কিন্তু থামেনি!
- **NAV/শেয়ার 169.79** — বর্তমান দাম 219.90, মানে আপনি এখনও বইমূল্যের মাত্র 1.30 গুণে একটি সুপার ব্র্যান্ড কিনছেন।
- **নগদ 52,013 মিলিয়ন BDT** — প্রায় ৫২ বিলিয়ন টাকা নগদে পড়ে আছে! মোট দায় всего 825.50 মিলিয়ন BDT। অর্থাৎ কোম্পানির হাতে **ঋণের তুলনায় 63 গুণের বেশি নগদ**
এটা কি সাউন্ড কোম্পানি না, বন্ধু? ইন্ট্রাডে চার্টের দিকে তাকিয়ে আছেন, কিন্তু ব্যালেন্স শিট দেখছেন না?
---
## ৩. লভ্যাংশ: নগদে ভাসছে শেয়ারহোল্ডাররা
বেয়িশরা সাধারণত বলে "গেম্বলারদের জন্য স্টক, বিনিয়োগকারীদের জন্য লভ্যাংশ"। তাহলে SQURPHARMA-কে দেখুন:
| বছর | নগদ লভ্যাংশ |
|-----|------------|
| 2019 | 42% (4.20 BDT/share) |
| 2021 | 60% (6.00 BDT/share) |
| 2023 | 105% (10.50 BDT/share) |
| 2024 | 110% (11.00 BDT/share) |
| 2025 | **120% (12.00 BDT/share)** |
প্রতি বছর লভ্যাংশ বাড়ছে! 12 টাকা ডিভিডেন্ড মানে 219.90 টাকায় কেনা শেয়ারে **5.46% নগদ রিটার্ন** — আর এটা তো শুধু লভ্যাংশ; সাথে আছে শেয়ার দরের সম্ভাব্য মূলধনী লাভ। ব্যাংক FDR-এ তো 7-8% পাবেন, কিন্তু সেখানে বৃদ্ধির সম্ভাবনা নেই। এখানে আপনি পাচ্ছেন **নগদ প্রবাহ + 7 বছরের 89% নিট মুনাফা বৃদ্ধির প্রমাণিত ট্র্যাক রেকর্ড**
---
## ৪. "২২০-এ রেজিস্ট্যান্স" — ভাঙতে বেশি দেরি নেই
আমি রেজিস্ট্যান্সের কথা অস্বীকার করছি না — 224.88-এ বোলিঞ্জার আপার ব্যান্ড, 232-236-এ রেঞ্জের উচ্চপ্রান্ত। কিন্তু আপনি কি লক্ষ্য করেছেন, **একই সাথে 216.72-এ নিচের ব্যান্ড, আর 213.44-এ 200-SMA**? অর্থাৎ নিচেও শক্ত জায়গা আছে। আর সবচেয়ে গুরুত্বপূর্ণ বিষয়: **ATR এখন 2.03**। এটি গত ২ সপ্তাহে ক্রমাগত কমেছে।
ইতিহাস বলে, ATR যখন এত সংকুচিত হয়, তখন একটি শক্তিশালী ব্রেকআউট আসন্ন। দেখুন:
- 2026-07-16: RSI ছিল 64.4, দাম ছিল ~232-এর কাছাকাছি
- তারপর পুলব্যাকে RSI 40.2 পর্যন্ত নেমেছে
- এখন RSI 48.73 — মাঝপথে ফিরে এসেছে
অর্থাৎ দর কষাকষির পর এখন **সাপ্লাই আর ডিমান্ড প্রায় সমান**। এ অবস্থা থেকে সাধারণত দাম ওপরের দিকেই রেজোলিউশন হয়, বিশেষত যখন ফান্ডামেন্টাল এত শক্তিশালী। কেন? কারণ 7 দিন আগে যারা 225-এর উপরে কিনেছিল, তারা এখন লাভে আছে; আর যারা বিক্রি করেছে, তারা ইতিমধ্যে বেরিয়ে গেছে। নতুন কেনার আগ্রহ এলেই রেজিস্ট্যান্স ভাঙবে।
---
## ৫. স্পনসর/পরিচালক হোল্ডিং: সবচেয়ে শক্তিশালী বুলিশ সিগনাল
আপনি কি দেখেছেন, **স্পনসর/পরিচালকদের শেয়ারহোল্ডিং 2023-এর 34.67% থেকে বেড়ে 2026-এ 44.15% হয়েছে**? বাংলাদেশের কোনো কোম্পানিতে অভ্যন্তরীণ ব্যক্তিরা এতটা শেয়ার জমাচ্ছেন — এটাকে আমি সবচেয়ে বড় বুলিশ সিগনাল বলব।
যারা কোম্পানির ভেতরের খবর সবচেয়ে ভালো জানেন, তারা কি করে শেয়ার কিনছেন যদি ভবিষ্যৎ খারাপ হয়? উল্টো, বেয়িশরা সাধারণত পরিচালকদের বিক্রির খবর নিয়ে চিন্তিত থাকে। এখানে তো পরিচালকরাই দামের নিচে বারবার শেয়ার কিনে নিজেদের অংশ বাড়াচ্ছেন! 44.15% মানে প্রায় 391.5 মিলিয়ন শেয়ার — এক বিশাল অংশ। এই মানুষগুলো দীর্ঘমেয়াদে কোম্পানির প্রবৃদ্ধিতে শতভাগ আস্থাশীল।
---
## ৬. বেয়িশদের "কম ভলিউম" যুক্তির জবাব
আপনি বলছেন, "ভলিউম 140,479 — কম, তাই কেনার আগ্রহ দুর্বল।" আমি বলছি, এটা অস্বাভাবিক কিছু নয়। SQURPHARMA-এর মতো একটি প্রতিষ্ঠিত, বৃহৎ ক্যাপ কোম্পানিতে দাম যখন রেঞ্জের মাঝামাঝি থাকে, তখন দিনের পর দিন কম ভলিউমে ট্রেড হওয়া স্বাভাবিক। মনে রাখবেন, এই শেয়ারের মোট বাজার মূলধন (মার্কেট ক্যাপ) ≈ 195,000 মিলিয়ন BDT (প্রায় ২ লাখ কোটি টাকা)। এত বড় কোম্পানিতে প্রতিদিন ১৪০ হাজার শেয়ার ট্রেড হওয়াই যথেষ্ট, কারণ বেশিরভাগ শেয়ার (44.15% স্পনসর + 14.81% বিদেশি) লং-টার্ম বিনিয়োগকারীদের কাছে লকড।
**কম ভলিউমের নিচে দাম ভাঙেনি!** 216.72 (boll_lb) বা 213.44 (200-SMA) ভাঙেনি। দাম 219-220-এ স্থিতিশীল। এটাই প্রমাণ করে বিক্রয়চাপ নেই; দুর্বল হাতগুলো ইতিমধ্যে বেরিয়ে গেছে।
---
## ৭. সেক্টর প্রবণতা: বাংলাদেশের ওষুধ শিল্পের সোনালি সময়
বাংলাদেশের ফার্মাসিউটিক্যাল শিল্প এখন স্থানীয় চাহিদার 97% পূরণ করে, আর রপ্তানি বাড়ছে। Square Pharmaceuticals-কে কেন্দ্র করেই এই শিল্পের নেতৃত্ব। কোম্পানির পণ্য ৪০টিরও বেশি দেশে রপ্তানি হয়। বিশ্ববাজারে জেনেরিক ওষুধের চাহিদা বাড়ছে — এটা তো বৈশ্বিক প্রবণতা। কোম্পানির বর্তমান উৎপাদন সক্ষমতা, R&D-তে বিনিয়োগ এবং নতুন প্রোডাক্ট লঞ্চ — সবই ভবিষ্যৎ প্রবৃদ্ধিকে সমর্থন করছে।
FY2026-এর ৯ মাসের EPS 23.29 দেখে আপনি কি মানবেন না যে বৃদ্ধি অব্যাহত? বার্ষিক প্রজেক্ট করলে FY2026-এ EPS 30+ হতে পারে। সেই হিসেবে বর্তমান P/E তো 7.3-এ নেমে আসবে! বিশ্বের যেকোনো মানদণ্ডে এটি অতি সস্তা।
---
## ৮. বেয়িশ "ব্রেকডাউন" ঝুঁকির জবাব
আপনি বলছেন, "216.72 ভেঙে গেলে 207-208 পর্যন্ত নামতে পারে।" হ্যাঁ, মার্কেটে সবসময় দুই দিকের সম্ভাবনা থাকে। কিন্তু প্রশ্ন হলো: প্রোবাবিলিটি কোন দিকে বেশি?
প্রযুক্তিগতভাবে:
- 200-SMA 213.44-তে — 3% নিচে
- 52-সপ্তাহের লো 198 — 10% নিচে
- অন্যদিকে 52-সপ্তাহের হাই 236 — 7% উপরে
ফান্ডামেন্টালি:
- EPS 27.04, লভ্যাংশ 12.00, নগদ 52 বিলিয়ন, ঋণ প্রায় নেই, পিএই 7.73
- ৯ মাসের EPS 23.29 — বছরে 30+ সম্ভব
**ঝুঁকি-রিটার্ন অনুপাত:** নিচে মাত্র 3-7% ঝুঁকি, উপরে 7-15% সম্ভাবনা। আর দীর্ঘমেয়াদি বিনিয়োগকারীদের জন্য তো এটি আরও ভালো — 213-216-এ ভালো সাপোর্ট, আর ব্রেকআউট হলে 232-236-এ টার্গেট।
---
## ৯. এক মিনিটের জন্য ইন্ট্রাডে চার্টের বাইরে আসুন
আমরা যদি ২০১৯ থেকে আজকের ছবিটা এক নজরে দেখি:
- 2019: EPS 16.03, দাম 235 টাকার কাছাকাছি (P/E 14.68)
- 2025: EPS 27.04, দাম 219.90 (P/E 7.73)
**৭ বছর আগের তুলনায় EPS 69% বেশি, কিন্তু দাম আজও সেবছরের সমান!** এর মানে হলো — বাজারের সামগ্রিক মন্দা, অস্বাভাবিক বিনিয়োগকারী মনস্তত্ত্ব, আর নন-ফান্ডামেন্টাল কারণে শেয়ারটি বছরের পর বছর অবমূল্যায়িত হয়েছে। বুলিশ বিশ্লেষক হিসেবে এটাই আমার সবচেয়ে বড় যুক্তি: **আপনি যখন কোনো কোম্পানির আয় দ্বিগুণের কাছাকাছি হচ্ছে, কিন্তু দাম একই জায়গায় আটকে আছে — তখন সেটি "মন্দা" নয়, "ছাড়ে বিক্রি" (sale)।**
---
## ১০. বেয়িশদের HOLD বনাম আমাদের BUY
আপনি HOLD বলছেন, কারণ "নিরপেক্ষ অবস্থানে কোনো স্পষ্ট ব্রেকআউট নেই।" কিন্তু যে বিনিয়োগকারী 2019 সালে 235 টাকায় শেয়ার কিনেছিলেন, আজ 219.90-তে দাম — তিনি যদি HOLD-ই করে থাকেন, তবে 7 বছরে তার শেয়ারে শুধু লভ্যাংশই এসেছে। এখন যদি 219.90-তে BUY করা যায়, তাহলে তার চেয়ে ভালো এন্ট্রি পয়েন্ট আর কী হতে পারে?
**আমার প্রস্তাব:** যারা দীর্ঘমেয়াদে বিনিয়োগ করতে চান, তাদের জন্য এখানে HOLD না বলে **BUY (যোগ/সঞ্চয়)** করা উচিত। বিশেষত:
- যাদের পোর্টফোলিওতে SQURPHARMA নেই, তারা 216-220 জোনে প্রথম কিস্তিতে কেনা শুরু করতে পারে
- যাদের আছে, তারা 213-216 (200-SMA)-এর কাছাকাছি আরও যোগ করতে পারে
- 221+ ভলিউমে ব্রেকআউট হলে দ্বিতীয় কিস্তি যোগ করুন
---
## উপসংহার: সময় ঘুরে দাঁড়ানোর
বেয়িশ বন্ধু, আপনার প্রতিটি প্রযুক্তিগত সূচক সঠিক — কিন্তু সেই সূচকগুলো কেবল বর্তমান মুহূর্তের ছবি দেখায়। আমি আপনাকে সেই ছবির ফ্রেমের বাইরে তাকাতে বলছি।
**SQURPHARMA এমন একটি কোম্পানি যার:**
- টানা ৭ বছর EPS বৃদ্ধি পেয়েছে
- নগদ ৫২ বিলিয়ন টাকা
- ঋণ প্রায় নেই
- পরিচালকরা ৪৪% শেয়ার ধরে রাখছেন
- লভ্যাংশ ১২০%-তে
- P/E ৭.৭৩ — ইতিহাসের সর্বনিম্ন অঞ্চলে
- FY26-এর ৯ মাসের EPS ২৩.২৯ — প্রবৃদ্ধি বজায়
আমি এটাকে **"মন্দা"** না বলে **"নীরব সুযোগ"** বলব। এমন একটি দৃঢ় ফান্ডামেন্টাল কোম্পানি যখন 200-SMA-এর ঠিক উপরে, 52-সপ্তাহের রেঞ্জের নিম্ন-মাঝামাঝি, এবং P/E 7-এ — তখন প্রকৃত বুলিশ বিশ্লেষক আতঙ্কিত হন না, বরং **ক্রয়ের সুযোগ গ্রহণ করেন**। দাম 221-224-এ গেলে বোলিঞ্জার ব্যান্ডের ওপরের দিকে যাবে; 232 ভাঙলে পরবর্তী টার্গেট 236+। নিচের ঝুঁকি 200-SMA-তে সীমাবদ্ধ — মাত্র ৩%।
সুতরাং, আমার চূড়ান্ত প্রস্তাব: **HOLD নয় — ACCUMULATE/BUY**। 219.90-তে এই স্টক, বাংলাদেশের সেরা ফার্মাসিউটিক্যাল কোম্পানি, ৭.৭ গুণ আয়ের বিনিময়ে — এটি আমি হাতে ছাড়তে চাই না, বরং দুই হাতে কুড়াতে চাই। সময়ই প্রমাণ করবে, আজকের "হতাশার দাম" ১২ মাস পরে "দর কষাকষির সাফল্য" হয়ে উঠবে। 🚀
Bull Analyst: # SQURPHARMA — চূড়ান্ত বুলিশ প্রতিউত্তর: "ভ্যালু ট্র্যাপ" নয়, "ভ্যালু স্টোর" — সময় এসেছে সিদ্ধান্তের
প্রিয় বেয়িশ বন্ধু,
আপনার যুক্তিগুলো তীক্ষ্ণ, বন্ধু — আমি সেটা স্বীকার করছি। আপনি প্রতিটি পয়েন্টকে ঘুরিয়ে ফিরিয়ে উপস্থাপন করেছেন, কিন্তু আজকের এই আলোচনায় আমি প্রমাণ করতে চাই যে **আপনি সংখ্যাগুলো দেখেছেন, কিন্তু গল্পটা পড়েননি**। আসুন, আপনার প্রতিটি আপত্তি নিয়ে খোলাখুলি বিতর্ক করি — যেখানে তথ্য ও যুক্তি দিয়ে আমি প্রমাণ করব, কেন `SQURPHARMA`-তে এখনই BUY করা উচিত, HOLD বা SELL নয়।
---
## ১. "Q3-এ EPS কমছে" — আপনি ভুল জায়গায় লাল দাগ দেখছেন
আপনি বলছেন, Q1: 8.35 → Q2: 8.20 → Q3: 6.73 — টানা তিন কোয়ার্টারে EPS কমছে, এটা প্রবৃদ্ধি মন্দার সংকেত। কিন্তু আমি আপনাকে SQURPHARMA-র **ঋতুভিত্তিক (seasonal) আয়ের প্যাটার্ন** মনে করিয়ে দিই:
| FY | Q1 EPS | Q2 EPS | Q3 EPS | Q4 EPS | বার্ষিক EPS |
|---|---|---|---|---|---|
| FY2024 | ~6.1 | ~6.3 | ~5.8 | ~5.4 | 23.61 |
| FY2025 | ~6.9 | ~7.1 | ~7.1 | ~5.9 | 27.04 |
| FY2026 | 8.35 | 8.20 | 6.73 | ? | প্রক্ষেপিত 30+ |
**লক্ষ্য করেছেন?** প্রতিটি বছরে Q3/Q4-তে EPS স্বাভাবিকভাবেই কমে — কারণ ঔষধ শিল্পের বিক্রি মৌসুমি (seasonal), আর বাজেট-পরবর্তী সময়ে বিক্রি কিছুটা স্থবির থাকে। কিন্তু FY2026-এর Q1 (8.35) এবং Q2 (8.20) — ইতিহাসের **সেরা দুই কোয়ার্টার**। অর্থাৎ ভিত্তি অনেক উঁচু থেকে শুরু হচ্ছে। এমনকি Q3-এ 6.73 এসেও, **৯ মাসের EPS (23.29) গত বছরের ৯ মাসের EPS (21.15) থেকে 10% বেশি** — আগের বছরেও Q3/Q4-এ সাময়িক দুর্বলতা ছিল, কিন্তু বার্ষিক প্রবৃদ্ধি থেমে থাকেনি।
এখন Q4-এ যদি গত বছরের মতোই ~6.5-7.0 আসে, তাহলে বার্ষিক EPS হবে **~30** — যা FY2025-এর 27.04 থেকে 11% প্রবৃদ্ধি। আপনি কি বলছেন, 11% প্রবৃদ্ধি "শ্লথ"? বিশ্বের যেকোনো উন্নত বাজারে এটি দারুণ প্রবৃদ্ধি। আর P/E 7.73-এর সাথে এই 11% প্রবৃদ্ধি মিলিয়ে — এটি এখনও **PEG রেশিও 0.70** — মানে মারাত্মক সস্তা।
---
## ২. "লভ্যাংশ = প্রবৃদ্ধির অভাব" — এই সমীকরণ ভুল
আপনার যুক্তি: "৫২ বিলিয়ন টাকা নগদ জমানো, লভ্যাংশ দেওয়া — মানে নতুন বিনিয়োগের সুযোগ নেই।" বন্ধু, এটা বাংলার শীর্ষ কর্পোরেট গল্পের ভুল ব্যাখ্যা।
গণিতটা দেখুন: **নগদ ৫২ বিলিয়ন + বাজারযোগ্য সিকিউরিটিজ ৯.৩ বিলিয়ন** — মোট তরল সম্পদ প্রায় **৬১ বিলিয়ন BDT**। অথচ মোট ঋণ মাত্র ৮২৫ মিলিয়ন BDT। এখন প্রশ্ন: কেন একটি কোম্পানি এত নগদ জমায়?
এর কারণ — **কৌশলগত সুযোগ ও সম্প্রসারণ**। Square শুধু ওষুধ নয়, ভোক্তা পণ্য (Square Toiletries), খাদ্য (Square Food & Beverage) — সর্বত্র সম্প্রসারণ করছে। নতুন ওষুধ ক্যাটাগরিতে (ইনসুলিন, অনকোলজি, বায়োসিমিলার) বিনিয়োগ, রপ্তানি বাজারে সম্প্রসারণ — সবকিছুর জন্যই এই নগদ।
আর লভ্যাংশ? 120% লভ্যাংশ মানে প্রতি শেয়ারে 12 টাকা নগদ — এটি প্রমাণ করে কোম্পানির **ক্যাশ জেনারেশনের ক্ষমতা**। যে কোম্পানি EPS-এর 44% নগদে দেয়, বাকি 56% ধরে রাখে, আর ৫২ বিলিয়ন নগদে রাখে — সেটি "প্রবৃদ্ধির অভাব" নয়, **আর্থিক শৃঙ্খলার প্রতীক**। Apple-ও তো বিলিয়ন বিলিয়ন ডলার নগদে রাখে — কেউ কি বলবে Apple-এর প্রবৃদ্ধি শেষ?
---
## ৩. "Free float ২৭% — লিকুইডিটি ফাঁদ" — উল্টো, এটাই স্থিতিশীলতার বড় প্রমাণ
আপনি বলছেন, 72.77% শেয়ার লকড থাকায় তরলতা কম। আমি বলছি — **এই লকড থাকাটাই সবচেয়ে বড় শান্তির কারণ**
মনে করুন:
- স্পনসর/পরিচালকদের হোল্ডিং ৪৪.১৫% — তারা কেন কিনছেন? কারণ কোম্পানির ভবিষ্যৎ সম্পর্কে তাদের পূর্ণ আস্থা।
- বিদেশি হোল্ডিং ১৪.৮১% — আন্তর্জাতিক বিনিয়োগকারীরা সক্রিয়ভাবে শেয়ার নিচ্ছেন।
- এই ৫৯% শেয়ার (স্পনসর+বিদেশি) **আউট-অফ-মার্কেট** — তারা ডাম্পিং করছে না।
ফলে বাজারে আসল বিক্রয়যোগ্য শেয়ার (free float) ৪১%-এর কাছাকাছি, যার মধ্যে প্রাতিষ্ঠানিক ১৩.৮১% আছে — তারা সাধারণত দীর্ঘমেয়াদি। অর্থাৎ, প্রকৃত "হট মানি" খুবই কম। এত কম ফ্লোটিং শেয়ার থাকলে **যেকোনো ভালো খবরে দাম দ্রুত উপরে উঠতে পারে**, কারণ সাপ্লাই সীমিত। ডিসেম্বর ২০২৫-এ দাম ১৯৯-এ নেমেছিল — কিন্তু সেটা **বাজার-ব্যাপী মন্দার সময়**, SQURPHARMA-নির্দিষ্ট সমস্যায় নয়। সেই ১৯৯ থেকে আজ ২২০ — 10.5% রিকভারি হয়েছে।
---
## ৪. "টেকনিক্যালি নিচে যাওয়ার ঝুঁকি" — আপনি আয়নাটা ওলট করে ধরছেন
আপনার টেবিল:
| লেভেল | মান | দূরত্ব |
|---|---|---|
| উপরে: বোলিঞ্জার UB | 224.88 | +2.3% |
| উপরে: 52-সপ্তাহের হাই | 236.00 | +7.3% |
| নিচে: 200-SMA | 213.44 | -2.9% |
| নিচে: 52-সপ্তাহের লো | 198.00 | -10% |
আপনি বলছেন, ঝুঁকি-রিটার্ন ৫০:৫০। আমি বলছি — **এটা ৭০:৩০, উপরের দিকের পক্ষে**। কেন?
- **200-SMA (213.44) ২ বছর ধরে অক্ষত:** দীর্ঘমেয়াদি ট্রেন্ডের স্বাস্থ্য ভালো।
- **52-সপ্তাহের লো (198) স্পর্শ করেছে 8 মাস আগে** — তখন বাজার-ব্যাপী আতঙ্ক ছিল (DSEX ১১% পড়েছিল)। আজকের বাজার পরিস্থিতি স্থিতিশীল — এমনকি DSEX-এর সাথে তুলনা করলে ঔষধ সেক্টর আউটপারফর্ম করেছে।
- **ম্যাক্রো-পরিস্থিতি উন্নতি:** মূল্যস্ফীতি কমছে, বাংলাদেশ ব্যাংকের হার নীতিও স্থিতিশীল — ১৯৯-এ যাওয়ার শর্ত আর নেই।
আর প্রযুক্তিগত দিক থেকে — আপনি বলছেন "দাম 10-EMA এবং 50-SMA-এর সংযোগস্থলে ঠেকেছে, MACD নেতিবাচক"। কিন্তু দেখুন:
- RSI 48.73 — **আমি বলি এটি 40-এর নিচে থেকে ফিরে আসা**। 07-29-এ RSI ছিল 40.2, এখন 48.73 — নির্দেশ করে **নিম্নমুখী চাপ কমছে**
- MACD -0.24 — এটি **সিগনাল লাইন (macds = -0.01)-এর কাছাকাছি**। খুব দ্রুত ক্রসওভার হতে পারে। আর MACD-এর মান এত ছোট (-0.24) — এটি "শক্তিশালী বিয়ারিশ" নয়, "নিরপেক্ষ"।
- ATR 2.03 — কমেছে, কিন্তু **দাম 200-SMA-এর 3% উপরে** — ঊর্ধ্বমুখী কাঠামো বজায় আছে।
এখনই BUY না করার কোনো যুক্তি নেই — বিশেষত যখন দাম এই সাপোর্টগুলোর কাছাকাছি আসছে।
---
## ৫. "ভ্যালু ট্র্যাপ" — আমি বলি, "ভ্যালু স্টোর"
আপনি সবচেয়ে জোর দিয়েছেন এখানে: "2019 থেকে 2025 পর্যন্ত EPS 69% বাড়লেও দাম 6% কমেছে — এটা ভ্যালু ট্র্যাপ।"
বন্ধু, **এটাই ভ্যালু স্টোরের সংজ্ঞা**। যখন বাজার আতঙ্ক, তারল্য সংকট, বা সেক্টর-নির্দিষ্ট কারণে একটি কোম্পানির শেয়ার **আয়ের তুলনায় অনেক কম দামে** লেনদেন হয় — তখন সেটি ভ্যালু ট্র্যাপ নয়, **ভ্যালু সুযোগ**
গুরুত্বপূর্ণ প্রশ্ন: **বাজার কি ঠিক না বাজার ভুল?**
আপনার পক্ষে প্রমাণ:
- Q3 EPS কমেছে
- P/E কমেছে
আমার পক্ষে প্রমাণ:
- **টানা ৭ বছর বার্ষিক EPS বৃদ্ধি**
- **টানা ৬ বছর নগদ লভ্যাংশ বৃদ্ধি** (60% → 120%)
- **টানা ৩+ বছর স্পনসর হোল্ডিং বৃদ্ধি** (34.67% → 44.15%)
- **নগদ ৫২ বিলিয়ন + ঋণ ০.৮২ বিলিয়ন** — নিট নগদ ≈ 51 বিলিয়ন
- **ROE এখনও 17%+** (EPS 27.04 ÷ NAV 157.88)
এই সবকিছু মিলিয়ে — **বাজার সঠিক নয়, বাজার উদাসীন**। আর উদাসীন বাজারই লাভের সুযোগ তৈরি করে।
---
## ৬. "সেক্টর স্যাচুরেশন ঝুঁকি" — আপনার তথ্য পুরনো
আপনি বলেছেন, "দেশে 97% সরবরাহ — স্যাচুরেশন হয়ে গেছে।" আমি বলছি, বাংলাদেশের ফার্মাসিউটিক্যাল রপ্তানি **২০২৪-২৫ সালে ২০%+ বেড়েছে**, এখন প্রায় ২০০ মিলিয়ন ডলার ছাড়িয়েছে। Square-এর রপ্তানি আয়ও বাড়ছে — পূর্ব ইউরোপ, আফ্রিকা, এশিয়ায় নতুন বাজার। ওষুধ তো এমন পণ্য নয়, যা ২-৩ বার কিনে শেষ — **এটি রেকারিং আয়ের উৎস**। জনসংখ্যা বৃদ্ধি, বয়স্ক জনসংখ্যা, নন-কমিউনিকেবল ডিজিজের (ডায়াবেটিস, উচ্চরক্তচাপ) প্রাদুর্ভাব — সবই দীর্ঘমেয়াদি চাহিদা তৈরি করছে।
আপনি প্রতিযোগীদের নাম নিয়েছেন — ইনসেপ্টা, বেক্সিমকো, এসকেএফ। কিন্তু **Square এখনও মার্কেট শেয়ারে শীর্ষে**, বাংলাদেশের মোট ঔষধ বাজারে ১৭-১৮% অংশ নিয়ে। এত বড় প্রতিষ্ঠানের কাছে প্রতিযোগিতা — দাম কমানোর সুযোগ তো দূর, বরং **ব্র্যান্ডিং শক্তিতে প্রতিটি চ্যালেঞ্জারকে ছাড়িয়ে যাওয়ার সক্ষমতা** রয়েছে। R&D-তে বিনিয়োগ চলছে — নতুন ড্রাগ ডেলিভারি সিস্টেম, বায়োসিমিলার — এগুলো ভবিষ্যৎ আয়ের পথ আরও প্রশস্ত করবে।
---
## ৭. বেয়িশের "SELL/AVOID" — সময়োপযোগী সিদ্ধান্ত, নাকি সুযোগ হারানো?
আপনার চূড়ান্ত পরামর্শ: "SELL/AVOID — নগদে থাকুন, Q4-এর ফলাফল দেখুন।" বন্ধু, আমি প্রশ্ন করি — **Q4-এর ফলাফল ভালো আসলে আপনি কি ২৫০-এ ফিরে কিনবেন?** তখন P/E বেড়ে ৯-১০ হবে, আর আপনার "নিরাপদ নগদ" সিদ্ধান্তের সুযোগ হারিয়ে যাবে।
বাজারে যারা সর্বদা অপেক্ষায় থাকে, তারা আমরা আগের বুলিশদের সেই জায়গায় দেখি — **অপেক্ষারত বিনিয়োগকারীরা কখনো ধনী হয় না, তাদের উত্তরাধিকারীরা হয়**। সত্যিকারের বিনিয়োগ হয় **অনিশ্চয়তার মধ্যে আস্থা** আর **মূল্যহ্রাসের সময় সাহস** নিয়ে।
আপনি যে "ঝুঁকি" নিয়ে কথা বলছেন — 213.44-এ 200-SMA ব্রেক হলে 207-208 যেতে পারে — তার ডাউনসাইড খুবই সীমিত (6%)। অথচ উপরের দিকে, Q4 ভালো ফলাফল + বার্ষিক EPS 30 + লভ্যাংশ বাড়িয়ে 125-130% হলে — শেয়ার 250-260-এ যেতে পারে (12-18% আপসাইড)। **ঝুঁকি-রিটার্ন অনুপাত গণিতের দিক থেকেই উপরের দিকে অনুকূল।**
---
## ৮. যোগ করুন, অপেক্ষা নয় — আপনার পোর্টফোলিওতে যোগ করুন
আমি আপনাকে আরও সুনির্দিষ্ট প্রস্তাব দিচ্ছি:
**এখনই BUY/ACCUMULATE করুন:**
- যারা নতুন — 216-220 জোনে প্রথম কিস্তিতে ৫০% কেনাকাটি করুন
- যারা আছেন — 213-216-এ দ্বিতীয় কিস্তির জন্য টাকা রাখুন (স্টপ-লস: 210-এর নিচে ক্লোজে)
- যারা ঝুঁকি কমাতে চান — 221-এ ব্রেকআউট নিশ্চিত হলে বাকি ৫০% যোগ করুন
**টার্গেট:**
- স্বল্পমেয়াদি: 224-232 (বোলিঞ্জার UB + রেঞ্জ-হাই)
- মাঝারি-মেয়াদি (৬-১২ মাস): 250+ (P/E 9-এ)
- দীর্ঘমেয়াদি (২-৩ বছর): 300+ (যদি EPS 35-40 হয় — Square-এর ট্র্যাক রেকর্ড এটি সম্ভব করে)
---
## উপসংহার: এই জঙ্গলে গাছ নয়, গোটা বন
প্রিয় বেয়িশ বন্ধু, আপনি লাল পতাকা তুলেছেন — আমি সেগুলোকে সবুজ বাতি হিসেবে দেখছি। আপনি উদ্বেগকে যুক্তি বানিয়েছেন — আমি আত্মবিশ্বাসকে বিশ্লেষণ বানিয়েছি। মার্কেটে সবসময় দুই দিক থেকেই যুক্তি দেওয়া যায়। কিন্তু **যে সংখ্যাগুলো গত ৭ বছর এত শক্তিশালী ছিল, সেই সংখ্যাগুলোর কথা আজ বদলায়নি** — বরং উল্টো আরও ভালো হয়েছে (EPS 16→27, লভ্যাংশ 42%→120%, স্পনসর 34%→44%)।
**`SQURPHARMA` কোন ভ্যালু ট্র্যাপ নয়** — এটা বাংলাদেশের শেয়ারবাজারের **সবচেয়ে অবমূল্যায়িত নীল-চিপ**। যাঁরা 2019 সালে ১৪.৬৮ P/E-তে কিনেছিলেন, তাঁরা আজও শেয়ার ধরে আছেন — কারণ তাঁরা ফান্ডামেন্টাল দেখে বিনিয়োগ করেছেন, ইন্ট্রাডে চার্ট দেখে নয়। আজ ৭.৭৩ P/E-তে কেনা তাঁদের চেয়েও বেশি লাভজনক হবে।
সুতরাং, আমার চূড়ান্ত প্রস্তাব — **BUY / ACCUMULATE** — কিন্তু এই মাত্র, প্রতিটা দামে। Q4-এর ফলাফল আসবে, MACD ক্রসওভার করবে, আর 220-221 ভাঙবে — ততদিনে যাঁরা এই স্টকের কিনে বসে থাকবেন, তাঁরাই হবেন স্মার্ট মানি।
**FINAL RECOMMENDATION: BUY/ACCUMULATE `SQURPHARMA` @ 219.90 — মূল লক্ষ্য: 250+ (12-মাস টাইমফ্রেম)।** 🚀
Bull Analyst: # SQURPHARMA — চূড়ান্ত বুলিশ বিবৃতি: "মন্দা" নয়, এই মুহূর্তটাই স্বর্ণালী সুযোগ
প্রিয় বেয়িশ বন্ধু,
আপনার শেষ বক্তব্য পড়ে মনে হলো — আপনি **কোম্পানিটিকে ভালো বলেই মানছেন, কিন্তু শেয়ারটিকে এড়িয়ে যেতে বলছেন**। আপনার যুক্তি হলো, "দারুণ কোম্পানি মানেই দারুণ স্টক নয়।" আমি বলব — **এমন একটি কোম্পানিকে যখন বাজার ৭.৭৩ P/E-তে ছেড়ে দেয়, তখন সেটিই সেরা স্টক হয়ে ওঠে।** আজকের বাজারে ক্যাটালিস্ট খুঁজতে খুঁজতে যারা কালকের সুযোগ হাতছাড়া করে, তারাই পরে সবচেয়ে বড় আফসোস করে। আসুন, আপনার প্রতিটি বুলেট আমি কাঁচা সংখ্যা দিয়ে ভেঙে দিই।
---
## ১. "Q3-এ EPS কমেছে" — আপনি ইতিহাসের সাথে তুলনা করছেন না, এক বছরের সাথে করছেন
আপনার টেবিলে আমি Q1 (+21%) ও Q2 (+15%)-এর YoY প্রবৃদ্ধি দেখেছি, কিন্তু Q3-এ (-5.2%) দেখে আপনি এলার্ম বাজাচ্ছেন। বন্ধু, **একটি অস্বাভাবিক ভালো Q1 ও Q2-এর পরে Q3-এ সামান্য কমাটাই স্বাভাবিক** — বিশেষত যখন আগের বছরের Q3 ছিল 7.1 (তখন ৭ বছরের মধ্যে সর্বোচ্চ Q3 ছিল)।
আমি আপনাকে গত ৫ বছরের সিজনাল প্যাটার্ন দেখাই:
- FY2024: Q1 (~6.1), Q2 (~6.3), Q3 (~5.8), Q4 (~5.4) — Q3-এ 8% কমে, Q4-এ আরও কমে
- FY2025: Q1 (~6.9), Q2 (~7.1), Q3 (~7.1), Q4 (~5.9) — Q4-এ 17% কমে
- FY2026: Q1 (8.35), Q2 (8.20), Q3 (6.73) — Q3-এ 18% কমে, Q4-এ আরও কিছুটা কমার সম্ভাবনা
**লক্ষ্য করুন, প্রতি বছর Q4-এ EPS সবচেয়ে কমে!** FY2024-এর Q4 ছিল 5.4, FY2025-এর Q4 ছিল 5.9। এবার যদি Q4-এ 6.3-6.5 আসে — তাহলে বার্ষিক EPS হবে **~29.5-30**। মানে FY2025-এর 27.04 থেকে **প্রায় 10% প্রবৃদ্ধি**! আপনি বলছেন এটি "মন্থর"। আমি বলছি — **বাংলাদেশের শেয়ারবাজারে 10% EPS প্রবৃদ্ধি + 120% লভ্যাংশ + P/E 7.7 হলে সেটি জাদু**। পৃথিবীর কোনো উন্নত বাজারে এমন সুযোগ নেই।
---
## ২. "P/E কমছে মানে বাজার ভবিষ্যৎ দেখছে না" — বরং বাজার অতীতের ভুল শুধরে নিচ্ছে
আপনার যুক্তি: "P/E 14.68 থেকে 7.73-এ নামা মানে ডি-রেটিং।" আমি বলি — **ডি-রেটিং হয়েছে কারণ 2019 সালের P/E ছিল অযৌক্তিকভাবে বেশি**। তখন কোম্পানির EPS ছিল 16.03, বাজারের প্রত্যাশা ছিল 20%+ স্থায়ী প্রবৃদ্ধি। কিন্তু বাস্তবে প্রবৃদ্ধি হয়েছে 11-14%। তাই বাজার একে **পরিণত কোম্পানি** হিসেবে মূল্য দিতে শুরু করেছে। এটি নেতিবাচক নয় — এটি **বাস্তবতার সাথে সামঞ্জস্য**
এখন প্রশ্ন: এই 7.73 P/E-তে কি ঝুঁকি ডিসকাউন্টেড? আসুন দেখি:
| অনুপাত | SQURPHARMA | সেক্টর গড় (DSE) |
|---|---|---|
| P/E | 7.73 | 12-15 |
| P/B | 1.30 | 2.5-3.0 |
| Dividend Yield | 5.46% | 2-3% |
| ROE | 17.1% | 8-12% |
**এই কোম্পানি সেক্টর গড়ের তুলনায় 40-50% ডিসকাউন্টে ট্রেড করছে, অথচ ROE দ্বিগুণের বেশি এবং লভ্যাংশ ফলন দ্বিগুণ!** এটাকে "মন্দার প্রাইসিং" বলবেন? আমি বলি — **এটা অজ্ঞতা বা পুঁজিবাজারের তারল্যসংকটের কারণে অযৌক্তিক ডিসকাউন্ট**, যা একদিন অবশ্যই বন্ধ হবে।
---
## ৩. "লভ্যাংশ মানে প্রবৃদ্ধির সুযোগ নেই" — এই যুক্তি ২০২০-এ ভুল ছিল, ২০২৬-এ আরও ভুল
আপনি বলছেন, "৫২ বিলিয়ন নগদ + লভ্যাংশ দেওয়া = প্রবৃদ্ধির অভাব।" বন্ধু, **যে কোম্পানি ৪৪% পেআউট রেশিও রেখে ৫২ বিলিয়ন টাকা নগদ জমায়, তার হাতে এখন ব্যালেন্স শিটে যে কৌশলগত সম্প্রসারণের অপশন আছে, তা বাংলাদেশের কোনো কোম্পানির নেই।**
আমি আপনাকে গত ২ বছরের ঘটনা বলি:
- ২০২৩-এ কোম্পানি নতুন অ্যান্টিবায়োটিক ও ডায়াবেটিস পণ্য লঞ্চ করেছে
- ২০২৪-এ রপ্তানি বাজার সম্প্রসারণ করেছে — পূর্ব ইউরোপ ও আফ্রিকায়
- Q3 FY26-এ NAV 169.79 — মানে সম্পদ প্রতিটি কোয়ার্টারে বাড়ছে
**এবং ১২০% লভ্যাংশ?** এটি প্রমাণ করে কোম্পানির **ক্যাশ জেনারেশন ক্ষমতা আসল** — এটি EPS-এর সাথে প্রতারণা নয়। 2019 সালে লভ্যাংশ ছিল 42%, 2025-এ 120% — মানে প্রতি বছর শেয়ারহোল্ডাররা আরও বেশি টাকা ফেরত পাচ্ছেন। **আপনি FDR-এ 8% পাবেন, এখানে 5.46% লভ্যাংশ + সম্ভাব্য মূলধনী লাভ।** FDR-এ কি ৭ বছরে ৬৯% EPS প্রবৃদ্ধি দেখার সুযোগ আছে? না, কখনোই না।
---
## ৪. "Free float কম — লিকুইডিটি ফাঁদ" — আমি বলি, এটি আস্তে আস্তে জ্বলতে থাকা আগুন
আপনি 72.77% লকড শেয়ারকে ঝুঁকি বলছেন। আমি বলছি — **এই 44.15% স্পনসর হোল্ডিং ইতিহাসের সর্বোচ্চ এবং ক্রমবর্ধমান**। আপনি কি জানেন এর অর্থ কী?
- 2023: স্পনসর 34.67% → 2024: 35.46% → 2025: 43.59% → 2026: 44.15%
- **কোম্পানির ভেতরের মানুষজন যারা সবচেয়ে ভালো জানে, তারা গত ৩ বছরে তাদের অংশ ৩৪.৬৭% থেকে বাড়িয়ে 44.15% করেছে!**
এখন, এই লোকেরা কি বোকা? তারা কি স্টক বিক্রি করে লাভ করতে জানেন না? তারা জানেন, কিন্তু তারা বিক্রি করছেন না — **কেননা তারা জানেন ভবিষ্যৎ সুন্দর**। বিদেশি হোল্ডিং 13.76% → 14.81% — তারাও বাড়াচ্ছেন। আপনি "আস্থার প্রতীক" আর "লিকুইডিটি ফাঁদ" আলাদা করেছেন — কিন্তু আমি বলি, **আস্থা এবং লিকুইডিটি একই মুদ্রার দুই পিঠ**। যখন স্পনসররা 44% ধরে আছেন, তখন বাজারে সাপ্লাই কম — মানে একটু ভালো খবর এলেই দাম উপরে উঠবে দ্রুত। 2025-এর ডিসেম্বরে 199 থেকে আজ 220 — এটি 10.5% রিকভারি হয়েছে **কম ভলিউমেই**। এখন কল্পনা করুন, Q4 ফলাফল ভালো এলে কী হবে!
---
## ৫. "ঝুঁকি-রিটার্ন ১:১" — আপনার ক্যালকুলেশন ভুল, আমার গণিত স্পষ্ট
আপনি বলছেন, উপরে 2.3% আর নিচে 2.9% — তাই ঝুঁকি-রিটার্ন ১:১। বন্ধু, **আপনি শুধু তাত্ক্ষণিক প্রযুক্তিগত লেভেল দেখছেন, কিন্তু সম্ভাব্যতা হিসাব করছেন না।** আসুন সঠিকভাবে দেখি:
**নিচের দিকের সম্ভাবনা:**
- 200-SMA (213.44) ব্রেক করার জন্য প্রয়োজন হবে **নতুন নেতিবাচক সংবাদ** — যেমন Q4-এ বিপর্যয় বা সেক্টর-মন্দা। কিন্তু বর্তমান তথ্যে সেরকম ইঙ্গিত নেই
- 52-সপ্তাহের লো 198-এ নামতে হলে DSEX-এ ধস লাগতে হবে — যা এখন নেই
- **আর সর্বোচ্চ ডাউনসাইড 10% (198), যেখানে 7 বছরের সাপোর্ট জোন**
**উপরের দিকের সম্ভাবনা:**
- Q4-এর EPS 6.3-6.5 = বার্ষিক EPS ~30, P/E 8-এ = দাম 240 (তাত্ক্ষণিক টার্গেট)
- বার্ষিক লভ্যাংশ 120% + বার্ষিক 10% EPS প্রবৃদ্ধি = P/E 10-এ যেতে সময় লাগবে মাত্র 12-18 মাস — টার্গেট 280-300
- FII/বিদেশি বিনিয়োগ বাড়লে (14.81% থেকে) দাম 236 রেঞ্জ-হাই ভেঙে নতুন উচ্চতায় যাবে
**সুতরাং ঝুঁকি-রিটার্ন: নিচে 3-10% সম্ভাব্য, উপরে 10-30% সম্ভাবনা।** অংক আপনা-আপনিই বলে দিচ্ছে কোন দিকে ঢাল বেশি!
---
## ৬. "216.72 ভাঙলে সব বিক্রি করবে" — ভাঙার আগ পর্যন্ত সেটা শুধু কাল্পনিক ভয়
আপনি বলছেন, 216.72 ভাঙলে টেকনিক্যাল ট্রেডাররা সব বেরোবে। আমি বলি — **তারা বের হলেও 213-207-এ নতুন বিনিয়োগকারী ঢুকবে, কারণ ফান্ডামেন্টাল সেখানে অত্যন্ত আকর্ষণীয়।**
আরও গুরুত্বপূর্ণ — **193 দিনে ATR 2.03, দাম 216-224-এর মধ্যে আটকা**। আমি আপনাকে ইতিহাস বলি:
- যখনই ATR এত কমেছে (১৯৯-২০০-এর রেঞ্জে), তখনই বড় ব্রেকআউট হয়েছে
- 2025-এর ডিসেম্বরে দাম 199-এ এসেছিল — তারপর 232-এ গিয়েছিল (16% রিকভারি)
- 2026-এর মে মাসে 207-এ এসেছিল — তারপর 225-এ গিয়েছিল (8% রিকভারি)
এই স্টক **নিচে গেলেই কেনা হয়**, কারণ স্মার্ট মানি জানে এটি বাংলাদেশের সেরা ফ্র্যাঞ্চাইজ। আপনি "Q4-এর আগে অপেক্ষা" বলছেন, কিন্তু Q4-এর ফলাফল আসার আগেই দাম 230-240-এ চলে গেলে আপনি আর 219.90-তে কিনতে পারবেন না। **অপেক্ষা করার মূল্যই সবচেয়ে বড়।**
---
## ৭. "সেক্টর স্যাচুরেশন" — বাস্তবে যা ঘটছে তা সম্পূর্ণ ভিন্ন
আপনি বলছেন, "বাজার সম্পৃক্ত, প্রবৃদ্ধি কেবল রপ্তানিমুখী, প্রতিযোগিতা বাড়ছে।" আমি বলছি:
- বাংলাদেশের ফার্মাসিউটিক্যাল রপ্তানি FY2024-25-এ **20%+ বেড়ে 200 মিলিয়ন ডলার ছাড়িয়েছে**
- `SQURPHARMA`-এর রপ্তানি পূর্ব ইউরোপ, আফ্রিকা, মিয়ানমার, ভুটান, নেপাল, আফগানিস্তান, ফিলিপাইনে হচ্ছে — **নতুন নতুন বাজারে প্রবেশ করছে**
- বাংলাদেশের ওষুধ চাহিদা প্রতি বছর 10-12% বাড়ছে (জনসংখ্যা বৃদ্ধি + বয়স্ক জনসংখ্যা + ডায়াবেটিস/হৃদরোগের প্রাদুর্ভাব)
- কোম্পানির Q3 FY26-এ NAV 169.79, EPS 6.73 — এত ভালো সংখ্যার পর আপনি "সেক্টর স্যাচুরেশন" বলছেন?
প্রতিযোগীদের কথা বললেন — ইনসেপ্টা, বেক্সিমকো, এসকেএফ। **কিন্তু আজও `SQURPHARMA`-র মার্কেট শেয়ার 17-18% — সবচেয়ে বড়**। আরও বড় কথা — **স্কয়ার ব্র্যান্ডের সাথে বাংলাদেশের মানুষের আস্থা এবং ডাক্তারদের পছন্দ** — এটি এক দিনে বদলায় না। প্রতিযোগীরা ছোট ছোট সেগমেন্টে সুযোগ নিচ্ছে, কিন্তু সামগ্রিক নেতৃত্ব এখনও স্কয়ারের হাতে।
---
## ৮. "ভ্যালু স্টোর = ভ্যালু ট্র্যাপ" — ভিন্ন দৃষ্টিভঙ্গি
আপনার মূল যুক্তি — "7 বছর ধরে দাম বাড়েনি।" আমি বলছি — **এর মানে হলো, 7 বছরের জমা সুদ (বাটা) এখন ফুলতে শুরু করবে।**
মনে করুন, 2019-এ আপনি 1000 টাকার শেয়ার কিনেছিলেন 14.68 P/E-তে। 7 বছর পর সেই শেয়ারের EPS 69% বেড়েছে, কিন্তু P/E কমে 7.73 হয়েছে — তাই দাম প্রায় একই আছে। এখন 2026-তে যদি মাত্র P/E 10-এ রেট হয়, তাহলে দাম **350+ টাকা** হবে! **এটাই ভ্যালু ইনভেস্টিংয়ের জাদু — একদিন সবাই এসে দেখবে এবং দাম বাড়বে**
আপনি ক্যাটালিস্ট চাচ্ছেন? আমি দিচ্ছি:
1. **Q4 FY26 ফলাফল** (আগস্ট/সেপ্টেম্বর ২০২৬) — EPS 30+ হলে P/E 8-এ দাম 240+
2. **বার্ষিক লভ্যাংশ ঘোষণা** (ডিসেম্বর ২০২৬) — 125-130% হলে শেয়ার 250+
3. **স্পনসর হোল্ডিং আরও বাড়লে** — আস্থার প্রতীক শক্তিশালী
4. **রপ্তানি নতুন চুক্তি** — যেকোনো ভালো খবরে স্টক জ্বলে উঠবে
আপনি বলবেন, "এগুলো তখন হবে, এখন না।" কিন্তু বিনিয়োগ মানেই ভবিষ্যৎ কেনা — বর্তমান নয়। **যারা অপেক্ষা করে, তারা কখনো গাড়িতে ওঠে না; গাড়ি চলে যায়।**
---
## ৯. "SELL/AVOID" — এই পরামর্শ ২০২৬-এর জন্য নয়, ২০২০-এর ছিল
বন্ধু, ২০২০-এ P/E 10.38-এর সময় আপনি "SELL" বললে যুক্তি ছিল — তখন EPS ছিল 15.82, এখন 27.04। ২০২৩-এ P/E 9.80-র সময় "SELL" বললে যুক্তি ছিল — এখন 7.73। **প্রতি বছর আপনি "SELL" বলেছেন, আর কোম্পানি প্রতি বছর EPS এবং লভ্যাংশ বাড়িয়েছে।** এখন 7.73 P/E-তে — যা ইতিহাসের সর্বনিম্ন — আপনি আবারও "SELL" বলছেন!
আমি বলছি, **এবার সময় এসেছে বেয়িশ সাইড থেকে বেরিয়ে আসার**। Q4-এর ফলাফলই বলে দেবে কে সঠিক। কিন্তু Q4-এর আগেই দাম 230-240-এ চলে গেলে আপনি আফসোস করবেন। আমি Q4-এর ফলাফল দেখার আগেই বলছি — **আজকের দাম 219.90, বার্ষিক EPS 30 প্রজেক্টেড, P/E 7.73, লভ্যাংশ 120%, নগদ ৫২ বিলিয়ন** — এই মুহূর্তে BUY না করলে আর কবে করবেন?
---
## উপসংহার: সময় এখনই, দাম এখনই
বেয়িশ বন্ধু, আপনি প্রতিটি পয়েন্টে প্রযুক্তিগত সূচক, সেক্টর উদ্বেগ, লিকুইডিটি সমস্যা — সব তুলে ধরেছেন। আমি স্বীকার করি, এগুলো বাস্তব। কিন্তু **বিনিয়োগের সিদ্ধান্ত নিতে হয় সামগ্রিক ছবি দেখে**:
- **কোম্পানির কাছে ৫২ বিলিয়ন টাকা নগদ আছে** — বাংলাদেশের কোনো কোম্পানির কাছে নেই
- **ঋণ প্রায় শূন্য** — আর্থিক ঝুঁকি প্রায় নেই
- **EPS ৭ বছরে ৬৯% বেড়েছে** — প্রবৃদ্ধির ট্র্যাক রেকর্ড অটুট
- **লভ্যাংশ ৬ বছরে ৪২% → ১২০%** — শেয়ারহোল্ডার বান্ধব
- **P/E ৭.৭৩, P/B ১.৩০** — ইতিহাসের সর্বনিম্ন অঞ্চলে
- **স্পনসর ৪৪% হোল্ডিং** — কোম্পানির প্রতি সর্বোচ্চ আস্থার প্রমাণ
**আমার চূড়ান্ত প্রস্তাব:**
> **BUY / ACCUMULATE `SQURPHARMA` — বর্তমান মূল্য 219.90 BDT**
> - নতুন বিনিয়োগকারী: 216-220 জোনে ৫০% কেনাকাটি করুন
> - 213-216-এ এলে দ্বিতীয় ৩০% যোগ করুন
> - 221+ ভলিউমসহ ব্রেকআউট হলে বাকি ২০% যোগ করুন
> - স্টপ-লস: 205 (বার্ষিক EPS 30-এ P/E 6.8 — অসম্ভব, কিন্তু নিরাপত্তার জন্য)
> - টার্গেট: **240 (৬ মাস) → 280 (১২-১৮ মাস) → 350+ (২-৩ বছর)**
**এটি ভ্যালু ট্র্যাপ নয় — এটি ভ্যালু স্প্রিং**। স্প্রিং যত বেশি চাপা পড়ে, তত জোরে লাফ দেয়। ৭ বছরের চাপা দাম এখন মুক্তির অপেক্ষায়। আজ BUY করুন — ১২ মাস পরে আমাকে ধন্যবাদ দেবেন। 🚀
**FINAL RECOMMENDATION: BUY — TARGET 280+ (12-18 মাস), স্টপ-লস 205।**
\ No newline at end of file
**Recommendation**: Buy
**Rationale**: প্রিয় ট্রেডার, এই বিতর্কটা সত্যিই দুটি শিবিরের মধ্যে তীক্ষ্ণ এবং উভয় পক্ষই শক্ত যুক্তি দিয়েছে — তাই আমি সতর্কভাবে দুই পক্ষের দিকে তাকিয়ে সিদ্ধান্তে পৌঁছেছি।
বুলিশ শিবিরের যুক্তি সংখ্যার দিক থেকে খুবই শক্তিশালী এবং আমার কাছে সেটা বেশি গুরুত্বপূর্ণ: SQURPHARMA-র P/E মাত্র 7.73 — যা কোম্পানির ইতিহাসের সর্বনিম্ন অঞ্চলের কাছাকাছি, যেখানে 2019 সালে ছিল 14.68। EPS টানা ৭ বছর ধরে 16.03 থেকে 27.04-এ বেড়েছে (প্রায় 69% বৃদ্ধি), কিন্তু দাম সেই সময়ের চেয়েও নিচে। NAV/share 169.79, P/B 1.30, ROE 17%+, নগদ ৫২ বিলিয়ন টাকা এবং ঋণ মাত্র 0.82 বিলিয়ন — অর্থাৎ নিট নগদ প্রায় ৫১ বিলিয়ন। লভ্যাংশ 42% থেকে ক্রমাগত বেড়ে 120% হয়েছে, মানে 5.46% নগদ ফলন। আর সবচেয়ে গুরুত্বপূর্ণ — স্পনসর/পরিচালক হোল্ডিং 34.67% থেকে বেড়ে 44.15% হয়েছে। যারা কোম্পানির ভেতরের খবর সবচেয়ে ভালো জানেন, তারা ক্রমাগত নিজেদের অংশ বাড়াচ্ছেন — এটা একটি প্রকৃত আস্থার সংকেত।
বেয়িশ শিবিরের যুক্তিও অবহেলা করার মতো নয় — বিশেষ করে Q3-এ YoY ভিত্তিতে EPS প্রায় -5.2% কমেছে, এবং প্রবৃদ্ধির গতি 14.5% থেকে 10%-এ নেমে এসেছে। MACD নেতিবাচক, RSI 50-এর নিচে (48.73), দাম বোলিঞ্জার মধ্যমার নিচে, এবং 7 বছর ধরে দাম 198-236-এর রেঞ্জে বন্দি — বেয়িশের "ভ্যালু ট্র্যাপ" উদ্বেগটির একটা বাস্তব ভিত্তি আছে। লিকুইডিটিও কম (ফ্রি ফ্লোট মাত্র ~27%)।
কিন্তু আমি যখন সামগ্রিক ছবিটা দেখি, বুলিশ শিবিরের পক্ষে ভারের পার্থক্যটা বেশি। বেয়িশ যে "ক্যাটালিস্ট নেই" বলেছে — সেটা পুরোপুরি ঠিক নয়; Q4 ফলাফল, লভ্যাংশ ঘোষণা, এবং রপ্তানি সম্প্রসারণ — এগুলো বাস্তব সম্ভাব্য ট্রিগার। আর সবচেয়ে বড় কথা, 7.73 P/E-তে ঝুঁকি-রিটার্ন উপরের দিকে অনুকূল: নিচে 200-SMA 213.44 (প্রায় 3%) এবং 52-সপ্তাহের লো 198 (প্রায় 10%), যেখানে উপরে বোলিঞ্জার আপার 224.88, রেঞ্জ-হাই 236, এবং P/E 9-10-এ রিটার্ন হলে 240-280 পর্যন্ত সম্ভাবনা। Q3-এর দুর্বলতা ঋতুভিত্তিক প্যাটার্নের (প্রতি বছর Q3-Q4 দুর্বল) সঙ্গেও সামঞ্জস্যপূর্ণ।
সুতরাং বেয়িশের টেকনিক্যাল সতর্কতাকে আমি সম্মান করি এবং দামের গতিবিধির প্রতি সতর্ক থাকব, কিন্তু ফান্ডামেন্টাল ও মূল্যায়নের দিক থেকে বুলিশ শিবির জয়ী। এটি "ভ্যালু ট্র্যাপ" নয় — এটি বাংলাদেশের সেরা ফার্মাসিউটিক্যাল ফ্র্যাঞ্চাইজকে গভীর ছাড়ে কেনার সুযোগ। আমার সিদ্ধান্ত: Buy — কিন্তু কিস্তিতে (staged), যাতে টেকনিক্যাল দুর্বলতা থাকা সত্ত্বেও এন্ট্রি পয়েন্টগুলো সামঞ্জস্যপূর্ণ হয়।
**Strategic Actions**: SQURPHARMA-তে Buy রেটিং অনুযায়ী নিচের ধাপগুলো বাস্তবায়ন করুন:
১. পজিশন সাইজিং: দীর্ঘমেয়াদি মূল পোর্টফোলিওর কোর-হোল্ডিং হিসেবে মাঝারি-বড় সাইজের পজিশন (যেমন সম্পূর্ণ প্ল্যানড পজিশনের ১০০%-এর লক্ষ্য) নিন, কিন্তু মাসিক-মেয়াদি জুড়ে তা ৩টি কিস্তিতে ভাগ করুন। "Buy" রেটিং অনুযায়ী ৭০-১০০%-এর মধ্যে সম্পূর্ণ পজিশন নেওয়ার ইচ্ছা রাখুন, তবে টেকনিক্যাল অস্থিরতা মাথায় রেখে প্রথম কিস্তি ৪০-৫০% দিয়ে শুরু করুন।
২. কিস্তিভিত্তিক এন্ট্রি (Staged entry):
- প্রথম কিস্তি (৪০-৫০%): বর্তমান জোন 216-220 BDT-তে (200-SMA 213.44-এর উপরে থাকা অবস্থায়) নিন।
- দ্বিতীয় কিস্তি (৩০%): 213-216 BDT (200-SMA-এর কাছাকাছি) বা 221+ ভলিউমসহ ব্রেকআউট নিশ্চিত হলে যোগ করুন — যেটা আগে ঘটে।
- তৃতীয় কিস্তি (বাকি): দামে 224.88 (বোলিঞ্জার UB) ভাঙলে বা কনফার্মড ব্রেকআউটের পর সম্পূর্ণ করুন।
৩. স্টপ-লস ও ঝুঁকি ব্যবস্থাপনা: যারা নতুন পজিশন নিচ্ছেন তাদের জন্য কঠোর স্টপ-লস 205 BDT-এর নিচে ক্লোজে রাখুন (P/E 6.8-এর কাছাকাছি — ঝুঁকি-রিটার্ন সুরক্ষিত)। যাদের আগে থেকে পজিশন আছে, তারা 213.44 (200-SMA) নিচে ক্লোজে স্টপ রাখুন। ঝুঁকিও ৩-১০% এর মধ্যে সীমাবদ্ধ রাখতে প্রতি বিনিয়োগে বরাদ্দ এমনভাবে করুন।
৪. টার্গেট: স্বল্প-মেয়াদি টার্গেট 224-232 (বোলিঞ্জার UB ও রেঞ্জ-হাই); মাঝারি-মেয়াদি (৬-১২ মাস) 250-280 (P/E 9-10-এ); দীর্ঘমেয়াদি (২-৩ বছর) 300+ ধারাবাহিক EPS ও লভ্যাংশ প্রবৃদ্ধির ওপর ভিত্তি করে।
৫. মনিটরিং ট্রিগার: Q4 FY26 ফলাফলে EPS >7.5 এলে ও MACD পজিটিভ ক্রস দিলে বুলিশ থিসিস শক্তিশালী হবে — পজিশন সম্পূর্ণ করার সুযোগও। বিপরীতে Q4-এ EPS <6.0 বা দাম 213.44-এর নিচে ক্লোজ করলে থিসিস দুর্বল হবে — তখন সম্পূর্ণ পজিশন গ্রহণ বন্ধ করুন ও স্টপ সম্মান করুন।
৬. ভারসাম্য: এটি একটি ডিফেন্সিভ ব্লু-চিপ — তাই পোর্টফোলিওর ঝুঁকিপূর্ণ/গ্রোথ অংশের বিপরীতে এটিকে স্থিতিশীল অ্যাংকর পজিশন হিসেবে রাখুন।
\ No newline at end of file
**Action**: Buy
**Reasoning**: SQURPHARMA-র ফান্ডামেন্টাল ও মূল্যায়ন উভয়ই বুলিশ শিবিরের পক্ষে ভারসাম্য ঝুঁকেছে। মাত্র 7.73 P/E (ইতিহাসের সর্বনিম্ন অঞ্চলের কাছাকাছি), ধারাবাহিক EPS বৃদ্ধি (৭ বছরে 16.03 থেকে 27.04), NAV/share 169.79, P/B 1.30, ROE 17%+, নিট নগদ ~৫১ বিলিয়ন টাকা এবং লভ্যাংশ 120% (5.46% নগদ ফলন) — এই সবই শক্তিশালী ফান্ডামেন্টাল। সর্বোপরি স্পনসর/পরিচালক হোল্ডিং 34.67% থেকে 44.15%-এ বৃদ্ধি ভেতরের আস্থার শক্তিশালী সংকেত। Q3-এর সাময়িক দুর্বলতা ঋতুভিত্তিক প্যাটার্নের সঙ্গে সামঞ্জস্যপূর্ণ এবং 'ভ্যালু ট্র্যাপ' নয়, বরং গভীর ছাড়ে কেনার সুযোগ। টেকনিক্যাল সতর্কতা থাকা সত্ত্বেও কিস্তিভিত্তিক (staged) এন্ট্রিতে ঝুঁকি-রিটার্ন উপরের দিকে অনুকূল।
**Entry Price**: 216.0
**Stop Loss**: 205.0
**Position Sizing**: মাঝারি-বড় কোর-হোল্ডিং; ৩টি কিস্তিতে বিভক্ত, প্রথম কিস্তি ৪০-৫০%
FINAL TRANSACTION PROPOSAL: **BUY**
\ No newline at end of file
Aggressive Analyst: শোনো, কনজারভেটিভ এবং নিউট্রাল বিশ্লেষকদের কথা শুনে আমার মনে হচ্ছে তারা যেন একটা চলন্ত ট্রেনের সামনে দাঁড়িয়ে টাইমটেবল দেখছে। তারা বলছে "HOLD" — কিন্তু কেন? কারণ MACD -0.24 আর RSI 48.73? এই দুর্বল প্রযুক্তিগত সংকেতগুলো নিয়ে এত মাথা ঘামানোর সময়ই তো আমরা মূল ছবিটা হারিয়ে ফেলছি। আসল ছবিটা হলো, এই কোম্পানিটি বাংলাদেশের ফার্মাসিউটিক্যাল খাতের মুকুটহীন রাজা, আর সেটা এখন বিক্রি হচ্ছে মাত্র 7.73 P/E-তে।
নিউট্রাল বিশ্লেষক বলছেন, দাম 50-SMA আর 10-EMA-র সংযোগস্থলে, তাই সিদ্ধান্ত নেওয়া ঠিক নয়। আর কনজারভিটিভ বলছেন, MACD নেতিবাচক, তাই সতর্ক থাকা উচিত। কিন্তু আমি বলছি, এই সংযোগস্থলটাই তো সবচেয়ে বড় সুযোগ। দাম 219.90, আর VWMA 219.76 — মানে বাজারের গড় ক্রেতার ক্রয়মূল্যের সাথে বর্তমান দামের প্রায় কোনো পার্থক্য নেই। এটা কোনো ভয়ের জায়গা নয়, এটা একটা স্প্রিং-এর মতো চাপা অবস্থা। ATR কমে 2.03-এ এসেছে, মানে ভোলাটিলিটি সংকুচিত — আর কম ভোলাটিলিটির পরেই তো বড় ব্রেকআউট আসে। এটা তো দুশ্চিন্তার কারণ নয়, এটা হলো লোড হওয়ার মঞ্চ।
এখন ফান্ডামেন্টাল দেখো। ৭ বছরে EPS 16.03 থেকে 27.04 — মানে ৬৯% প্রবৃদ্ধি। NAV প্রতি শেয়ার 169.79 টাকা, আর দাম মাত্র 216 টাকা — P/B 1.30। একই সঙ্গে কোম্পানির হাতে নিট নগদ ৫২ বিলিয়ন টাকা, যেখানে মোট দায় প্রায় নেই বললেই চলে। ROE 17%+। এই হিসাবে কোম্পানিটা কী, একটা সোনার খনি — যেটা বাজারে আখেরে তেলের দামে বিক্রি হচ্ছে। কোনো সন্দেহ নেই এটা। তাছাড়া 120% ক্যাশ ডিভিডেন্ড, মানে 5.46% নগদ ফলন — ব্যাংকের ফিক্সড ডিপোজিটের চেয়েও বেশি। এই লেভেলে দাঁড়িয়ে "HOLD" বলাটা মানে নিজের পায়ে কুড়াল মারা। এখানে অপেক্ষা করার কিছু নেই, এখানে কেনার সময়।
আর কনজারভেটিভ বিশ্লেষক যে অ্যাসেট-লাইট আর্গুমেন্টটা এনেছেন, সেটার জবাব হলো — স্পনসর/পরিচালক হোল্ডিং ৩৪.৬৭% থেকে বেড়ে ৪৪.১৫% হয়েছে। এই মানুষগুলো কোম্পানির ভেতরের খবর সবচেয়ে ভালো জানে। তারা যখন নিজেদের হোল্ডিং বাড়ায়, সেটা কি শুধুই অনুষ্ঠানের জন্য? না, এটা হলো ভেতরের মানুষের আস্থার সবচেয়ে বড় প্রমাণ। বাইরের যে রিসার্চ রিপোর্টগুলোতে MACD-এর হিসাব দেখানো হচ্ছে, সেগুলোর চেয়ে এই হোল্ডিং ডেটা অনেক বেশি শক্তিশালী সংকেত।
ওরা বলে, Q3-এ EPS কমে 6.73 হয়েছে, সেটা নাকি দুর্বলতা। কিন্তু ৯ মাসের EPS 23.29, যা গত বছরের একই সময়ের 21.15-এর চেয়ে বেশি। ঋতুভিত্তিক কিছু ওঠানামা থাকবেই — এটা ফার্মাসিউটিক্যাল ব্যবসার স্বাভাবিক চক্র। এটাকে 'ভ্যালু ট্র্যাপ' বলাটা সম্পূর্ণ ভুল ধারণা। ভ্যালু ট্র্যাপ ওই কোম্পানিগুলোর জন্য, যাদের মৌলিক শক্তি নেই। আর এখানে তো মৌলিক শক্তির পাহাড়। ৫২ বিলিয়ন নগদ, নেগেটিভ ডেট নয়, ক্রমবর্ধমান ডিভিডেন্ড, ক্রমবর্ধমান ইকুইটি — এই ছবিটা কোনো ট্র্যাপের ছবি না, এটা হলো সোনার খনির ছবি।
আমাদের বুঝতে হবে ঢাকা স্টক এক্সচেঞ্জে এই কোম্পানিটাকে মার্কেট যে রেট দিচ্ছে, সেটা একদম অন্যায়। ফার্মাসিউটিক্যাল সেক্টরের অন্য কোম্পানিগুলো ১৫-২০ P/E-তে ট্রেড করে, আর আমাদের সেরা কোম্পানিটা ৭.৭৩ P/E-তে? এটা হলো বাজারের একটি ভুল মূল্যায়ন, আর সেই ভুলটাই হলো আমাদের বিনিয়োগের সুযোগ। এই ভুলটা শুধরে যাবে, প্রশ্ন হলো কবে। আর প্রশ্নটা যদি হয় কবে, তাহলে কেন আমরা অপেক্ষায় থাকব? আমরা তো আরও আগে এন্ট্রি নিয়ে লাভটা পুরোপুরি ঘরে তুলতে পারি।
ট্রেডার যে প্ল্যান দিয়েছেন, সেটাও খুবই চমৎকার। তিন কিস্তিতে এন্ট্রি — প্রথম কিস্তি ৪০-৫০%, বাকিটা পরে। এটা তো কোনো পাগলামি না, এটা হলো কৌশলগত সাহস। স্টপ-লস ২০৫ — সর্বশেষ ক্লোজ থেকে মাত্র ৫% নিচে। অথচ উপরের দিকে টার্গেট আছে ২৩২-২৩৬ পর্যন্ত। ঝুঁকি-রিটার্ন অনুপাত এখানে অসাধারণ। আপনি মাত্র ৫% ঝুঁকি নিচ্ছেন একটা ১০-১৫% রিটার্নের জন্য, সেটাও সম্ভবত ছয় মাসের মধ্যে। আর ATR 2.03 অনুযায়ী, ২০৫-এ স্টপ রাখা মানে বাজারের সাধারণ ওঠানামায় ধাক্কা খেয়ে বের হয়ে যাওয়ার সম্ভাবনাও কম। এটা তো একটা রিজনেবল, সু-পরিকল্পিত রিস্ক।
আমি যখন দেখি নিউট্রাল বিশ্লেষকরা বলছেন, "ব্রেকআউটের দিক নির্ধারণ না হওয়া পর্যন্ত HOLD," তখন আমার মনে হয় তারা যেন একটা ঘোড়দৌড়ে অংশ না নিয়ে ঘোড়াটা কোনদিকে দৌড়াবে সেটা দেখার অপেক্ষায় আছে। কিন্তু ততক্ষণে তো ঘোড়াটা ছুটে গেছে! বড় বিনিয়োগ করতে হয় ভয়-ভীতির মধ্যেই, যখন অন্যরা বোকার মতো পাশে দাঁড়িয়ে থাকে। এই ভ্যালুয়েশন, এই ফান্ডামেন্টাল, এই ম্যানেজমেন্ট আস্থা — সবকিছু মিলিয়ে এটাই হলো সেই মুহূর্ত, যখন ভয়কে পেছনে ফেলে সাহসের সাথে এগিয়ে যেতে হয়।
তাই আমি স্পষ্টভাবে বলছি — BUY। আর এই BUY-তে কোনো শর্ত নয়, কোনো সংশয় নেই। কারণ, এই কোম্পানিতে দীর্ঘমেয়াদে বিনিয়োগ করলে হারানোর সম্ভাবনা খুবই কম, আর লাভের সম্ভাবনা অনেক বেশি। কনজারভেটিভ আর নিউট্রালের এই "HOLD" শুধুই একটা ভুল সতর্কতা, যেটা আমাদের সম্পদ গড়ার পথে বাধা হয়ে দাঁড়াতে পারে। বাজারের এই অদক্ষতাকে আমরা কাজে লাগাবই, কারণ এটাই হলো অ্যাগ্রেসিভ রিস্ক অ্যানালিস্টের কাজ — সুযোগ দেখলেই ছিনিয়ে নেওয়া।
Aggressive Analyst: কনজারভেটিভ এবং নিউট্রাল অ্যানালিস্ট — দুজনের বক্তব্যই শুনলাম। কিন্তু বলুন তো, আমরা কী নিয়ে বিতর্ক করছি? একটা কোম্পানি যার ফান্ডামেন্টাল এত শক্তিশালী যে দুই বিশ্লেষকই সেটা স্বীকার করতে বাধ্য হয়েছেন — EPS ৭ বছরে ৬৯% বেড়ে ২৭.০৪, NAV ১৬৯.৭৯, ৫২ বিলিয়ন টাকা নিট নগদ, ঋণ প্রায় শূন্য, ROE ১৭%+, স্পনসর হোল্ডিং ৩৪.৬৭% থেকে ৪৪.১৫% — এই কোম্পানিটা এখন বিক্রি হচ্ছে মাত্র ৭.৭৩ P/E-তে। বাংলাদেশের ফার্মাসিউটিক্যাল সেক্টরের সবচেয়ে ভালো কোম্পানিটা যখন এই মূল্যে পাওয়া যাচ্ছে, তখন কনজারভেটিভ অ্যানালিস্ট বলছেন, "অপেক্ষা করুন, দাম আরও নামতে পারে।" আর নিউট্রাল অ্যানালিস্ট বলছেন, "কিনুন, কিন্তু অর্ধেক আত্মবিশ্বাসে।"
আমি এখানে দুইজনের কাছেই একটা মৌলিক ভুল দেখছি। তারা দুজনেই মনে করছেন যে তারা "নিরাপদ" বিকল্প বেছে নিচ্ছেন। কিন্তু আসল নিরাপত্তাটা কোথায়? আপনি যদি ২১৩-এ পুলব্যাকের জন্য অপেক্ষা করেন, আর দাম সেদিকে না গিয়ে ২২৫-এ উঠে যায় — তাহলে আপনার "নিরাপত্তা" আপনাকে কত লাভ দিল? আর নিউট্রাল অ্যানালিস্ট যদি ২৫-৩০% নিয়ে শুরু করেন, প্রথম কিস্তিতে — তাহলে বাকি ৭০% টাকা বসে থাকল ব্যাংকে, যেখানে ফলন ৮-৯%। অথচ এই কোম্পানির ক্যাশ ডিভিডেন্ড ফলনই ৫.৪৬%, সেটার ওপরে আছে ক্যাপিটাল অ্যাপ্রিসিয়েশনের সম্ভাবনা। অপেক্ষা করার প্রতিটা মাস, প্রতিটা সপ্তাহ — এটা একটা সুযোগ খরচ, যেটা তারা হিসেবের বাইরে রেখে দিচ্ছেন।
এখন কনজারভেটিভ অ্যানালিস্টের রিস্ক-রিওয়ার্ড হিসেবটা দেখুন। তিনি বলছেন, "স্টপ-লস ২০৫, টার্গেট ২৩২ — এটা মাত্র ১.৮:১ রিস্ক-রিওয়ার্ড, যা যথেষ্ট নয়।" কিন্তু এই হিসেবটা একদম স্থির ধরে নেওয়া। বাজারের প্রকৃতিতে এত সহজ হিসেব চলে না। দাম ২১৬-তে প্রবেশ করলে, ২০৫-তে স্টপ — এটা ৫.১% ঝুঁকি। কিন্তু উপরে টার্গেট কিন্তু শুধু ২৩২ নয়। FY2026 ফুল-ইয়ার EPS যদি ২৭-২৮-এ আসে আর P/E ১০-এ রেট হয় — তাহলে টার্গেট ২৭০-২৮০। দীর্ঘমেয়াদি বিনিয়োগের দিকে তাকালে, স্পনসররা যখন ৪৪% হোল্ডিং নিয়ে বসে আছেন, তখন এই স্টকের প্রকৃত মূল্যায়ন আরও অনেক উপরে যাওয়ার কথা। ৬ মাসের টার্গেট নিয়ে ভাবলে আপনি শুধু একটা কিস্তির হিসেব দেখছেন — কিন্তু আমরা তো প্রাতিষ্ঠানিক বিনিয়োগকারী, আমাদের দিগন্ত ১২-১৮ মাসের। সেখানে ২০৫-এ স্টপ দিয়ে ২৫০+ পর্যন্ত ঝুঁকি নেওয়া একটি চমৎকার অ্যাসিমেট্রিক বেট।
আরেকটা কথা — কনজারভেটিভ বলছেন, "ফান্ডামেন্টাল ভালো, কিন্তু দাম কেন ২৩৬-এর ওপরে যায়নি?" আমি প্রশ্ন করব — দাম যদি ২৩৬-এর ওপরে যেত, তাহলে আপনি কি এত কম P/E-তে এই কোম্পানিটা কিনতে পারতেন? বাজারের এই "অদক্ষতা"টাই তো আমাদের বন্ধু। ২০১৯-২০২৪ পর্যন্ত দাম ২০০-২২০-তে ছিল বলেই কি এটা বোঝায় যে এটা আর কখনো ২৫০-২৬০-এ যাবে না? না। ফান্ডামেন্টাল বদলেছে — EPS ২১ থেকে বেড়ে ২৭ হয়েছে, NAV ১৩০ থেকে ১৭০ হয়েছে, ডিভিডেন্ড ১০৫% থেকে ১২০% হয়েছে। এই গুণগত পরিবর্তনগুলোর পরেও যদি দাম একই রকম থাকে, সেটাই অস্বাভাবিক। আর এই অস্বাভাবিকতাই বিনিয়োগের সুযোগ।
নিউট্রাল অ্যানালিস্টের দিকে তাকিয়ে বলি — তিনি বলেছেন, "ATR সংকুচিত মানেই ব্রেকআউটের নিশ্চয়তা নেই।" একদম ঠিক, এটা খুবই স্পষ্ট কথা। কিন্তু আমি বলছি না ATR সংকুচিত বলেই ব্রেকআউট হবে। আমি বলছি — ATR সংকুচিত, দাম ৫০-SMA-এর ঠিক উপরে, ২০০-SMA-এর ৩% উপরে, RSI ৪৮-এ নিরপেক্ষ, MACD মাত্র -০.২৪-এ — এই সবগুলো একসাথে পড়লে কী বোঝায়? বোঝায়, বিক্রয়ের চাপ শেষ, এখন দাম বেস বিল্ড করছে। আর এটার ওপর আছে ফান্ডামেন্টালের পাহাড়। এই অবস্থায় "HOLD" বলাটা মানে কোনো সিদ্ধান্তই না নেওয়া। আর "নিরাপদ" হয়ে থাকার যে ভান, সেটা আসলে সবচেয়ে বড় ঝুঁকি — কারণ, আপনি যখন নিশ্চিত হবেন দাম ২২৫-এ পৌঁছে গেছে, তখন আপনার এন্ট্রি পয়েন্ট ২২৫ হবে, আর স্টপ-লস ২০৫ মানে তখন ৮.৯% রিস্ক, অথচ এখন সেই রিস্ক মাত্র ৫.১%। এই পার্থক্যটা কি বুঝতে পারছেন? অপেক্ষা করলে আপনার রিস্ক বাড়ে, কমে না।
দ্বিতীয়ত, কনজারভেটিভ বলেছেন, "স্পনসররা ৫-১০ বছর ধরে হোল্ড করে, তারা দীর্ঘমেয়াদি।" কিন্তু তাদের হোল্ডিং বেড়ে ৪৪.১৫% হয়েছে সাম্প্রতিক সময়েই। ২০২৩-এ ৩৪.৬৭% ছিল, এখন ৪৪.১৫% — এই ৯.৪৮% বৃদ্ধি এক বছরেই হয়েছে। অভ্যন্তরীণ মানুষ যখন এই গতিতে শেয়ার কিনছে, তখন বাইরের বিশ্লেষকরা বলছেন "অপেক্ষা করুন।" আমি আপনাকে জিজ্ঞেস করছি — কোম্পানির ভেতরের খবর কে ভালো জানে — পরিচালক না বাইরের অ্যানালিস্ট? স্পনসররা বৃথা ১০% শেয়ার কেনেন না, সেটাও তো একটা সিগনাল।
আর তৃতীয়ত, নিউট্রাল অ্যানালিস্টের ২৫-৩০% প্রথম কিস্তির প্রস্তাব — আমি বুঝি, তিনি ঝুঁকি আর রিটার্নের ভারসাম্য খুঁজছেন। কিন্তু এই ভারসাম্যের মানে কী? মানে হলো, আপনি মোটামুটি নিশ্চিত যে কোম্পানিটা ভালো, কিন্তু দামের টাইমিং নিয়ে সন্দেহ আছে। আমি বলছি, যে কোম্পানির পিছনে ৫২ বিলিয়ন নগদ আর ১২৫ বিলিয়ন ইকুইটি আছে — সেখানে টাইমিং নিয়ে এত সন্দিহান হওয়ার কিছু নেই। বাজারের স্বল্পমেয়াদি ওঠানামা (যেমন Q3-এ EPS কমেছে ৬.৭৩) — এগুলো তো চেনা প্যাটার্ন। গত বছরও Q3-এ EPS কমেছিল, তারপর Q4-এ আবার বেড়ে ফুল-ইয়ার EPS ২৭ হয়েছে। এই পর্যায়ক্রমিক (seasonal) ওঠানামাকে "দুর্বলতা" বলাটা বাজার বোঝার অভাব।
আমি আবারও বলছি — ট্রেডারের প্ল্যানটা দারুণ। ৩টি কিস্তি, প্রথম কিস্তি ৪০-৫০%, স্টপ-লস ২০৫। এটা অ্যাগ্রেসিভ সাহসিকতা নয়, এটা হলো ডেটা-ড্রিভেন সাহস। ২০০-SMA ২১৩.৪৪-এর উপরে দাম ২১৯.৯০ — লং-টার্ম ট্রেন্ড এখনো বুলিশ। আর ২০৫-এ স্টপ — ওটা যেকোনো টেকনিক্যাল সাপোর্ট থেকে অনেক নিচে, মানে বাজারের সাধারণ নয়েজে বের হয়ে যাওয়ার সম্ভাবনা নেই। অথচ উপরে টার্গেট তারকা আকাশ — বোলিঞ্জার আপার ২২৪.৮৮, তারপরে রেঞ্জের হাই ২৩২-২৩৬। যদি এই ভ্যালুয়েশনে (P/E ৭.৭৩) এত ভালো কোম্পানি আরও ৬-১২ মাস এই লেভেলে থাকে — তবুও আপনি ডিভিডেন্ড ৫.৪৬% পাবেন, যেখানে ব্যাংক ডিপোজিট ৮-৯% — পার্থক্যটা মাত্র ৩-৪%, কিন্তু তার বদলে আপনার কাছে আছে সীমাহীন আপসাইড।
তাই আমার অবস্থান স্পষ্ট — BUY, পূর্ণ আত্মবিশ্বাসে। ৪০-৫০% দিয়ে শুরু করুন, বাকি দুটি কিস্তিতে যোগ করুন। কনজারভেটিভ বলছেন "প্রুডেন্স" — আমি বলছি, এই প্রুডেন্সই আমাদের দীর্ঘমেয়াদে আন্ডারপারফর্ম করবে। যে সুযোগ এতটা পরিষ্কার, সেখানে অপেক্ষা না করে কাজ করার সময়। কারণ, বাজারের এই ভুল মূল্যায়ন শুধরতে বেশি সময় লাগবে না — আর যখন শুধরবে, তখন দৌড়াতে দেরি হয়ে যাবে।
Aggressive Analyst: কনজারভেটিভ আর নিউট্রাল বিশ্লেষক, আমি তোমাদের কথা শুনলাম। কিন্তু তোমাদের এই "সতর্কতা"গুলো আসলে কী? টেকনিক্যাল চার্টের ছোটখাটো সিগনাল আর স্বল্পমেয়াদী হিসাব নিয়ে এত ব্যস্ত থাকার সময় আমরা মূল ছবিটাই ভুলে যাচ্ছি। আমি আবারও বলছি, এই কোম্পানি বাংলাদেশের সবচেয়ে ভালো ফার্মাসিউটিক্যাল কোম্পানি, রাজকীয় ফান্ডামেন্টাল নিয়ে বসে আছে, আর তুমি কনজারভেটিভ বলছ "HOLD, অপেক্ষা করো ২১৩-তে নামুক।" কেন? দাম নামার কোনো নিশ্চয়তা আছে? নাকি এটা শুধুই অনুমান?
তুমি কনজারভেটিভ, বললে ২০১৯-২০২৪ পর্যন্ত দাম ২০০-২২০ রেঞ্জে ছিল, তাই এই রেঞ্জই থাকবে। কিন্তু তুমি ভুলে যাচ্ছ, তখন EPS ছিল ১৬-২৩, আর এখন ২৭.০৪। তখন NAV ছিল ৮৬-১৪২, আর এখন ১৬৯.৭৯। ফান্ডামেন্টাল দ্বিগুণ হয়েছে, দাম সেই একই জায়গায়। এটাকে কি তুমি "বাজারের দক্ষতা" বলবা? না। এটাকে বলা হয় "বাজারের গুরুতর অদক্ষতা" — আর এই অদক্ষতাই আমাদের বন্ধু। এরপরও তুমি বলছ দাম ২৩২-তে গেলে হয়তো ভালো হবে। কিন্তু দাম তো উঠতেই চাইছে না এই ভুল বোঝাবুঝির কারণে, কারণ সবাই তোমার মতো অপেক্ষা করছে। কেউ না কিনলে কারেন্ট ডিমান্ড কোথা থেকে আসবে?
আর তোমার রিস্ক-রিওয়ার্ড হিসাবটা একদম সংকীর্ণ। তুমি শুধু ২৩২-এর কথা বলছ, কিন্তু আমি বলছি যদি বাজার রিরেট করে P/E ১০-এ যায়, তাহলে টার্গেট ২৭০+। আর সেটা সম্ভব, কারণ বাজারের সেন্টিমেন্ট বদলাতে পারে। Q3-এর EPS কমাটাকে তুমি দুর্বলতা বলছ, কিন্তু গত ৯ মাসের EPS ২৩.২৯, যা গত বছরের একই সময়ের চেয়ে বেশি। আর Q3-য় এরকম প্যাটার্ন প্রতিবছরই আসে। ঋতুভিত্তিক ওঠানামাকে তুমি "টেকনিক্যাল দুর্বলতা" বলছ, সেটা বাজারের সাইকেল না বোঝার পরিচয়। আর যেটা সবচেয়ে গুরুত্বপূর্ণ, স্পনসররা এক বছরে ৩৪.৬৭% থেকে ৪৪.১৫% হোল্ডিং বাড়িয়েছে — ৯% শেয়ার কিনেছে নিজেদের টাকায়। তারা কি বোকা? তারা কি বাইরের অ্যানালিস্টদের চেয়ে কম জানে? অবশ্যই জানে না। এই সিগনাল তোমরা গুরুত্ব দিচ্ছ না, কারণ চার্টে এটা দেখায় না।
আর নিউট্রাল, তুমি বলছ ২৫-৩০% দিয়ে শুরু করতে। এটা আবার কেমন সাহস? তুমি নিজেই স্বীকার করেছ ফান্ডামেন্টাল খুবই শক্তিশালী, আবার বলছ "টাইমিং নিয়ে নিশ্চিত নই।" টাইমিং নিশ্চিত হওয়ার কী দরকার, যখন এমন ভ্যালুয়েশনে ৫.৪৬% ডিভিডেন্ড মিলছে? তোমার প্রথম কিস্তি ২৫-৩০%, আর বাকি টাকা ব্যাংকে পড়ে থাকবে ৮% সুদে। এই সুযোগ খরচটা তুমি হিসাব করছ না। তুমি যদি ২২১-এ ব্রেকআউটের জন্য অপেক্ষা করো, তখন তোমার এন্ট্রি প্রাইস ২২৫ হবে, আর স্টপ-লস ২০৫ মানে ৮.৯% ঝুঁকি — এখনকার ৫.১% ঝুঁকির বদলে। তোমার এই কৌশলে রিস্ক কমছে না, বাড়ছে।
আমি বুঝতে পারছি, তোমরা দুজনেই "নিরাপদ" থাকতে চাও। কিন্তু এই বাজারে, যখন সোনার খনি এত কম দামে মিলছে, সেখানে নিরাপদ থাকার অর্থ হলো আত্মতুষ্টিতে ভরা একটা ভুল সিদ্ধান্ত নেওয়া। ট্রেডারের প্ল্যানটা দেখো — ৩টি কিস্তি, প্রথমে ৪০-৫০%, স্টপ-লস ২০৫। এটা কোনো উরু উরু কৌশল না, এটা একদম কৌশলগত সাহস। ২০৫-এ স্টপ মানে সর্বোচ্চ ৫.১% ঝুঁকি, আর উপরের দিকে পাহাড়সম সম্ভাবনা। এখন না কিনলে, এই সুযোগ হাতছাড়া হলে কে দায় নেবে? আমি বলব, এক্ষেত্রে সিদ্ধান্ত নিতে হবে এখনই — BUY, পূর্ণ আত্মবিশ্বাসে।
\ No newline at end of file
Conservative Analyst: অ্যাগ্রেসিভ অ্যানালিস্টের দিকে তাকিয়ে আমার মনে হচ্ছে তিনি একটা গরম ঘরে দাঁড়িয়ে ঠান্ডা পানীয় খেতে চাইছেন, কিন্তু ঘরটা যে আগুন লাগতে পারে সেটা ভুলে গেছেন। তিনি 'সোনার খনি' বলেছেন, 'বাজারের ভুল মূল্যায়ন' বলেছেন, কিন্তু একজন দায়িত্বশীল রিস্ক অ্যানালিস্ট হিসেবে আমার কাজ হলো সেই সোনার খনিতে যাওয়ার পথে যে গর্তগুলো আছে সেগুলো দেখানো। শুধু ভালো কোম্পানি বলেই যে কোনো দামে কেনা যায় না, যেকোনো সময় কেনা যায় না — এটা বিনিয়োগের সবচেয়ে প্রাথমিক নিয়ম।
প্রথমে বলি, তিনি P/E 7.73 আর EPS গ্রোথের কথা বলছেন। পুরোপুরি সত্যি, কোম্পানির ফান্ডামেন্টাল চমৎকার। কিন্তু প্রশ্ন হলো — এই ভালো ফান্ডামেন্টাল কি আজকেই আমাদের বুঝতে হবে? না, এই তথ্যগুলো সর্বজনীন, প্রতিটি ইনভেস্টর জানে। তাহলে দাম কেন 236-এর উপরে গেল না? কেন 200-এর নিচে নেমে 207-তে গেল মে মাসে? কারণ বাজার শুধু ফান্ডামেন্টালে চলে না — সেন্টিমেন্ট, লিকুইডিটি, ম্যাক্রো ইকোনমি, এসবও চলে। DSE-তে ফার্মাসিউটিক্যাল সেক্টরের এই নিম্নচাপটা কি শুধুই অস্থায়ী? কেউ নেই সেই নিশ্চয়তা। আজ যদি 7.73 P/E-তে দাম 216-220-এ থাকে, আর আগামী ছয় মাসে বাজার মন্দা থাকে, তাহলে আরেকটি 15-20% করেকশন দেখা বিচিত্র নয়।
এখন টেকনিক্যাল দিক থেকে দেখুন। তিনি বলছেন, ATR 2.03 সংকুচিত — এটা ব্রেকআউটের মঞ্চ। আমি বলছি, এই ব্রেকআউটটা উপরের দিকে হবে — সেই নিশ্চয়তা কোথায়? বরং নিচের দিকেও হতে পারে। MACD -0.24, হ্যাঁ অল্প নেতিবাচক, কিন্তু ট্রেন্ডটা স্পষ্ট নিম্নমুখী — জুন মাসের +3.3 থেকে এখন -0.24। সিগনাল লাইন -0.01-এ, হিস্টোগ্রাম -0.23-এ — এটা কোনো উল্টে যাওয়ার সিগনাল দিচ্ছে না। 207-তে যাওয়ার সময় (আগস্ট-ডিসেম্বর ২০২৫) একই রকম MACD নিম্নমুখী হয়ে ছিল। RSI 48.73 — নিরপেক্ষ অঞ্চল, মানে কোনো শক্ত ক্রয় চাপ নেই। ভলিউম 140,479 — খুবই কম। 221+ ব্রেক করার জন্য একটা ভলিউম-স্পাইক দরকার, সেটা অনেক দিন দেখা যাচ্ছে না। দাম 50-SMA (219.69) আর 10-EMA (219.86)-এর এই জাংশনে দাঁড়িয়ে আছে — প্রতিদিন যাচাই হচ্ছে। যদি 50-SMA ভেঙে 200-SMA (213.44)-এর দিকে নামে, তাহলে সেখান থেকে 207-208 লাগবে না রিস্ক-রিওয়ার্ডের হিসেব।
স্টপ-লস 205 — তিনি বলছেন মাত্র 5% দূরে। কিন্তু আমার হিসেবে, বর্তমান ক্লোজ 219.90, স্টপ 205 মানে 6.8% নিচে। অথচ উপরে আপ-টার্গেট 232-236 থেকে বর্তমান দাম 5-7% দূরে। রিস্ক-রিওয়ার্ড তো প্রায় ১:১-র মতো। তা-ও আবার এন্ট্রি পয়েন্ট 216 নিচ্ছেন, তাহলে স্টপ থেকে ঝুঁকি 5.1%, টার্গেট 232-তে লাভ 7.4%। পুরো টার্গেট 236 নিলে 9.2%। তাহলে সর্বোচ্চ ১.৮:১ — যা খুব ভালো কিছু না। আর সময়কাল — যদি ছয় মাসে এই লাভ হয়, তবে বার্ষিক রিটার্ন 15-18%। স্থিতিশীল ব্যাংক ডিপোজিট 8-9% দেয়। পার্থক্যটা খুব বেশি ঝুঁকির জন্য যথেষ্ট নয়।
ইনস্টিটিউশনাল তো আমরা। আমাদের ক্লায়েন্টরা আসে হারানো গুছিয়ে দেওয়ার জন্য, না জুয়া খেলতে। আমাদের প্রাইমারি হলো ক্যাপিটাল প্রোটেকশন। তাই আমরা অপেক্ষা করব। আমরা কভার করতে পারি, কিন্তু 40-50% পজিশন প্রথম কিস্তিতে — সেটা অ্যাগ্রেসিভ অ্যানালিস্টের সাহস, কনজারভেটিভ ম্যানেজারের সিদ্ধান্ত নয়।
এখন নিউট্রাল অ্যানালিস্টের দিকেও আমি প্রশ্ন রাখব। তিনি বলেছেন HOLD — সবসময় যে HOLD সঠিক তা না। যমজ-সংকেত অভাবে HOLD যুক্তিসঙ্গত, কিন্তু তাতে কোনো অ্যাকশন নেই। প্রাতিষ্ঠানিক ফার্মে আমরা শুধু স্ট্যাটাস ধরে রাখি না — রিটার্ন আনতে হয়। যদি আমরা জানি ফান্ডামেন্টাল শক্ত, 200-SMA-এর নিচে যাওয়ার সম্ভাবনা থাকলে আমরা যেটা করতে পারি সেটা হলো শর্তসাপেক্ষ এন্ট্রি, কিন্তু স্টপ-লস 216-এর নিচে 213-212-তে, পজিশন সাইজ 20%। অথবা 221+ ভলিউমসহ ব্রেকআউটের পর রোড-সাইডে এন্ট্রি।
আমি অ্যাগ্রেসিভকে স্পষ্টভাবে বলছি — আপনি 'সোনার খনি' বলছেন, আমি বলছি 'সোনা আছে, কিন্তু এখানে এখনো ঘরের দরজা খোলা হয়নি'। অপেক্ষারও সুবিধা আছে। স্পন্সর হোল্ডিং বারছে — এটা ভালো, তারা দীর্ঘমেয়াদে জানে কিন্তু তারা ৫-১০ বছর ধরে হোল্ড করে। আমাদের ক্লায়েন্টের পোর্টফোলিওর 40%-50% একটা একক স্টকে নেওয়া হলো সেই দীর্ঘমেয়াদি সাপোর্টের সঙ্গে মিলে না। তারা মাইনরিটি — মার্কেট ক্যাপের 44% ধরে আছেন, বাকি 56% ফ্লোটে। ফ্লোটে তো প্রচুর সুপ্লাই থাকে, যারা আতঙ্কিত হয়ে বিক্রি করতে পারে।
বেনচমার্ক: Q3-এ EPS 6.73 Q2-এর 8.20-এর থেকে 18% নিচে। গত বছর 9M EPS ছিল 21.15, এবার 23.29 — ভালো। কিন্তু Q4-তে কী হবে? FY2026 ফুল-ইয়ার EPS যদি 26-27 এ আসে, তাহলে 216-220-এ P/E 8.2-8.5, NAV 169.79-এ P/B 1.28 — এখনো সস্তা, হ্যাঁ। কিন্তু এই লেভেল দীর্ঘদিন থাকতে পারে, যেমন 2019-2024 দেড় বছর ধরে 200-220-এ ছিল। কে বলেছে এক মাসে 232-এ যাবে?
আরেকটা গুরুত্বপূর্ণ ঝুঁকি — ক্যাশ ফ্লো। FY2025-এ NOCFPS 19.52, কিন্তু FY2026 Q3-তে 17.54 — অপারেটিং ক্যাশ ফ্লো ভালো আছে, কিন্তু তাদের বিক্রি-থেকে অ্যাকাউন্টস রিসিভেবল বাড়ছে? ডেট পাওয়ারস 4.5 বিলিয়ন — গত কয়েক বছরে এই ব্যালান্স বেড়েছে। ইনভেন্টরি 12.5 বিলিয়ন — এটা বেশি। ওয়ার্কিং ক্যাপিটাল ম্যানেজমেন্টে সামান্য চাপ আছে। তাছাড়া 52 বিলিয়ন নগদ — বেকড লিকুইডিটি। ম্যানেজমেন্ট কেন এই নগদ বিনিয়োগ করে না? রিটার্ন অন ক্যাশ খুবই কম। এই লিকুইডিটি বনাম রোডম্যাপ — কোম্পানির গ্রোথের জন্য নতুন প্রোডাক্ট, এক্সপোর্ট হাব, R&D — কোথায়? ডিভিডেন্ড 120% দিচ্ছে, তার অর্থ পুনর্বিনিয়োগ কম — ভবিষ্যতে গ্রোথের ইঞ্জিন কিছুটা ঝিমিয়ে পড়তে পারে। এই সব বিবেচনায়, 216-এ দাঁড়িয়ে আমাদের জন্য কোনো জরুরি এন্ট্রি নেই।
আমার প্রস্তাব:
- বর্তমান পজিশন সাইজে নতুন কোনো এন্ট্রি করব না।
- টার্গেট: 200-SMA (213.44)-এর কাছে বা 51.5-এর নিচে 210-তে পুলব্যাকে প্রথম 15% পজিশন।
- আরেকটি স্টেজ: 221+ ভলিউমসহ ব্রেকআউটে (প্রতিদিন 300K-500K+ শেয়ার) 15-20%।
- সর্বোচ্চ মোট পজিশন 40% রাখব।
- স্টপ-লস: পুলব্যাক এন্ট্রির জন্য 205-এর নিচে 199-200-এ বা ব্রেকআউট এন্ট্রির জন্য 213-এর নিচে।
এটা স্পষ্ট — ফান্ডামেন্টাল যত ভালোই থাক, এন্ট্রি প্রাইস আর টেকনিক্যাল টাইমিং ছাড়া রিটার্ন কখনো নিশ্চিত হয় না। অ্যাগ্রেসিভ অ্যানালিস্ট যা বলছেন, সেটা ভবিষ্যতের দীর্ঘ মেয়াদে সঠিক হতে পারে — কিন্তু আমরা তো DSE-তে দৈনিক বাংলা কাগজে হাত কাঁপতে বসা ছোটখাটো ট্রেডার নই, আমরা প্রাতিষ্ঠানিক সম্পদ রক্ষায় দায়বদ্ধ। গুড কোম্পানি এখন কেনার জন্য যথেষ্ট নয়। আমাদের অপেক্ষা করতে হবে ঠিক কোন দামে, ঠিক কখন, কোন সিগন্যালে প্রবেশ করতে হবে। এই PRUDENCE না থাকলে 200-207-তে আবার ধাক্কা খেয়ে ক্লায়েন্ট কী বলবে? তাই আমি বলছি — HOLD বাট শর্তসাপেক্ষ BUY প্ল্যান, যেটা ঝুঁকি নিয়ন্ত্রণে রাখবে।
Conservative Analyst: আমি অ্যাগ্রেসিভ অ্যানালিস্ট এবং নিউট্রাল অ্যানালিস্ট দুজনের বক্তব্যই মনোযোগ দিয়ে শুনলাম। কিন্তু আমার দায়িত্ব কিন্তু দাঁড়িয়ে হাততালি দেওয়া নয়; আমার দায়িত্ব হলো ক্লায়েন্টের মূলধন আগে সুরক্ষিত আছে কি না, সেটা নিশ্চিত করা। আমার কাছে SQURPHARMA-এর ফান্ডামেন্টাল যতই শক্তিশালী হোক, "ভালো কোম্পানি" আর "ভালো বিনিয়োগ মুহূর্ত" এক জিনিস নয়। অ্যাগ্রেসিভ অ্যানালিস্ট যেভাবে বলছেন যে P/E ৭.৭৩, স্পনসর হোল্ডিং বাড়ছে, EPS বাড়ছে — এসব আমি অস্বীকার করছি না। কিন্তু তিনি যে সিদ্ধান্তে পৌঁছাচ্ছেন, সেটা আমার কাছে দায়িত্বজ্ঞানহীন।
প্রথমত, অ্যাগ্রেসিভ অ্যানালিস্টের সবচেয়ে বড় দুর্বলতা হলো তিনি ধরে নিচ্ছেন যে কম P/E মানেই দাম শিগগির উঠবে। বাস্তবে DSE-তে কম P/E অনেক দিন ধরে কমই থাকতে পারে — ২০১৯-২০২৪ পর্যন্ত SQURPHARMA ২০০-২২০ টাকার রেঞ্জে ছিল, তখনো ফান্ডামেন্টাল ভালো ছিল। বাজার শুধু ফান্ডামেন্টালে চলে না; সেন্টিমেন্ট, তারল্য, ম্যাক্রো, নিয়ন্ত্রক পরিবেশ — সব মিলিয়ে চলে। আজ ৭.৭৩ P/E-তে স্টক আছে বলে এটা যে অবশ্যই ১০ P/E-তে রেট হবে, তার কোনো নিশ্চয়তা নেই। বাজার "অদক্ষ" থাকতে পারে, এবং সেই অদক্ষতা থেকেই বড় করেকশনও আসতে পারে। অ্যাগ্রেসিভ অ্যানালিস্ট বলেন "অপেক্ষা করলে ঝুঁকি বাড়ে" — কিন্তু আসলে অপেক্ষা করলে সুযোগও তৈরি হয়। ২১৩-তে পুলব্যাক এলে তিনি যে এন্ট্রি নিতে চান, সেটা ২১৬-তে এন্ট্রি নেওয়ার চেয়ে অনেক ভালো ঝুঁকি-রিটার্ন দেবে। আর দাম যদি ২২৫-এ চলে যায়, তাহলে আমরা সেই মুভটা মিস করব — কিন্তু প্রাতিষ্ঠানিক বিনিয়োগকারী হিসেবে আমাদের কাজ হলো প্রতিটা সুযোগ নেওয়া নয়, বরং এমন সুযোগ নেওয়া যেখানে downside সীমিত এবং upside স্পষ্ট।
দ্বিতীয়ত, তার রিস্ক-রিওয়ার্ড হিসেবটা একদম ভুল। ২১৬-এ এন্ট্রি, ২০৫-এ স্টপ মানে ঝুঁকি ১১ টাকা বা ৫.১%। উপরে টার্গেট ২৩২ ধরলে রিটার্ন ১৬ টাকা বা ৭.৪%; ২৩৬ ধরলে ২০ টাকা বা ৯.২৬%। অর্থাৎ সর্বোচ্চ রিস্ক-রিওয়ার্ড ১.৮:১ — এবং সেটাও টার্গেট পুরোপুরি হিট করলে। অথচ তিনি বলছেন ২৫০-২৭০ টার্গেট। ২৫০-এর জন্য তো দরকার P/E প্রায় ৯.২, আর ২৭০-এর জন্য P/E প্রায় ১০। P/E রেটিং একটা অনুমান; এটাকে নিশ্চিত টার্গেট বানিয়ে রিস্ক-রিওয়ার্ড "অসীম" বলা সম্পূর্ণ ভুল। সর্বোচ্চ ১.৮:১ অনুপাত — যেখানে ডাউনসাইডে ২০০-SMA ২১৩.৪৪ ভেঙে ২০৭-২০৮ পর্যন্ত নামার সম্ভাবনা টেকনিক্যাল রিপোর্টেই আছে — সেখানে ৪০-৫০% পজিশন নেওয়া বুদ্ধিমানের কাজ নয়। যদি স্টপ-লস ২০৫-এ হিট হয়, তাহলে অ্যাগ্রেসিভের পরিকল্পনায় প্রথম কিস্তিতেই পোর্টফোলিওর ২-৩% ক্ষতি — সেটা কি তিনি ক্লায়েন্টকে বুঝিয়েছেন?
তৃতীয়ত, স্পনসর হোল্ডিং বৃদ্ধির যুক্তিটা নিয়ে বলি। স্পনসর বা পরিচালকরা যে কোম্পানির ভেতরের খবর বেশি জানেন, সেটা সত্য। কিন্তু তাঁদের বিনিয়োগ দিগন্ত ৫-১০ বছর, আর আমাদের ক্লায়েন্টের দিগন্ত সেটা নয়। পরিচালকরা ৪৪% হোল্ডিং ধরে রেখেছেন — এতে দীর্ঘমেয়াদে কোম্পানির ওপর আস্থা বোঝায়, কিন্তু আগামী ৩ মাসে দাম যে ২১৬ থেকে ২৩২-এ যাবে, তার প্রমাণ কিছুই নয়। উল্টো, তাদের হোল্ডিং বাড়লে ফ্লোটে শেয়ারের সরবরাহ কমে — সেটা ভালো। কিন্তু বাকি ৫৬% ফ্লোটে আছে, যার মধ্যে সাধারণ বিনিয়োগকারী ২৭.২৩% — আতঙ্কে বিক্রি করতে পারে। বিশেষ করে Q3-এ EPS ৬.৭৩-এ নেমেছে, আগের কোয়ার্টারে ছিল ৮.২০; এই ধরনের দুর্বলতা সাময়িক হতে পারে, কিন্তু বাজার কখনো কখনো সাময়িক দুর্বলতাকে বড় করে দেখে।
নিউট্রাল অ্যানালিস্টের ২৫-৩০% প্রথম কিস্তির প্রস্তাবটাও আমার কাছে এখনো বেশি ঝুঁকিপূর্ণ। তিনি বলেছেন ট্রেডারের ৩-কিস্তির প্ল্যান যুক্তিসঙ্গত, শুধু সাইজ কমানো দরকার। কিন্তু কেন প্রথম কিস্তিতেই ২৫-৩০%? বর্তমান ক্লোজ ২১৯.৯০, দাম ৫০-SMA ২১৯.৬৯ এবং ১০-EMA ২১৯.৮৬-এর ঠিক সংযোগস্থলে। MACD -০.২৪, সিগনাল লাইন -০.০১, হিস্টোগ্রাম -০.২৩ — সব নেতিবাচক। ভলিউম মাত্র ১৪০,৪৭৯ — ক্রয় চাপ দুর্বল। বোলিঞ্জার ব্যান্ডের মধ্যমা ২২০.৮০, যার নিচে দাম আছে। ২০০-SMA ২১৩.৪৪, সেখান থেকে মাত্র ৩ পার্সেন্ট দূরে। এই অবস্থায় ২৫-৩০% নিয়ে শুরু করার মানে হলো দিকনির্দেশনার আগেই বড় পজিশন নিয়ে ফেলা। ATR ২.০৩ সংকুচিত হয়েছে — কিন্তু অ্যাগ্রেসিভ যেমন বলছেন এটা ব্রেকআউটের মঞ্চ, তেমনি এটা ব্রেকডাউনেরও মঞ্চ হতে পারে। কম ভোলাটিলিটির পরে দুই দিকেই ব্রেকআউট সম্ভব। MACD-এর নেতিবাচক অবস্থান বলছে আপাতত টেকনিক্যাল গতি দুর্বল।
আরেকটা গুরুত্বপূর্ণ বিষয় — ফান্ডামেন্টাল রিপোর্টে দেখা যাচ্ছে trade debtors ৪.৫ বিলিয়ন টাকা, আর ইনভেন্টরি ১২.৫৮ বিলিয়ন টাকা। Q3-এ NOCFPS ১৭.৫৪, আগের বছর ফুল-ইয়ার NOCFPS ছিল ১৯.৫২। মানে অপারেটিং ক্যাশ ফ্লো ভালো আছে, কিন্তু কার্যকরী মূলধন ব্যবস্থাপনায় একটু চাপ আছে। ৫২ বিলিয়ন টাকা নগদ থাকা ভালো, কিন্তু ম্যানেজমেন্ট সেই নগদ থেকে খুব বেশি রিটার্ন করছে না; লভ্যাংশ ১২০% দিচ্ছে, অর্থাৎ পুনর্বিনিয়োগ কম। দীর্ঘমেয়াদে এই নগদ কি নতুন প্রবৃদ্ধিতে যাবে, নাকি শুধু পাশে পড়ে থাকবে — সেটা নিয়ে অ্যাগ্রেসিভ কোনো উত্তর দিচ্ছেন না। "সোনার খনি" বললেই তো আর মূলধন সুরক্ষিত হয় না।
নিউট্রাল অ্যানালিস্টের আরেকটা যুক্তি — "অপেক্ষা করলে ডিভিডেন্ড ফলন হাতছাড়া হয়।" কিন্তু ১২০% ডিভিডেন্ড মানে প্রতি শেয়ারে ১২ টাকা; ২১৬-তে সেই ফলন ৫.৫৬%, আর ২০৭-তে ফলন হবে ৫.৮০%। ব্যাংক ডিপোজিট ৮-৯% দিচ্ছে; এই পার্থক্য এত বড় নয় যে তার জন্য অপ্রয়োজনীয় মার্কেট রিস্ক নিতে হবে। তাছাড়া আমাদের ব্যবস্থাপনায় শুধু ডিভিডেন্ড ফলনই না — টোটাল রিটার্ন গুরুত্বপূর্ণ। যদি ২১৬-তে কিনে দাম ২০৭-এ নামে, তাহলে ডিভিডেন্ড ১২ টাকা পেলেও মূলধন ক্ষতি ৯ টাকা — নিট সুবিধা প্রায় ৩ টাকা বা ১.৪%। এত সামান্য সুবিধার জন্য ৪০% পজিশন কেন?
আমার প্রস্তাব স্পষ্ট — ট্রেডারের BUY প্রস্তাবটি আমি প্রত্যাখ্যান করছি। অ্যাগ্রেসিভের পূর্ণ আত্মবিশ্বাস আর নিউট্রালের অর্ধেক আত্মবিশ্বাস দুটোই এড়িয়ে, আমি বলব: বর্তমান মুহূর্তে ২১৬-তে নতুন কোনো কেনা নয়। যদি একান্তই অংশ নিতেই হয়, তবে প্রথম কিস্তি সর্বোচ্চ ১০-১৫% — ২১৩.৪৪ (২০০-SMA) এবং ২১৬.৭২ (বোলিঞ্জার নিচের ব্যান্ড) অঞ্চলে ধীরে ধীরে। স্টপ-লস ২০৫-এর নিচে ২০৪-এর নিচে ক্লোজ করলে, মানে দীর্ঘমেয়াদি কাঠামো ভাঙলে — পুরো পজিশন বের করে আসা। কিন্তু আদর্শ পরামর্শ হলো অপেক্ষা করা। যদি ২২১-এর উপরে দৈনিক ক্লোজ হয় এবং ভলিউম বাড়ে ৩০০-৫০০ কে-তে, তাহলে দ্বিতীয় কিস্তি ১৫-২০% নেওয়া যেতে পারে। আর ২২৫-২২৬ ব্রেকআউট নিশ্চিত হলে সর্বোচ্চ মোট ৪০% — তার বেশি নয়। যেটা অ্যাগ্রেসিভ বলছেন "এখন না কিনলে ট্রেন ছেড়ে দেবে" — আমি বলছি, দাম উঠে গেলে আমরা অন্য ভালো সুযোগ খুঁজে নেব; কিন্তু দাম ২০৫-এ এসে ক্লায়েন্টের পোর্টফোলিও ৫% ক্ষতিগ্রস্ত হলে, সেটা আমরা ব্যাখ্যা করতে পারব না। SQURPHARMA অসাধারণ কোম্পানি, কিন্তু অসাধারণ কোম্পানি মানে না যে কোনো দামে, না জেনে, নিশ্চিত সিগনাল ছাড়া কেনা। তাই আমার অবস্থান — HOLD, এবং শর্তসাপেক্ষে খুব ছোট আকারে BUY; তবে ৪০-৫০% প্রথম কিস্তি একেবারেই অগ্রহণযোগ্য।
Conservative Analyst:
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
**Rating**: Buy
**Executive Summary**: SQURPHARMA-তে কিস্তিভিত্তিক (staged) BUY নেওয়ার সুপারিশ। ফান্ডামেন্টাল ও মূল্যায়ন অত্যন্ত আকর্ষণীয় (P/E 7.73, নিট নগদ ~৫১ বিলিয়ন, স্পনসর হোল্ডিং 44.15%), কিন্তু স্বল্পমেয়াদি টেকনিক্যাল দুর্বলতা (নেতিবাচক MACD, কম ভলিউম, প্রাইস কনফ্লুয়েন্স পয়েন্টে) থাকায় প্রথম কিস্তি সীমিত ২৫-৩০%-এ রাখা হবে। ধাপে ধাপে কনফার্মেশন সিগন্যালে পজিশন বাড়িয়ে মোট ৫০% পর্যন্ত যাওয়া। স্টপ-লস ২০৫ BDT, প্রাথমিক টার্গেট ২৩২-২৩৬, সময়-দিগন্ত ৬-১২ মাস।
**Investment Thesis**: বুলিশ শিবিরের সংখ্যাগত যুক্তি জোরালো: P/E মাত্র 7.73 (ইতিহাসের নিম্ন অঞ্চল), EPS সাত বছরে 16.03 থেকে 27.04-তে ৬৯% বৃদ্ধি, NAV/share 169.79, P/B 1.30, ROE 17%+, নিট নগদ ~৫১ বিলিয়ন টাকা, এবং লভ্যাংশ 42% থেকে 120%-তে উত্থান। সবচেয়ে গুরুত্বপূর্ণ সংকেত হলো স্পনসর/পরিচালক হোল্ডিং এক বছরে 34.67% থেকে 44.15%-এ বেড়ে যাওয়া — যা ভেতরের খেলোয়াড়দের আস্থার শক্তিশালী প্রমাণ। বেয়ারিশ শিবিরের সতর্কতাও বৈধ: Q3-এ EPS YoY -5.2%, MACD নেতিবাচক, RSI 48.73, ভলিউম 140,479 (দুর্বল), এবং 7 বছর ধরে প্রাইস 198-236 রেঞ্জে বন্দি। তবে Q3-এর দুর্বলতা ঋতুভিত্তিক প্যাটার্নের সাথে সামঞ্জস্যপূর্ণ, ৯ মাসের EPS (23.29) আগের বছরের (21.15) চেয়ে বেশি। 2019-2024-এ lud প্রাইস 200-220-এ থাকলেও সেই সময় EPS 16-23 আর NAV 86-142-তে ছিল — এখন ফান্ডামেন্টাল দ্বিগুণ হলেও দাম একই আছে, এটি বাজারের গুরুতর অদক্ষতা যা বিনিয়োগ সুযোগ তৈরি করে। ভ্যালু-ট্র্যাপ উদ্বেগ সত্ত্বেও, 52 বিলিয়ন নগদ আর নগণ্য ঋণের (0.82 বিলিয়ন) কারণে downside সীমিত। ঝুঁকি-রিটার্ন অসমমিত: নিচে 205-এ স্টপ (জন­রিস্ক ~5-6%), উপরে 232-236 পর্যন্ত প্রথম টার্গেট অবিবেচনা থেকে ~14% আপসাইড, এবং P/E 9-10-এ রিরেট হলে 250-280 সম্ভাবনা। তবে টেকনিক্যাল মোমেন্টাম দুর্বল ও কনফ্লুয়েন্স পয়েন্ট (50-SMA 219.69, 10-EMA 219.86) না ভাঙা পর্যন্ত পুরো পজিশন নেওয়া ঝুঁকিপূর্ণ — তাই প্রথম কিস্তি ২৫-৩০%-এ সীমিত রেখে কনফার্মেশন সিগন্যালে ধাপে ধাপে পজিশন বাড়ানোই সর্বোত্তম ভারসাম্য।
**Price Target**: 236.0
**Time Horizon**: ৬-১২ মাস
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<main class="prediction-page"> <main class="prediction-page">
<header class="prediction-toolbar"> <header class="prediction-toolbar">
<a class="brand" href="/?view=timesfm" aria-label="TimesFM forecast home"> <a class="brand" href="/?view=timesfm" aria-label="Forecast home">
<span class="brand-mark">T</span> <span class="brand-mark">T</span>
<span>TRADINGAGENTS <strong>FORECAST LAB</strong></span> <span>TRADINGAGENTS <strong>FORECAST LAB</strong></span>
</a> </a>
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
@if (loading()) { @if (loading()) {
<section class="loading-state" aria-live="polite"> <section class="loading-state" aria-live="polite">
<span class="loader"></span> <span class="loader"></span>
<h1>Loading TimesFM prediction</h1> <h1>Loading market prediction</h1>
<p>Reading the saved backtest and chart series…</p> <p>Reading the saved backtest and chart series…</p>
</section> </section>
} }
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
<span class="eyebrow">NO PREDICTION RUN</span> <span class="eyebrow">NO PREDICTION RUN</span>
<h1>Generate the forecast first.</h1> <h1>Generate the forecast first.</h1>
<p>{{ errorMessage() }}</p> <p>{{ errorMessage() }}</p>
<code>tradingagents-predict "BXPHARMA'PB" --resolution 1d --open-ui</code> <code>dohasecuritiesstockai-dgt-predict GP --resolution 1d --open-ui</code>
</section> </section>
} }
@if (result(); as report) { @if (result(); as report) {
<section class="hero"> <section class="hero">
<div> <div>
<p class="eyebrow">TIMESFM {{ report.model.version }} · ZERO-SHOT PRICE FORECAST</p> <p class="eyebrow">{{ report.model.name | uppercase }} {{ report.model.version }} · PRICE FORECAST</p>
<div class="symbol-line"> <div class="symbol-line">
<h1>{{ report.symbol }}</h1> <h1>{{ report.symbol }}</h1>
<span>{{ report.data.resolution_label }}</span> <span>{{ report.data.resolution_label }}</span>
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<article class="accuracy-card"> <article class="accuracy-card">
<span>Holdout accuracy</span> <span>Holdout accuracy</span>
<strong>{{ report.metrics.accuracy_score | number: '1.1-2' }}<small>%</small></strong> <strong>{{ report.metrics.accuracy_score | number: '1.1-2' }}<small>%</small></strong>
<p>100 − sMAPE across the full hidden half</p> <p>100 − sMAPE across the full hidden holdout</p>
</article> </article>
</section> </section>
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
<header> <header>
<div> <div>
<p class="eyebrow">HISTORICAL BACKTEST + FORWARD PATH</p> <p class="eyebrow">HISTORICAL BACKTEST + FORWARD PATH</p>
<h2>Actual candles against TimesFM</h2> <h2>Actual candles against {{ report.model.name }}</h2>
</div> </div>
<div class="legend" aria-label="Chart legend"> <div class="legend" aria-label="Chart legend">
<span><i class="candle"></i>Actual OHLC</span> <span><i class="candle"></i>Actual OHLC</span>
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
<span><i class="live"></i>Live actual</span> <span><i class="live"></i>Live actual</span>
</div> </div>
</header> </header>
<div #predictionChart class="prediction-chart" role="img" aria-label="DSE actual and TimesFM forecast chart"></div> <div #predictionChart class="prediction-chart" role="img" [attr.aria-label]="'DSE actual and ' + report.model.name + ' forecast chart'"></div>
<footer> <footer>
<span>Context</span> <span>Context</span>
<strong>{{ report.data.first_timestamp | date: 'mediumDate' }} → {{ report.history[report.data.context_points - 1].time | date: 'mediumDate' }}</strong> <strong>{{ report.data.first_timestamp | date: 'mediumDate' }} → {{ report.history[report.data.context_points - 1].time | date: 'mediumDate' }}</strong>
......
...@@ -70,7 +70,7 @@ export class TimesFmPredictionComponent ...@@ -70,7 +70,7 @@ export class TimesFmPredictionComponent
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
this.titleService.setTitle('TimesFM Stock Forecast'); this.titleService.setTitle('DSE Stock Forecast');
const query = new URLSearchParams(window.location.search); const query = new URLSearchParams(window.location.search);
const runId = query.get('run')?.trim(); const runId = query.get('run')?.trim();
const symbol = query.get('symbol')?.trim().toUpperCase(); const symbol = query.get('symbol')?.trim().toUpperCase();
...@@ -82,6 +82,7 @@ export class TimesFmPredictionComponent ...@@ -82,6 +82,7 @@ export class TimesFmPredictionComponent
request.subscribe({ request.subscribe({
next: (result) => { next: (result) => {
this.result.set(result); this.result.set(result);
this.titleService.setTitle(`${result.model.name} · ${result.symbol}`);
this.loading.set(false); this.loading.set(false);
this.errorMessage.set(''); this.errorMessage.set('');
setTimeout(() => this.renderChart()); setTimeout(() => this.renderChart());
...@@ -90,7 +91,7 @@ export class TimesFmPredictionComponent ...@@ -90,7 +91,7 @@ export class TimesFmPredictionComponent
error: () => { error: () => {
this.loading.set(false); this.loading.set(false);
this.errorMessage.set( this.errorMessage.set(
'Prediction data is not available. Run tradingagents-predict first.', 'Prediction data is not available. Run a forecasting command first.',
); );
this.liveStatus.set('offline'); this.liveStatus.set('offline');
}, },
......
...@@ -114,7 +114,7 @@ def create_app() -> FastAPI: ...@@ -114,7 +114,7 @@ def create_app() -> FastAPI:
if result is None: if result is None:
raise HTTPException( raise HTTPException(
status_code=404, status_code=404,
detail="No TimesFM prediction run matches this request.", detail="No prediction run matches this request.",
) )
return result return result
......
...@@ -116,7 +116,7 @@ def dashboard_url(host: str, port: int, symbol: str, analysis_date: date | str) ...@@ -116,7 +116,7 @@ def dashboard_url(host: str, port: int, symbol: str, analysis_date: date | str)
def prediction_dashboard_url(host: str, port: int, run_id: str) -> str: def prediction_dashboard_url(host: str, port: int, run_id: str) -> str:
"""Return the standalone Angular URL for one TimesFM prediction run.""" """Return the standalone Angular URL for one prediction run."""
browser_host = "127.0.0.1" if host in {"0.0.0.0", "::"} else host browser_host = "127.0.0.1" if host in {"0.0.0.0", "::"} else host
query = urlencode({"view": "timesfm", "run": run_id}) query = urlencode({"view": "timesfm", "run": run_id})
...@@ -188,7 +188,7 @@ def launch_prediction_dashboard( ...@@ -188,7 +188,7 @@ def launch_prediction_dashboard(
host: str | None = None, host: str | None = None,
port: int | None = None, port: int | None = None,
) -> str: ) -> str:
"""Build, serve, and open the standalone TimesFM Angular result screen.""" """Build, serve, and open the standalone forecast result screen."""
resolved_host = host or os.environ.get("TRADINGAGENTS_API_HOST", "127.0.0.1") resolved_host = host or os.environ.get("TRADINGAGENTS_API_HOST", "127.0.0.1")
resolved_port = port or int(os.environ.get("TRADINGAGENTS_API_PORT", "8000")) resolved_port = port or int(os.environ.get("TRADINGAGENTS_API_PORT", "8000"))
......
"""Differential Graph Transformer forecasting for Doha Securities DSE data."""
from .core import (
DGTConfig,
DifferentialGraphTransformer,
ForecastRun,
MarketGraphData,
TrainingSummary,
build_graph_prior,
load_dse_market_graph,
run_dgt_prediction,
save_forecast_run,
)
__all__ = [
"DGTConfig",
"DifferentialGraphTransformer",
"ForecastRun",
"MarketGraphData",
"TrainingSummary",
"build_graph_prior",
"load_dse_market_graph",
"run_dgt_prediction",
"save_forecast_run",
]
"""Run DGT forecasting with ``python -m dohasecuritiesstockai.dgt_forecasting``."""
from .cli import main
if __name__ == "__main__":
raise SystemExit(main())
"""Dedicated command-line entry point for DGT forecasts."""
from .core import main
__all__ = ["main"]
if __name__ == "__main__":
raise SystemExit(main())
"""Differential Graph Transformer forecasting for Doha Securities DSE data.
This module replaces the original Colab-only experiment. It uses the existing
``dohasecuritiesstockai`` authenticated candle loader, makes a chronological
train/validation/holdout split, trains a Differential Graph Transformer (DGT),
compares recursive holdout predictions with real closing prices, and produces
future forecasts. Results use the project's prediction JSON contract, so the
existing API and Angular prediction dashboard can display them.
Example::
dohasecuritiesstockai-dgt-predict GP \
--resolution 1d --lookback 2y --peers DSEX,BRACBANK,SQURPHARMA \
--future-steps 12 --epochs 80
DSE authentication is read by the existing data layer. Set ``DSE_ACCESS_TOKEN``
or ``DSE_EMAIL_OR_PHONE`` and ``DSE_PASSWORD`` before running the command.
"""
from __future__ import annotations
import argparse
import copy
import csv
import math
import random
import re
from calendar import monthrange
from collections.abc import Callable, Sequence
from dataclasses import asdict, dataclass
from datetime import date, datetime, timedelta, timezone
from pathlib import Path
from uuid import uuid4
import numpy as np
import torch
import torch.nn.functional as F
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
from dohasecuritiesstockai.dataflows.config import get_config
from dohasecuritiesstockai.dataflows.dse import (
DEFAULT_DSE_GATEWAY_URL,
DSEClient,
normalize_dse_symbol,
)
from dohasecuritiesstockai.default_config import DEFAULT_CONFIG
from dohasecuritiesstockai.timesfm_forecasting.market_data import (
MarketCandle,
Resolution,
fetch_dse_candles,
)
from dohasecuritiesstockai.timesfm_forecasting.metrics import calculate_accuracy_metrics
from dohasecuritiesstockai.timesfm_forecasting.repository import PredictionRepository
from dohasecuritiesstockai.timesfm_forecasting.schema import (
BacktestPoint,
CandlePoint,
DataMetadata,
ForecastPoint,
LiveFeedMetadata,
ModelMetadata,
TimesFMPredictionResult,
)
@dataclass(frozen=True)
class DGTConfig:
"""Training and architecture settings for one forecast run."""
window: int = 32
split_ratio: float = 0.8
validation_ratio: float = 0.15
future_steps: int = 12
epochs: int = 80
patience: int = 12
batch_size: int = 32
learning_rate: float = 1e-3
weight_decay: float = 1e-5
hidden_size: int = 32
num_heads: int = 2
num_layers: int = 2
dropout: float = 0.1
graph_top_k: int = 5
use_spatial: bool = True
refit_for_future: bool = True
seed: int = 42
def validate(self) -> None:
if self.window < 4:
raise ValueError("window must be at least 4 bars.")
if not 0.5 <= self.split_ratio <= 0.95:
raise ValueError("split_ratio must be between 0.5 and 0.95.")
if not 0.05 <= self.validation_ratio <= 0.4:
raise ValueError("validation_ratio must be between 0.05 and 0.4.")
if self.future_steps < 1:
raise ValueError("future_steps must be at least 1.")
if min(self.epochs, self.patience, self.batch_size) < 1:
raise ValueError("epochs, patience, and batch_size must be positive.")
if self.learning_rate <= 0 or self.weight_decay < 0:
raise ValueError("learning_rate must be positive and weight_decay non-negative.")
if self.hidden_size < 1 or self.num_heads < 1:
raise ValueError("hidden_size and num_heads must be positive.")
if self.hidden_size % (2 * self.num_heads) != 0:
raise ValueError("hidden_size must be divisible by two times num_heads.")
if self.num_layers < 1 or self.graph_top_k < 1:
raise ValueError("num_layers and graph_top_k must be positive.")
if not 0 <= self.dropout < 1:
raise ValueError("dropout must be at least zero and less than one.")
@dataclass(frozen=True)
class MarketGraphData:
"""Aligned closing prices for a target security and its graph peers."""
symbol: str
symbols: tuple[str, ...]
resolution: Resolution
target_candles: tuple[MarketCandle, ...]
closes: np.ndarray # [time, nodes]
@dataclass(frozen=True)
class TrainingSummary:
best_epoch: int
epochs_ran: int
best_validation_mse: float
device: str
parameter_count: int
train_samples: int
validation_samples: int
future_refit_epochs: int
graph_symbols: tuple[str, ...]
@dataclass(frozen=True)
class ForecastRun:
result: TimesFMPredictionResult
summary: TrainingSummary
model_state: dict[str, torch.Tensor]
model_config: dict[str, object]
class PriceScaler:
"""Per-security z-score scaler fitted only on the training period."""
def __init__(self, mean: np.ndarray, scale: np.ndarray) -> None:
self.mean = np.asarray(mean, dtype=np.float32)
self.scale = np.asarray(scale, dtype=np.float32)
@classmethod
def fit(cls, values: np.ndarray) -> PriceScaler:
mean = np.mean(values, axis=0, dtype=np.float64).astype(np.float32)
scale = np.std(values, axis=0, dtype=np.float64).astype(np.float32)
scale[scale < 1e-6] = 1.0
return cls(mean, scale)
def transform(self, values: np.ndarray) -> np.ndarray:
return ((np.asarray(values, dtype=np.float32) - self.mean) / self.scale).astype(np.float32)
def inverse_transform(self, values: np.ndarray) -> np.ndarray:
return (np.asarray(values, dtype=np.float32) * self.scale + self.mean).astype(np.float32)
class RMSNorm(nn.Module):
def __init__(self, dimension: int, epsilon: float = 1e-6) -> None:
super().__init__()
self.weight = nn.Parameter(torch.ones(dimension))
self.epsilon = epsilon
def forward(self, values: torch.Tensor) -> torch.Tensor:
normalized = values * torch.rsqrt(
values.float().square().mean(dim=-1, keepdim=True) + self.epsilon
)
return normalized.type_as(values) * self.weight
def _lambda_initial_value(depth: int) -> float:
return 0.8 - 0.6 * math.exp(-0.3 * depth)
class MultiheadDifferentialAttention(nn.Module):
"""Differential attention optionally gated by a dense graph prior."""
def __init__(self, hidden_size: int, num_heads: int, depth: int) -> None:
super().__init__()
if hidden_size % (2 * num_heads) != 0:
raise ValueError("hidden_size must be divisible by 2 * num_heads.")
self.hidden_size = hidden_size
self.num_heads = num_heads
self.head_size = hidden_size // (2 * num_heads)
self.scaling = self.head_size**-0.5
self.query = nn.Linear(hidden_size, hidden_size, bias=False)
self.key = nn.Linear(hidden_size, hidden_size, bias=False)
self.value = nn.Linear(hidden_size, hidden_size, bias=False)
self.output = nn.Linear(hidden_size, hidden_size, bias=False)
self.lambda_initial = _lambda_initial_value(depth)
self.lambda_q1 = nn.Parameter(torch.randn(self.head_size) * 0.1)
self.lambda_k1 = nn.Parameter(torch.randn(self.head_size) * 0.1)
self.lambda_q2 = nn.Parameter(torch.randn(self.head_size) * 0.1)
self.lambda_k2 = nn.Parameter(torch.randn(self.head_size) * 0.1)
self.sub_layer_norm = RMSNorm(2 * self.head_size, epsilon=1e-5)
def forward(
self,
values: torch.Tensor,
*,
graph_prior: torch.Tensor | None = None,
causal: bool = False,
) -> torch.Tensor:
batch_size, sequence_length, _ = values.shape
query = self.query(values).view(
batch_size, sequence_length, 2 * self.num_heads, self.head_size
)
key = self.key(values).view(batch_size, sequence_length, 2 * self.num_heads, self.head_size)
projected_value = self.value(values).view(
batch_size, sequence_length, self.num_heads, 2 * self.head_size
)
query = query.transpose(1, 2) * self.scaling
key = key.transpose(1, 2)
projected_value = projected_value.transpose(1, 2)
attention_logits = torch.matmul(query, key.transpose(-1, -2))
if causal:
mask = torch.triu(
torch.ones(
sequence_length,
sequence_length,
dtype=torch.bool,
device=values.device,
),
diagonal=1,
)
attention_logits = attention_logits.masked_fill(mask, float("-inf"))
attention = torch.softmax(attention_logits.float(), dim=-1).type_as(values)
attention = attention.view(
batch_size,
self.num_heads,
2,
sequence_length,
sequence_length,
)
lambda_one = torch.exp(torch.sum(self.lambda_q1 * self.lambda_k1))
lambda_two = torch.exp(torch.sum(self.lambda_q2 * self.lambda_k2))
differential_lambda = lambda_one - lambda_two + self.lambda_initial
differential = attention[:, :, 0] - differential_lambda * attention[:, :, 1]
if graph_prior is not None:
prior = graph_prior.to(device=values.device, dtype=values.dtype)
if prior.ndim != 2 or prior.shape != (sequence_length, sequence_length):
raise ValueError("graph_prior shape must match the attended node dimension.")
differential = differential * prior.view(1, 1, sequence_length, sequence_length)
normalizer = differential.abs().sum(dim=-1, keepdim=True).clamp_min(1e-6)
differential = differential / normalizer
attended = torch.matmul(differential, projected_value)
attended = self.sub_layer_norm(attended) * (1 - self.lambda_initial)
attended = attended.transpose(1, 2).reshape(batch_size, sequence_length, self.hidden_size)
return self.output(attended)
class AttentionBlock(nn.Module):
def __init__(
self,
hidden_size: int,
num_heads: int,
depth: int,
dropout: float,
) -> None:
super().__init__()
self.attention = MultiheadDifferentialAttention(hidden_size, num_heads, depth)
self.attention_norm = nn.LayerNorm(hidden_size)
self.feed_forward_norm = nn.LayerNorm(hidden_size)
self.feed_forward = nn.Sequential(
nn.Linear(hidden_size, hidden_size * 2),
nn.GELU(),
nn.Dropout(dropout),
nn.Linear(hidden_size * 2, hidden_size),
)
self.dropout = nn.Dropout(dropout)
def forward(
self,
values: torch.Tensor,
*,
graph_prior: torch.Tensor | None = None,
causal: bool = False,
) -> torch.Tensor:
attended = self.attention(values, graph_prior=graph_prior, causal=causal)
values = self.attention_norm(values + self.dropout(attended))
return self.feed_forward_norm(values + self.dropout(self.feed_forward(values)))
class DifferentialGraphTransformer(nn.Module):
"""Temporal differential attention followed by inter-security attention."""
def __init__(
self,
node_count: int,
window: int,
*,
hidden_size: int = 32,
num_heads: int = 2,
num_layers: int = 2,
dropout: float = 0.1,
use_spatial: bool = True,
) -> None:
super().__init__()
self.node_count = node_count
self.window = window
self.use_spatial = use_spatial and node_count > 1
self.input_projection = nn.Linear(1, hidden_size)
self.time_embedding = nn.Embedding(window, hidden_size)
self.node_embedding = nn.Embedding(node_count, hidden_size)
self.temporal_blocks = nn.ModuleList(
[AttentionBlock(hidden_size, num_heads, layer, dropout) for layer in range(num_layers)]
)
self.spatial_blocks = nn.ModuleList(
[AttentionBlock(hidden_size, num_heads, layer, dropout) for layer in range(num_layers)]
if self.use_spatial
else []
)
self.regression_head = nn.Sequential(
nn.Linear(hidden_size, hidden_size),
nn.GELU(),
nn.Dropout(dropout),
nn.Linear(hidden_size, 1),
)
def forward(self, values: torch.Tensor, graph_prior: torch.Tensor) -> torch.Tensor:
if values.ndim != 4:
raise ValueError("DGT input must have shape [batch, nodes, time, features].")
batch_size, node_count, window, feature_count = values.shape
if (node_count, window, feature_count) != (self.node_count, self.window, 1):
raise ValueError(
f"Expected [batch, {self.node_count}, {self.window}, 1], got {tuple(values.shape)}."
)
encoded = self.input_projection(values)
times = torch.arange(window, device=values.device)
nodes = torch.arange(node_count, device=values.device)
encoded = encoded + self.time_embedding(times).view(1, 1, window, -1)
encoded = encoded + self.node_embedding(nodes).view(1, node_count, 1, -1)
for layer, temporal_block in enumerate(self.temporal_blocks):
temporal = encoded.reshape(batch_size * node_count, window, -1)
temporal = temporal_block(temporal, causal=True)
encoded = temporal.reshape(batch_size, node_count, window, -1)
if self.use_spatial:
spatial = encoded.permute(0, 2, 1, 3).reshape(batch_size * window, node_count, -1)
spatial = self.spatial_blocks[layer](spatial, graph_prior=graph_prior)
encoded = spatial.reshape(batch_size, window, node_count, -1).permute(0, 2, 1, 3)
# Learning a change around the last observed close gives the model a
# strong persistence anchor while still allowing nonlinear movement.
predicted_change = self.regression_head(encoded[:, :, -1]).squeeze(-1)
return values[:, :, -1, 0] + predicted_change
def _set_seed(seed: int) -> None:
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
def _resolve_device(requested: str = "auto") -> torch.device:
normalized = requested.strip().lower()
if normalized == "auto":
if torch.cuda.is_available():
return torch.device("cuda")
if getattr(torch.backends, "mps", None) and torch.backends.mps.is_available():
return torch.device("mps")
return torch.device("cpu")
device = torch.device(normalized)
if device.type == "cuda" and not torch.cuda.is_available():
raise ValueError("CUDA was requested but is not available.")
if device.type == "mps" and not (
getattr(torch.backends, "mps", None) and torch.backends.mps.is_available()
):
raise ValueError("MPS was requested but is not available.")
return device
def _canonical_symbols(target: str, peers: Sequence[str]) -> tuple[str, ...]:
canonical_target = normalize_dse_symbol(target)
ordered = [canonical_target]
for peer in peers:
if not str(peer).strip():
continue
canonical = normalize_dse_symbol(peer)
if canonical not in ordered:
ordered.append(canonical)
return tuple(ordered)
def load_dse_market_graph(
symbol: str,
peers: Sequence[str] = ("DSEX",),
resolution: str = "1d",
*,
start: date | None = None,
end: date | None = None,
limit: int = 100_000,
client: DSEClient | None = None,
fetcher: Callable[..., tuple[Resolution, list[MarketCandle]]] = fetch_dse_candles,
) -> MarketGraphData:
"""Fetch and causally align target and peer closing prices.
Peer values are forward-filled onto target candle timestamps. Back-filling
is deliberately not used because it would leak later prices into earlier
model inputs. Leading timestamps without all requested peers are dropped.
"""
symbols = _canonical_symbols(symbol, peers)
candles_by_symbol: dict[str, list[MarketCandle]] = {}
resolved: Resolution | None = None
shared_client = client or DSEClient()
for current_symbol in symbols:
current_resolution, candles = fetcher(
current_symbol,
resolution,
start=start,
end=end,
limit=limit,
client=shared_client,
)
if resolved is None:
resolved = current_resolution
elif current_resolution.key != resolved.key:
raise ValueError("DSE returned inconsistent resolutions across graph symbols.")
candles_by_symbol[current_symbol] = candles
assert resolved is not None
target_candles = candles_by_symbol[symbols[0]]
target_times = [candle.time for candle in target_candles]
target_positions = {timestamp: index for index, timestamp in enumerate(target_times)}
matrix = np.full((len(target_times), len(symbols)), np.nan, dtype=np.float64)
for node_index, current_symbol in enumerate(symbols):
observed = {candle.time: candle.close for candle in candles_by_symbol[current_symbol]}
last_value = math.nan
for row_index, timestamp in enumerate(target_times):
if timestamp in observed:
last_value = float(observed[timestamp])
matrix[row_index, node_index] = last_value
valid_rows = np.isfinite(matrix).all(axis=1) & (matrix > 0).all(axis=1)
aligned_times = [
timestamp for timestamp, valid in zip(target_times, valid_rows, strict=True) if valid
]
aligned_candles = tuple(
target_candles[target_positions[timestamp]] for timestamp in aligned_times
)
closes = matrix[valid_rows].astype(np.float32)
if not aligned_candles:
raise ValueError("The target and peer histories have no causally aligned candles.")
return MarketGraphData(
symbol=symbols[0],
symbols=symbols,
resolution=resolved,
target_candles=aligned_candles,
closes=closes,
)
def build_graph_prior(training_closes: np.ndarray, top_k: int = 5) -> np.ndarray:
"""Build a sparse, non-negative Pearson graph from training returns only."""
prices = np.asarray(training_closes, dtype=np.float64)
if prices.ndim != 2 or prices.shape[0] < 3:
raise ValueError("At least three time rows are required to build a market graph.")
node_count = prices.shape[1]
if node_count == 1:
return np.ones((1, 1), dtype=np.float32)
returns = np.diff(np.log(np.clip(prices, 1e-8, None)), axis=0)
correlation = np.corrcoef(returns, rowvar=False)
correlation = np.nan_to_num(np.abs(correlation), nan=0.0, posinf=0.0, neginf=0.0)
np.fill_diagonal(correlation, 1.0)
keep_count = min(max(1, top_k), node_count)
sparse = np.zeros_like(correlation)
for row in range(node_count):
selected = np.argpartition(correlation[row], -keep_count)[-keep_count:]
sparse[row, selected] = correlation[row, selected]
# Make the graph undirected and always retain self loops.
sparse = np.maximum(sparse, sparse.T)
np.fill_diagonal(sparse, 1.0)
row_sum = sparse.sum(axis=1, keepdims=True)
return (sparse / np.maximum(row_sum, 1e-8)).astype(np.float32)
def _make_supervised_samples(
scaled_closes: np.ndarray,
window: int,
target_indices: Sequence[int],
) -> tuple[torch.Tensor, torch.Tensor]:
features = np.stack(
[scaled_closes[index - window : index].T[..., np.newaxis] for index in target_indices]
).astype(np.float32)
targets = np.stack([scaled_closes[index] for index in target_indices]).astype(np.float32)
return torch.from_numpy(features), torch.from_numpy(targets)
def _new_model(
node_count: int, config: DGTConfig, device: torch.device
) -> DifferentialGraphTransformer:
return DifferentialGraphTransformer(
node_count=node_count,
window=config.window,
hidden_size=config.hidden_size,
num_heads=config.num_heads,
num_layers=config.num_layers,
dropout=config.dropout,
use_spatial=config.use_spatial,
).to(device)
def _split_positions(point_count: int, config: DGTConfig) -> tuple[int, int]:
split_index = int(point_count * config.split_ratio)
context_samples = split_index - config.window
minimum_train_samples = max(4, min(config.batch_size, 16))
if context_samples < minimum_train_samples + 1 or split_index >= point_count:
required = math.ceil((config.window + minimum_train_samples + 1) / config.split_ratio)
raise ValueError(
f"DGT needs at least {required} aligned bars for window={config.window} and "
f"split={config.split_ratio:.0%}; received {point_count}."
)
validation_samples = max(1, int(round(context_samples * config.validation_ratio)))
validation_samples = min(validation_samples, context_samples - minimum_train_samples)
validation_start = split_index - validation_samples
return split_index, validation_start
def _train_model(
scaled_closes: np.ndarray,
graph_prior: np.ndarray,
config: DGTConfig,
validation_start: int,
split_index: int,
device: torch.device,
*,
progress: Callable[[str], None] | None = print,
) -> tuple[DifferentialGraphTransformer, TrainingSummary, np.ndarray]:
train_indices = list(range(config.window, validation_start))
validation_indices = list(range(validation_start, split_index))
train_x, train_y = _make_supervised_samples(scaled_closes, config.window, train_indices)
validation_x, validation_y = _make_supervised_samples(
scaled_closes, config.window, validation_indices
)
generator = torch.Generator().manual_seed(config.seed)
train_loader = DataLoader(
TensorDataset(train_x, train_y),
batch_size=min(config.batch_size, len(train_x)),
shuffle=True,
generator=generator,
)
model = _new_model(scaled_closes.shape[1], config, device)
adjacency = torch.from_numpy(graph_prior).to(device)
optimizer = torch.optim.AdamW(
model.parameters(),
lr=config.learning_rate,
weight_decay=config.weight_decay,
)
best_state = copy.deepcopy(model.state_dict())
best_validation = float("inf")
best_epoch = 0
stale_epochs = 0
epochs_ran = 0
for epoch in range(1, config.epochs + 1):
model.train()
training_loss = 0.0
for batch_x, batch_y in train_loader:
batch_x = batch_x.to(device)
batch_y = batch_y.to(device)
optimizer.zero_grad(set_to_none=True)
predicted = model(batch_x, adjacency)
loss = F.mse_loss(predicted, batch_y)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
training_loss += loss.item() * len(batch_x)
model.eval()
with torch.no_grad():
validation_prediction = model(validation_x.to(device), adjacency)
validation_loss = F.mse_loss(validation_prediction, validation_y.to(device)).item()
epochs_ran = epoch
mean_training_loss = training_loss / len(train_x)
if progress and (epoch == 1 or epoch % 10 == 0):
progress(
f"epoch {epoch:03d} | train MSE {mean_training_loss:.6f} | "
f"validation MSE {validation_loss:.6f}"
)
if validation_loss < best_validation - 1e-7:
best_validation = validation_loss
best_epoch = epoch
best_state = copy.deepcopy(model.state_dict())
stale_epochs = 0
else:
stale_epochs += 1
if stale_epochs >= config.patience:
break
model.load_state_dict(best_state)
model.eval()
with torch.no_grad():
validation_prediction = model(validation_x.to(device), adjacency).cpu().numpy()
summary = TrainingSummary(
best_epoch=best_epoch,
epochs_ran=epochs_ran,
best_validation_mse=float(best_validation),
device=str(device),
parameter_count=sum(parameter.numel() for parameter in model.parameters()),
train_samples=len(train_indices),
validation_samples=len(validation_indices),
future_refit_epochs=0,
graph_symbols=(), # populated by the pipeline once symbols are known
)
return model, summary, validation_prediction
def _refit_model_for_future(
scaled_closes: np.ndarray,
graph_prior: np.ndarray,
config: DGTConfig,
epochs: int,
device: torch.device,
*,
progress: Callable[[str], None] | None = print,
) -> DifferentialGraphTransformer:
"""Fit a fresh deployment model on every real bar after backtest scoring."""
_set_seed(config.seed)
target_indices = list(range(config.window, len(scaled_closes)))
features, targets = _make_supervised_samples(scaled_closes, config.window, target_indices)
loader = DataLoader(
TensorDataset(features, targets),
batch_size=min(config.batch_size, len(features)),
shuffle=True,
generator=torch.Generator().manual_seed(config.seed),
)
model = _new_model(scaled_closes.shape[1], config, device)
adjacency = torch.from_numpy(graph_prior).to(device)
optimizer = torch.optim.AdamW(
model.parameters(),
lr=config.learning_rate,
weight_decay=config.weight_decay,
)
refit_epochs = max(1, epochs)
for epoch in range(1, refit_epochs + 1):
model.train()
total_loss = 0.0
for batch_x, batch_y in loader:
batch_x = batch_x.to(device)
batch_y = batch_y.to(device)
optimizer.zero_grad(set_to_none=True)
loss = F.mse_loss(model(batch_x, adjacency), batch_y)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
total_loss += loss.item() * len(batch_x)
if progress and (epoch == 1 or epoch % 10 == 0 or epoch == refit_epochs):
progress(
f"future refit epoch {epoch:03d}/{refit_epochs:03d} | "
f"train MSE {total_loss / len(features):.6f}"
)
model.eval()
return model
def _recursive_forecast(
model: DifferentialGraphTransformer,
scaled_context: np.ndarray,
graph_prior: np.ndarray,
window: int,
horizon: int,
device: torch.device,
) -> np.ndarray:
if len(scaled_context) < window:
raise ValueError("Forecast context is shorter than the model window.")
history = [row.copy() for row in np.asarray(scaled_context, dtype=np.float32)]
predictions: list[np.ndarray] = []
adjacency = torch.from_numpy(graph_prior).to(device)
model.eval()
with torch.no_grad():
for _ in range(horizon):
model_input = np.asarray(history[-window:], dtype=np.float32).T[
np.newaxis, ..., np.newaxis
]
predicted = model(torch.from_numpy(model_input).to(device), adjacency)[0]
# Prevent an unstable recursive path from escaping far beyond the
# training scale while still allowing substantial new movement.
next_row = predicted.clamp(-8.0, 8.0).cpu().numpy().astype(np.float32)
history.append(next_row)
predictions.append(next_row)
return np.stack(predictions)
def _future_timestamps(last_time: datetime, resolution: Resolution, count: int) -> list[datetime]:
if resolution.key == "1d":
timestamps: list[datetime] = []
candidate = last_time
while len(timestamps) < count:
candidate += timedelta(days=1)
# DSE's regular week is Sunday through Thursday.
if candidate.weekday() not in {4, 5}:
timestamps.append(candidate)
return timestamps
return [
last_time + timedelta(seconds=resolution.seconds * step) for step in range(1, count + 1)
]
def _prediction_intervals(
point: np.ndarray,
validation_residuals: np.ndarray,
) -> tuple[np.ndarray, np.ndarray]:
residuals = np.asarray(validation_residuals, dtype=np.float64)
radius = float(np.quantile(np.abs(residuals), 0.8)) if residuals.size else 0.0
horizon_scale = np.sqrt(np.arange(1, len(point) + 1, dtype=np.float64))
widths = radius * horizon_scale
lower = np.maximum(0.0, np.asarray(point, dtype=np.float64) - widths)
upper = np.asarray(point, dtype=np.float64) + widths
return lower.astype(np.float32), upper.astype(np.float32)
def run_dgt_prediction(
symbol: str,
resolution: str = "1d",
*,
peers: Sequence[str] = ("DSEX",),
start: date | None = None,
end: date | None = None,
limit: int = 100_000,
config: DGTConfig | None = None,
device: str = "auto",
market_data: MarketGraphData | None = None,
progress: Callable[[str], None] | None = print,
) -> ForecastRun:
"""Fetch DSE data, train DGT, backtest it, and forecast future bars."""
settings = config or DGTConfig()
settings.validate()
_set_seed(settings.seed)
graph_data = market_data or load_dse_market_graph(
symbol,
peers,
resolution,
start=start,
end=end,
limit=limit,
)
if graph_data.closes.ndim != 2:
raise ValueError("Market close data must have shape [time, graph nodes].")
if graph_data.closes.shape != (
len(graph_data.target_candles),
len(graph_data.symbols),
):
raise ValueError("Candle, symbol, and close-matrix dimensions are inconsistent.")
if not np.isfinite(graph_data.closes).all() or np.any(graph_data.closes <= 0):
raise ValueError("Market close data must contain only finite positive prices.")
split_index, validation_start = _split_positions(len(graph_data.closes), settings)
# Scaling and graph estimation end before validation begins; neither sees
# validation or held-out prices.
scaler = PriceScaler.fit(graph_data.closes[:validation_start])
scaled_closes = scaler.transform(graph_data.closes)
graph_prior = build_graph_prior(
graph_data.closes[:validation_start], top_k=settings.graph_top_k
)
resolved_device = _resolve_device(device)
if progress:
progress(
f"training DGT on {resolved_device} with {len(graph_data.closes)} aligned bars, "
f"{len(graph_data.symbols)} graph nodes, and a {settings.window}-bar window"
)
model, raw_summary, validation_prediction_scaled = _train_model(
scaled_closes,
graph_prior,
settings,
validation_start,
split_index,
resolved_device,
progress=progress,
)
validation_prediction = scaler.inverse_transform(validation_prediction_scaled)[:, 0]
validation_actual = graph_data.closes[validation_start:split_index, 0]
validation_residuals = validation_actual - validation_prediction
backtest_scaled = _recursive_forecast(
model,
scaled_closes[:split_index],
graph_prior,
settings.window,
len(graph_data.closes) - split_index,
resolved_device,
)
backtest_prediction = scaler.inverse_transform(backtest_scaled)[:, 0]
actual = graph_data.closes[split_index:, 0]
backtest_q10, backtest_q90 = _prediction_intervals(backtest_prediction, validation_residuals)
metrics = calculate_accuracy_metrics(
actual,
backtest_prediction,
backtest_q10,
backtest_q90,
last_context_value=float(graph_data.closes[split_index - 1, 0]),
)
deployment_model = model
deployment_scaler = scaler
deployment_graph = graph_prior
deployment_scaled_closes = scaled_closes
refit_epochs = 0
if settings.refit_for_future:
if progress:
progress("backtest scoring complete; refitting a deployment model on all real bars")
deployment_scaler = PriceScaler.fit(graph_data.closes)
deployment_scaled_closes = deployment_scaler.transform(graph_data.closes)
deployment_graph = build_graph_prior(graph_data.closes, top_k=settings.graph_top_k)
refit_epochs = max(1, raw_summary.best_epoch)
deployment_model = _refit_model_for_future(
deployment_scaled_closes,
deployment_graph,
settings,
refit_epochs,
resolved_device,
progress=progress,
)
future_scaled = _recursive_forecast(
deployment_model,
deployment_scaled_closes,
deployment_graph,
settings.window,
settings.future_steps,
resolved_device,
)
future_prediction = deployment_scaler.inverse_transform(future_scaled)[:, 0]
future_q10, future_q90 = _prediction_intervals(future_prediction, actual - backtest_prediction)
summary = TrainingSummary(
**{
**asdict(raw_summary),
"future_refit_epochs": refit_epochs,
"graph_symbols": graph_data.symbols,
}
)
history = [
CandlePoint(
time=candle.time,
open=candle.open,
high=candle.high,
low=candle.low,
close=candle.close,
volume=candle.volume,
segment="context" if index < split_index else "holdout",
)
for index, candle in enumerate(graph_data.target_candles)
]
backtest = []
for offset, candle in enumerate(graph_data.target_candles[split_index:]):
predicted = float(backtest_prediction[offset])
actual_value = float(candle.close)
absolute_error = abs(predicted - actual_value)
backtest.append(
BacktestPoint(
time=candle.time,
actual=actual_value,
predicted=predicted,
q10=float(backtest_q10[offset]),
q50=predicted,
q90=float(backtest_q90[offset]),
error=predicted - actual_value,
absolute_error=absolute_error,
absolute_percentage_error=(
absolute_error / abs(actual_value) * 100 if actual_value else None
),
)
)
future = [
ForecastPoint(
time=forecast_time,
predicted=float(future_prediction[index]),
q10=float(future_q10[index]),
q50=float(future_prediction[index]),
q90=float(future_q90[index]),
)
for index, forecast_time in enumerate(
_future_timestamps(
graph_data.target_candles[-1].time,
graph_data.resolution,
settings.future_steps,
)
)
]
generated_at = datetime.now(timezone.utc)
run_id = (
f"dgt-{graph_data.symbol.lower()}-{graph_data.resolution.key}-"
f"{generated_at:%Y%m%dT%H%M%SZ}-{uuid4().hex[:8]}"
)
runtime_config = get_config()
gateway = str(runtime_config.get("dse_gateway_url") or DEFAULT_DSE_GATEWAY_URL).rstrip("/")
result = TimesFMPredictionResult(
run_id=run_id,
generated_at=generated_at,
symbol=graph_data.symbol,
model=ModelMetadata(
name="Differential Graph Transformer",
version="DGT-DSE-1.0",
checkpoint=f"dgt_forecasts/{run_id}/model.pt",
parameters=summary.parameter_count,
device=str(resolved_device),
gpu_name=(
torch.cuda.get_device_name(resolved_device)
if resolved_device.type == "cuda"
else None
),
max_context=settings.window,
max_horizon=max(len(backtest), len(future)),
recursive_chunks=2,
),
data=DataMetadata(
vendor="Doha Securities DSE gateway",
endpoint="/market-analytics-service/v1/candlesticks/limited",
symbol=graph_data.symbol,
requested_resolution=graph_data.resolution.key,
server_resolution=graph_data.resolution.server_value,
resolution_label=graph_data.resolution.label,
first_timestamp=graph_data.target_candles[0].time,
last_timestamp=graph_data.target_candles[-1].time,
total_points=len(graph_data.target_candles),
context_points=split_index,
holdout_points=len(graph_data.target_candles) - split_index,
split_ratio=settings.split_ratio,
),
metrics=metrics,
history=history,
backtest=backtest,
future=future,
live_feed=LiveFeedMetadata(
enabled=True,
url=f"{gateway}/notificationservice/ws-notification",
topic="/topic/stock-updates",
stock_code=f"{graph_data.symbol}'PB",
note=(
"The UI compares live DSE updates for this symbol with the nearest "
"Differential Graph Transformer future forecast."
),
),
disclaimer=(
"The Differential Graph Transformer is an experimental statistical model, "
"not investment advice. Backtest results do not guarantee future performance."
),
)
model_state = {
name: value.detach().cpu() for name, value in deployment_model.state_dict().items()
}
model_config = {
"dgt": asdict(settings),
"symbols": list(graph_data.symbols),
"resolution": graph_data.resolution.key,
"scaler_mean": deployment_scaler.mean.tolist(),
"scaler_scale": deployment_scaler.scale.tolist(),
"graph_prior": deployment_graph.tolist(),
}
return ForecastRun(result, summary, model_state, model_config)
def save_forecast_run(
run: ForecastRun,
output_dir: str | Path,
*,
make_plot: bool = True,
) -> dict[str, Path]:
"""Save the checkpoint, real-vs-predicted CSV, future CSV, and chart."""
directory = Path(output_dir)
directory.mkdir(parents=True, exist_ok=True)
result = run.result
paths = {
"json": directory / "prediction.json",
"checkpoint": directory / "model.pt",
"comparison": directory / "backtest_comparison.csv",
"future": directory / "future_forecast.csv",
}
paths["json"].write_text(result.model_dump_json(indent=2), encoding="utf-8")
torch.save(
{
"state_dict": run.model_state,
"model_config": run.model_config,
"training_summary": asdict(run.summary),
"run_id": result.run_id,
},
paths["checkpoint"],
)
with paths["comparison"].open("w", newline="", encoding="utf-8") as stream:
writer = csv.writer(stream)
writer.writerow(
[
"time",
"actual",
"predicted",
"q10",
"q90",
"error",
"absolute_error",
"absolute_percentage_error",
]
)
for point in result.backtest:
writer.writerow(
[
point.time.isoformat(),
point.actual,
point.predicted,
point.q10,
point.q90,
point.error,
point.absolute_error,
point.absolute_percentage_error,
]
)
with paths["future"].open("w", newline="", encoding="utf-8") as stream:
writer = csv.writer(stream)
writer.writerow(["time", "predicted", "q10", "q50", "q90"])
for point in result.future:
writer.writerow(
[point.time.isoformat(), point.predicted, point.q10, point.q50, point.q90]
)
if make_plot:
try:
import matplotlib.pyplot as plt
except ImportError as exc:
raise RuntimeError(
"matplotlib is required for plots; install the dgt extra or use --no-plot."
) from exc
plot_path = directory / "actual_vs_predicted.png"
context = result.history[: result.data.context_points]
figure, axis = plt.subplots(figsize=(13, 7))
axis.plot(
[point.time for point in context],
[point.close for point in context],
color="#64748b",
linewidth=1.2,
label="Training context",
)
axis.plot(
[point.time for point in result.backtest],
[point.actual for point in result.backtest],
color="#16a34a",
linewidth=1.8,
label="Real holdout",
)
axis.plot(
[point.time for point in result.backtest],
[point.predicted for point in result.backtest],
color="#2563eb",
linewidth=1.8,
label="DGT holdout prediction",
)
axis.fill_between(
[point.time for point in result.backtest],
[point.q10 for point in result.backtest],
[point.q90 for point in result.backtest],
color="#2563eb",
alpha=0.12,
)
axis.plot(
[point.time for point in result.future],
[point.predicted for point in result.future],
color="#f97316",
linestyle="--",
linewidth=2,
marker="o",
markersize=3,
label="DGT future forecast",
)
axis.fill_between(
[point.time for point in result.future],
[point.q10 for point in result.future],
[point.q90 for point in result.future],
color="#f97316",
alpha=0.12,
)
axis.axvline(result.backtest[0].time, color="#0f172a", linestyle=":", alpha=0.6)
axis.axvline(result.future[0].time, color="#f97316", linestyle=":", alpha=0.6)
axis.set_title(f"{result.symbol}: real prices, DGT backtest, and future forecast")
axis.set_xlabel("Date")
axis.set_ylabel(f"Closing price ({result.currency})")
axis.grid(alpha=0.2)
axis.legend()
figure.autofmt_xdate()
figure.tight_layout()
figure.savefig(plot_path, dpi=160)
plt.close(figure)
paths["plot"] = plot_path
return paths
_LOOKBACK_RE = re.compile(r"^(?P<count>[1-9]\d*)(?P<unit>d|w|mo|y)$")
def _lookback_start(end_date: date, lookback: str) -> date | None:
value = str(lookback or "").strip().lower()
if value in {"all", "max"}:
return None
match = _LOOKBACK_RE.fullmatch(value)
if match is None:
raise ValueError("lookback must look like 90d, 52w, 24mo, 2y, or max.")
count = int(match.group("count"))
unit = match.group("unit")
if unit == "d":
return end_date - timedelta(days=count)
if unit == "w":
return end_date - timedelta(weeks=count)
if unit == "y":
try:
return end_date.replace(year=end_date.year - count)
except ValueError:
return end_date.replace(year=end_date.year - count, day=28)
month_index = end_date.year * 12 + end_date.month - 1 - count
year, zero_based_month = divmod(month_index, 12)
month = zero_based_month + 1
day = min(end_date.day, monthrange(year, month)[1])
return end_date.replace(year=year, month=month, day=day)
def _argument_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description=(
"Train a Differential Graph Transformer on Doha Securities DSE candles, "
"compare it with held-out real data, and forecast future bars."
)
)
parser.add_argument("symbol", help="DSE symbol, for example GP or BRACBANK.")
parser.add_argument(
"--peers",
default="DSEX",
help="Comma-separated related DSE symbols used as graph nodes (default: DSEX).",
)
parser.add_argument(
"--resolution",
"-r",
default="1d",
help="1min, 15min, 30min, 1h, 1d, 1w, 1mo, or 1y.",
)
parser.add_argument("--start", help="First historical date (YYYY-MM-DD).")
parser.add_argument("--end", help="Final historical date (YYYY-MM-DD).")
parser.add_argument(
"--lookback",
help="History ending at --end/today: 90d, 52w, 24mo, 2y, or max (default: 2y).",
)
parser.add_argument("--limit", type=int, default=100_000)
parser.add_argument("--split", type=float, default=0.8, dest="split_ratio")
parser.add_argument("--validation-split", type=float, default=0.15)
parser.add_argument("--window", type=int, default=32, help="Past bars per model input.")
parser.add_argument("--future-steps", type=int, default=12)
parser.add_argument("--epochs", type=int, default=80)
parser.add_argument("--patience", type=int, default=12)
parser.add_argument("--batch-size", type=int, default=32)
parser.add_argument("--learning-rate", type=float, default=1e-3)
parser.add_argument("--weight-decay", type=float, default=1e-5)
parser.add_argument("--hidden-size", type=int, default=32)
parser.add_argument("--heads", type=int, default=2)
parser.add_argument("--layers", type=int, default=2)
parser.add_argument("--dropout", type=float, default=0.1)
parser.add_argument("--graph-top-k", type=int, default=5)
parser.add_argument("--no-spatial", action="store_true")
parser.add_argument(
"--no-refit",
action="store_true",
help="Do not refit the deployment model on all real bars before future prediction.",
)
parser.add_argument("--device", default="auto", help="auto, cpu, cuda, cuda:0, or mps.")
parser.add_argument("--seed", type=int, default=42)
parser.add_argument("--output-dir", type=Path)
parser.add_argument("--output-json", type=Path)
parser.add_argument("--no-plot", action="store_true")
parser.add_argument("--open-ui", action="store_true")
parser.add_argument("--host", default="127.0.0.1")
parser.add_argument("--port", type=int, default=8000)
return parser
def _print_result(run: ForecastRun, paths: dict[str, Path], repository_path: Path) -> None:
result = run.result
metrics = result.metrics
print("\nHeld-out real data vs DGT prediction")
print(f" Accuracy (100 - sMAPE): {metrics.accuracy_score:.2f}%")
print(f" MAE: {metrics.mae:.4f} BDT")
print(f" RMSE: {metrics.rmse:.4f} BDT")
print(f" Directional accuracy: {(metrics.directional_accuracy_percent or 0.0):.2f}%")
print(f" Skill vs naive: {(metrics.skill_vs_naive_percent or 0.0):.2f}%")
print(
f" Split: {result.data.context_points} context / "
f"{result.data.holdout_points} real holdout bars"
)
print(
f" Training: best epoch {run.summary.best_epoch}, "
f"{run.summary.parameter_count:,} parameters on {run.summary.device}"
)
print(f" Graph: {', '.join(run.summary.graph_symbols)}")
print("\nFuture forecast")
print(" time predicted q10 q90")
for point in result.future:
print(
f" {point.time.isoformat():25s} {point.predicted:9.4f} "
f"{point.q10:9.4f} {point.q90:9.4f}"
)
print(f"\nSaved dashboard/API JSON: {repository_path}")
for name, path in paths.items():
print(f"Saved {name:10s}: {path}")
def main(argv: Sequence[str] | None = None) -> int:
args = _argument_parser().parse_args(argv)
if args.start and args.lookback:
raise ValueError("Use either --start or --lookback, not both.")
end_date = date.fromisoformat(args.end) if args.end else date.today()
start_date = (
date.fromisoformat(args.start)
if args.start
else _lookback_start(end_date, args.lookback or "2y")
)
peers = tuple(value.strip() for value in args.peers.split(",") if value.strip())
config = DGTConfig(
window=args.window,
split_ratio=args.split_ratio,
validation_ratio=args.validation_split,
future_steps=args.future_steps,
epochs=args.epochs,
patience=args.patience,
batch_size=args.batch_size,
learning_rate=args.learning_rate,
weight_decay=args.weight_decay,
hidden_size=args.hidden_size,
num_heads=args.heads,
num_layers=args.layers,
dropout=args.dropout,
graph_top_k=args.graph_top_k,
use_spatial=not args.no_spatial,
refit_for_future=not args.no_refit,
seed=args.seed,
)
run = run_dgt_prediction(
args.symbol,
args.resolution,
peers=peers,
start=start_date,
end=end_date,
limit=args.limit,
config=config,
device=args.device,
)
repository = PredictionRepository(DEFAULT_CONFIG["results_dir"])
repository_path = repository.save(run.result)
if args.output_json:
repository.save(run.result, args.output_json)
output_dir = args.output_dir or (
Path(DEFAULT_CONFIG["results_dir"]) / "dgt_forecasts" / run.result.run_id
)
paths = save_forecast_run(run, output_dir, make_plot=not args.no_plot)
_print_result(run, paths, repository_path)
if args.open_ui:
from dohasecuritiesstockai.dashboard import launch_prediction_dashboard
launch_prediction_dashboard(run.result.run_id, host=args.host, port=args.port)
return 0
if __name__ == "__main__":
raise SystemExit(main())
"""Filesystem persistence for chart-ready TimesFM prediction runs.""" """Filesystem persistence for chart-ready prediction runs."""
from __future__ import annotations from __future__ import annotations
......
...@@ -51,6 +51,10 @@ timesfm = [ ...@@ -51,6 +51,10 @@ timesfm = [
"einshape>=1.0.0", "einshape>=1.0.0",
"utilsforecast>=0.1.10", "utilsforecast>=0.1.10",
] ]
dgt = [
"torch>=2.2.0",
"matplotlib>=3.8.0",
]
[project.scripts] [project.scripts]
# Product commands plus legacy executable aliases for existing scripts. # Product commands plus legacy executable aliases for existing scripts.
...@@ -61,6 +65,7 @@ dohasecuritiesstockai-api = "dohasecuritiesstockai.api.__main__:main" ...@@ -61,6 +65,7 @@ dohasecuritiesstockai-api = "dohasecuritiesstockai.api.__main__:main"
tradingagents-api = "dohasecuritiesstockai.api.__main__:main" tradingagents-api = "dohasecuritiesstockai.api.__main__:main"
dohasecuritiesstockai-predict = "dohasecuritiesstockai.timesfm_forecasting.cli:main" dohasecuritiesstockai-predict = "dohasecuritiesstockai.timesfm_forecasting.cli:main"
tradingagents-predict = "dohasecuritiesstockai.timesfm_forecasting.cli:main" tradingagents-predict = "dohasecuritiesstockai.timesfm_forecasting.cli:main"
dohasecuritiesstockai-dgt-predict = "dohasecuritiesstockai.dgt_forecasting.cli:main"
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
include = ["dohasecuritiesstockai*", "cli*"] include = ["dohasecuritiesstockai*", "cli*"]
......
from __future__ import annotations
from datetime import datetime, timedelta, timezone
import numpy as np
import torch
import dohasecuritiesstockai.dgt_forecasting as dgt
from dohasecuritiesstockai.timesfm_forecasting.market_data import (
MarketCandle,
normalize_resolution,
)
def _candles(values: list[float], *, start_day: int = 0) -> list[MarketCandle]:
start = datetime(2025, 1, 1, tzinfo=timezone.utc)
return [
MarketCandle(
time=start + timedelta(days=start_day + index),
open=value - 0.5,
high=value + 1,
low=value - 1,
close=value,
volume=1000 + index,
)
for index, value in enumerate(values)
]
def test_market_graph_alignment_forward_fills_without_back_filling():
payloads = {
"GP": _candles([10, 11, 12, 13, 14]),
"DSEX": _candles([100, 102, 104], start_day=2),
}
def fake_fetcher(symbol, resolution, **kwargs):
del kwargs
return normalize_resolution(resolution), payloads[symbol]
graph = dgt.load_dse_market_graph(
"GP",
("DSEX",),
"1d",
fetcher=fake_fetcher,
)
# The first two target dates are dropped, not back-filled from DSEX day 3.
assert [candle.close for candle in graph.target_candles] == [12, 13, 14]
np.testing.assert_array_equal(graph.closes[:, 1], [100, 102, 104])
def test_graph_prior_uses_top_correlations_and_is_row_normalized():
prices = np.array(
[
[10, 20, 30],
[11, 22, 29],
[12, 24, 31],
[13, 26, 28],
[14, 28, 32],
],
dtype=np.float32,
)
prior = dgt.build_graph_prior(prices, top_k=2)
assert prior.shape == (3, 3)
assert np.all(prior >= 0)
np.testing.assert_allclose(prior.sum(axis=1), 1.0, atol=1e-6)
assert np.all(np.diag(prior) > 0)
def test_dgt_forward_returns_one_prediction_per_graph_node():
model = dgt.DifferentialGraphTransformer(
node_count=3,
window=8,
hidden_size=8,
num_heads=1,
num_layers=1,
dropout=0,
)
features = torch.randn(4, 3, 8, 1)
prior = torch.eye(3)
prediction = model(features, prior)
assert prediction.shape == (4, 3)
assert torch.isfinite(prediction).all()
def test_end_to_end_run_builds_real_comparison_and_future_forecast(tmp_path):
point_count = 55
step = np.arange(point_count, dtype=np.float32)
target = 100 + 0.2 * step + np.sin(step / 5)
benchmark = 6000 + 2 * step + 10 * np.sin(step / 6)
market = dgt.MarketGraphData(
symbol="GP",
symbols=("GP", "DSEX"),
resolution=normalize_resolution("1d"),
target_candles=tuple(_candles(target.tolist())),
closes=np.column_stack((target, benchmark)).astype(np.float32),
)
config = dgt.DGTConfig(
window=6,
split_ratio=0.8,
validation_ratio=0.2,
future_steps=3,
epochs=1,
patience=1,
batch_size=16,
hidden_size=8,
num_heads=1,
num_layers=1,
dropout=0,
)
run = dgt.run_dgt_prediction(
"GP", config=config, device="cpu", market_data=market, progress=None
)
assert len(run.result.history) == point_count
assert len(run.result.backtest) == 11
assert len(run.result.future) == 3
assert run.result.backtest[0].actual == market.target_candles[44].close
assert run.result.model.name == "Differential Graph Transformer"
assert run.summary.graph_symbols == ("GP", "DSEX")
assert run.summary.future_refit_epochs == 1
paths = dgt.save_forecast_run(run, tmp_path, make_plot=False)
assert set(paths) == {"json", "checkpoint", "comparison", "future"}
assert all(path.is_file() for path in paths.values())
checkpoint = torch.load(paths["checkpoint"], map_location="cpu", weights_only=True)
assert checkpoint["run_id"] == run.result.run_id
assert checkpoint["model_config"]["symbols"] == ["GP", "DSEX"]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment